home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / clipper / doors10.zip / DOORS.501 / DOORS.DOC next >
Text File  |  1993-06-13  |  76KB  |  1,804 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.          ▄▄▄▄▄▄▄                                     Keep our Earth green,
  13.          ██     █                                    Our air clean,
  14.          ██    .█                           █▀▀▀▀    and code lean and mean.
  15.          ██     █   ▄▄▄▄▄   ▄▄▄▄▄   █▄▄▄▄   █▄▄▄▄
  16.          ██     █   █   █   █   █   █   ▀       █    Re-cycle and RE - USE.
  17.          ▀▀▀▀▀▀▀    ▀▀▀▀▀   ▀▀▀▀▀   ▀       ▀▀▀▀▀
  18.  
  19.  
  20.                        Copyright (C) 1991, 92, 93
  21.                             Codesmythe, Inc.
  22.                           All Rights Reserved.
  23.                           CSERVE [73057,3204]
  24.                              (214) 319-8517
  25.  
  26.                          DOORSxxx.ZIP   License
  27.  
  28.      Copyright (c) 1993 Codesmythe, Inc. All Rights Reserved.
  29.  
  30.      This product has been redered to the PUBLIC DOMAIN. You are free to
  31.      use, copy and distribute DOORSxxx.ZIP providing that:
  32.  
  33.           NO FEE IS CHARGED FOR USE, COPYING OR DISTRIBUTION.
  34.  
  35.           IT IS NOT MODIFIED IN ANY WAY.
  36.  
  37.           ALL DOCUMENTATION FILES ARE (UNMODIFIED) AND ACCOMPANY ALL COPIES.
  38.  
  39.      This program is provided AS IS without any warranty, expressed or
  40.      implied, including but not limited to fitness for a particular
  41.      purpose.
  42.  
  43.      dBASE II, dBASE III, dBASE IV are trademarks of Ashton-Tate. Clipper is a
  44.      trademark of Computer Associates.  FoxBASE, FoxBASE+ and FoxPro are
  45.      trademarks of Microsoft Corp.
  46.  
  47.      For Warrantee information please refer to LICENSE.DOC
  48.  
  49.  
  50.  
  51.  
  52.                                DOORS.LIB
  53.  
  54.                            TABLE of CONTENTS
  55.  
  56. TOPIC                                                             PAGE
  57. ──────────────────────────────────────────────────────────────────────
  58.  
  59. I.  INTRODUCTION TO / PURPOSE OF DOORS                              1
  60.  
  61. II. FEATURES OF DOORS                                               1
  62.  
  63. III. USING DOORS                                                    2
  64.     A. Installation.                                                2
  65.     B. Out of the Box.                                              2
  66.     C.  HOW THE LIBRARY IS ORGANIZED (DF VS. DP VS. DB)             3
  67.     D. INCLUDING HEADER FILES and 1ST Level Optimization.           3
  68.     E. REGS and SREGS                                               5
  69.     F.  LINKING WITH DOORS                                          5
  70.  
  71. IV. MULTIPLE DEVELOPER LEVELS.                                      6
  72.     A.  USING HEADER FILES                                          6
  73.     B.  CHANGING HEADER FILES                                       7
  74.         1.  MODIFYING #XTRANSLATES                                  8
  75.         2.  CREATING #XTRANSLATES                                   8
  76.     C.  CREATING NEW LIBRARY FUNCTIONS                              8
  77.     D.  OPTIMIZING for SIZE or SPEED                                8
  78.  
  79. V.  SOME PITFALLS IN USING DOORS                                    9
  80.     A.  DONT GET BIT BY AN INTERRUPT                                9
  81.     B. WARNINGS ON INLINE OPERATORS (++)                            9
  82.     C. SCOPE                                                        9
  83.  
  84. VI. MODIFYING SUPPLIED CODE                                        10
  85.     A. WHY?                                                        10
  86.     B. WHEN?                                                       10
  87.     C. MAINTAINABILITY                                             10
  88.  
  89. VII. ADVANCED TOPICS.                                              11
  90.      A. Networking                                                 11
  91.      C. Fonts                                                      11
  92.      D. Mouse                                                      11
  93.      E. Memory Accessing                                           11
  94.  
  95. VIII. FUNCTIONS.                                                   12
  96.    A. DF_DOS.                                                      12
  97.    B. DF_AT.                                                       14
  98.    C. DF_PSEC()                                                    15
  99.    D. DF_ASCVAL()                                                  15
  100.  
  101.                                    i
  102.  
  103.  
  104.                            TABLE of CONTENTS
  105.  
  106. TOPIC                                                             PAGE
  107. ──────────────────────────────────────────────────────────────────────
  108.  
  109. IX. DOS.CH DP_ Pseudo Function Calls.                              16
  110.    A. dp_ver()                                                     16
  111.    B. dp_curdrive()                                                16
  112.    C. dp_driveno(<x>)                                              17
  113.    D. dp_changedrive(<x>)                                          17
  114.    E. dp_lastdrive()                                               17
  115.    F. dp_drivesize([<x>])                                          18
  116.    G. dp_curdir([<x>])                                             18
  117.    H. dp_mkdir(<x>)                                                19
  118.    I. dp_rmdir(<x>)                                                19
  119.    J. dp_chdir(<x>)                                                19
  120.    K. dp_getdate()                                                 20
  121.    L. dp_setdate( <ddate> [,<day> ,<yr>] )                         20
  122.    M. dp_gettime()                                                 21
  123.    N. dp_settime( <hr> [,<min> ] [, <sec>] )                       21
  124.    O. dp_isverify()                                                22
  125.    P. dp_setverify(<x>)                                            23
  126.    Q. dp_getpsp() =>                                               23
  127.    R. dp_getcmdline()                                              23
  128.    S. dp_maxfiles()                                                24
  129.  
  130.  
  131. X. THE FUTURE of DOORS.                                            25
  132.  
  133.    APPENDICIES                                                     26
  134.  
  135.                                    ii
  136.  
  137.  
  138.                                DOORS.LIB
  139.  
  140.  
  141. I.  INTRODUCTION TO / PURPOSE OF DOORS
  142.  
  143.         Thank you for purchasing Doors, the only user expandable
  144.     programming library for Clipper.  Doors is a library that gives Clipper
  145.     programmers access to low level operating system calls and routines to
  146.     allow a graceful extension to the capabilities of their Clipper
  147.     programs. At the heart of Doors are a select number of reliable and
  148.     efficient routines.  These provide a firm foundation for a library
  149.     that can be molded to meet your specific needs.  Before you can start
  150.     using Doors to its full potential, you need to be introduced to the
  151.     ideas behind Doors and the way Doors works.  The following sections are
  152.     designed to give you a running start in using Doors.  If you would
  153.     prefer to skip the manual and simply "wing it" -- at least read the
  154.     overview and consult the online documentation when necessary.  Thanks
  155.     again for your support.  We at Codesmythe hope that Doors will play a
  156.     large role in the development of your Clipper applications.
  157.  
  158.  
  159.  
  160. II. FEATURES OF DOORS
  161.  
  162.         Doors has a lot to offer because of it's size, relative speed, and
  163.     extensibility.  Doors is written almost entirely in assembly language,
  164.     and it's size and speed should reflect this.  Doors is also granular,
  165.     i.e. there are few interlibrary calls, by design. This granularity
  166.     reduces the size of the executable because only what is directly called
  167.     is linked.
  168.  
  169.     Doors is the first User Definable Library.  We say User
  170.     Definable because one doesn't NEED to LINK precompiled code to further
  171.     extend the library.  There are very few true Doors functions. Most of
  172.     the Doors routines are #xtranslates (functions beginning with DP --
  173.     Doors Preprocessed functions) which are contained in header files.  You
  174.     can construct similar #xtranslates or #defines that will take you in
  175.     any direction you need to go. The headers supplied with Doors are a
  176.     collection of the most commonly used interrupt routines.  Which
  177.     routines you add to the library is totally up to you--all you need is a
  178.     good DOS reference and you can add any DOS interrupt routine to your
  179.     clipper program as you need or desire it.
  180.  
  181.     OR you can register the software and get the .ch files and support
  182.     tools that have already been developed and tested in distributed
  183.     applications.  The point NOW you have a choice.
  184.  
  185.                                  PAGE 1
  186.  
  187. III. USING DOORS
  188.  
  189.     A. Installation.
  190.  
  191.        It is highly recommended to unzip the DOORS.ZIP file used for
  192.     distribution in it's own subdirectory. At that point copy the .lib
  193.     files to you clipper lib directory (probably C:\CLIPPER5\LIB ).
  194.     Then modify the environment variable INCLUDE to point to the doors
  195.     directory you created.  This keeps the .ch files seperate and easily
  196.     maintained.
  197.  
  198.     For example, if your include files are in C:\CLIPPER5\INCLUDE and
  199.     you setup doors in C:\DOORS, then modify your .bat file that sets up
  200.     the clipper environment with :
  201.  
  202.        SET INCLUDE=C:\CLIPPER5\INCLUDE;C:\DOORS
  203.  
  204.  
  205.     B. Out of the Box.
  206.  
  207.        Now that you're set up, using DOORS 'out of the box' is really a
  208.     matter of including the header file and typing the PSEUDO function
  209.     name for the servive you desire. No other set up is needed. Oh, you
  210.     can make new .ch files and additionally optimize the speed of doors,
  211.     but the basic steps are as identified above.
  212.  
  213.     Here's a simple test function for displaying the current directory:
  214.  
  215.     #include "dos.ch"
  216.     func test()
  217.       ? dp_curdir()
  218.     return nil
  219.  
  220.     Now pop this into a file and compile it.  Link with :
  221.        RTLINK fi xxx lib doors
  222.  
  223.        or
  224.  
  225.        BLINKER fi xxx lib doors
  226.        (or Blinker fi xxx allocate doors ) (Great for saving some
  227.        space).
  228.  
  229.     DF_DOS() is the most important function in the doors
  230.     libary.  Many of the functions in Doors are actually #xtranslates
  231.     that are contained within header files. These extremely small
  232.     #xtranslates will give you access to commonly used interrupt
  233.     routines without having to consult a DOS reference manual on how to
  234.     call a specific interrupt.  Using these #xtranslates as your model
  235.     you can extend Doors in any direction you want.  Doors gives you
  236.     priveledged access to the operating system. Doors allows you to call
  237.     ALMOST any DOS interrupt from Clipper using one function --
  238.     DF_DOS().  This one function is the cornerstone of the Doors
  239.     library.  These #xtranslates call DF_DOS() for their interrupt
  240.     services. Doors is designed to be user definable because you can use
  241.     DF_DOS() as the bases for many different functions and codeblocks.
  242.     Doors provides all of this without violating the integrity of
  243.     Clipper because it follows Nantucket's standards for the Clipper
  244.     Extend system, to the letter. Doors should be primarily compatable
  245.     with all versions of Clipper after 5.0.
  246.  
  247.                                  PAGE 2
  248.  
  249.     Using Doors is quite easy.  First, find the Doors function you need
  250.     using the appendix, making note of the required header file(s).
  251.     The online documentation also includes the proper
  252.     syntax for using the routine and an example.  After including the
  253.     proper header file(s) ( and optionally optimizing by declaring the
  254.     proper local variables), simply make the call to the Doors routine.
  255.     When linking your program, you need to include the Doors library,
  256.  
  257.     ie:      cl myprog
  258.              rtlink fi myprog lib doors
  259.              or blinker fi myprog lib doors               (BLINKER 1.4/5)
  260.              or blinker fi myprog allocate doors, extend   (BLINKER 2.0+)
  261.  
  262.     C.  HOW THE LIBRARY IS ORGANIZED (DF VS. DP  VS. DB)
  263.  
  264.         Throughout this manual, you will see references to Doors functions,
  265.     Doors Clipper Functions, and Doors DP functions.  Doors functions (they
  266.     are the functions that start with a DF_ ) are the functions that are
  267.     actually complied in the library itself.  There are only 40 or less of
  268.     these assembly/Clipper language routines.  Doors functions can
  269.     be called by your own functions and by Doors Clipper and Doors DP
  270.     functions.  Some Doors Clipper functions are also compiled into the
  271.     library. The Doors DP functions are not really part of the actual
  272.     library, but instead are found in the Doors include files.  These
  273.     PSEUDO-functions are #XTRANSLATES (DP means Doors Preprocessed).
  274.     These DP functions are comprised of doors DB (doors block definitions).
  275.  
  276.     Why codeblocks and xtranslates?  The intrinsic difference between
  277.     doors and ALL other libraries is that it is A USER DEFINABLE
  278.     LIBRARY, it is OPTIMIZABLE (with a little work can be made faster),
  279.     very GRANULAR (what you don't call won't get linked in), and USER
  280.     MODIFIABLE.  Doors is an interrupt call library.
  281.  
  282.     Doors is user definable by creating header files of the DATA to be
  283.     used with a dos interrupt, Clipper can be used to place the data
  284.     and an associated codeblock ON DISK until needed.  This provides you
  285.     with the information you need NOT in a FUNCTION in a symbol table
  286.     which has to be examined, but in a codeblock in the local symbol
  287.     space for fast retrevial.
  288.  
  289.     Additionally, if something doesn't work on a machine the way it
  290.     should OR heaven forbid, Microsoft or IBM decides to change the
  291.     behavior of an INTERNAL DOS interrupt, you WON'T have to wait on me,
  292.     YOU can fix it! You have the Clipper compatable code and the dos()
  293.     funciton to do it.  Simply copy the .ch involved and modify the call
  294.     to the new data.
  295.  
  296.     Additionally, because of the NATURE of a codeblocks storage
  297.     requirments, you have COMPLETE freedom to pursue learing more about
  298.     DOS and Clipper.  Additionally, you have two more ways of OPTIMIZING
  299.     the behavior of your calls. See Section III.D for additional details
  300.     on the way to optimize doors.
  301.  
  302.  
  303.     D. INCLUDING HEADER FILES and 1ST Level Optimization.
  304.  
  305.         To find out which header files to include for your Doors calls look
  306.     at appendixes, or the norton guides, for which header files reference
  307.     the 'DP_XXX()' calls.  Remember, DF_XXX() are for true functions.
  308.  
  309.                                  PAGE 3
  310.  
  311.         One can gain a level of better speed and smaller size by a
  312.     little work.  Lets go back to the CURDIR example from earlier.
  313.  
  314.     #define I_CONTROLL
  315.     #include "DOS.CH"
  316.  
  317.     func test()
  318.     local regs
  319.     local sregs
  320.  
  321.        ? dp_curdir()
  322.     RETURN nil
  323.  
  324.     Doesn't look much different, does it?  Just three line changes.
  325.  
  326.     What's that "#define I_CONTROLL" thingy?  Thats an identifier that
  327.     the include files recognize.  It's telling the Clipper preprocessor
  328.     that you've read the documentation and DEFINED the needed vars for
  329.     allowing the optimized versions of the xtranslates to run.
  330.  
  331.     Optimized versions?  Won't that enlarge the amount of symbol space
  332.     at compile time? Only slightly, as ONLY ONE set gets defined at compile
  333.     time.
  334.  
  335.     What gets defined?  The include files build codeblock and codeblock
  336.     evaluation definitions.
  337.  
  338.     Codeblocks?  Yes.  This way you have complete flexibility in your
  339.     prgs for the way to capture and express the methods and algorithms
  340.     now available to a compiler with advanced parsing. You could just as
  341.     easily have done this:
  342.  
  343.        local regs
  344.        local sregs
  345.        local mycurdir := db_curdir
  346.  
  347.        ? eval( db_curdir)
  348.        return nil
  349.  
  350.     While these function will do the same as the first, it is at least
  351.     7-10% faster and 2K smaller than if built without the two locals.
  352.  
  353.     We've done a fair amount of 'C' and ASM work.  THREE of the things
  354.     we've learned in DOS to keep our code smaller and more maintainable
  355.     is REUSE DEBUGED CODE, REUSE DEBUGGED CODE, and REUSE DEBUGGED CODE.
  356.  
  357.     It IS faster to have a DEDICATED function hide the data, IF IT ISN'T
  358.     in an OVERLAY! It will not contribute to a smaller .exe and will add
  359.     overhead in the form of maintenance, especially if it's only called
  360.     once or twice per .exe. Therefore, this library is designed with
  361.     you, the developer, in mind.
  362.  
  363.     When you need to get something working, take the shortcuts and use
  364.     the includes 'out of the box'.  When you need more speed and size
  365.     optimization, just follow these examples.
  366.  
  367.                                   PAGE 4
  368.  
  369.  
  370.  
  371. III. E. REGS and SREGS.
  372.  
  373.        Regs and SREGS are var names used throughout the DOORS include
  374.     systems.  These var take their names from the MICROSFT introduced
  375.     function INT86() and INT86X() funcitons.  These two functions are to
  376.     'C' programmers what DF_DOS() is to Clipper.  In 'C' one need only
  377.     fill the specified fields of a named REGS union ( and a SREGS struct
  378.     if calling int86x()) to pass information to the CPU for calling an
  379.     internal DOS function.
  380.  
  381.        Optionally you could use the defines in REGS.CH.
  382.  
  383.        USES <scope> REGISTERS
  384.        USES <scope> SEGMENT REGISTERS
  385.  
  386.     where <scope> may be LOCAL, STATIC, PUBLIC or PRIVATE.  The POINT is
  387.     to define the vars REGS (and optionally SREGS) if you wish to gain
  388.     the 1 level of optimization and to define I_CONTROLL.  If I_CONTROLL
  389.     is defined, IT IS YOUR RESPONSIBILITY TO CONTROL THE APPLICATION!!!
  390.  
  391.        The reason for doing this is that the call to DF_DOS() passes
  392.     these variables by reference.  This is how the results of the function
  393.     call are returned to your Clipper application.  It is HIGHLY
  394.     RECOMMENDED to use locals in all cases for 3 reasons.
  395.  
  396.            1.  Scoping.
  397.                Having local scope means that after a call to DF_DOS() any
  398.                other call to DF_DOS() not in the same SCOPE of code
  399.                PRESERVES the contents of the return value of the last local
  400.                call.
  401.  
  402.            2.  Automatic memory management.
  403.                Once the function that makes the DF_DOS() call completes ALL
  404.                locals will be recollected into the FREE MEMORY POOL
  405.                automatically.
  406.  
  407.            3.  Speed.
  408.                It is simply faster to access LOCALs / STATICS throuht
  409.                the modules' symbol table rather than PUBLICs or PRIVATEs
  410.                through the PUBLIC symbol table. Local symbol tables are
  411.                discarded upon exit.
  412.  
  413.          Many Doors functions use these same variables so if you make
  414.     several calls to Doors routines from within a block of code, make sure
  415.     you preserve a copy if you need one to keep track of which variables
  416.     are being changed. (For details, see Section V., C)
  417.  
  418.  
  419.     F.  LINKING WITH DOORS
  420.  
  421.         Doors has been developed over the last 2+ years.  Seems like
  422.     every time some stability was gained, a new feature was added to the
  423.     linkers which needed further testing.  We've worked hard nights,
  424.     evenings and weekends to try bring a LIBRARY of choice to the Clipper
  425.     Community.  One we believe will prove to be smaller and more useful
  426.     than anything previously seen.
  427.  
  428.                                  PAGE 5
  429.  
  430.  
  431. IV. MULTIPLE DEVELOPER LEVELS.
  432.  
  433.         One nice aspect of Doors is that, in addition to being able to be
  434.     used right out of the box, it can also be modified and extended if you
  435.     need more than what has been already provided.  Thus there are several
  436.     levels to using doors in your development.  This may range from simply
  437.     using what has already been provided to extending Doors to the limits
  438.     of your imagination.
  439.  
  440.     A.  USING HEADER FILES
  441.  
  442.         At first, most Clipper programmers will be satisfied in just using
  443.      what has already been provided in Doors.  At this preliminary level,
  444.      the most important things to worry about are the header files.  The
  445.      header files contain the DB_ blocks and DP_ functions (that are not
  446.      in the library itself) and the #defines that go along with these
  447.      functions.  Very little knowledge of the Clipper preprocessor is
  448.      needed to use Doors in this manner.  Your main job in using Doors
  449.      will be making sure that you have included the proper header files
  450.      ( and optionally defined the proper local variables) before calling
  451.      a Doors function.
  452.  
  453.         A simple illustration was given in Section III.B with some
  454.      optimizaiton shown in Section III.D.  Compile that  example with
  455.      the /p switch. This tells the compiler to generate a .PPO file with
  456.      the translated code. The examle above should generate a line like
  457.      this:
  458.  
  459.  
  460.       ? EVAL({|z| IIF( z = NIL, z := 0, z := ASC(SUBSTR(UPPER(z),1,1))-64),;
  461.             REGS := { B2INT(x47),,,z,,,}, SREGS := {REPLICATE(CHR(0),64),},    ;
  462.             IIF( df_dos( x21, @REGS , @SREGS ), DS, "") } ,  )
  463.  
  464.          Very strange to look at isn't it?  Well this is just the
  465.       evaluation of a percompiled codeblock which says create a local
  466.       parameter (z).  If z is nil there was nothing passed so set it to
  467.       zero for the INT 21, subfunction x47 (decimal 71 ) call.
  468.  
  469.       What the heck is an x47?  Because of the structure of the DOS
  470.       operating system and the documentation for it,  I constucted a
  471.       header file with x0 to xFF defined so I didn't have to translate
  472.       the HEX notation to decimal in my head and worry every time I read
  473.       it if I had specified the correct value.  See HEX.CH if you wish
  474.       to know more.
  475.  
  476.  
  477.  
  478.          REGS := { B2INT(x47),,,z,,,}, SREGS := {REPLICATE(CHR(0),64),},    ;
  479.  
  480.  
  481.                                   PAGE  6
  482.  
  483.  
  484.          To continue, the var REGS is assigned an array of 7 elements,
  485.       where each element represents one of the 9 primary CPU registers.
  486.       Why only 7 elements, well just as it isn't nice to fool MOTHER NATURE
  487.       it ISN'T nice to fool with the stack frame pointers, BP and SP.  So
  488.       they aren't referenced ( althought BP is settable, for this call
  489.       it's not needed).  SP isn't settable.   You may pass A flag
  490.       setting, but the current code won't allow you to set it.  The
  491.       registers which you have priveledged access to are (NOTE the
  492.       underscores used for references) :
  493.  
  494.              _AX, _BX, _CX, _DX, _SI, _DI, _FLAGS [, _BP]   ( See, 7 [8]!)
  495.             [_AH,_AL] The high register of _AX to _DX and the low are
  496.                       individually accessable and AFFECT the _AX value.
  497.                  [_BH,_BL]
  498.                      [_CH,_CL]
  499.                           [_DH,_DL]
  500.  
  501.          The next var is SREGS and with it you are allowed to access up to
  502.       two strings for the interrup requests.  The first is _DS and the
  503.       second is _ES.  This is how strings and structures for files,
  504.       filename, and other resources are passed and returned.  Also, note
  505.       that in the DF_DOS() call itself the arrays are passed by REFERENCE
  506.       (use the @ symbol). This is how DF_DOS() returns the results and
  507.       additionally how you will get information back on what happened.
  508.  
  509.          DF_DOS() is priveledged, so you know if an error occured upon
  510.       return, as ERRORSYS() will NOT get called.  This gives you a great
  511.       deal of power as you don't have to modify ERRORSYS() to TAKE DIRECT
  512.       CORRECTIVE ACTION as you see fit, or igore the return and process some
  513.       other condition.
  514.  
  515.          You should see by now that DF_DOS() returns a TRUE/FALSE status
  516.       depending upon the result of the operation requested.  So, I put this
  517.       call into an immediate IIF() to return the contents of _DS if a true
  518.       was returned ( See the replicate( chr(0) in initializing the call) or
  519.       an empty string otherwise.
  520.  
  521.          You will see and learn as much about the nature of the DOS
  522.       operating system as YOU choose.  With DOORs, you have more freedom,
  523.       with comlete access to a depth NEVER before shared by ANY developer
  524.       with the PRIVELEDGE of DIRECT ACCESS to the INNER CIRCLE of the CPU.
  525.  
  526.     B.  CHANGING HEADER FILES
  527.  
  528.         As you become more comfortable with using Doors, you might become
  529.      curious as to how Doors does it's job.  This is where you need to
  530.      know more about what is in the header files.  Understanding the header
  531.      files is the key to extending Doors.  You will need some knowledge of
  532.      the Clipper preprocessor to modify Doors's header files because
  533.      #xtranslates and #defines are used heavily.  If you ever have to
  534.      modify a Doors function that uses DF_DOS(), it would be wise to
  535.      consult a DOS manual about calling a particular interrupt.  If you
  536.      don't have such a manual, there is a list of several good ones in
  537.      Appendix D.
  538.  
  539.                                  PAGE 7
  540.  
  541.         1.  MODIFYING #XTRANSLATES
  542.  
  543.             Learning how to modify the existing #xtranslates is the first
  544.         step in learning how to extend Doors.  The existing #xtranslates
  545.         can be modified to suit your specific needs.  It is far easier to
  546.         find an #xtranslate that does something close to what you want to
  547.         do and modify it than it would be to make your own #xtranslate.  Be
  548.         sure to document your changes, though, to prevent confusion.
  549.         Also, copy the base document BEFORE making changes.
  550.  
  551.         2.  CREATING #XTRANSLATES
  552.  
  553.             After you've had some experience modifying #xtranslates, you'll
  554.         be ready to write some of your own. Essentially, now this is my design
  555.         criteria, it should be a FUNCTION type of return ( I really don't like
  556.         COMMANDs as I DON'T know if they successfully completed).
  557.  
  558.     C.  CREATING NEW LIBRARY FUNCTIONS
  559.  
  560.         1.  Use THE PREPROCESSOR TO CREATE NEW HEADER FILES
  561.  
  562.         2.  CREATING NEW FUNCTIONS -- LIB'ED INTO A CUSTOM LIBRARY
  563.  
  564.     D.  OPTIMIZING for SIZE or SPEED
  565.  
  566.        By now you should see that including a header with a defined
  567.     block in a module or prg repeatedly can add size to you .exe.  As
  568.     stated, there is a simple method to OPTIMIZING this situation.
  569.  
  570.     1. The default inclusion of a codeblock with an evaluaiton help
  571.     optimize for size.
  572.  
  573.     2. The 1St level of optimization is gained by adding speed with the
  574.     use of the I_CONTROLL #define and scoped vars REGS and SREGS.
  575.  
  576.     3. The 2nd level of optimization is to create a FUNCTION from the
  577.     codeblock that takes the same paramteres and returns the state of
  578.     the defined block.
  579.  
  580.        #define I_CONTROLL
  581.        #include "DOS.CH"
  582.  
  583.        FUNCTION DF_CURDIR()
  584.        local regs
  585.        local sregs
  586.  
  587.        return dp_curdir()
  588.  
  589.        /* Done! */
  590.  
  591.        Now you can call df_curdir() like any other funciton you write.
  592.  
  593.     4. The final level of optimization is to rewrite the function
  594.        INLINE. For detail and examples please refer to the example in
  595.        Appendix E.
  596.                                  PAGE 8
  597.  
  598.  
  599. V.  SOME PITFALLS IN USING DOORS
  600.  
  601.     A.  DONT GET BIT BY AN INTERRUPT
  602.  
  603.         Along with the power that interrupts provide comes the danger that
  604.     you could really foul something up by accidently calling the wrong
  605.     interrupt. Be careful and pay very close attention when writing the
  606.     data passed to these functions. They have proven reliable and quick but,
  607.     because something as simple as a typo could lead to disaster, PAY
  608.     attention.
  609.  
  610.        Imagine mistakingly calling interrupt 13 subfuntion 7
  611.     (format drive) instead of subfunction 8 (find drive parameters).
  612.     Such a bug could be disasterous if it was not caught before the
  613.     first trial run of the program <g>.
  614.  
  615.        This example is ONLY meant to scare those looking into adding or
  616.     adapting the current doors headers or functions.  By makeing mistakes,
  617.     we learn, since we've learned so much, you can only guess at the number
  618.     of mistakes we've make.
  619.  
  620.     B. WARNINGS ON INLINE OPERATORS (++)
  621.  
  622.         When using DP functions, be careful what you pass.  The DP_
  623.     functions are text substitutions so if you pass expressions that modify
  624.     the variables being passed, you could run into trouble.  If for
  625.     instance you have the following CodeBlock.
  626.  
  627.     #xtranslate getmax(<x>, <y>) =>  ;
  628.         EVAL({|max| IIF( <x> > <y>, max := <x>, max := <y>)})
  629.  
  630.     Imagine what would happen if called this:
  631.         c := getmax(a++, b++)
  632.  
  633.     what would have been in the code would be:
  634.  
  635.         c := EVAL({|max| IIF( a++ > b++, max := a++, max := b++)})
  636.  
  637.     and assuming a > b, then a was incremented twice while b was
  638.     incremented once.  This unintended result can cause some pretty hard to
  639.     find bugs.  As a rule do not pass parameters that modify themselves
  640.     to any #xtranslates.
  641.  
  642.  
  643.     C. SCOPE
  644.  
  645.     You could inadvertantly pass some extra values to a routine because
  646.     they were left in REGS or SREGS from a previous routine. Or call a
  647.     DF_DOS() translate for the value to place into the var just after
  648.     partially filling the structure.
  649.  
  650.                                  PAGE 9
  651.  
  652.  
  653. VI. MODIFYING SUPPLIED CODE
  654.  
  655.     A. WHY?
  656.  
  657.           The real importance of the supplied headers and source code (to
  658.        those which register the product) is in being able to fix oversights
  659.        or respond to irregularites within the environments within which we
  660.        all must produce code.
  661.  
  662.           Working on 3com I found a condition which was contrary to the
  663.        documentation on the 503c cards.  The hardware returned failure
  664.        codes but the request to the netbios layer worked correctly!!
  665.        Further checking indicated that 3com's nb.exe (partial netbios,
  666.        returned a version of 0.0 and the network cards id was reversed (a
  667.        card with an id of '1234' was returning '4321'!  So, I wrote a
  668.        3COM_NETID() function and documented it as OVERRIDDING the one in
  669.        the library in which I ignored the return status of the hardware
  670.        interface and checked the contents of the netbios version to
  671.        determine how to evalute the the correct order of the ID to return.
  672.        This would not have been possible for them without the source as
  673.        a guide!
  674.  
  675.     B. WHEN?
  676.  
  677.        The main reasons are:
  678.  
  679.        1) Something doesn't work as expected, described, or documented.
  680.           Heavens forbid that something not work as docuemnted!!!
  681.           Since commercial class programmmers NEVER make mistakes it may
  682.           never happen that you need to modify the behavior of some define,
  683.           directive, or function.
  684.  
  685.        2) Extending the functionality.  I've overlooked something or
  686.           some new feature comes out (MS DOS 111.2.1, <g>).
  687.  
  688.  
  689.     C. MAINTAINABILITY
  690.  
  691.        This can be the reason to avoid making small changes.  IF you
  692.        change a directive or function and put it back into the
  693.        directories replacing the current one, you may loose it and have
  694.        to undo it on a update or upgrade.  ALWAYS, absolutely ALWAYS,
  695.        create a secondary subdir and copy the changed file there and put
  696.        it in the path (INCLUDEs specifically may be chained). On an
  697.        update you have a copy to bring forward or edit easily for the
  698.        differences.
  699.  
  700.              (SET INCLUDE=C:\CLIPPER6\INCLUDE;C:\ASPEN;C:\MASM . . . )
  701.  
  702.                                 PAGE 10
  703.  
  704.  
  705. VII. ADVANCED TOPICS.
  706.  
  707.      A. Networking
  708.  
  709.         Thank goodness for the improvements to Netware, Lan Manager, 3+,
  710.         and all the smaller market netbios compatable networks available
  711.         to the general public.  The coming years will see a growing
  712.         exansion in the demand for network and group aware software that
  713.         resolves, reliably and quickly, the mundane tasks for businesses.
  714.  
  715.         Networking has been found to be quick and simple with the
  716.         addition of DOORs to the Clipper environment.  Doors has been
  717.         designed to be network aware (NOT for a specific Network).  The
  718.         Microsoft design for device redirection allows the NETWORK
  719.         software to hook into the DOS operating system, and therefore
  720.         the most common services needed are available as an INT request.
  721.  
  722.  
  723.      C. Fonts
  724.         Yes, Font mapping and manipulation is avialable to registered
  725.         users.
  726.  
  727.      D. Mouse
  728.         Yes, the mouse is availbe to registered users.
  729.  
  730.      E. Memory Accessing
  731.         Yes, DIRECT memory accessing is availble to registered users.
  732.  
  733.                                 PAGE 11
  734.  
  735.  
  736. VIII. FUNCTIONS.
  737.  
  738.    NOTE: Granularity ratings are an indication of the NUMBER of external
  739.          references made by a function to other library routines. The
  740.          higher the number the more references there are and the WORSE
  741.          the link impact.
  742.  
  743.    A. DF_DOS.
  744.  
  745.       SYNTAX: DF_DOS( iInt, @Regs, @Sregs, lTrim1, lTrim2 )
  746.  
  747.       GRANULARITY: 0
  748.  
  749.       ARGUMENTS: iInt           REQUIRED - Numeric, valid values 0 to 255
  750.                                                                 x0 to xFF
  751.  
  752.                  aRegs          REQUIRED - SIZE 7,  all Numerics, EACH REQUIRED
  753.                                            Eight is OPTIONAL
  754.                                 ^RHIGHLY RECOMMENDED TO PASS BY REFERENCE^R
  755.                  ^bRegs[1]^b     Number to be placed in the CPU's AX Register
  756.                  ^bRegs[2]^b     Number to be placed in the CPU's BX Register
  757.                  ^bRegs[3]^b     Number to be placed in the CPU's CX Register
  758.                  ^bRegs[4]^b     Number to be placed in the CPU's DX Register
  759.                  ^bRegs[5]^b     Number to be placed in the CPU's SI Register
  760.                  ^bRegs[6]^b     Number to be placed in the CPU's DI Register
  761.                  ^bRegs[7]^b     Number to be returned from the CPU's FLAGS Register
  762.                  ^bRegs[7]^b     Number to be placed in the CPU's BP Register
  763.  
  764.                  Sregs         OPTIONAL - Used to pass strings and SEGMENT
  765.                                            registers into the INTERRUPT Call
  766.                  ^bSregs[1]^b    Number to be placed in the CPU's DS Register
  767.                  ^bSregs[1]^b    Number to be placed in the CPU's ES Register
  768.  
  769.                  lTrim1, lTrim2  Either is OPTIONAL and indicate whether to
  770.                                  TRIM() the return in the DS and/or ES
  771.                                  register (Sregs[1] and/or Sregs[2]). Both
  772.                                  defaul to .T.
  773.  
  774.                  ^rNOTE:^r        ^bRegs and Sregs SHOULD Always be passed^b
  775.                                   ^bBY REFERENCE so VMM won't swap them to disk^b
  776.                                   ^band forget to update them IF there is a delayed^b
  777.                                   ^breturn or a deep function CALLSTACK.^b
  778.  
  779.       RETURNS: Logical  (TRUE if CARRY FLAG not set, FALSE if CARRY FLAG set )
  780.  
  781.       ^uCOMMENTS:^u Could write a thesis (AND maybe I'll go back for a Master's
  782.                 and do just that) on this function alone. I had the original
  783.                 concept in August, '90 and started coding it in MS 'C', 6.0.
  784.                 Well, MICROSOFT wanted Licensing options on the INT86() and INT86x()
  785.                 functions called out of the library.  The first version was about
  786.                 4 K in size, but ran well.  Anyway, I taught myself all about
  787.                 the DOS interrupt system, MASM 5.10 (ugggggh) and rewrote it.
  788.                 The version in this library is about 2 times faster, is compatible
  789.                 with MASM 6.0 (the assembler used for this package) and with
  790.                 all the string trimming code INLINE is less than 2 K, TOTAL.
  791.  
  792.                                 PAGE 12
  793.  
  794.                 The concept is objective in nature and the function is basically
  795.                 a translator from CLIPPER structures into CPU values and structures,
  796.                 and back.  You'll find it to be quick. I'm studying how to optimize
  797.                 it for speed, not just size. There are well over 100 Possible
  798.                 uses for this function with the array passing and the Network
  799.                 systems available.
  800.  
  801.                 Although the carry flag is generally used to signify the success
  802.                 of the dos function, be aware that not all dos functions will set
  803.                 the carry flag, so it's a good idea to also check AX for an error
  804.                 condition.
  805.  
  806.                 The current version is in it's 5th incarnation. But it basically
  807.                 is the workhorse of the INCLUDE FILE Codeblocks. Why codeblocks?
  808.                 Entry is in the module SYMBOL Table (More memory for apps).  Reusable so
  809.                 it can be linked into the root to minimize overlay paging.
  810.                 Objective so that we can use the Code provided by the operating
  811.                 system, AS IT STANDS (Inheriting Code is Nice, you know it
  812.                 probably works).
  813.  
  814.                 This function doesn't pretend to have the speed of some other
  815.                 libraries, just better size and STRICT OBEDIENCE to Clipper's
  816.                 extend system.
  817.  
  818.                 There are ^rABSOLUTELY NO INTERNAL^r calls to Clipper. There are
  819.                 ^uZERO Macro's^u, there are ^uZERO xgrabs, xfrees, and xalloc calls^u.
  820.                 This thing is so small and modular it'll go whereever Clipper
  821.                 goes. It'll travel NOW as a .OBJ LIB, and Later as a CLASS .DLL.
  822.                 It's going to be easy to support, and I think of it as the
  823.                 ^bFIRST^b ^RUSER DEFINED LIBRARY^r. Handily, it will expand as
  824.                 MS DOS expands.
  825.  
  826.       EXAMPLE:
  827.                ^rFUNCTION CURDRIVE()^r        // EXAMPLE ONLY, NOT the recommended
  828.                LOCAL REGS                 // way to do it.
  829.  
  830.                REGS := { B2INT(x19),,,,,,}
  831.                                             // NOTE that arrays is 7 (6 Commas)
  832.                                             // Need them going in if you want
  833.                                             // Something BACK (like the results)
  834.  
  835.                // x19 is Decimal 25, B2INT(x)
  836.                // becomes ((25)*256)
  837.                // which puts x2500 into AX
  838.  
  839.                RETURN IIF( DF_DOS( x21, @REGS ), CHR(AL+1), "" )
  840.                               // IF carry not set after the interrupt return
  841.                               // the char value from the lower half of AX after
  842.                               // adding 1, else return ""
  843.                                    // AL #defines to (REGS[1]%256)
  844.                                    // which is the lower 8 bits
  845.  
  846.                                 PAGE 13
  847.  
  848.                ^rFUNCITON CURDIR(cDrive)^r
  849.                 LOCAL REGS, SREGS
  850.  
  851.                 REGS := { B2INT(x47),,,ASC(SUBSTR(cDrive,1,1))-1,,,}
  852.                                                  // NOTE that arrays are 7 and 2
  853.                 SREGS := { REPLICATE(CHR(0),64) , } // Just provide a buffer to
  854.                                               // to be filled by the INT request
  855.  
  856.                      // FOR SPEED the DF_DOS() function does
  857.                      // ONLY THE MOST MINIMIAL PARAM TESTING
  858.                      // You're a Programmer, PASS the correct paramters
  859.  
  860.                      // You can break this funciton if really want to,
  861.                      // OR you can RE-USE it easily by passing correct params
  862.           RETURN IIF( DF_DOS( x21, @REGS , @SREGS ), SREGS[1], "") } )
  863.  
  864.  
  865.    B. DF_AT.
  866.  
  867.      Just like clippers' AT() but much more powerful.
  868.  
  869.       SYNTAX: DF_AT(cChar, cString, iTimes, lNomatch)
  870.  
  871.       GRANULARITY: 0
  872.  
  873.       ARGUMENTS: cChar          REQUIRED - character or substring sought
  874.                  cString        REQUIRED - character sting holding substring (maybe)
  875.                  iTimes         OPTIONAL - Numeric, if true scans like RAT()
  876.                                            Defaults to 1, MAX repeat is 127
  877.                                                           MIN back repeat is -128
  878.  
  879.                  lNomatch       OPTIONAL - Logical, (the twist) scan for first
  880.                                            NON matching
  881.  
  882.       RETURNS: iFoundat  (Numeric, 0 if not found)
  883.  
  884.       ^uCOMMENTS:^u   The two main features of this function are that it can
  885.                   search from either direction and that it can search for the
  886.                   first matching character or the xth NON matching character.
  887.                   These features are controlled by the two options iTimes and
  888.                   lNomatch.  If no paramaters are passed for these flags, they
  889.                   will default to 1 and false and the function will search
  890.                   fowards for the first matching character.  There are times,
  891.                   however, when setting these flags can greatly simplify a
  892.                   problem.  If for instance, you have a displayable string
  893.                   that has been centered by using spaces, you could easily
  894.                   find the last character in the string by setting both
  895.                   lBackwards and lNomatch to true, and searching backwards for
  896.                   the first non-space character.
  897.  
  898.  
  899.       EXAMPLE:  DF_AT("a", "Char")                --> 3
  900.                 DF_AT("aBa","Haba", -1)          --> 2   (Scaned from right)
  901.                 DF_AT(" ", "   WHAT   ",, .T.) --> 4   ( 'W' is first
  902.                                                             non-space from left )
  903.                 DF_AT(" ", "   WHAT   ",-1, .T.) --> 7   ( 'T' is first
  904.                                                             non-space from right)
  905.                 DF_AT("xz", "This is a xz or xz a is This", 2) --> 17
  906.                 DF_AT("ab", "-4 ab -2 ab -1 ab", -3)  --> 4
  907.  
  908.       SOURCEFILE: AT.ASM
  909.  
  910.                                 PAGE 14
  911.  
  912.    C. DF_PSEC()
  913.  
  914.       Finally, someone has added a true relative timer to Clipper.
  915.       DF_PSEC() is IT!
  916.  
  917.       SYNTAX: DF_PSEC( [iPrecision] )
  918.  
  919.       GRANULARITY: 2
  920.  
  921.       ARGUMENTS: iPrecision     OPTIONAL - Numeric, the number of place after
  922.                                            the decimal for rounding.
  923.                                            Defaults to 4, MAX DOUBLE limitati
  924.                                                           MIN 0
  925.  
  926.       RETURNS: iSeconds  ( SSS.xxxx, in Clipper DOUBLE format)
  927.  
  928.       ^uCOMMENTS:^u   The primary feature of this function is to get MORE
  929.                   precise timings.  This function is as Accurate as SECONDS(),
  930.                   except that it uses some assembler to monitor the decay
  931.                   value in the 825x timers.
  932.  
  933.                   This Function isn't ABSOLUTELY accurate.  The PC isn't an
  934.                   atomic clock, and therefore this function is only relatively
  935.                   accurate. The real value of this function is in relative
  936.                   timings. This means that the two readings relative to each
  937.                   other will yield more precise information that two simialar
  938.                   calls to SECONDS().
  939.  
  940.  
  941.       EXAMPLE:  t = df_psec()       --> 1001.2122
  942.                 ? at('?', "Question ?")
  943.                 ? df_psec() - t     --> 0.0012      (Timing on 386-33).
  944.  
  945.  
  946.    D. DF_ASCVAL()
  947.  
  948.       Save a SUBSTR() CAll.
  949.  
  950.       SYNTAX: DF_ASCVAL(cChar, ioff)
  951.  
  952.       GRANULARITY: 0
  953.  
  954.       ARGUMENTS: cChar          REQUIRED - character or substring to conver
  955.                  iOff           OPTIONAL - Numeric, if true scans like RAT()
  956.                                            Defaults to 0, MAX is 65535
  957.  
  958.       RETURNS: iASCII  (Numeric, ASCII value of 'S' would be 83)
  959.  
  960.       ^uCOMMENTS:^u   The  main feature of this function is that it saves
  961.                   calls to SUBSTR().
  962.  
  963.       EXAMPLE:  DF_ASCVAL( "A" ) == ASC("A")     --> 65
  964.  
  965.                 DF_ASCVAL( "ABCEFG1", 7) == ASC( SUBSTR("ABCEFG1",7,1) )
  966.  
  967.       SOURCEFILE: ASCVAL.ASM
  968.  
  969.                                 PAGE 15
  970.  
  971. IX. DOS.CH DP_ Pseudo Function Calls.
  972.  
  973.    A. dp_ver()
  974.  
  975.       SYNTAX: dp_ver()            Numeric Dos version information.
  976.  
  977.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  978.  
  979.       ARGUMENTS: None.
  980.  
  981.       RECOMMENDED LOCALS: ^bREGS^b
  982.  
  983.       RETURNS:  Numeric, two place DOS Version.
  984.  
  985.       ^uCOMMENTS:^u MS-DOS 5.00 Aware.  Even with SETVER aimed at your
  986.                 program, you'll get the correct DOS Version.
  987.  
  988.       EXAMPLE:
  989.                 #include "dos.ch"
  990.  
  991.                 func startup
  992.                 LOCAL REGS      // RECOMMENDED USAGE TO AVOID private clashes
  993.                 Local version := dp_ver()
  994.  
  995.                 IF version > 3.1
  996.  
  997.                 ELSE
  998.                           // Shutdown processing after notifing user
  999.  
  1000.                 ENDIF
  1001.                 return nil
  1002.  
  1003.    B. dp_curdrive()
  1004.  
  1005.       SYNTAX: dp_curdrive()       Get the Numeric drive ID for the
  1006.                                   CURRENT Drive
  1007.  
  1008.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1009.  
  1010.       ARGUMENTS: None
  1011.  
  1012.       RECOMMENDED LOCALS: ^bREGS^b
  1013.  
  1014.       RETURNS: Upper case Character Drive Designator
  1015.                               OR
  1016.                "" if there was an error
  1017.  
  1018.                                 PAGE 16
  1019.  
  1020.       EXAMPLE:
  1021.                 #include "dos.ch"
  1022.  
  1023.                 func startup
  1024.                 LOCAL REGS      // RECOMMENDED USAGE TO AVOID private clashes
  1025.                 Local iCurrdrive := dp_curdrive()
  1026.  
  1027.                 IF iCurdrive < "C"
  1028.                    IF ! dp_changedrive("C")
  1029.                              // IF can't get to a harddisk forget running
  1030.                              //  a Clipper App, BUT Someday it ought to check
  1031.                              //  if we're running on a 21 Meg. Floppy!
  1032.  
  1033.                              //  Use dp_drivesize() for that.
  1034.  
  1035.                    ENDIF
  1036.  
  1037.                 ENDIF
  1038.  
  1039.                 return nil
  1040.  
  1041.    C. dp_driveno(<x>)      This is an INLINE substition for getting
  1042.                            the numeric drive ID from a STRING.
  1043.                            (ASC(UPPER( SUBSTR( <x>, 1,1)))-64)
  1044.  
  1045.    D. dp_changedrive(<x>)
  1046.  
  1047.       SYNTAX: dp_changedrive(cDrive)  Change to or make the specified drive active
  1048.  
  1049.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1050.  
  1051.       ARGUMENTS: cDrive           REQUIRED, character
  1052.  
  1053.       RECOMMENDED LOCALS: ^bREGS^b
  1054.  
  1055.       RETURNS: Logical (success/fail)
  1056.  
  1057.       EXAMPLE: See dp_curdrive()
  1058.  
  1059.    E. dp_lastdrive()
  1060.  
  1061.       SYNTAX: dp_lastdrive()      Determine the Last Logical Drive Setting
  1062.  
  1063.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1064.  
  1065.       ARGUMENTS: None
  1066.  
  1067.       RECOMMENDED LOCALS: ^bREGS^b
  1068.  
  1069.       RETURNS: Character ( 'A', ... 'Z')
  1070.  
  1071.       ^uCOMMENTS:^u Don't bother opening and reading the CONFIG.SYS, just place a
  1072.                 CALL TO DP_LASTDRIVE()
  1073.  
  1074.                                 PAGE 17
  1075.  
  1076.       EXAMPLE:
  1077.                 #include "dos.ch"
  1078.  
  1079.                 func startup
  1080.                 LOCAL REGS      // RECOMMENDED USAGE TO AVOID private clashes
  1081.                 Local cLast := dp_lastdrive()
  1082.  
  1083.                 IF cLast > "B"
  1084.                    //
  1085.                 ELSE
  1086.                    // Shutdown processing after notifing user of LASTDRIVE
  1087.                    // OR Open config.sys
  1088.                    IF (ihand := fopen("c:\config.sys")) > 0
  1089.                       // Read in and process
  1090.                    ELSE
  1091.                       // Give UP.
  1092.                    ENDIF
  1093.                 ENDIF
  1094.                 return nil
  1095.  
  1096.    F. dp_drivesize([<x>])
  1097.  
  1098.       SYNTAX: dp_drivesize(cDrive)   Determine the TOTAL Disk Volume (bytes) of a Drive
  1099.  
  1100.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1101.  
  1102.       ARGUMENTS: cDrive           Optional, If nil, assumes the current drive
  1103.                                   Character
  1104.  
  1105.       RECOMMENDED LOCALS: ^bREGS^b
  1106.  
  1107.       RETURNS: Numeric (Total bytes of drive, NOT KBytes, BYTES)
  1108.  
  1109.       ^uCOMMENTS:^u Please note that to specify a drive using this function, pass
  1110.                 the character representation of the drive--not the defines from
  1111.                 BIOS.CH.
  1112.  
  1113.       EXAMPLE:  #define I_CONTROLL
  1114.                 #include "dos.ch"
  1115.  
  1116.                 func percentfree
  1117.                 LOCAL REGS      // RECOMMENDED USAGE TO AVOID private clashes
  1118.                 Local iTotbytes := dp_drivesize('a')
  1119.                 return (diskspace('a')/iTotbytes) * 100
  1120.  
  1121.    G. dp_curdir([<x>])
  1122.  
  1123.       SYNTAX: dp_curdir(cDrive)   Get the current directory from a specified Drive
  1124.  
  1125.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1126.  
  1127.       ARGUMENTS: cDrive           Optional, character, "C", etc.
  1128.                                   IF NIL assumes the current drive
  1129.  
  1130.       RECOMMENDED LOCALS: ^bREGS, SREGS^b
  1131.  
  1132.       RETURNS: cDirectory (NO preceding drive path:  "dos" not "c:\dos")
  1133.  
  1134.       ^uCOMMENTS:^u  Similar to Clipper's curdir() but smaller
  1135.  
  1136.                                 PAGE 18
  1137.  
  1138.       EXAMPLE:
  1139.                 LOCAL REGS, SREGS
  1140.  
  1141.                 ? dp_curdir()        // Pass a nil
  1142.                 ? dp_curdir("A")     // Returns   "", means at the root
  1143.                 ? dp_curdir("C")
  1144.  
  1145.    H. dp_mkdir(<x>)
  1146.  
  1147.       SYNTAX: dp_mkdir(cDirectory)        Create or Make a directory
  1148.  
  1149.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1150.  
  1151.       ARGUMENTS: cDirectory       REQUIRED
  1152.  
  1153.       RECOMMENDED LOCALS: ^bREGS, SREGS^b
  1154.  
  1155.       RETURNS: Logical (success/failure)
  1156.  
  1157.       ^uCOMMENTS:^u "cDirectory" must be a valid MSDOS directory.  It may not
  1158.                 contain any wildcards.
  1159.  
  1160.       EXAMPLE: Look at about line 50 of DIRR.PRG  (+- 200 Lines, HA)
  1161.  
  1162.          LOCAL REGS, SREGS
  1163.  
  1164.          IF( dp_mkdir(dirr), NIL, DOS_Quit( REGS ) )  // IF ok, do nada, else outta here
  1165.  
  1166.    I. dp_rmdir(<x>)
  1167.  
  1168.       SYNTAX: dp_rmdir(cDirectory)     Remove a directory
  1169.  
  1170.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1171.  
  1172.       ARGUMENTS: cDirectory       REQUIRED
  1173.  
  1174.       RECOMMENDED LOCALS: ^bREGS, SREGS^b
  1175.  
  1176.       RETURNS: Logical (success/failure)
  1177.  
  1178.       EXAMPLE: Look at about line 100 of DIRR.PRG
  1179.  
  1180.          LOCAL REGS, SREGS
  1181.  
  1182.          IF ! dp_chdir("..")  .OR. ! dp_rmdir(dirr)  // NOTE: Relative directory
  1183.                                                      // spec ".."
  1184.  
  1185.    J. dp_chdir(<x>)
  1186.  
  1187.       SYNTAX: dp_chdir(cDirectory)   Change to a directory
  1188.  
  1189.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1190.  
  1191.       ARGUMENTS: cDirectory       REQUIRED, character, can specify full path
  1192.                                   (ie, c:\other\dir)
  1193.  
  1194.       RECOMMENDED LOCALS: ^bREGS, SREGS^b
  1195.  
  1196.                                 PAGE 19
  1197.  
  1198.       RETURNS: Logical (success/failure)
  1199.  
  1200.       ^uCOMMENTS^u  This function takes as an argument the destination directory.
  1201.                 The destination directory may be preceeded by a drive
  1202.                 specification.  If no drive specification is given, dp_chdir()
  1203.                 assumes the current drive.
  1204.  
  1205.       EXAMPLE: Look at about line 100 of DIRR.PRG
  1206.  
  1207.          LOCAL REGS, SREGS
  1208.  
  1209.          IF ! dp_chdir("..")  .OR. ! dp_rmdir(dirr)
  1210.                            // NOTE: Relative parent directory spec ".."
  1211.  
  1212.    K. dp_getdate()
  1213.  
  1214.       SYNTAX: dp_getdate()        Get the system Date
  1215.  
  1216.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1217.  
  1218.       ARGUMENTS: None.
  1219.  
  1220.       RECOMMENDED LOCALS: ^bREGS^b
  1221.  
  1222.       RETURNS: ARRAY ({iWeekday,iMonth,iDay,iYear})
  1223.  
  1224.            iWeek    0   to  6,  -1 on Error  (Seems odd, but that's the way it is)
  1225.  
  1226.            iMonth   1   to  12 (Don't ask me, I'm not the designer, just inheritor)
  1227.            iDay     1   to  31
  1228.            iYear   1980 to 2099
  1229.  
  1230.       ^uCOMMENTS:^u Check the date() and set it without a run to the DATE command.
  1231.                 See dp_setdate().  Not extremely important in the USA, but try
  1232.                 getting the date on a box that's running in Japan or Europe.  Date()
  1233.                 MAY work there, but this WILL work anywhere.
  1234.  
  1235.       EXAMPLE:
  1236.                LOCAL REGS
  1237.                LOCAL aIdateinfo := dp_getdate()
  1238.  
  1239.    L. dp_setdate( <ddate> [,<day> ,<yr>] )
  1240.  
  1241.       SYNTAX: dp_setdate(iMo,iDay,ar) the system Date
  1242.  
  1243.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1244.  
  1245.       ARGUMENTS: dMo    REQUIRED - DATE
  1246.  
  1247.                     --- OR ---
  1248.  
  1249.                  iMo    Numeric, 1    to 12     REQUIRED
  1250.                  iDay   Numeric, 1    to 31
  1251.                  iYear  Numeric, 1980 to 2099
  1252.  
  1253.       RECOMMENDED LOCALS: ^bREGS^b
  1254.  
  1255.       RETURNS: Logical (success/failure)
  1256.  
  1257.                                 PAGE 20
  1258.  
  1259.       Example:
  1260.                ddate = ctod('07/04/1993')
  1261.                if dp_setdate( ddate )
  1262.                   ? 'System date reset.'
  1263.                endif
  1264.  
  1265.                -----     OR   ------
  1266.  
  1267.                if dp_setdate( 7, 4, 1993)
  1268.                   ? 'System date reset'
  1269.                endif
  1270.  
  1271.    M. dp_gettime()
  1272.  
  1273.       SYNTAX: dp_gettime()        Get the System Time
  1274.  
  1275.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1276.  
  1277.       ARGUMENTS: None.
  1278.  
  1279.       RECOMMENDED LOCALS: ^bREGS^b
  1280.  
  1281.       RETURNS: ARRAY ({iHour,iMinute,iSecs,iHundreths})
  1282.  
  1283.           iHour       0 to 23     ( Military Time )
  1284.           iMinute     0 to 59
  1285.           iSecs       0 to 29     (Mul by 2 to get Seconds. {I know, I know.})
  1286.           iHundreths  0 to 99
  1287.  
  1288.       ^uCOMMENTS:^u If there is an error, iHour will be -1.
  1289.  
  1290.       EXAMPLE:
  1291.           #include "dos.ch"
  1292.           LOCAL REGS
  1293.           LOCAL theTime
  1294.  
  1295.           theTime := dp_gettime()
  1296.           ? "The current time is " theTime[1] ":" theTime[2] ":" ( 2 * theTime[3] )
  1297.  
  1298.    N. dp_settime( <hr> [,<min> ] [, <sec>] )
  1299.  
  1300.       SYNTAX: dp_settime(iHr,iMin, iSec) Set the system clock
  1301.  
  1302.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1303.  
  1304.       ARGUMENTS: cHr   Character Time string as returned by TIME()
  1305.                    ---  OR  ---
  1306.  
  1307.                  iHr   0 TO 23    REQUIRED
  1308.                  iMin  0 to 59
  1309.                  iSec  0 to 59
  1310.  
  1311.       RECOMMENDED LOCALS: ^bREGS^b
  1312.  
  1313.       RETURNS: Logical (Time set as requested, if true)
  1314.  
  1315.                                 PAGE 21
  1316.  
  1317.       EXAMPLE:
  1318.           include "DOS.CH"
  1319.  
  1320.           FUNCTION ChangTime( cTime )
  1321.  
  1322.           LOCAL cString := "      "
  1323.           LOCAL REGS
  1324.           LOCAL newHours, newMinutes, newSeconds
  1325.  
  1326.           IF cTime == NIL
  1327.               @ 0,0 SAY "Enter the new time " GET cString PICT "@R XX:XX:XX"
  1328.               READ
  1329.           ELSE
  1330.               cString := cTime
  1331.           ENDIF
  1332.  
  1333.           IF EMPTY( cString )
  1334.               RETURN .F.
  1335.           ELSE
  1336.               newHours := Substr( cString, 1, 2 )      // parse out the hours,
  1337.               newMinutes := Substr( cString, 3, 2 )    // minutes, and seconds
  1338.               newSeconds := Substr( cString, 5, 2 )    // from the time string
  1339.           ENDIF
  1340.           newHours := IIF( EMPTY( newHours ), seconds() / 3600, newHours )
  1341.           newMinutes := IIF( EMPTY( newMinutes ), seconds() % 3600, newMinutes )
  1342.           newSeconds := IIF( EMPTY( newSeconds ), newMinutes % 60, newSeconds )
  1343.                          // make sure the string wasn't empty
  1344.           RETURN dp_settime( newHours, newMinutes, newSeconds )
  1345.                          // make the call to dp_settime to set the time
  1346.  
  1347.               ----      OR     -----
  1348.  
  1349.           return dp_settime("06:13:22")
  1350.  
  1351.    O. dp_isverify()
  1352.  
  1353.       SYNTAX: dp_isverify()       Determine the status of VERIFY (File Writes)
  1354.  
  1355.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1356.  
  1357.       ARGUMENTS: None.
  1358.  
  1359.       RECOMMENDED LOCALS: ^bREGS^b
  1360.  
  1361.       RETURNS: Logical (Verify on if true)
  1362.  
  1363.       EXAMPLE:
  1364.  
  1365.                LOCAL REGS           // Available definitions
  1366.                                     // #define DO_NOT_VERIFY    0
  1367.                                     // #define VERIFY_WRITES    1
  1368.                IF dp_isverify()
  1369.                   // Haven't had much occassion to try this. Try it.
  1370.                   // Time it if it's on--you may want to turn if off to speed up
  1371.                   // disk writes.
  1372.  
  1373.                ENDIF
  1374.  
  1375.                                 PAGE 22
  1376.  
  1377.    P. dp_setverify(<x>)
  1378.  
  1379.       SYNTAX: dp_setverify( iOnoff )    Set the STATE of Write Verifications
  1380.  
  1381.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1382.  
  1383.       ARGUMENTS: iOnoff           REQUIRED - 0 turns WRITE VERIFICATION OFF
  1384.                  (Numeric)                   1 turns WRITE VERIFICATION ON
  1385.  
  1386.       RECOMMENDED LOCALS: ^bREGS^b
  1387.  
  1388.       RETURNS: Logical (success/fail)
  1389.  
  1390.       ^uCOMMENTS:^u Verification request on a NETWORK workstation writing to the
  1391.                 server are NOT GUARANTEED under DOS. Verification slows the
  1392.                 system down, so only use this feature for critical files for when
  1393.                 your application is running stand-alone. There are significant
  1394.                 doubts about the accuracy of the DOS SETVERIFY behavior on a
  1395.                 network.
  1396.  
  1397.       EXAMPLE:
  1398.           include "DOS.CH"
  1399.           LOCAL REGS
  1400.  
  1401.           IF dp_setverify( VERIFY_WRITES )    // if the verification was successfully turned on
  1402.               write_important_file()   // write the file that needs verifying
  1403.               dp_setverify( DO_NOT_VERIFY )        // turn verification off
  1404.           ELSE
  1405.               return_error()      // there was an error turning on the verification
  1406.           ENDIF                   // so let the user know his file is not verified
  1407.  
  1408.  
  1409.    Q. dp_getpsp() =>
  1410.  
  1411.       SYNTAX: dp_getpsp()         Get the current programs' Program Segment Prefix
  1412.  
  1413.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1414.  
  1415.       ARGUMENTS: None.
  1416.  
  1417.       RECOMMENDED LOCALS: ^bREGS^b
  1418.  
  1419.       RETURNS: Numeric (Representing the FIRST Segment of the CLIPPER Code)
  1420.  
  1421.       EXAMPLE:
  1422.  
  1423.                LOCAL REGS
  1424.                LOCAL iPsp
  1425.  
  1426.                iPsp := dp_getpsp()  // Now can access info in the PSP Table
  1427.  
  1428.    R. dp_getcmdline()
  1429.  
  1430.       SYNTAX: dp_getcmdline()     Get command line parameters.
  1431.  
  1432.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1433.  
  1434.       ARGUMENTS: None.
  1435.  
  1436.       RECOMMENDED LOCALS: ^bREGS^b
  1437.  
  1438.                                 PAGE 23
  1439.  
  1440.       RETURNS: cCommandline
  1441.  
  1442.       ^uCOMMENTS:^u This function returns the command line parameters that were
  1443.                 passed from DOS when your application was loaded.  See the
  1444.                 exmaple below. Also, reading command line parameters can be handy
  1445.                 for debugging purposes.
  1446.  
  1447.       EXAMPLE:
  1448.                LOCAL REGS
  1449.                LOCAL cDevrequest := dp_getcmdline()
  1450.                // cDevrequest now contains the command line parameters that were
  1451.                // issued when your program was loaded by DOS
  1452.                //     ie.  If your program is called "MYPROG.EXE" and the user
  1453.                // typed "MYPROG c:\files\myfile.doc -d" at the DOS prompt
  1454.                // cDevrequest would return a string containing:
  1455.                //                             "c:\files\myfile.doc -d"
  1456.                // If no parameter was passed from the DOS prompt, dp_getcmdline()
  1457.                // returns an empty string.
  1458.                // In this example, "-d" might be used to put the program into
  1459.                // debugging mode
  1460.  
  1461.    S. dp_maxfiles()
  1462.  
  1463.       SYNTAX: dp_maxfiles()       Determine MAXIMUM AVAILABLE files to Program
  1464.  
  1465.       ^rINCLUDE FILE:^r  ^bDOS.CH^b
  1466.  
  1467.       ARGUMENTS: None.
  1468.  
  1469.       RECOMMENDED LOCALS: ^bREGS^b
  1470.  
  1471.       RETURNS: iMaxfiles (available)
  1472.  
  1473.       ^uCOMMENTS:^u This function checks the maximum number of files that can be
  1474.                 open at any one time.  It knows to count the standard dos files
  1475.                 (PRN, CON, AUX, etc), but does not check to see if these files
  1476.                 are in use.  Even though this does not fully track down resource
  1477.                 consumption, it does provide a fast method of checking resource
  1478.                 allocation.
  1479.  
  1480.       EXAMPLE:
  1481.  
  1482.                LOCAL REGS
  1483.  
  1484.                IF dp_maxfiles() < 33
  1485.  
  1486.                   // Notify User and shut down.
  1487.  
  1488.                ENDIF
  1489.  
  1490.                                 PAGE 24
  1491.  
  1492.  
  1493. X. THE FUTURE of DOORS.
  1494.  
  1495.         The future for doors is left in the hands of the community to which
  1496.      it is being delivered.  If YOU like the concept of minimized size with
  1497.      GOOD speed AND are willing to support this with your dollars and use,
  1498.      I'LL guarantee to offer support and extensions in the future.  If
  1499.      we can survive off this library, I'll take it into the event driven
  1500.      arena. In case you haven't thought of it, DOING DOS BASED GRAPHIC
  1501.      programming is just a INTERRUPT away, right now with this library.
  1502.      Anyone fimailiar with the NOVELL API's should see the possibilities
  1503.      in this library for growth.
  1504.  
  1505.      An archive utility is available via WORKing compression and
  1506.      decompression technology.  Not as compact as PKZIP, but 10 times
  1507.      smaller code and twice as fast.  Additionally, .ini files for your
  1508.      Clipper application becomes a SNAP to use with INI_xxx() services.
  1509.  
  1510.      We have ideas for doing a training video on DOORS, CLIPPER and another
  1511.      on the extend system.  As ASPEN arrives, I hope that we will be
  1512.      among the first with a .DLL supporting the GLITZY User Interfaces.
  1513.  
  1514.      Additionally, windowing, file utilities, relationaly manipulation
  1515.      and referential integrity are capabilites which are available. We
  1516.      are a known contractor in the DALLAS, TX telecommunications market
  1517.      (hopefully WELL known, <g>) at Ericsson, GTE, and NationsBank.
  1518.      All of these are technologies with which we're comfortable and for
  1519.      which superior working code can be delivered.
  1520.  
  1521.      We at Codesmythe are dedicated to pushing the limits of code size,
  1522.      algorithm speed and diversity, and reusability.  As the world of OOP
  1523.      catches up to the production environments, we have every intention of
  1524.      helping to provide the tools necessary to make the developer's life
  1525.      and work easier and faster, with the ultimate goal of providing
  1526.      user friendly features which are as FAST as possible within the
  1527.      design constraints.
  1528.  
  1529.                                 PAGE 25
  1530.  
  1531. IX. APPENDIXES
  1532.  
  1533.     A. DOORS FUNCTIONS
  1534.  
  1535.     B. CLIPDOOR FUNCTIONS
  1536.  
  1537.     B. DP_FUNCTIONS
  1538.         1. FILE FUNCTIONS
  1539.         2. DIRECTORY FUNCTIONS
  1540.         3. DISK FUNCTIONS
  1541.         4. VIDEO FUNCTIONS
  1542.         5. PRINTER FUNCTIONS
  1543.         6. MOUSE FUNCTIONS
  1544.         7. NETWORK FUNCTIONS
  1545.         8. DATE / TIME / COUNTRY FUNCTIONS
  1546.         9. MISC DOS FUNCTIONS
  1547.         10. MISC HARDWARE FUNCTIONS
  1548.         11. KEYBOARD I/O FUNCTIONS
  1549.         12. BIT, NIBBLE, AND BYTE FUNCTIONS
  1550.  
  1551.     D. DOS REFERENCE MANUALS
  1552.  
  1553.     E. 4Th Level Optimization
  1554.  
  1555.                                 PAGE 26
  1556.  
  1557.                                APPENDIXES
  1558.  
  1559.  
  1560. APPENDIX A: DOORS FUNCTIONS
  1561.  
  1562.     NOTE: Those functions which are network aware are indicated as
  1563.     such with a 'N' preceeding the name and the description. An 'I'
  1564.     indicates INTERNATIONAL support.
  1565.  
  1566.  NI DF_DOS()          The cornerstone of the Library. Fire that INTERRUPT.
  1567.  I  DF_AT()           Replacement AT(), RAT() Function with a TWIST
  1568.     DF_ASCVAL()       Replacement/speedup for ASC( substr( string, at('a',string), 1) )
  1569.  I  DF_CPUIS()        Find the Current CPU Type, XT, AT, 386, 486.
  1570.  I  DF_DOSFILE()      Determine System Files available to the application.
  1571.  NI DF_EXEPATH()      Reports the location from which the application began
  1572.  NI DF_FHAVAIL()      Determine FILE HANDLEs Available at RUNTIME.
  1573.     DF_INT33()        What are you doing you rodent you? (Talk to MICE)
  1574.     DF_ISBIT()        Determine if a particular bit is set in a Numeric
  1575.     DF_ISVID()        Determine the video adapter type in the System
  1576.     DF_JUMP()         Make the Far jump to SEGMENT:OFFSET
  1577.     DF_MASKBIT()      Numerical AND, OR, NOT, and XOR of values
  1578.     DF_MEMSET()       Read/Write Byte, Word or Sting into Memory (Direct)
  1579.  N  DF_NBEXEC()       Handles calls to the NETBIOS and IPX/SPX ACCESS Layer
  1580.     DF_PTIME()        Report the current FIXED presion count of 8253 Timer.
  1581.     DF_PTINIT()       Check on and set the precision state of 8253 Timer.
  1582.     DF_SHIFT()        Shift bits left or right in an INTEGER value.
  1583.     DF_DIMAT()        Dim string attributes for DISPLAY shadowing.
  1584.     DF_STRTYPE()      Determine the contents of string by NUMERIC Code.
  1585.                           (ie a REAL isalpha(), isdigit(), etc)
  1586.     DF_VSPAINT()      Paint strings with positional offsets, odd or even
  1587.                       fill, etc.
  1588.  
  1589.              /* The following functions are PRGS */
  1590.  
  1591.  N  DF_ALLDRIVES()      Determine all available drive specifications
  1592.  N  DF_DRIVETYPE()      ID the drive type, Local/remote/floppy (Defs regs.ch.)
  1593.     DF_MDSORT()         Multi Dimensional ARRAY sorter/Indexer
  1594.  N  DF_NETCMD()         General purpose NETBIOS call interface.
  1595.  N  DF_NBERR()          Get the NET ERROR if DF_NETCMD() returns .F.
  1596.  N  DF_NBETEXT()        Returns the string description for a NET ERROR.
  1597.  N  DF_NETID()          Get the adapter ID from Netbios.
  1598.  N  DF_NETRESULT()      Get the resultant array after a NETBIOS Call.
  1599.  N  DF_NETTIME()        Get the Date and time as an ARRAY from a SERVER.
  1600.     DF_PSEC()           Similar to Clipper's SECONDS(), but 4 Place precision.
  1601.                         NOTE: Will require use of INTEL 8253 or 8254 Timer.
  1602.  I  DF_QSEARCH()        Quickly find which item in ordered ARRAYS.
  1603.  N  DF_SETTONETTIME()   Set the workstations date\time from a SERVER.
  1604.  
  1605. APPENDIX B: CLIPDOOR FUNCTIONS
  1606.  
  1607.     NOTE: Those functions used for networking are indicated as
  1608.     such with a 'N' preceeding the name and the description. Those with
  1609.     an 'I' indicate INTERNATIONAL codepage support.
  1610.  
  1611.     DF_ARCOLORS()       Array color function for testing, setting
  1612.   I DF_ASCIISCR()       READ ON SCREEN TEXT
  1613.     DF_COLORCHR()       Get a Numeric color from a character spec
  1614.   I DF_DATEFORMAT()     Determine Recommended Date format from Codepage
  1615.     DF_DBL_CLK_DELAY()  Query / set mouse Double Click Delay period
  1616.     DF_INEVENT()        MOUSE/KEY Wait state function similar to INKEY()
  1617.     DF_LASTEVENT()      Query the DF_LASTEVENT() status.
  1618.     DF_KADVANCE()       @ GET .. WHEN Cursor Locator(++)
  1619.     DF_MBUTTONS()       Query for number of mouse buttons.
  1620.   I DF_MONEYSTRING()    Format a Numeric to Country Currency for display
  1621.     DF_MOUSE()          Query or initialize the internal mouse TRACKER
  1622.     DF_MSAYSPOT()       Display a Mouseable event spot with KEY info
  1623.     DF_MSHOWN()         Query / set mouse visibility
  1624.     DF_MTEST()          Test if mouse event is in a particular area
  1625.     DF_ONKEY()          Event key test function and Loop controller.
  1626.     DF_PROPCASE()       Convert a string to proper case (Leading Caps).
  1627.     DF_REPAINT()        Highlight SCREEN area in alternate Attribute.
  1628.     DF_READWHILE()      A 'SAVE CHANGES' Shell for readmodal().
  1629.   N DF_REDLIST()        Lists available redirected device and server resources
  1630.   I DF_TIMESTRING()     Query / format the current time using Codepage info
  1631.   I DF_WHEREAMI()       Country setup function.
  1632.   I DF_WHICHCOUNTRY()   Query the code page and Country text string
  1633.  
  1634.  
  1635.  
  1636. APPENDIX C: DP_FUNCTIONS
  1637.  
  1638.     NOTE: Those 'dp_' translates which are network aware are indicated as
  1639.     such with a 'N' preceeding the name and the description.
  1640.  
  1641.     Also, There is an equivalent db_ codeblock defined for each of the
  1642.     'dp_' pseudo functions.
  1643.  
  1644.     1. FILE FUNCTIONS - DOS.CH and FILES.CH
  1645.  
  1646.  N  dp_clrattrib()       Clear a File attribute such as Hidden or Read Only
  1647.  N  dp_isattrib()        Query for current file attributes
  1648.     dp_isverify()        Determine the status of VERIFY (File Writes)
  1649.     dp_maxfiles()        Determine MAXIMUM ALLOWED files to Program
  1650.     dp_nofile()          Available error check after calling dp_isattrib()
  1651.     dp_noexist()         Available error check after calling dp_isattrib()
  1652.     dp_nochange()        Available error check after calling dp_isattrib()
  1653.  N  dp_rename()          Rename a file or MOVE a file on the SAME drive
  1654.  N  dp_setattrib()       Set a file attirbute such as Hidden or Readonly
  1655.     dp_setverify()       Set the STATE of Write Verifications
  1656.  N  dp_tempfile()        Create a temparary file in an identified Directory
  1657.  
  1658.     2. DIRECTORY FUNCTIONS - DOS.CH
  1659.  
  1660.  N  dp_chdir()           Change to a directory
  1661.  N  dp_curdir()          Get the current directory from a specified Drive
  1662.  N  dp_mkdir()           Create or Make a directory
  1663.  N  dp_rmdir()           Remove a directory
  1664.  
  1665.     3. DRIVE FUNCTIONS - DOS.CH and BIOS.CH
  1666.  
  1667.  N  dp_chdrive()         Change to or make the specified drive active
  1668.  N  dp_curdrive()        Get the Numeric drive ID for the CURRENT Drive
  1669.     dp_diskchanged()     Determine if floppy disk volume changed
  1670.  N  dp_drivesize()       Determine the TOTAL Disk Volume (bytes) of a Drive
  1671.     dp_floppytype()      Determine Drive Parameters information
  1672.     dp_hasfloppy()       Determines if there is a Floppy disk available.
  1673.     dp_isdrive()         Determine FLOPPY Drive status before access
  1674.  N  dp_lastdrive()       Determine the Last Logical Drive Setting
  1675.     dp_numfloppy()       Determines how many floppy disk drives attached
  1676.  
  1677.     4. VIDEO FUNCTIONS - BIOS.CH
  1678.  
  1679.     dp_cgapalette()      Change the CGA Pallette to desired 2 of 4 Colors
  1680.     dp_egapalette()      Change the EGA/VGA Color spectrum to your choosing
  1681.     dp_getvmode()        Returns cryptic information about the video mode
  1682.     dp_getvpage()        Determine the current active video page
  1683.     dp_setvpage()        Set a new or different video page to be active
  1684.  
  1685.     5. PRINTER FUNCTIONS - BIOS.CH
  1686.  
  1687.  N  dp_isprinter()       Finally a REAL is printer, even on a NETWORK
  1688.     dp_lptinit()         Initilaize the printer specified, unless error
  1689.     dp_lpttimeout()      Available error check after calling dp_isprinter()
  1690.     dp_lptio()           Available error check after calling dp_isprinter()
  1691.     dp_lptselect()       Available error check after calling dp_isprinter()
  1692.     dp_lptnopaper()      Available error check after calling dp_isprinter()
  1693.     dp_lptack()          Available error check after calling dp_isprinter()
  1694.     dp_lptbusy()         Available error check after calling dp_isprinter()
  1695.     dp_numlpts()         Determines how many printer ports are attached
  1696.  
  1697.       NOTE: The following ARE ONLY for the event that PRINT.COM is loaded.
  1698.     dp_printcancel()     Delete's a specific file from the PRINT.COM Queue
  1699.     dp_printclear()      Clears all files from the PRINT.COM Queue
  1700.     dp_printstatus()     Determines status or installed state of PRINT.COM
  1701.  
  1702.     6. MOUSE FUNCTIONS - MOUSE.CH
  1703.  
  1704.     dp_m_is()            Query to find if there is a Mouse in the Box!
  1705.     dp_m_reset()         Reset the mouse for different video modes, etc.
  1706.     dp_m_show()          Show the mouse cursor
  1707.     dp_m_hide()          Hide the mouse cursor
  1708.     dp_m_stat()          Determine the current button status on the mouse
  1709.     dp_m_to()            Relocate the mouse cursor to x,y
  1710.     dp_m_downs()         Query for the count of button click downs
  1711.     dp_m_ups()           Query for the count of mouse button releases
  1712.     dp_m_climit()        Sets a column barrier for mouse movement
  1713.     dp_m_rlimit()        Sets a row barrier to the mouse movement
  1714.     dp_m_gcshape()       Set the graphical mouse cursor
  1715.     dp_m_tctype()        Query or set the mouse text cursor type
  1716.     dp_m_motion()        Returns the mouse movements since last queried
  1717.  
  1718.     7. NETWORK FUNCTIONS - NET.CH
  1719.  
  1720.  N  dp_netname()         Returns the net work adapter card tag string
  1721.  N  dp_netdelete()       UNUSE a redirected network resource
  1722.  N  dp_netuse()          Redirect a device available on the network
  1723.  N  dp_reditem()         Returns information about redirected devices
  1724.  N  dp_reddrive()        Determine if a Drive is redirected
  1725.  
  1726.  
  1727.     8. DATE / TIME / COUNTRY FUNCTIONS - DOS.CH and COUNTRY.CH
  1728.  
  1729.     dp_getdate()         Get the system Date
  1730.     dp_gettime()         Set the System Time
  1731.     dp_setcountryinfo()) Set the country code information
  1732.     dp_setdate()         Set the system Date
  1733.     dp_settime()         Set the system clock
  1734.     dp_whereintheworld() Sets up Country info, returns numeric ID
  1735.  
  1736.     9. MISC DOS FUNCTIONS - DOS.CH and BIOS.CH
  1737.  
  1738.     dp_appendstatus()    Determines status or installed state of APPEND.EXE
  1739.     dp_assignstatus()    Determines status or installed state of ASSIGN.COM
  1740.     dp_coldboot()        Restart the computer, reinitialize ALL Hardware
  1741.     dp_dosram()          Determine system DOS Ram (Below 640 K)
  1742.     dp_getcmdline()      Get the command line as the user entered it.
  1743.     dp_getpsp()          Get the current programs' Program Segment Prefix
  1744.     dp_sharestatus()     Determines status or installed state of SHARE.EXE
  1745.     dp_ver()             Numeric Dos version information. MS DOS 5.0 aware.
  1746.     dp_warmboot()        Reboot the computer. Just what we all need.
  1747.  
  1748.     10. MISC HARDWARE FUNCTIONS - BIOS.CH
  1749.  
  1750.     dp_equiplist()       The first step in finding available hardware.
  1751.     dp_hasgame()         Determines if there is a game port.
  1752.     dp_hasmodem()        Is there an internal modem?
  1753.     dp_numserial()       Determines the number of serial Ports
  1754.  
  1755.     11. KEYBOARD I/O FUNCTIONS - BIOS.CH
  1756.  
  1757.     dp_isextkey()        Bios interface to checking EXTENDED Shift keys
  1758.     dp_iskeydown()       Bios interface to check CAPS, ALT, CTRL, etc.
  1759.  
  1760.     12. BIT, NIBBLE, AND BYTE FUNCTIONS - REGS.CH
  1761.  
  1762.               NOTE: The following are case SENSATIVE as they are defines.
  1763.     B2INT()              Promotes a byte value to a 16 Bit Word (INTEGER)
  1764.     DP_HIGHNIB()         Determine the value of the high 4 bits in a Byte
  1765.     DP_LOWNIB()          Determine the value of the low 4 bits in a byte
  1766.     HIGHBYTE()           Determine high byte value from an INTEGER
  1767.     LOWBYTE()            Determine the low byte value from an Integer
  1768.  
  1769.  
  1770.  
  1771. APPENDIX D: DOS REFERENCE MANUALS
  1772.  
  1773.     'The MS-DOS Bible', The Waite Group, 1989, Howard W. Sams    ~ $44.00
  1774.     'The MS-DOS Encyclopedia', Duncan,1988, Microsoft Press  ~ 65.00
  1775.     'The Programmer's PC Sourcebook, 2Nd Edition', Thom Hogan, 1988,
  1776.                   Microsort Press ~$39.00
  1777.     'The Waite Groups MS-DOS Developers Guide', The Waite Group, 1989,
  1778.          Howard W. Sams   ~ 35.00
  1779.     'The Peter Norton Programmer's Guide to the IBM PC', 2nd Edition',
  1780.          Peter Norton, 1988, Microsoft Press
  1781.     'The MS-DOS Programmer's Reference', Microsoft Press, 1991, ~25.00
  1782.  
  1783.     Special Topics:
  1784.  
  1785.     'Network Programming in 'C''., Nance, B., Que, 1990, ~29.95 with disk
  1786.     'Microsoft Mouse Programmer's Reference', Microsoft Press, 1991, ~34.95
  1787.  
  1788.  
  1789.      I'm sure there is a PLETHORA of others.  The ones listed I own or have
  1790.      browsed.  This isn't an endorcement or recommendation for any one of
  1791.      the books, just a suggestion for a good resource. Do remember, you get
  1792.      what you pay for in these books.
  1793.  
  1794. APPENDIX E: Fourth Level Optimization.
  1795.  
  1796.      The fourth level of optimization is RESERVED for paying customers.
  1797.      Hey, my wife thinks I shouldn't put out ANYTHING for free! <g>.
  1798.  
  1799.      (Quick, while she isn't looking - you can directly access and assign
  1800.       to _AX, _AH, _AL etc and call DF_DOS() directly to write you own
  1801.       DOS calls INLINE. Can't give away too much, you might not order and
  1802.       I MUST keep peace on the home front at ALL costs.<g>)
  1803.  
  1804.