home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / BASIC / GLIB14.ZIP / GLIB14.DOC < prev    next >
Encoding:
Text File  |  1988-02-06  |  101.3 KB  |  2,524 lines

  1.  
  2.                             GLIB version 1.40
  3.                          Released: February 6,1988
  4.                         Copr InfoSoft, 1986-1987, 1988
  5.  
  6.  
  7.     The files that should be included on this disk or .ARC archive are:
  8.     GLIB14.NEW    - Overview of new stuff in GLIB 1.4.
  9.     GLIB14.DOC    - This documentation.
  10.     GLIB14.QRF    - A quick reference guide to using the routines.
  11.     GLIBDEMO.BAS  - A QB demo of some of the routines.
  12.     GLIB14.QLB    - The same routines for use with QB4 environment.
  13.     DIR.SUB       - Interface to replicate DOS DIR command in QB4.
  14.     EMP.DAT       - Sample data file for FED-DEMO.BAS
  15.     CHGFLD.SUB    - Subroutine handler for FED (example).
  16.     FED-DEMO.BAS  - Demo of FED, text input handler.
  17.     FED.DOC       - Documentation for care and feeding of the Field Editor.
  18.     GLIB14.INC    - Declarations for GLIB 1.4
  19.     GQLB14.MAC    - Macro responce file for LINK to make GLIB14.QLB
  20.     MAILER        - Quick Mailer for registering.
  21.     ANNOUNCE.TXT  - Major annoucement on GLIB
  22.  
  23.  
  24.     Note: Due to the popularity of QB4, user libraries for prior versions
  25.           of QB are not supplied, but are available on request.
  26.  
  27.  
  28.     License, Terms and Use:
  29.     =======================
  30.        Under no circumstances may these routines be distributed individually
  31.     or without the accompanying documentation, which is an integral part of
  32.     the package, nor may the documentation be altered in anyway.  This
  33.     includes, but is not limited to distributing, GLIB14.QLB for use in
  34.     executing applications compiled to BRUN format.
  35.  
  36.        Under no circumstances may the routines in the GLIB14 package,
  37.     source, object files, libraries or documentation be distributed by or
  38.     otherwise become a part of, or affiliated with any group or organization
  39.     involved in the distribution of what is generally been come to be known
  40.     as SHAREWARE for disk or distribution fees, or for fees of any sort
  41.     without my express WRITTEN consent.  This includes supplying the
  42.     routines, library and or documentation for so-called disk fees.
  43.  
  44.        Finally, as the author, I make no claims that the routines herein
  45.     will fit your needs, simply that in all testing and prior use that they
  46.     worked for me and that you may find them interesting and helpful in your
  47.     programming.  Any liability for the use, misuse or inability to use the
  48.     GLIB14 routines or libraries, is solely the users.
  49.  
  50.  
  51.     1.   Compatibility
  52.        The routines used in GLIB14 are written mostly in assembler and
  53.     assembled under MASM 5.0.  The few BASIC based routines that there are,
  54.     were written under QuikBASIC 4.0.
  55.        GLIB14 will almost certainly choke under earlier versions
  56.     of QB as I have made it a point to take advantage of functions and
  57.     structures new and unique to QB 4.0 where it makes sence and was
  58.     prudent.  I would be amazed if more than a few worked under the BASCOM
  59.     BASIC compiler.
  60.  
  61.  
  62.  
  63.         DO NOT attempt to combine older QB3 routines with QB4 routines into
  64.     a QB4 compiled program or library.  ASM based routines require signif-
  65.     icant conversion for use under QB4.  Linking QB3 and QB4 BASIC based
  66.     routiens will require that both runtime modules be used, BCOM/BRUN30
  67.     and BCOM/BRUN40 - which WILL yield certain disaster.
  68.  
  69.  
  70.     2.    Support
  71.        As long as it exists, I will support and entertain questions
  72.     regarding QB and/or GLIB  via the QuickBASIC conference on
  73.     The Information Booth, (316) 684 8744, 1200 - 19200 bps, 24 hrs.
  74.        If you have a problem or question on GLIB, PLEASE be prepared to
  75.     supply some sort of source code to demonstate your problem.  I am more
  76.     than a little interested in any GLIB or QB bugs that you might find,
  77.     but PLEASE do not waste my time with general, vague inquiries without
  78.     supporting source examples.
  79.  
  80.  
  81.  
  82.     3.   License
  83.        You are granted free and unlimited use of any and all routines in
  84.     GLIB14 that you may find of value.  Furthermore, you are free to pass
  85.     along the BBS distribution files (listed at the start of this document)
  86.     as long as they are passed along as a whole according to the guidlines
  87.     listed above.
  88.        No one is granted any permission to share or pass along the BCOM
  89.     library or any BCOM object files.
  90.  
  91.  
  92.  
  93.     4.    Purchase
  94.        As distributed, GLIB14 documentation, the demo and the environment
  95.     library provide you with everything you need to call and execute GLIB14
  96.     routines from within the editor/environment.  Furthermore, as described
  97.     above you are given unlimited rights for such use.  This provides an
  98.     ample forum for purposes of sampling, testing and evaluation and allows
  99.     unlimited latitude in terms of personal use or as a tutorial regarding
  100.     some of the more advanced features in today's QuickBASIC.  If any of
  101.     these are your intention, then the files included with this
  102.     documentation provide everything you need, and you are free to use them
  103.     in that format.
  104.  
  105.        However, you might find some of the routines of value and want to
  106.     incorporate them into a standalone (.EXE) application.  In this case,
  107.     the library of routines and permission to use them in such applications
  108.     is able to be purchased as described below.
  109.  
  110.        It is my contention that this is the best of all worlds.  You get
  111.     unlimited personal and/or evaluation use.  If you find it of value, the
  112.     BCOM library can be purchased.  If GLIB does NOT fit your needs, then
  113.     you are 'out' nothing (not even the time to download the .LIB) and do
  114.     not need the .LIB file.
  115.  
  116.  
  117.  
  118.        To get the latest version of GLIB14 as well as the standalone
  119.     library (.LIB), do any of the following:
  120.  
  121.     a. Fill out the enclosed mailer, with $20 and mail it to the address
  122.        below and I will mail back a diskette containing documentation, and
  123.        environment library(s) for release 1.4.
  124.  
  125.     b. Upgrades can be had in 2 ways:
  126.        Fill out the mailer, indicating an upgrade and send it back
  127.        indicating that you are upgrading with $10.00 and get a diskette
  128.        back in the mail.
  129.  
  130.  
  131.  
  132.  
  133.     Mailing Address:
  134.                                  InfoSoft
  135.                                PO Box 782057
  136.                                 Wichita, Ks
  137.                                        67278-2057
  138.  
  139.  
  140.        Upgrading:  Upgrades are avialable to anyone who has purchased ANY
  141.     previous version of GLIB.  That is, if you purchased 1.0, but not 1.1 or
  142.     1.2, you are still able to get 1.3 at the upgrade price rather than as a
  143.     new purchase.  So, if any given release does not have anything that you
  144.     have a specific use for, there is no need for you to upgrade simply to
  145.     keep your upgrade path open.
  146.  
  147.  
  148.  
  149.  
  150.  
  151.     I.  GLIB14 - Introduction
  152.  
  153.  
  154.        GLIB14 is a set of routines that are callable from either
  155.     QB3 or QB4.  Some, such as ERRMSG, more resemble sub-programs
  156.     than sub-routines.  To say this is not to overstate their value, but to
  157.     point out that, in general, they perform or can perform multiple
  158.     functions or entire routines.
  159.  
  160.        Most of the routines are assembler based, but where it makes more
  161.     sence, they are in QB.  In terms of speed and such, assembler based is
  162.     undoubtedly faster (though I doubt that the amount by which it is faster
  163.     is always noticeable), QB routines on the otherhand can be a bit more
  164.     useful: the most noticable difference being that QB subroutines can
  165.     alter string lengths while assembler cannot.  The downside is that QB
  166.     routines are a bit bigger, but I still appreciate having them right on
  167.     hand and not having to type them in numerous times.
  168.  
  169.  
  170.  
  171.     II.  Calling Conventions
  172.       If you are not familiar with calling library routines from QB, you
  173.     are advised to STUDY this in the QB books, as it is an important aspect
  174.     of calling sub programs.
  175.  
  176.     Brief Rules:
  177.     A.  The passed parameters shown do not need to be used literally as is.
  178.         That is, if a routine is documented as:
  179.         CALL myroutine(StringParm$, IntegerParm%)
  180.         The following convention will work just as well:
  181.         CALL myroutine(parm1$, parm2%)
  182.         The following will not (because the variable data types are
  183.         reversed):
  184.         CALL myroutine(StringParm%, IntegerParm$)
  185.  
  186.        What this is saying is that called subroutine parameters are only
  187.     POSITIONAL, but they can have any name you choose ("IntegerParm%" vs
  188.     "parm2%"), and as long as the TYPE is correct (integer versus string
  189.     variables, versus double precision etc), and as long as the passed
  190.     arguments are initialized correctly.
  191.  
  192.  
  193.  
  194.     B.  Unless otherwise noted, subroutines require non-string arguments to
  195.         be INTEGERS.  This means that either a DEFINT a-z statements is re-
  196.         quired early on in your program, or numeric arguments must be im-
  197.         plicitly designated as integers, (the "%") integer declaration used.
  198.  
  199.  
  200.  
  201.     C.  Aside from the right TYPE of argument or parameter being passed,
  202.         and the use of integers, make sure you pass the right NUMBER of
  203.         arguments.  If a program requires you to pass 7 arguments and
  204.         either as a typo or because you only use 6, you miss one within the
  205.         parentheses, then as they say, unpredictable results may occur.
  206.  
  207.  
  208.  
  209.  
  210.     D. In most cases, the examples shown will reference parameters as
  211.        variables. ie:  CALL subr(x%, y%, z$); where x, y and z$ are set to
  212.        certain values to get specific results from the routine.  However in
  213.        many cases, you can pass arguments directly.  ie:
  214.        CALL subr(1, 4, "String").
  215.        The times when you CANNOT do such direct passing is when the
  216.        subroutine is going to modify or return one of the arguments passed.
  217.  
  218.        Some routines will change one of the arguments to indicate an error
  219.        or a level of success.   Those arguments do, MUST be passed as a
  220.        variable.  For example, if "subr" above uses x, y and z$ to
  221.        specify what you want it to do and y returns a level of success or
  222.        error situation, it would have to be passed as a variable:
  223.        CALL subr(1, y%, "String")
  224.  
  225.  
  226.     E.  FUNCTIONS
  227.  
  228.          There is a reasonably simple way of structuring ASM subroutines
  229.        to perform the same way that one of your BASIC functions will, or
  230.        the same way that INSTR does.  In many cases this is highly
  231.        productive for us because we can keep the number of parameters we
  232.        need to pass and simply return error conditions in the NAME of the
  233.        function.
  234.           As of GLIB 1.4, we have implemented this feature.  In all but a
  235.        very few cases this FUNCTION return only indicates some sort of
  236.        error condition.
  237.  
  238.                WHAT you need to do to use ASM FUNCTIONS:
  239.          The absolute simplest way is to merely $INCLUDE the enclosed
  240.        GLIB14.INC file and let it do the work.  This must be done BEFORE
  241.        any executing statements like CLEAR, or DEFINT (DEFLNG etc).
  242.  
  243.           To do it by hand, refer to the syntax in the QB book, but keep in
  244.        mind that since the DECLARE's are BEFORE any DEFINT statement, that
  245.        each argument AS WELL AS THE FUNCTION NAME must have the integer
  246.        type identifier or else they will default to BASIC's float.
  247.  
  248.     RIGHT:   DECLARE FUNCTION dayofyr%
  249.     WRONG:   DECLARE FUNCTION lastdrv             ' all FUNCTIONS use integer
  250.  
  251.     RIGHT:   DECLARE FUNCTION feof%(fhandle%)
  252.     WRONG:   DECLARE FUNCTION funiq%(fil$, mode, fhandle%)
  253.               ' all arguments/parameters are NOT integers!
  254.  
  255.        The rule of thumb is that if everything has a $ or a % next to it, it
  256.        will work alright.
  257.  
  258.        We also use a combo of FUNCTIONS and SUBS.  In the example above for
  259.        FUNIQ - we pass a path and mode and FUNIQ will return a file handle
  260.        to us OR a error code in the function name if some went awry.
  261.  
  262.  
  263.  
  264.        The obvious benefit to us in our BASIC code is that if we have a
  265.        FUNCTION named EXIST (which we do) the code becomes much more
  266.        readable:
  267.  
  268.        FUNCTION:
  269.        IF NOT exist("GLIBDEMO.BAS") THEN END
  270.  
  271.        Subroutine:
  272.        CALL exist("GLIBDEMO.BAS", ReturnCode)
  273.        IF NOT ReturnCode THEN END
  274.  
  275.  
  276.  
  277.     III.    DOS File Functions:
  278.  
  279.        With the release of GLIB 1.4, we have implemented several important
  280.     DOS file functions to open, write to, close files as well as create
  281.     truly unique scratch files and set the file pointer to the End Of a
  282.     File.   The benefit of DOS File Functions over BASIC's native access
  283.     methods is that is that rather than causing a runtime error, we can get
  284.     a return code back from DOS.  Additionally, there are some benefits
  285.     inherent to the functions themselves (see FUNIQ).  In interfacing to
  286.     other languages like C and ASM, we can pass an already open DOS file
  287.     handle they can use, which cannot be done with the native commands.
  288.  
  289.  
  290.        Aside from avoiding runtime errors, the advantage of these functions
  291.     is easier and error free access to files by other languages.  For
  292.     example, the routine LCOUNT counts the number of lines in a text file
  293.     (carriage returns actually).  If you were to have the file OPEN in BASIC
  294.     and attemptted to open, read, then close the file in assembler, the
  295.     file could be damaged depending on the mode it is open in and how much
  296.     is data is buffered by BASIC and not yet to disk.  If LCOUNT opened it
  297.     itself and then closed it upon completion, would the BASIC buffered
  298.     data be put to disk?
  299.        In its actual implementation, LCOUNT is passed a file handle opened
  300.     via FOPEN.  LCOUNT neither opens nor closes the file, just acts upon the
  301.     file handle you pass it so that nothing unwittingly happens to the file.
  302.     Buffered, unwritten data from a BASIC file mode is still a question, but
  303.     you maintain control over that via error returns from FOPEN and LCOUNT,
  304.     and LCOUNT does not even attempt to open or close the subject file.
  305.  
  306.  
  307.        With the use of DOS File Function come new terms: mode, access
  308.     rights, attributes, file handles and etc.  Here is a brief overview:
  309.  
  310.     FILENAME:  The name is any legal DOS filename (see VFNAME), there is
  311.          no need to tack on a NUL ( CHR$(0) ) to make it ASCIIZ, InfoSoft's
  312.          routines are intelligent enough to do it themselves.
  313.  
  314.     FILE HANDLE:  The DOS File Functions return or deal with a file handle
  315.          which is just a 16 bit token identifier used by DOS, ASM and C
  316.          that  identifies a particular file and access mode to the
  317.          operating system.   In normal use, the first file handle to be
  318.          issued is 5.  This is NOT the same as attempting to OPEN fil$ FOR
  319.          OUTPUT AS #5.  The concept is the same but the BASIC file numbers
  320.          mean nothing to DOS, only to BASIC.  Simply put, the BASIC file
  321.          numbers are handles of handles issued by DOS.
  322.  
  323.  
  324.  
  325.          The first 5 file handles are reserved for what is called the
  326.          standard devices, these are:
  327.            0 - STDIN (keyboard)
  328.            1 - STDOUT (monitor)
  329.            2 - STERR (monitor again)
  330.            3 - STDAUX (first serial device)
  331.            4 - STDPRN (printer)
  332.          Given that, DOS will issue 5 as the first available handle.  After
  333.          you FOPEN or FCREAT the file with handle 5 it remains open and
  334.          active until you FCLOSE it, that is, it is not affected by BASIC's
  335.          native CLOSE statement.
  336.  
  337.     SHARE MODE: The mode parameter allows for control over file sharing
  338.          when the program is to be used in a Network or multitasking
  339.          environment.  For simplicity, for normal mode set the mode
  340.          parameter to 0, for multitasking, set it to one (1).  In order to
  341.          be able to actually take advantage of the sharing rights, the DOS
  342.          SHARE.EXE program must be loaded and resident.
  343.  
  344.     ACCESS MODE: The mode refers to whether the file is to be opened with
  345.          read, write or read/write access.  In order to keep this simple,
  346.          for the time being, FOPEN automatically opens all files to Read and
  347.          Write access.  This is to keep it simple and to keep the nunmber of
  348.          parameters managable.
  349.  
  350.  
  351.     FILE ATTRIBUTES:  Do not get this read/write access confused with file
  352.          attributes.  The access mode refers to how a file is opened, with
  353.          what rights while file attributes refers to the characteristics of
  354.          the physical disk file.  SETFATTR and GETFATTR allow you complete
  355.          access to get or set or reset file attributes of ANY file on the
  356.          disk - so be careful.  Additionally, to FCREAT a file, you must
  357.          specify what attributes are to be used.  File Attributes are:
  358.             00  -  Normal: like most files on disk
  359.             01  -  Read Only: may be opened for read, but not writing
  360.             02  -  Hidden: does not show in DOS 'dir' command
  361.             04  -  System: used for the hidden system files
  362.             32  -  Archive: used to flag files that need to be backed up.
  363.  
  364.          To combine attributes, add up the values: a hidden, system,
  365.          read-only file has an attribute of 7 (1+2+4).
  366.  
  367.     ERROR CODES:  The File functions actually return 2 types of error
  368.          indicator.  One reflects any DOS level error and the other attempts
  369.          to catch and warn of operator error.   In the case of FOPEN, the
  370.          file handle is returned as a parameter.  If an error occurs, that
  371.          error is passed in the function name:
  372.  
  373.     IF fopen(fil$, mode%, fhandle%) THEN PRINT "Error!"
  374.  
  375.          This should do wonders for making code more readable.  All the File
  376.          functions implemented work in a similar fashion: error codes are
  377.          returned in the name to allow you to either assign the result or to
  378.          evaluate it directly.  See "ASM FUNCTIONS"
  379.  
  380.  
  381.  
  382.          As a rule, -1 indicates some sort of parameter error that the
  383.          called routine notices.  An example would be a nul string as a
  384.          filename or an attempt to FCREAT a standard DOS handle (0-4).  This
  385.          varies a little from routine to routine so be sure to check the
  386.          documentation for each function.
  387.  
  388.          For the most part DOS uses the same error codes throughout the file
  389.          functions, and since these routines all just pass back any such
  390.          error report, you could write a single SELECT CASE construct to
  391.          sort out the error and provide user feedback or attempt to correct
  392.          the error for ALL of the DOS File Functions provided.
  393.  
  394.     DOS Error Codes:
  395.          1 - Invalid function (unlikely you will get this one)
  396.          2 - File Not Found
  397.          3 - Path not found (can also mean that an indicated drive is
  398.              invalid or not found)
  399.          4 - No Handle Available.  BASIC reports such a condition as
  400.              "Too Many Files".  The config.sys FILES= statement may need
  401.              to be modified to correct this or simply FCLOSE and CLOSE a few
  402.              file handles.  By default DOS allows 12 files open at a time,
  403.              and 5 are always open as standard handles.
  404.          5 - Access denied.  An attempt to open a file for Writing that is
  405.              READ only or another node on a network has exclusive rights on.
  406.          6 - Invalid Handle.  The handle passed is not OPEN, or not open in
  407.              the right mode.
  408.         18 - No more files - unlikely you will get this one.
  409.         80 - File already exists.  Possible return by FUNIQ.
  410.  
  411.  
  412.  
  413.     III.  Classifications.
  414.        Each routine description following is titled by a header with some
  415.        general information about the routine:
  416.        o  ROUTINE NAME (FUNCTIONS are so labeled).
  417.        o  The TYPE indicates the type of function it is;
  418.        o  The LEVEL is meant to designate the probability of the routine
  419.           running on the less compatible clones.  QB level routines are
  420.           written in QB and should run no problem, BIOS and DOS level
  421.           routines are written in Assembler, thus it depends on the
  422.           compatibility level of your skinjob (see BLADERUNNER) whether it
  423.           will work ok or not.  Hardware level routines require clones of
  424.           the highest compatibility to run correctly.
  425.  
  426.  
  427.  
  428.     IV.  Major QB bug(s)
  429.  
  430.     A.  NOTE WELL:
  431.         There is a fairly well known bug in QB3 that creates non
  432.     executing .EXE files when your program performs calls to assembler
  433.     routines.  The work around is this:
  434.  
  435.     DO NOT compile your source from INSIDE the editor to make a .OBJ file.
  436.     DO exit to DOS and make the .OBJ file from DOS:
  437.     C>QB myprog /o;
  438.     Then when you link it, the EXE file will run.
  439.  
  440.        By "fairly well known bug" I mean that most serious users know about
  441.     it.  I have let MicroSoft know and provided 4 examples and they now
  442.     understand what the problem is, but DO NOT expect a fix for it,
  443.     because they are more intent on OS/2 and QB4 is now out.
  444.  
  445.  
  446.     B.   Note Well also:
  447.          A very similar bug appears to be present in QB4.  When you compile
  448.     and LINK from inside the environment, QB4 has a nasty tendency to add
  449.     the ENTIRE referenced library to your executable, NOT just the called
  450.     routines.  (Glad the beta testers caught that).
  451.          Further, odd things also happen when making QLB's from inside the
  452.     editor.  The moral is to link, compile and create LIBs from DOS.
  453.  
  454.  
  455.  
  456.       GLIB 1.4 Index
  457.       --------------
  458.       BOXES ........... Outline one of 6 menu type boxes to the screen.
  459.       CHRP ............ Sound the speaker in a CHiRP fashion.
  460.       CLOFF / CLON .... Disengage-engage keyboard Caps Lock.
  461.       CLRKBD .......... Clear keyboard buffer of type-ahead keys.
  462.       CMDLINE ......... Parse the command line into a string array.
  463.       CPUINFO ......... Returns very low level system info, CPU type etc.
  464.       DATE ............ Returns current day, month, year and DOW as integers.
  465.   **  DAYOFYR ......... Returns the current day of the year (1 - 366).
  466.       DFRMAT .......... Date Formatting.
  467.   **  DLIGHT .......... Trigger a floppy disk light on.
  468.    *  DIR.............. Returns DOS directory in a string array.
  469.       DLRFRMAT ........ Numeric string formatting to Dollar conventions.
  470.       DLY ............. Delay for x number of seconds.
  471.       DOSV............. Return DOS Version installed.
  472.       DRVSPACE ........ Return total and free drive space.
  473.       ERRMSG .......... Display temporary message with color, sound control.
  474.       EXIST ........... Determines if a file exists on disk or not.
  475.       EXTMEM .......... Return the amount of Extended (AT) memory installed.
  476.       FADE ............ Screen fade or dissolve routine, maintains attributes.
  477.   **  FCOPY ........... Copy a file, as quickly as DOS.
  478.       FILCNT........... Returns the number of files in disk matching a mask.
  479.       FED ............. BASIC text input routine.
  480.   **  FEOF ............ Set file pointer to the end of a file.
  481.   **  FCREAT .......... Creat a new file, returning a DOS File handle.
  482.   **  FOPEN ........... Open a disk file, getting a DOS file handle.
  483.   **  FUNIQ ........... Creste a unique/temporary file.
  484.   **  FWRITE .......... WRite a string to s file opened with a DOS handle.
  485.   **  GETCH ........... Allow input from predefined string.
  486.       GETDSEG ......... Returns BASIC's DS (Data Segment)
  487.   **  GET/SET FATTR ... Get, set or reset file attributes.
  488.       GETSTACK ........ Returns the state of BASIC's Stack.
  489.       GET/SET DRV ..... Get or set the default drive.
  490.       GET/SET VERFY ... Get or set the system VERIFY state.
  491.       GRAPH ........... Produce a Vertical or Horizontal graph from an array.
  492.   **  INCR / DECR ..... Replicate TURBO BASIC functions
  493.   **  INSON / INSOFF .. Toggle insert state on or off
  494.       KBLOOP .......... Enter a blind loop until a key is pressed.
  495.   **  LASTDRV ......... Return last logical drive on the system
  496.   **  LCOUNT .......... Count the number of lines in a text file QUICKLY.
  497.   **  LNAMEF .......... Swap names to last-name-first format.
  498.       MDLY ............ Delay processing for a number of milliseconds.
  499.   **  MCSRINC / MCSRDEC Decrement mouse cursor flag
  500.   **  MCSRON / MCSROFF  Mouse cursor on or off.
  501.   **  MGETXY .......... Get mouse cursor location
  502.   **  MLONG /MNORM .... Set / reset mouse Mickey Factor.
  503.   **  MPRESS .......... Get number of mouse button presses.
  504.   **  MRELEASE ........ Get number of mouse button releases.
  505.   **  MSETXY .......... Set mouse cursor location
  506.   **  MSETXRNG / MSETYRNG: Define/limit mouse work area.
  507.   **  MTYPE ........... Test for mouse existance, get number buttons
  508.       NFRMAT .......... Extensive Numeric string formatting.
  509.       NLOFF / NLON .... Disengage-engage Keyboard Num Lock
  510.       PCASE ........... Convert string to proper case.
  511.  
  512.  
  513.  
  514.  
  515.  
  516.       GLIB 1.4 Index (con't)
  517.       ----------------------
  518.  
  519.   **  PGETCH .......... GETCH with cenetered prompt.
  520.       PINIT ........... Initialize the printer.
  521.       PFILE ........... Send a disk file to printer.
  522.       PRTSCRN ......... Print the current display on the printer.
  523.       PSTAT ........... Return the printer status.
  524.       QUIKPRT ......... Another implementation of BYTE's QPRINT routine.
  525.       RAMFREE ......... Returns memory installed in the system.
  526.   **  RINSTR .......... Returns LAST position of a char in a string
  527.   **  READSCRN ........ Quickly read a string from the CRT at currect location
  528.       RSTSCRN / SVSCRN. Restores a screen previously saved by SVSCRN
  529.       U-,D- SCROLL .... Scroll a portion of the screen up or down.
  530.       SCROLLER ........ Scroll the screen left or right.
  531.       SCRLOFF / SCRLON. Set Scroll Lock Off.
  532.       SCRNDUMP ........ Dump the current display to disk.
  533.       SETERR .......... Sets DOS "ERRORLEVEL" code upon program termination.
  534.       SINFO ........... Equipment info: RAM, parallel, serial, EGA and VGA.
  535.   **  SYSTIME ......... Return system time as integers.
  536.       TFRMAT .......... Time formatting
  537.   **  VFNAME .......... Test a string to see if it is a valid filename.
  538.   **  VIDOFF .......... Turn CRT off.
  539.   **  VIDON ........... Turn CRT back on.
  540.       WDW ............. Windowing subroutine with sound, color control.
  541.  
  542.       *  DIR is actually a facade for a FINDF and FNEXT Functions
  543.      **  NEW with this release.
  544.  
  545.  
  546.  
  547.     Name: CHRP                 Type: MISC              Level: ASM
  548.  
  549.     This routine is used to sound the speaker in either a fast tone of
  550.     ascending or descending pitch.  The same method is used in WDW to make
  551.     the popping sound.  CHRP is provided to allow you to make a un-popping
  552.     sound when removing a window.
  553.     There are 2 modes in the CHRP routine:
  554.     mode 1 = ascending frequecy (up)
  555.          2 = descending frequency (down)
  556.  
  557.     Syntax:
  558.     -------
  559.     m=1
  560.     CALL CHRP(m%)  ' will sound a "chirp" of ascending frequency as will:
  561.     CALL CHRP(1)
  562.  
  563.  
  564.  
  565.     Name: CLON, CLOFF          Type: KEYBOARD          Level: BIOS
  566.  
  567.     Neither of these take an argument or pass a parameter.  They simply
  568.     engage (CLON) or disengage (CLOFF) the Caps Lock key.
  569.  
  570.     CALL CLON
  571.     CALL CLOFF
  572.  
  573.  
  574.  
  575.     Name: CLRKBD              Type: Misc               Level: BIOS
  576.  
  577.     Clear the keyboard buffer of any and all waiting keystrokes.  This is
  578.     an effective way of eliminating type-ahead in critical portions of your
  579.     program
  580.  
  581.     CALL clrkbd
  582.  
  583.  
  584.  
  585.     Name: CMDLINE              Type: STRING            Level: QB
  586.  
  587.     Read the command line into an array for return to calling program.
  588.     Whatever is on the command line will be returned with all leading and
  589.     trailing blanks removed.  Any delimiter that you instruct the user to
  590.     specify WILL be included in each element of the array, though no special
  591.     character is required other than a space.  That is,
  592.  
  593.     QBPROG /NC /DEF
  594.     will return 2 items in the array, "/NC" and "/DEF".
  595.     If so instructed, you could just as easily instruct the user to start
  596.     the program with:  QBPROG NC DEF or QBPROG -NC -DEF
  597.     It will be up to you to determine which, if any, delimiter is used, just
  598.     remember, CMDLINE only parses the command line it does not strip
  599.     "special" characters (other than blanks) from it.
  600.  
  601.        The string array ARG$ should be dimensioned to the MAXIMUM number
  602.     of command line arguments that you expect or that your application
  603.     has available or allows (in case ALL of them are called).
  604.  
  605.  
  606.  
  607.        Q simply tells the routine the offset in the array to start
  608.     storing the different arguments ie q=4 would place the first retieved
  609.     argument in ARG$(4).  This is to allow placement in a config array and
  610.     to allow for OPTION BASE 0 and 1.  After the call, Q may or may not
  611.     indicate the correct number of arguments passed, depending on your
  612.     OPTION BASE setting.
  613.  
  614.     Syntax:
  615.     -------
  616.     DIM arg$(x) : q=1
  617.     CALL cmdline(arg$(),q%)
  618.  
  619.     Q returns the number of elements in the array starting at position 1,
  620.     and arg$() holds the command line parameters.
  621.  
  622.  
  623.  
  624.  
  625.     Name: CPUINFO              Type: BIOS, Hardware    Level: Hardware
  626.  
  627.     This is a fairly comprehensive routine to determine just what is in the
  628.     system.  A few people had asked for some routines to determine how
  629.     fast a system is running, this is product of those requests.
  630.  
  631.  
  632.  
  633.     This routine returns several things:
  634.     1) ID Code - This is the byte in low memory, that is supposed to help
  635.                  identify the type or class of machine.  It is probably 90%
  636.                  accurate (I have seen very cheap clones return pure garbage
  637.                  regarding what type machine they are).
  638.      The codes range from 249 to 255:
  639.         255 - Original PC type          254 - Some Later PC's, original XT's
  640.         253 - PCjr                      252 - 286 class, PS/2 Model 50 or 60
  641.         251 - XT/286 type machine       250 - PS/2 Model 30
  642.         249 - Convertible               248 - PS/2 Model 80
  643.  
  644.  
  645.     The machine also contains a revison level code called the revision level
  646.     to help distinguish the original 6 Mhz AT from the 8 and the Model 50.
  647.     The revision level is not yet returned by GIZLIB, but will at some time
  648.     in the future.  This revision level helps differentiate a Model 50 from
  649.     a Model 60 from a AT.
  650.  
  651.  
  652.  
  653.     2) CPU type installed, NDP type:
  654.        CPU returns the significant numbers in the central processor
  655.     identification and NDP returns info on any numerical processor:
  656.            Type      CPU parameter        Type       NDP parameter
  657.            ----      -------------        ----       -------------
  658.            8086           86              None            0
  659.           NEC V30         30              8087            87
  660.            8088           88              80287          287
  661.           NEC V20         20              80387          387
  662.            80186          186
  663.            80188          188
  664.            80286          286
  665.            80386          386
  666.  
  667.     Syntax:
  668.     -------
  669.     idcode=0 : cpu=0 : ndp=0
  670.     CALL cpuinfo(idcode%, cpu%, ndp%)
  671.  
  672.  
  673.  
  674.     Name: DATE                 Type: Time and Date     Level: BIOS
  675.  
  676.     Return the current system date information.  Day, month, year and day of
  677.     the week (1 - 7) are returned as integers.  The day of the week itself
  678.     is helpful, but the day, month and year can be immediately used in
  679.     DFRMAT.
  680.  
  681.     Syntax:
  682.     d=0 : m=0 : y=0 : w=0               ' be sure to do this
  683.     CALL date(m, d, y, w)
  684.  
  685.  
  686.  
  687.     Name: DAYOFYR              Type: Misc             Level: ASM
  688.     FUNCTION
  689.  
  690.       This simply returns the day of year as an integer.  It is accurate
  691.     for dates of 01-01-1980 to 02-28-2100 (The year 2100 is a centenial skip
  692.     leap year - every 400 years we skip a leap year).  This is a FUNCTION
  693.     that works off the current system date, returning the day count in the
  694.     FUNCTION name.
  695.  
  696.     Syntax:
  697.     DECLARE FUNCTION dayofyr%
  698.     .
  699.     .
  700.     todaycount =  dayofyr
  701.  
  702.  
  703.  
  704.     Name: DFRMAT               Type: String            Level: QB
  705.  
  706.        Allows for DATE formatting.  The routine will pass back a date
  707.     string formatted, for you to do whatever with.  This is handy in
  708.     formatting DOS/BASIC's sterile date format into something that has a
  709.     more pleasing appearance on the screen.
  710.        You pass it valid integers representing the day, month and year, and
  711.     DFRMAT returns a string similar to "August 1, 1987".  You can pass
  712.     integers culled from BASIC's DATE$, those from DATE or any integer
  713.     represeting a vaild date.
  714.        DFRMAT has a lower range of 1800 as the year, and any year passed
  715.     that is lower than 1800 had 1900 added to it, making 87 as valid an
  716.     argument as 1987.
  717.  
  718.     Syntax:
  719.     m=8 : d=1 : yr=87
  720.     CALL dfrmat(m, d, yr, nudate$)
  721.     PRINT nudate$                   ' output is August 1, 1987
  722.  
  723.     Alternative:
  724.     m=0 : d=0 : y=0 : w=0
  725.     CALL date(m, d, y, w)
  726.     CALL dfrmat(m, d, y, nudate$)
  727.  
  728.  
  729.  
  730.     Name: DIR                  Type: DOS / File        Level: DOS
  731.  
  732.     DIR is actually a facade for 2 separate routines called FIRSTF and
  733.     NEXTF to get the first filename matching a mask, then each of the other
  734.     files matching that mask.
  735.  
  736.     To use them individually:
  737.     mask$="*.bas"               ' any legal DOS mask will work
  738.     fil$=SPACE$(12)             ' IMPORTANT!
  739.     CALL firstf(mask$, fil$)    ' gets 1, the first name
  740.  
  741.     FOR x=1 to MaxFileCount     ' Use FILCNT to determine MaxFileCount
  742.        fil$=SPCAE$(12)
  743.        CALL nextf(fil$)         ' no mask
  744.     NEXT x
  745.  
  746.  
  747.     I have provided a file called DIR.SUB that handles much of this and
  748.     stores all the names found in an array.  To Use:
  749.     CALL filcnt(mask$, quan)         ' get how many there are
  750.     REDIM fil$(qaun)                 ' size array to fit
  751.  
  752.     CALL dir(mask$, fil$(1))         ' dir will fill it up with names.
  753.  
  754.  
  755.  
  756.     Name: DLIGHT               Type: System           Level: BIOS
  757.     FUNCTION
  758.  
  759.        DLIGHT triggers the A: or B: drive light for the length of a 2
  760.     sector disk read.  This is helpful in demo or training programs to
  761.     add realism to the session.  It uses a BIOS level diskette service call
  762.     and will return a FUNCTION error of -1 if you attempt to invoke it on
  763.     a drive other than 0 or 1 (A: and B: respectively).  On the otherhand,
  764.     the drive light will come on even if the drive is open without causing
  765.     a "Drive Not Ready" error!
  766.  
  767.     Syntax:
  768.     DECLARE FUNCTION dlight%(drive%)
  769.     .
  770.     .
  771.     IF dlight(drv%) THEN
  772.        PRINT "Hey, dummy - I said A: or B: !")
  773.     END IF
  774.  
  775.  
  776.  
  777.     Name: DLRFRMAT             Type: String            Level: QB
  778.  
  779.     This allows you to read input from a user in an application, and format
  780.     it in various ways to currency conventions.  Your options include
  781.     allowing a "$" in front or not: if you allow it, DLRFRMAT will check to
  782.     see if it is there and add it if it is not; if you do not want it, it
  783.     will strip it off if it is entered.  You also are allowed to format it
  784.     out to 2 or 3 decimals (tenths of a cent).  This is useful for pay rates
  785.     in restaurants or sales people on commissions who will often get paid
  786.     rates to the tenth of a cent.
  787.  
  788.     Parameters:
  789.  
  790.     nst$=String containing only numbers, "." or "$" to be formatted.
  791.  
  792.     Mode 0 - Return numeric string without leading "$", forcing the
  793.              entry of a ".".   If an element of the string is a period,
  794.              an error is generated.
  795.  
  796.     Mode 1 - Returns the numeric string with a leading "$" (does not matter
  797.              if it is passed or not), and forces "." as an element.
  798.  
  799.     Use the 2 foloowing modes with caution (if ever since ASSUMING the
  800.     decimal position could be dangerous, however restoring dollar values to
  801.     correct format from a random file, these modes help TREMENDOUSLY):
  802.     Mode 2 - Strips any "$" present in the string, and assumes that if no
  803.              decimal point is passed that it is the last element.
  804.  
  805.     Mode 3 - Returns string with a leading "$", assumes that if no deciaml
  806.              point is passed that it is the last element.
  807.  
  808.     For logistical reasons, you must make sure that the mode parameter
  809.     passed matches the least dangerous format.  There is a big difference
  810.     between "$1.23" and "$12.30" and "$123.00", so you have the choice of
  811.     forcing DLRFRMAT to return an error if one character in the string is
  812.     NOT a ".".  You may also disable the forced error and assume that if
  813.     there is no ".", that one should be appended to  the end of the string:
  814.     ie "$123" is assumed to be "$123.00" NOT "$1.23" in this mode.
  815.  
  816.  
  817.  
  818.     P is used to tell DLRFRMAT how many decimals to pad to:
  819.          2 - pads "123." to "123.00"
  820.          3 - pads "45.1" to "45.100"
  821.          0 - automatic dollar decimal placement:
  822.             "5" becomes ".05",
  823.             "70" becomes ".70"
  824.             "146" becomes "1.46"
  825.  
  826.     Syntax:
  827.     -------
  828.     m=1 : p=3
  829.     INPUT "Enter your wage: ",nst$              'user keys '7.50'
  830.     CALL dlrfrmat(nst$,m%,p%)
  831.     wag$=nst$
  832.     PRINT nst$                                  'output: $7.500
  833.  
  834.  
  835.  
  836.     Note that in the case of an error, nst$ will return an appropriate error
  837.     message and m will indicate an error code.  This allows you to test the
  838.     return numerically by comparing m to 0,1,2 or 3.  You can then send the
  839.     error string to the screen or route the code to your own error handling.
  840.  
  841.     m=50  nst$="Programmer error invalid number of decimals" [p not set
  842.                right to 2 or 3]
  843.     m=99  nst$="Invalid cahracters in input!".  [The string passed
  844.           had ASCII characters above 57 ("9")] *
  845.     m=98  nst$="Invalid characters in input!"   [The string passed had
  846.           ASCII characters below 48 ("0")]  *
  847.     m=97  nst$="You must enter a decimal point!".  One decimal must be
  848.           passed if modes 0 or 1 are used.
  849.  
  850.     *   In both of these cases, p points to the position in string of the
  851.         errorroneous character. If p=4 then there is an error 4 places
  852.         right of any "$".
  853.  
  854.  
  855.  
  856.     Name: DLY                  Type: Misc              Level: BIOS
  857.  
  858.     DLY will pause a given number of seconds to allow the user to read a
  859.     display that you may have sent to the screen.
  860.  
  861.     Syntax:
  862.     -------
  863.     sec=5 :  CALL DLY(sec%)            '     or    CALL DLY(5)
  864.  
  865.     Either form will pause processing for 5 seconds.  DLY is assembler based
  866.     so pass only integers,  2.6 will crash the system.  If passing
  867.     by variable (the first example above), you must specify "sec" as an
  868.     integer when calling DLY (or declare all variables as an integer with a
  869.     DEFINT A-Z
  870.  
  871.  
  872.  
  873.     Name: DOSV                 Type: DOS               Level: DOS
  874.  
  875.     Returns the DOS Version the system is running under.  This returns a
  876.     whole number rather than the major and minor version numbers that you
  877.     might be familiar with.  On the other hand, the number returned must be
  878.     divided by 100 to convert it to conventional terms.  That is, DOS 2.11
  879.     will be returned as 211, where dividing by 100 will yeild the more
  880.     conventional 2.11 version.
  881.  
  882.  
  883.  
  884.     Name: DRVSPACE             Type: Disk              Level: DOS
  885.  
  886.     Returns Total clusters, bytes per sector, available clusters, and
  887.     sectors per cluster for the specified drive, allowing you to determine
  888.     the overall drive space and/or free space.
  889.  
  890.     Parameters:
  891.     a - drive number to poll, 1= A:, 2=B: etc; 0 = default.
  892.         Returns sectors per cluster
  893.     b - Returns available count of available clusters
  894.     c - Returns bytes per sector
  895.     d - Total clusters on drive
  896.  
  897.     Syntax:
  898.     a=0        ' read default drive
  899.     CALL drvspace(a%,b%,c%,d%)
  900.  
  901.     total#=CDBL(a%)*CDBL(c%)*CDBL(d%)
  902.     free#=CDBL(a%)*CDBL(c%)*CDBL(b%)       'total#=CDBL(a%*c%d%) won't work
  903.  
  904.  
  905.  
  906.     Name: ERRMSG               Type: Video             Level: BIOS
  907.  
  908.     ERRMSG is a fairly complex, very useful sub program completely in
  909.     assembler designed to flash a programmer defined message to the screen
  910.     pause 2 secs, then restore the screen.  It can be used for more than
  911.     just error messages, but since it restores the screen after the message
  912.     display, it seems best suited to error messages.  You determine the
  913.     line to use, the subroutine automatically centers the message.
  914.  
  915.  
  916.     Parameters:
  917.     msg$= Message to display
  918.     lin = Line for message to display on
  919.     attr = attribute to use (indicates foreground and background color
  920.            in one variable).  Calculated by the formula:
  921.            (BACKGROUND.COLOR * 16) + FOREGROUND.COLOR
  922.     sfx = Sound effects.  0=none 1=low tone
  923.  
  924.     Syntax:
  925.     msg$="You must enter a customer name!"
  926.     lin=15 : attr=31 : sfx=2
  927.     CALL errmsg(msg$, lin, attr, sfx)
  928.  
  929.  
  930.  
  931.     Output would be a low tone beep and high intensity white letters on a
  932.     dark blue background.  The message is centered on line 15.  The abilty
  933.     to choose the display line allows you to for instance, place the above
  934.     message right over the entry area for the customer name.  After the
  935.     error message is displayed, there is a 2 sec pause and the screen is
  936.     restored.
  937.  
  938.     Note: NFRMAT and DLRFRMAT in case of errors, returns an error message
  939.     suitable for use directly in ERRMSG.  For example DLRFRMAT returns an
  940.     error status in the mode parameter AND a message designed for the end
  941.     user in the string parameter.  Your code can determine an error status
  942.     via the change in mode and without knowing (or caring) what the error
  943.     is send the string message to the end user, then loop back to the data
  944.     entry point.
  945.  
  946.  
  947.  
  948.     Name: EXIST                Type: Disk / File       Level: DOS
  949.     FUNCTION
  950.  
  951.        This routine returns a zero value or if the given file DOES NOT
  952.     exist, and a non zero value (-1 actually) if it does.  There is no need
  953.     for you to ludicrously append a CHR$(0) to the filename, assembler is
  954.     very capable of doing that.
  955.         If you have scads of code that already calls a file exist test that
  956.     DOES add the null to the end of the filename prior to the call, you need
  957.     not change it, since the first null marks the EOS to the assembler
  958.     routine.
  959.  
  960.     Syntax:
  961.     DECALRE FUNCTION exist%(fil$)
  962.     IF exist("foo.bar") THEN PRINT fil$;" already exists! Overwrite?"
  963.  
  964.  
  965.  
  966.     Name: EXTMEM               Type: Misc              Level: DOS
  967.  
  968.     Returns the amount of extended, or AT memory, installed in a 286 based
  969.     machine.  This only works on AT's or AT clones.
  970.  
  971.     mem=0 : CALL extmem(mem%)
  972.     PRINT "AT has ";mem;" of extended memory installed."
  973.  
  974.  
  975.  
  976.     Name: FADE                 Type: Video             Level: BIOS
  977.  
  978.     This is an interesting alternative to CLS.  It quickly reads the
  979.     character at each location on the screen and decrements the ASCII value
  980.     of it until it reaches 32 (space).  The attribute (color) remains the
  981.     same during and after the FADE.
  982.  
  983.     Syntax:
  984.     CALL fade
  985.  
  986.  
  987.  
  988.  
  989.  
  990.     Name: FCLOSE               Type: Disk             Level: DOS
  991.     FUNCTION
  992.  
  993.       As expected FCLOSE performs the opposite of FOPEN, close out a file
  994.     handle open via FOPEN.  FCLOSE does some positive error checking to
  995.     make sure that you do not attempt to close one of the standard DOS file
  996.     handles (like the keyboard, monitor etc) and will return a error code of
  997.     6 - Invalid File handle.
  998.  
  999.     See also FOPEN FUNIQ, FCREAT, FEOF, DOS File Functions (preceeding
  1000.     the reference section).
  1001.  
  1002.     Syntax:
  1003.     DECLARE FUNCTION fclose%(fhandle)
  1004.     .
  1005.     .
  1006.     result = fclose(fhandle)
  1007.     IF result THEN GOSUB error.control
  1008.  
  1009.  
  1010.  
  1011.  
  1012.     Name: FCREAT               Type: Disk             Level: DOS
  1013.     FUNCTION
  1014.  
  1015.       FCREAT is similar to FOPEN except that instead of opening an existing
  1016.     file, we are CREATING a NEW file.  As with FOPEN, and all the DOS File
  1017.     Functions, error codes returned in the BASIC FUNCTION format and are:
  1018.     -1    Null string passed
  1019.      3    Path not found
  1020.      4    No handle available ("Too many files")
  1021.      5    Access denied
  1022.     Note: You are encouraged to use EXIST first to see if the file already
  1023.     exists, executing FCREAT on an existing file truncates it to 0 bytes.
  1024.  
  1025.     Syntax:
  1026.     DECLARE FUNCTION fcreat%(fil$, attrib%, fhandle%)
  1027.     .
  1028.     .
  1029.     fil$="mainprg.sys": attrib=0
  1030.     IF fcreat(fil$, attrib, fhandle)=0 THEN
  1031.        PRINT "New file, ";fil$;" successfully created!"
  1032.     ELSE
  1033.        GOSUB whats.going.on
  1034.     END IF
  1035.  
  1036.  
  1037.  
  1038.  
  1039.     Name: FCOPY                Type: Disk/File        Level: DOS
  1040.     FUNCTION
  1041.  
  1042.       This function copys a disk file using an internal buffer, allowing it
  1043.     to perform about as fast as the DOS COPY command.  You pass it a source
  1044.     and destination string (paths / drives are ok).  The FUNCTION returns
  1045.     a variety of error conditions:
  1046.     -1 = Null string passed as source or dest.
  1047.      2 = File Not Found
  1048.      3 = Path not Found
  1049.      4 = No Handle ("Too Many Files")
  1050.      5 = Access Denied
  1051.  
  1052.        Syntax:
  1053.     DECLARE FUNCTION fcopy%(source$, dest$)
  1054.     .
  1055.     .
  1056.     result = fcopy("GLIB140.ARC","\GOODSTUFF\SAVE\GLIB140.ARC"
  1057.     IF result THEN PRINT "Oops!  Error - Check parameters!"
  1058.  
  1059.  
  1060.  
  1061.  
  1062.     Name: FED                  Type: String, I/O       Level: QB
  1063.  
  1064.     This is a very comprehensive text input routine that allows you
  1065.     extensive control over user input.  It too, is CALLed to exert control
  1066.     over the user's input, recognizing all cursor keys and most function
  1067.     keys.
  1068.  
  1069.     There are several things that sets this text input routine apart from
  1070.     ALL others you may see and be tempted to try out:
  1071.     1 - It is self contained and standalone.  It depends on NO external
  1072.         routines from this library or others.
  1073.     2 - The function keys are completely soft coded.  Hitting one exits the
  1074.         routine and returns control to you but exerts no editting control
  1075.         on the text such as clearing, tabbing etc.  This allows that the
  1076.         function keys can be used for a WIDE variety of purposes in ALL
  1077.         your application such as paging thru records in a database, Help
  1078.         and so forth.  (See FED-DEMO)
  1079.     3 - Requires no special compile switches even though it recognizes
  1080.         cursor and function keys.
  1081.     4 - Sensible configuration.  Thru the use of a COMMON block (clearly
  1082.         exemplified in the demo), you have COMPLETE control over colors,
  1083.         sound etc without having to explicitlty set and pass formal
  1084.         parameters for each call.  Furthermore, as a /block/, it does not
  1085.         monopolize all the COMMON space, and requires a paltry
  1086.         (20 + LEN(num$) ) bytes of COMMON DGROUP memory.
  1087.     5 - The comprehensive FED-DEMO not only clearly shows how to use it
  1088.         with a variety of other GLIB routines, but also shows a few
  1089.         intricasies of using FED with QB4 data structures.
  1090.  
  1091.                       DO NOT be misled by others,
  1092.                          FED, Field EDitor,
  1093.                   is the one they are impersonating.
  1094.  
  1095.     Complete documentation and use is in FED.DOC.
  1096.  
  1097.  
  1098.  
  1099.     Name: FEOF                 Type: Disk             Level: DOS
  1100.     FUNCTION
  1101.  
  1102.        Sets the file pointer to the end of a file opened via FOPEN.  This
  1103.     actually sets the pointer to ONE BYTE less than the end of the file.
  1104.     This is to be sure that subsequent FWRITE funtions overwrite the hard
  1105.     EOF marker (ASCII 26) left by some text editors.  Additionally, FEOF
  1106.     checks for invalid handles as well as the 4 standard DOS handles and
  1107.     aborts to return an error code of 6 - Invalid handle.
  1108.  
  1109.     Syntax:
  1110.     DECLARE FUNCTION feof%(fhandle%)
  1111.     .
  1112.     .
  1113.     IF fopen("longtext.fil", 0, fhandle) THEN
  1114.        GOTO start.new.file
  1115.     ELSE
  1116.        j= feof(fhandle)
  1117.        IF j THEN GOSUB weird.error
  1118.        GOTO append.to.text
  1119.     END IF
  1120.  
  1121.  
  1122.  
  1123.     Name: FOPEN                Type: Disk             Level: DOS
  1124.     FUNCTION
  1125.  
  1126.       FOPEN is a standard DOS function to open a file via a file handle.
  1127.     FOPEN requires a 'mode' be passed, 1 = multitasking or networking,
  1128.     0 = normal.  There is a way to set access rights (read, write,
  1129.     read/write) that also may be implemented later.  FOPEN should not be
  1130.     used to open a device such as a printer, but DOS does reserve a special
  1131.     handle for your printer (see: "Dos File Functions" above.)
  1132.        In order to keep the number of parameters down, the fhandle parameter
  1133.     is used to pass back the file handle and FOPEN is designed as a FUNCTION
  1134.     in assembler to return any error codes the same as a FUNCTION operates
  1135.     in BASIC.
  1136.        An error can occur if the file handle is invalid, the file is already
  1137.     open, file not found etc.  In this case, the errorcode or result will
  1138.     indicate what happened and any fhandle number should be ignored.
  1139.  
  1140.     Syntax:
  1141.     DECLARE FUNCTION fopen%(fil$, mode%, fhandle%)
  1142.     .
  1143.     .
  1144.     fil$="myprog.dat" : mode=0
  1145.     IF fopen(fil$, mode, fhandle) THEN
  1146.         GOSUB file.error
  1147.     ELSE
  1148.         PRINT fil$;" opened with a handle of ";fhandle
  1149.     END IF
  1150.  
  1151.  
  1152.  
  1153.     Name: FUNIQ                Type: Disk             Level: DOS
  1154.     FUNCTION
  1155.  
  1156.        This DOS disk file function creates a file with a unique name, which
  1157.     makes it ideal for scatch data files.  Rather than HOPING that
  1158.     "mydat.@@@" is a unique filename, FUNIQ makes SURE that a file is infact
  1159.     unique.  DOS will create such a file in the specified directory and open
  1160.     it with read write access with the attributes you specify.
  1161.        Furthermore, FUNIQ can, at your option, return the actual file NAME
  1162.     as well as the handle.  Enter the call with a string containing the
  1163.     desired drive and path where you want the unique file created, BE SURE
  1164.     to include a trailing backslash ("\")!   FUNIQ will return a file handle
  1165.     or error code and if you add 12 trailing spaces to the pathname, it will
  1166.     return the filename.
  1167.         More often than not, the unique name will be just 8 chars long, but
  1168.     if not it would only return part of the name.  When the unique name IS
  1169.     less than 12 characters the name will be padded with spaces which allows
  1170.     you to use BASIC's native RTRIM$ to fix it.
  1171.  
  1172.        NOTE: The unique file is OPEN with a handle!  Subsequent file access
  1173.     should be thru FWRITE et all or FCLOSE the handle and then access the
  1174.     filename via BASIC functions.
  1175.        NOTE: Use of FUNIQ requires DOS 3.0 or greater.
  1176.  
  1177.        See 'DOS File FUNCTIONS' for possible error returns
  1178.  
  1179.  
  1180.     Syntax:
  1181.     DECLARE FUNCTION funiq%(fil$, attrib, fhandle%)
  1182.     ..
  1183.     ..
  1184.     tempfil$="C:\BIN\            "
  1185.     IF funiq(fil$, 0, fhandle) THEN              ' path, normal file
  1186.        GOSUB invalid.path
  1187.     ELSE
  1188.        j=fclose(fhandle)                         ' close the handle
  1189.        tnum=FREEFILE                             ' get BASIC handle
  1190.        OPEN tempfil$ FOR APPEND AS #tnum         ' reopen file in BASIC mode
  1191.     END IF
  1192.  
  1193.  
  1194.  
  1195.     Name: FWRITE               Type: Disk             Level: DOS
  1196.     FUNCTION
  1197.  
  1198.       FWRITE sends simple strings to the file or device using a handle
  1199.     gotten from FOPEN.  DOS and FWRITE will handle larger data writes such
  1200.     as an array, but I am holding off implementing new array routines until
  1201.     we see what MicroSoft does with their array handling.
  1202.       An error may be generated for the same reasons as FOPEN, the error
  1203.     code is returned as a FUNCTION so as not to destroy the fhandle
  1204.     variable.
  1205.     Note: Be sure to include carriage returns and line feeds as needed, DOS
  1206.     takes nothing for granted!
  1207.     See 'DOS File Function for possible Error Returns'
  1208.  
  1209.     Syntax:
  1210.     DECLARE FUNCTION fwrite%(text$, fhandle%)
  1211.     ..
  1212.     ..
  1213.     tempfil$="C:\BIN\            "
  1214.     IF funiq(fil$, 0, fhandle) THEN              ' path, normal file
  1215.        GOSUB invalid.path
  1216.     ELSE
  1217.        text$="This is my data file - do not touch!"+CHR$(13)
  1218.        j=fwrite(text$,fhandle)                   ' write to the file
  1219.        IF j=6 THEN
  1220.            GOSUB invalid.handle                  ' error ?
  1221.        ELSE
  1222.            ignore = fclose(fhandle)              ' close file - we are done
  1223.     END IF
  1224.  
  1225.  
  1226.  
  1227.     Name: GETCH                Type: Keyboard         Level: BIOS
  1228.  
  1229.        Return keystroke from allowable string of selections.  Pass this
  1230.     routine a string of okay characters (in upper case) it will return
  1231.     which of those were pressed.  GETCH ignores input other than those
  1232.     characters in the okay$.  If passed a null GETCH string or a null
  1233.     return string, GETCG will return the first key pressed.  Additionally,
  1234.     2 features found in GETCH not in other routines of this nature, is that
  1235.     it will not get confused by any ANSI keyboard redefintitions and when
  1236.     used on a network, will not hang the terminal or server when called.
  1237.     See also PGETCH.
  1238.  
  1239.     Syntax:
  1240.     PRINT "Are You Sure?": ky$=" "
  1241.     CALL getch("YN", ky$)             ' allows input of Y or N only
  1242.  
  1243.  
  1244.  
  1245.     Name: GETFATTR             Type: Disk             Level: DOS
  1246.     FUNCTION
  1247.  
  1248.       Access to get the file attributes for a given file.  Subsequent calls
  1249.     to SETFATTR (see also) allow you to set or reset a file attribute.
  1250.     File attributes are as follows:
  1251.         00  -  Normal             04  -  System
  1252.         01  -  Read Only          32  -  Archive
  1253.         02  -  Hidden
  1254.  
  1255.  
  1256.  
  1257.       The archive bit is usually used by back up programs to determine if
  1258.     a file has been backed up since the last write process.  To combine
  1259.     attributes, just add the values, ie: Read Only - Hidden would be 3
  1260.     because 1+2=3.
  1261.        This is a function and therefore also returns any error code in the
  1262.     name of the function that can be evaluated itself, or assigned.  An
  1263.     error will result if the filename passed is not found (6).
  1264.     Error Codes:
  1265.     -1 = Invlid File attribute
  1266.      2 = File not found
  1267.      3 = Path not found
  1268.      5 = Access denied
  1269.  
  1270.     Syntax:
  1271.     DECLARE FUNCTION getfattr%(fil$, attrib%)      ' do before CLEAR or DEF
  1272.     .
  1273.     .
  1274.     fil$="myfil.txt"
  1275.     failure = setfattr(fil$, attrib)
  1276.     IF failure THEN PRINT "Sorry, cannot filnd ";fil$
  1277.  
  1278.  
  1279.  
  1280.     NAME: GETDSEG              Type: Misc              Level: Assembler
  1281.  
  1282.        This is more a development utility than a usable subroutine.  This
  1283.     returns BASIC's default Data Segment (DS).  In tinkering with calling C
  1284.     and routines from other languages, I've found this useful in making
  1285.     sure that the data segment is intact, also this may be required in
  1286.     determining parameters for routines in future releases.
  1287.  
  1288.     Syntax:
  1289.     dataseg=0
  1290.     CALL getdseg(dataseg)
  1291.  
  1292.  
  1293.  
  1294.     NAME: GETSTACK             Type: Misc              Level: Assembler
  1295.  
  1296.        Returns the state of BASIC's stack.  This is very helpful in
  1297.     determining what (if any) the stack should be set to, via a
  1298.     'CLEAR,,xxxx' statement at the start of your program.  The stack grows
  1299.     DOWNWARD with each successive GOSUB, so at strategic points in your
  1300.     code, calling GETSTACK and comparing it to the state of the STACK at
  1301.     the start of the program, aids in determining if you do need to include
  1302.     a stack statement at the start.
  1303.  
  1304.     stack=0
  1305.     GETSTACK(stack)
  1306.  
  1307.  
  1308.     NAME: GETVERFY             Type: DOS/System        Level: Assembler
  1309.  
  1310.        Returns the current VERIFY setting of the system.  This is NOT a
  1311.     read-after-write test as some think, but is where DOS does a CRC check
  1312.     of data just written to make sure it is write.  To CHANGE the VERIFY
  1313.     switch, use SETVERFY.  This routine returns 0 for OFF, nonzero for ON.
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.     NAME: GETDRV               Type: DOS               Level: Assembler
  1320.  
  1321.        This gets the default disk drive.  It returns an uppercase letter to
  1322.     avoid the confusion of drive numbering.  Again, since assembler
  1323.     routines cannot alter string lengths, be SURE to initialize the string
  1324.     variable to (at least) one space.
  1325.  
  1326.     Syntax:
  1327.     drv$=" "
  1328.     CALL getdrv(drv$)
  1329.  
  1330.  
  1331.  
  1332.     Name: GRAPH                Type: VIDEO             Level: QB
  1333.  
  1334.     This is an interesting sub-program.  It is one that you might not
  1335.     use very often, but should you ever need to figure out the algorithm to
  1336.     print either a vertical or horizontal graph based on a set of elements
  1337.     that you may or may not know the exact values of.
  1338.  
  1339.     Parameters:
  1340.     elements%() - holds the integer values to be graphed.
  1341.     basis%      - the total value basis.  In most cases this might be
  1342.                   the total of all the array elements, but in some cases,
  1343.                   you might only be graphing a portion of the total, ie an
  1344.                   "Other" or "Misc" category might not be included in the
  1345.                   elements% array, but for graphic accuracy, their total
  1346.                   would need to be part of the dividend used in GRAPH to
  1347.                   determine bar lengths.
  1348.     label$()    - A set of string labels corresponding to the elements%
  1349.                   array, to be placed below each bar.
  1350.     title$      - Title to be centered across the top of the graph.
  1351.  
  1352.  
  1353.     Unfortunately, at the present time due to screen limitations, the two
  1354.     graph routines handle a maximum of 10 elements to graph.  If passed
  1355.     more than 10, GRAPH will only plot the first ten items.  On the other
  1356.     hand, if passed less than 10 items to plot, GRAPH will adjust the
  1357.     spacing between each bar for aesthetics.  GRAPH will not plot 1 item.
  1358.  
  1359.     Syntax:
  1360.     ' stuff elmts%() with the values to be graphed
  1361.     ' stuff label$() with corresponding labels to use
  1362.     bas=145       'or whatever the total graphed and non-graphed items are
  1363.     title$ = "Productivity Graph"
  1364.  
  1365.  
  1366.    ' produce vertical graph:
  1367.     CALL vgraph(elmts%(), bas%, label$(), title$)
  1368.  
  1369.    ' produce horizontal graph:
  1370.     CALL hgraph(elmts%(), bas%, label$(), title$)
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.     Name: INCR / DECR          Type: Misc             Level: ASM
  1377.  
  1378.        There are people out there who made the tragic mistake of getting
  1379.     into one of those inferior BASIC dialects, and are having trouble
  1380.     adapting to QB.  INCR and DECR are meant to help alleviate this.
  1381.     If DECLARED as a SUB, they will work just like Turbo BASIC's native
  1382.     functions of the same name.
  1383.  
  1384.     Syntax:
  1385.     DECLARE SUB Incr%(x, y)
  1386.     DECLARE SUB Decr%(x, y)
  1387.     ..
  1388.     ..
  1389.     Incr i, 5                      ' same as i=i+5
  1390.     Decr j, q                      ' same as j=j+q
  1391.  
  1392.  
  1393.  
  1394.     Name: INSON / INSOFF       Type: Keyboard         Level: ASM
  1395.  
  1396.       This subroutine, simple puts the keyboard into INSERT ON state (INSON)
  1397.     or turns the insert toggle off (INSOFF).
  1398.  
  1399.     Syntax:  CALL inson
  1400.              CALL insoff
  1401.  
  1402.  
  1403.  
  1404.     Name: LASTDRV              Type: Disk / Sysytem   Level: DOS
  1405.     FUNCTION
  1406.  
  1407.        Returns the last logical drive installed in the system.  This returns
  1408.     the drive in DOS designator format, but the example shows the somple
  1409.     conversion to a letter.   This function will not alter the logged drive.
  1410.  
  1411.     Syntax:
  1412.     DECLARE FUNCTION lastdrv%
  1413.     ..
  1414.     ..
  1415.     drv=lastdrv
  1416.     drv$=CHR$(drv+65)+":"
  1417.  
  1418.  
  1419.  
  1420.     Name: LCOUNT              Type: Disk/String        Level: ASM
  1421.     FUNCTION
  1422.  
  1423.        This is a nifty routine to scan a disk text file for ASCII 13
  1424.     (carriage return) and will count them.  This is handy for sequential
  1425.     file I/O where you might want to inform the user how long processing
  1426.     will take or to replace a WHILE NOT EOF(x)....WEND loop with a
  1427.     FOR x=1 to LineCount....NEXT x loop.
  1428.        LCOUNT is a function that requires a valid file handle via FOPEN
  1429.     and an attempt to LCOUNT a standard DOS handle (1-4) will result in
  1430.     a LCOUNT of -1.  LCOUNT uses an internal 5 k buffer so it is incredible
  1431.     fast: GLIBDEMO at 50K takes only .5 seconds to count on an AT.
  1432.  
  1433.  
  1434.  
  1435.  
  1436.     Syntax:
  1437.     DECLARE FUNCTION lcount%(fhandle%)
  1438.     ..
  1439.     ..
  1440.     fil$="GLIBDEMO.BAS"                    ' text, not QB quick save format!
  1441.     result = fopen(fil$, 0, fhandle)
  1442.     IF result = 0 THEN
  1443.         LineCount=lcount(fhandle)
  1444.         IF LineCount > 0 THEN
  1445.            GOSUB calc.time
  1446.            PRINT fil$;" will require ";CalcResult;" minutes to process."
  1447.         ELSE
  1448.            GOSUB error.control
  1449.         END IF
  1450.     ELSE
  1451.         GOSUB error.control
  1452.     END IF
  1453.  
  1454.  
  1455.  
  1456.  
  1457.     Name: LNAMEF               Type: String           Level: ASM
  1458.     FUNCTION
  1459.  
  1460.       This data entry routine is handy for rearranging names from some
  1461.     other source to convert them to "Lastname, FirstName".  It works on
  1462.     names of all types, those with middle initials, just first and middle
  1463.     initials, multiple middle names.  It does not work correctly on Jrs,
  1464.     people who are the II, III or IV (ad nauseum).  In this case, I'd
  1465.     suggest using BASIC's INSTR and LEFT$ to trim off the Jr or II etc and
  1466.     append it after the LNAMEF call.
  1467.  
  1468.       All that is required is that the name have one single trailing space
  1469.     and another space where the names get swapped.  The function will fail
  1470.     and return a -1 if either condition is found to be not true. Samples:
  1471.  
  1472.     "Mary Beth J. Sandra Brooks " =>  "Brooks, Mary Beth J. Sandra"
  1473.     "P. T. Barnum Bailey "        =>  "Bailey, P. T. Barnum"
  1474.     "Thomas Q. Hanlon III "       =>  "III, Thomas Q. Hanlon"
  1475.     "John Public"                 => "John Public"  This one fails due to no
  1476.                                                     trailing space$
  1477.  
  1478.     Syntax:
  1479.     DECLARE FUNCTION lnamef%(text$)
  1480.     ..
  1481.     ..
  1482.     text$="Roy Burrows"+" "               ' MUST have trailing space
  1483.     result=lnamef(text$)
  1484.     IF INSTR(text$, "IVJrR") THEN GOSUB reformat.name
  1485.  
  1486.     IF result=0 THEN
  1487.        PRINT text$                        ' "Burrows, Roy"
  1488.     ELSE
  1489.        GOSUB reformat.name
  1490.     END IF
  1491.  
  1492.  
  1493.  
  1494.  
  1495.     Name: KBLOOP               Type: Keyboard, I/O     Level: QB
  1496.  
  1497.     This comes in quite handy in a number of situations.  For example:
  1498.     - As part of a waiting for keyboard input, you want to refresh part of
  1499.       the screen such as a time display.
  1500.     - More importantly, if you have a security routine where you have the
  1501.       user enter a logon or ID code, then a function they want to perform,
  1502.       you might want to back up to the security code entry point if after
  1503.       a valid code is entered a number of seconds passes before a
  1504.       function is selected.  In such a situation, someone else on hand
  1505.       would have access to the system or functions under the guise of the
  1506.       identity of the person who entered the security code.
  1507.       Thru the use of KBLOOP, if a function is not selected within a
  1508.       certain number of seconds after the ID is, you can loop the program
  1509.       back to some other starting point.
  1510.  
  1511.  
  1512.     Parameters:
  1513.     kbin$ -  On the call set this to SPACE$(x) where x is the number of
  1514.              characters to wait for ie if kbin$=SPACE$(3), then KBLOOP will
  1515.              loop until the return string is 3 characters long.
  1516.              Returned in kbin$, is the actual characters entered.
  1517.  
  1518.  
  1519.     looptime - This is the length of time you want KBLOOP to loop
  1520.                internally waiting for x characters to be entered.
  1521.                If the time expired, this returns as Zero.
  1522.  
  1523.  
  1524.     Syntax / Example:
  1525.  
  1526.     label1:                 ' demo for a security routine
  1527.     kbin$=SPACE$(3) : LoopTime=30
  1528.     CALL kbloop(kbin$, LoopTime)
  1529.  
  1530.     IF LoopTime=0$ THEN GOTO label1
  1531.     ' This could also be a DO WHILE...LOOP routine.
  1532.  
  1533.  
  1534.  
  1535.     Name: MCSRINC / MCSRDEC    Type: Mouse            Level: BIOS
  1536.  
  1537.        Mouses are curious things.  Each call to turn off the mouse cursor
  1538.     requires an equal number of cursor-on calls to redisplay the cursor.
  1539.     The mouse driver tracks what is called an internal cursor flag.  Each
  1540.     call to turn off the cursor decrements the counter, each cursor-on
  1541.     call increments it and if (and only if) the internal flag is 0, the
  1542.     cursor is displayed.  Therefore each call to decrement the flag, needs
  1543.     one increment call if the cursor is to be displayed.  And this does
  1544.     NOT work the other way, if the cursor is on (flag=0) an additional
  1545.     call to increment the flag has no effect.  Finally, we have no access
  1546.     to be able to read what the cursor flag is to know how many MCSRINC
  1547.     calls we need to make to display the cursor.
  1548.  
  1549.  
  1550.  
  1551.        If you are new to mouse programming, beware: if you update the
  1552.     screen with the mouse cursor on, it will leave little reverse video
  1553.     blocks all over, and at times, doing a MSETXY with the cursor on will
  1554.     produce 2 cursors: one at the old and another at the new location.  To
  1555.     avoid this, turn the mouse cursor off before screen updates, including
  1556.     (indeed, especially with) screen saves and restores and forced mouse
  1557.     cursor relocations.
  1558.        MCSRINC and MCSRDEC do just that - increment or decrement the
  1559.     cursor.  Knowing what you do now, it would make sense to track a copy
  1560.     copy of the internal flag in your program.  If in the course of your
  1561.     program you want to BE SURE that the sursor is on or off, performing a
  1562.     call to MCSRON or MCSROFF will do so.  However in so doing, the mouse
  1563.     is reset: x and y range limits, cursor masks, mickey factors, the
  1564.     works.      SEE ALSO MCSRON, MCSROFF
  1565.  
  1566.     Syntax:                  Logical Equivalence
  1567.     CALL mcsrinc             ' InternalFlag=InternalFlag + 1
  1568.                              ' IF InternalFlag=0 THEN ShowCursor
  1569.  
  1570.     CALL mcsrdec             ' InternalFlag=InternalFlag - 1
  1571.                              ' IF InternalFlag<>0 THEN HideCursor
  1572.  
  1573.  
  1574.  
  1575.  
  1576.     Name: MCSRON / MCSROFF     Type: Mouse            Level: BIOS
  1577.  
  1578.        Reset the mouse to power on state and force an unconditional cursor
  1579.     on or off.   See also MCSRINC/MCSRDEC.
  1580.  
  1581.     Syntax:     CALL mcsron
  1582.                 CALL mcsroff
  1583.  
  1584.  
  1585.     Name: MGETXY               Type: Mouse            Level: BIOS
  1586.  
  1587.        As you could expect, this gets the current X,Y location of the
  1588.     mouse.  Note that the location of the 'normal' cursor has no bearing
  1589.     on what this returns.  Nor does it matter if the mouse cursor is on or
  1590.     off: MGETXY returns the CURRENT location of the cursor, NOT the LAST
  1591.     SEEN location.  Unlike some inferior "other" QB libraries, MGETXY and
  1592.     MGETXY (see also) use and act upon 80x25 coordinates, not pixel mode
  1593.     that you have to convert.
  1594.  
  1595.     Syntax:
  1596.     REM get mouse cursor
  1597.     CALL mgetxy(MouseRow, MouseCol)
  1598.  
  1599.     REM set Mcursor position to normal cursor position on double right click:
  1600.     CALL mrelease(Lbutton, Rbutton)        ' get current status
  1601.     IF rbutton>= 2 THEN                       ' what is the right status?
  1602.        CALL mgetxy(Mrow, Mcol)                ' get mouse location
  1603.        LOCATE Mrow, Mcol                      ' set location
  1604.     ELSEIF lbutton=>2 THEN                 ' double left
  1605.        SYSTEM
  1606.     END IF
  1607.     Lbutton=0: Rbutton=0                   ' Clear count
  1608.  
  1609.  
  1610.  
  1611.     Name: MLONG / MNORM        Type: Mouse            Level: BIOS
  1612.  
  1613.        You can also control the sensitivity of the mouse.  The ratio by
  1614.     which one mouse inch moves x number of characters or pixels on the
  1615.     screen is called the Mickey Factor.
  1616.        Unaltered, the default Mickey Factor of the New Microsoft Mouse is
  1617.     about 2 inches to move the cursor all the way across the screen and 1
  1618.     inch to travel the vertical distance of the screen.  MLONG alters the
  1619.     Mickey Factor so that it takes about twice as much desk space to
  1620.     travel the same screen distance: 4 inches horizontally, 2 inces
  1621.     vertically.
  1622.        MNORM resets the Mickey back to 2 horizontally, 1 vertically, as
  1623.     does a call to MCSRON (see also MCSRINC, MCSRDEC).
  1624.  
  1625.  
  1626.  
  1627.  
  1628.     Name: MRELEASE / MPRESS    Type: Mouse            Level: BIOS
  1629.  
  1630.        These mouse routines return the number of mouse button RELEASES and
  1631.     PRESSES since the last time the mouse driver was polled.  One obvious
  1632.     use of these two routines is to poll the driver to see if a double
  1633.     click has been executed since the last poll (say, while the program
  1634.     was off doing a disk access or such).
  1635.  
  1636.     Syntax:
  1637.     CALL mrelease(lbutton, rbutton)
  1638.     CALL mpress(lbutton, rbutton)
  1639.  
  1640.  
  1641.  
  1642.     Name: MSETXRNG / MSETYRNG  Type: Mouse            Level: BIOS
  1643.  
  1644.        MSETXRNG and MSETYRNG allow you to limit the minimum and maximum
  1645.     X and Y range that the mouse cursor is to be allowed to roam in.  A
  1646.     use for this would be to limit the mouse to an area in a window or a
  1647.     menu.  Further, this routine is suitable for use in either text or
  1648.     graphics modes thru a flag.
  1649.  
  1650.     Syntax:
  1651.     REM limit mouse area to a box of 5,1 to 12,40 in 80x25 mode:
  1652.     TextMode=1
  1653.     MinR=5: MaxR=12
  1654.     CALL msetxrng(TextMode, MinR, MaxR)
  1655.     MinC=1: MaxC=40
  1656.     CALL msetyrng(TextMode, MinC, MaxC)
  1657.  
  1658.  
  1659.     REM limit mouse area to horiz positions 100 - 150 (640x200):
  1660.     TextMode=0
  1661.     MinR=100: MaxR=150
  1662.     CALL msetxrng(TextMode, MinR, MaxR)
  1663.  
  1664.  
  1665.  
  1666.     Name: MSETXY               Type: Mouse            Level: BIOS
  1667.  
  1668.       This is the simple inverse of MGETXY, setting the current mouse
  1669.     cursor position.  MSETXY works off of 80 x 25 based coordinates so
  1670.     that you need not think in 80x25 for text and character output and
  1671.     mentally switch to pixel based locations for mouse I/O.
  1672.       Note that the mouse cursor normally seems to default to center
  1673.     screen (12,40) with a simple cursor on call (MCSRINC, MCSRON).
  1674.  
  1675.     Syntax:
  1676.     REM set Mcursor position to row 20, column 60
  1677.     MouseRow=20: MouseCol=60
  1678.     CALL msetxy(MouseRow, MouseCol)
  1679.  
  1680.  
  1681.  
  1682.     Name: MTYPE                Type: Mouse            Level: BIOS
  1683.  
  1684.        This routine returns whether a mouse exists or not as the number of
  1685.     mouse buttons.  Naturally, that means 0, 2 and 3 are the only MTYPE
  1686.     returns you should expect.
  1687.  
  1688.     Syntax:
  1689.     CALL mtype(MouseExist)
  1690.     IF MouseExist THEN
  1691.        ..
  1692.        ..
  1693.     END IF
  1694.  
  1695.  
  1696.     Name: MSETCSR              Type: Mouse            Level: BIOS
  1697.  
  1698.        This is a rather specialized routine for the mouse.  Some of the
  1699.     less compatible mice require a littel tweaking to get the cursor to
  1700.     display.  If you have trouble getting a cursor to display, calling
  1701.     MSETCSR should set the mask so that it does display when the cursor
  1702.     is on.  It appears to have no ill effect on mice who do not need it.
  1703.  
  1704.     Syntax:  CALL msetcsr
  1705.  
  1706.  
  1707.     Name: MHZ                  Type: Hardware          Level: BIOS
  1708.  
  1709.        This returns the approximate, effective Megahertz the system is run
  1710.     at.  Sound vague enough?  This return is the result of a very quick
  1711.     benchmark that it runs.  It is "approximate, effective" Mhz because
  1712.     it will be off a little depending on the number of wait states of the
  1713.     machine, and some faster PC clones return falsely high numbers.  This
  1714.     used to be part of CPUINFO, but because the CPU chip type and NDP chip
  1715.     are more useful and frequently called upon information and because the
  1716.     MHZ test does take a little while to run, I have split them up.
  1717.        MHZ returns the speed factor as a whole number: that is a return of
  1718.     935 means a effective MHZ speed of 9.35.  Divide the return by 100.
  1719.     It is advised that you cross reference the speed with the chip:
  1720.     if MHZ returns 1400 but CPUINFO indicates a 8088 machine, you know the
  1721.     speed is wrong and that the PC is more likley 8 to 10 MHz.
  1722.        This also acts just a touch flaky on some machines that I would call
  1723.     it once if I had to and store the number so as to have an idea of the
  1724.     system the program is on (esp w/ SINFO), but do not call it repeatedly.
  1725.  
  1726.  
  1727.     Name: MDLY                 Type: Misc              Level: BIOS
  1728.  
  1729.     MDLY works like DLY in that it enables you to insert controllable
  1730.     delays or slow downs into your code for effect or to allow the end user
  1731.     time to digest the screen.  MDLY halts processing a given number of
  1732.     milliseconds and works out great when a full second is too long.  MDLY
  1733.     appears to be accurate to about .055%.
  1734.  
  1735.     Syntax:
  1736.     CALL mdly(500)        ' delay .5 seconds
  1737.     CALL mdly(100)        ' delay .1 seconds
  1738.  
  1739.  
  1740.  
  1741.     Name: MENUCTRL             Type: Keyboard          Level: BIOS
  1742.  
  1743.     MENUCTRL is a keyboard - menu control module that is totally Network
  1744.     Compatible to trap specific keys, as such is ideal for menu driven
  1745.     routines.  When called, the routine intercepts all keyboard activity
  1746.     exiting only if a number key or function key is pressed - any other
  1747.     input is ignored.  MENUCTRL returns the value of the key or function
  1748.     key pressed, ie '1' and/or '[F1]' return 1, '2' and/or '[F2]' returns 2
  1749.     etc.  Pressing [Esc] returns 15.    These return codes are compatible
  1750.     with FED.
  1751.  
  1752.  
  1753.  
  1754.     Name: NFRMAT               Type: String            Level: QB
  1755.  
  1756.     This routine allows for extensive numeric string processing.  You can
  1757.     have it check an entry to make sure it is only numeric, allow or
  1758.     disallow "-" as a delimiter, and also have it format it to a 7 or 10
  1759.     digit phone number or even to social security format or an account
  1760.     number type format.
  1761.  
  1762.     Parameters:
  1763.     st$ =  string to process (presumably numeric)
  1764.     p = position of a single "-" for mode 6 (account number processing)
  1765.     m = mode or level of processing to perform (see below)
  1766.  
  1767.     mode 0 = Disallow "-" as an element.  This mode will check for
  1768.              purely numeric input, rejecting anything and everything else.
  1769.              (See Error Returns Below).
  1770.  
  1771.          1 = Allow "-" as an element.
  1772.              If your application is to allow some user formatting, this mode
  1773.              will allow the delimiter "-" as an element of the sting.  Note
  1774.              that there can be any number of "-"s and that they can appear
  1775.              anywhere! Use with care!
  1776.  
  1777.          2 = Formatting to phone type (7 digit: xxx-xxxx)
  1778.              This will format a numeric string as shown above,
  1779.              returning an error if any element of the string is non-numeric
  1780.              and not a "-".
  1781.  
  1782.          3 = Formatting to phone type [10 digit: (xxx) xxx-xxxx]
  1783.              This will format a numeric string as shown above,
  1784.              returning an error if any element of the string is non-numeric
  1785.              and not a "-".
  1786.  
  1787.  
  1788.     Note: As of yet, there is no universal phone number formatting, ie you
  1789.     must anticipate the correct 7 or 10 digit format.  Sending to mode 3 a
  1790.     7 digit string will result in an error as will sending to mode 2 a 10
  1791.     digit string.  I hope to be able to circumvent this in future versions
  1792.     of the LIB.  Also mode 3 (10 digit phone) will return an error if area
  1793.     code delimiters "(" and ")" are included.
  1794.  
  1795.  
  1796.           4 = Formatting to social security style [xxx-xx-xxxx]
  1797.               This will check to see that no non-numeric characters are
  1798.               are being sent, and that they are not "-" (ie "-"s are
  1799.               allowed"), then it will format it as shown above.  Letters and
  1800.               other non numeric charcters (except "-") will return an error
  1801.               code, as will a length other than 9.
  1802.  
  1803.           5 = Extract numbers from string sent, no exclusions.
  1804.               This one has little value in that severe errors can result:
  1805.               all we are doing is extracting the numeric characters from the
  1806.               input string and sending them back.  The only way that this one
  1807.               should be used would be to "screen" input by send a string to
  1808.               NFRMAT via mode 5 then sending the return BACK to NFRMAT via
  1809.               mode 2,3 or 4.
  1810.  
  1811.            6 = Extract numbers, place "-" in position p.
  1812.                This mode will allow for an account number style formatting
  1813.                by allowing you to define in what position a "-" should be
  1814.                placed.  Sorry, but "-" is the only delimiter currently
  1815.                allowed, and is only one of them returned per string.  This is
  1816.                to keep the number of parameters passed to a minimum.  To
  1817.                effectively get 2 "-"s into an 'account number' make 2 passes
  1818.                to NFRMAT via mode 6:
  1819.  
  1820.      To get 316-6848-744 out of 3166848744:
  1821.  
  1822.      INPUT "Account Number", st$               'receive 3166848744
  1823.      m=5:p=0
  1824.      CALL nfrmat(st$,m%,p%)                 'strip off -'s incase
  1825.  
  1826.      st1$=LEFT$(st$,5)                      'st1$ is now "31668"
  1827.      st2$=RIGHT$(st$,5)                     'st2$ is now "48744"
  1828.      m=6:p=4                                'mode 6 with "-" as 4th char
  1829.  
  1830.      CALL nfrmat(st1$,m%,p%)                'makes st1$ into "316-68"
  1831.      p=3                                    'set up for next pass
  1832.      CALL nfrmat(st2$,m%,p%)                'makes st2$ into "48-744"
  1833.  
  1834.      st$=st1$+st2$                     '"316-68" + "46-744" = "316-6846-744"
  1835.  
  1836.           While this is a round about way of getting 2 "-"s into it, it does
  1837.       do the trick.  If there is sufficient call for multiple delimiters
  1838.       and/or different delimiters, I can make "mode 6" a separate function
  1839.       from NFRMAT to allow programmer defined delimiters and support multiple
  1840.       delimiters...let me know.
  1841.  
  1842.  
  1843.  
  1844.     Syntax:
  1845.  
  1846.     DEFINT A-Z
  1847.     INPUT "Enter social security number",st$   'they key in 123456789
  1848.     m=4 : p=0
  1849.  
  1850.     CALL nfrmat(st$, m, p)
  1851.     PRINT st$                            'program returns 123-45-6789
  1852.  
  1853.  
  1854.     Mode 5 Example:
  1855.  
  1856.     DEFINT A-Z
  1857.     INPUT "Account Number:",st$          'they key in 3kj';lk9123
  1858.     m=5 : p=114                            'p can be anything - see below
  1859.     CALL nfrmat(st$,m%,p%)
  1860.     PRINT st$                            'output would be 39123
  1861.  
  1862.  
  1863.     Mode 6 Example:
  1864.  
  1865.     DEFINT A-Z
  1866.     INPUT "Account Number:",st$               'they key in 3145678
  1867.     m=6 : p=3                                 'place a - in position 3
  1868.     CALL nfrmat(st$,m%,p%)
  1869.     PRINT st$                                ' output would be 31-45678
  1870.  
  1871.  
  1872.     Note: REGARDLESS of what mode is used, the positional parameter 'p' must
  1873.     be defined and passed!
  1874.  
  1875.  
  1876.                                ERROR RETURNS
  1877.                                -------------
  1878.     If the string sent does not conform to the specifications you define by
  1879.     the mode assignment, NFRMAT will return an error code and an error
  1880.     message.  The string message will be returned in st$ and a code in m.
  1881.     (See ERRMSG.)
  1882.  
  1883.    M Return    ST$ Return
  1884.    --------   ----------
  1885.      99       "Numeric Entry Only!"
  1886.      98       "Too long-Looking for xx Digit [Phone/Social Security] Number!"
  1887.      97       "Too short-Looking for xx Digit [Phone/Social Security] Number!"
  1888.      50       "Programmer Error - Invalid mode specified."
  1889.                          (you screwed up!  This is also returned if p is not
  1890.                           defined or passed.)
  1891.  
  1892.      If all went as expected:
  1893.      M    =   Numeric string formatted to specifications.
  1894.  
  1895.  
  1896.  
  1897.     Name: NLON / NLOFF         Type: Keyboard          Level: BIOS
  1898.  
  1899.     Sets the Keyboard Num Lock key to on (NLON) or off (NL OFF).
  1900.  
  1901.  
  1902.  
  1903.     Name: PCASE                Type: String            Level: Assembler
  1904.  
  1905.     Converts a passed test string to 'proper case'.  That is, "bob smith"
  1906.     is returned as "Bob Smith".  Prior to calling PCASE convert the string
  1907.     to lower case.
  1908.  
  1909.     Syntax:
  1910.     CALL pcase(n$)
  1911.  
  1912.  
  1913.  
  1914.     Name: PGETCH               Type: Keyboard / Video    Level: BIOS
  1915.  
  1916.        This routine is similar to GETCH in that it allows keyboard input
  1917.     only from a predefined string, is ANSI compatible and Network
  1918.     functional, but additionally allows the addition of an automatically
  1919.     centered prompt.  By predefining a number of prompts and input masks, a
  1920.     variety of easy to use prompt-and-allowable-input-masks can be setup
  1921.     for very easy use.  See also GETCH.
  1922.  
  1923.     Syntax:
  1924.     REM display prompt on line 24, in yellow on red, allow only Y, N or A
  1925.     prompt$="Are You Sure Y/N/Abort": okay$="YNA" : row=24: ky$=" "
  1926.     CALL pgetch(prompt$, row, 78, okay$, ky$)
  1927.  
  1928.  
  1929.  
  1930.     NAME: PFILE                Type: Printer           Level: DOS
  1931.  
  1932.       Send a file from disk to the first printer (LPT1, PRN etc).  This is
  1933.     a much handier way to print a file rather than reading it line by line
  1934.     and LPRINTing it, and takes mush less memory than SHELL to DOS and
  1935.     copying it to the printer.   To cut down on disk I/O and speed up the
  1936.     overall operation, this routine reads in 4k blocks of the file, this
  1937.     does not act as a spooler however, since the routine will not return
  1938.     until the buffer is empty.  This routine does not abort if the printer
  1939.     is not ready, test for printer readiness with PSTAT.  As with all GLIB
  1940.     routines, you need not make the filename ASCIIZ, that is a job best
  1941.     left to assembler!
  1942.  
  1943.     Syntax:
  1944.     printfil$="GLIB14.DOC"
  1945.     CALL pfile(printfil$)
  1946.  
  1947.  
  1948.  
  1949.     Name: PINIT                Type: Printer           Level: BIOS
  1950.  
  1951.     Here is a handy routine: it initializes the printer, and if the offline
  1952.     button has sent it offline, it will put it online (Epsons anyway) and
  1953.     set the printer to TOF (Top Of Form).  Call it with the designated
  1954.     priter port to initialize (1 to 3 - Lord knows what it will do if you
  1955.     try to initialize printer # 53.7).  See also PSTAT.
  1956.  
  1957.     Syntax:
  1958.     printernum=1
  1959.     CALL pinit(printernum%)
  1960.  
  1961.  
  1962.  
  1963.  
  1964.     Name: PRTSCRN              Type: Printer           Level: BIOS
  1965.  
  1966.     This very simply sends the current display to the printer.  No
  1967.     arguments are passed, used or returned.
  1968.  
  1969.     Syntax:
  1970.     CALL prtscrn
  1971.  
  1972.  
  1973.  
  1974.     Name: PSTAT                Type: Printer           Level: BIOS
  1975.  
  1976.       Where PINIT intializes the printer, PSTAT returns the status of a
  1977.     designated printer in the form of  0, -1 so you can use the parameter
  1978.     passed in IF THEN statements.  Pass PSTAT the printer number to test
  1979.     (1-3) as a variable and the variable will be returned as 0 or -1
  1980.     indicating the staus.
  1981.     NOTE:  When testing the status immediately after calling PINIT, allow 1
  1982.     or seconds before calling PSTAT, this is to avoid polling the printer
  1983.     while it is still initializing.
  1984.  
  1985.     Syntax:
  1986.     -------
  1987.     prtnum=1
  1988.     CALL pinit(prtnum%)
  1989.     CALL dly(2)                   ' wait for the low tech item to get done
  1990.     CALL pstat(prtnum%)
  1991.     IF  prtnum THEN
  1992.        ...perform print job ...
  1993.     END IF
  1994.  
  1995.  
  1996.  
  1997.     Name: QUIKPRT              Type: VIDEO             Level: BIOS
  1998.  
  1999.     This is a replacement for BASIC's painfully slow PRINT function.  It is
  2000.     another implementation of the original quick print routine that was in
  2001.     BYTE magazine a few years ago.  As the demo shows it is faster than
  2002.     PRINT on an order of magnitude.  QUIKPRT correctly distinguishes EGA's
  2003.     and MONO systems from CGA's and proceeds to QUIKPRT in fast mode.  On
  2004.     CGA systems, it monitors the retrace to avoid snow.
  2005.  
  2006.     Parameters:
  2007.     text$ - Text string to QUIKPRT to the screen
  2008.     row - Row of screen to print text to.
  2009.     col - Column of screen to print to
  2010.     attr - color attributes to use for the text.  This is calculated in the
  2011.            same manner as the attribute is for WDW, ERRMSG and others that
  2012.            use it:
  2013.            attr=(BACKGROUND * 16) + FOREGROUND
  2014.  
  2015.     Syntax:
  2016.     msg$="QUIKPRT is very, very FAST !!"
  2017.     attr=(4*16)+14
  2018.     CALL quikprt(msg$, 2, 2, attr%)
  2019.     or directly,
  2020.     CALL quikprt("QUIKPRT is very, very FAST !!", 2, 2, 78)
  2021.  
  2022.  
  2023.  
  2024.     Both examples produce the same results: the message is printed on row
  2025.     2, column 2, in yellow-on-red.
  2026.  
  2027.     Eg:
  2028.     qprt:     'fills the screen quickly with the contents of the msg$ array.
  2029.        FOR x= 1 to 25
  2030.           CALL quikprt(msg$(x), x, 1, attr%)
  2031.        NEXT x
  2032.     RETURN
  2033.  
  2034.  
  2035.  
  2036.     Name: RAMFREE              Type: Equipment         Level: BIOS
  2037.  
  2038.     Returns the amount of memory installed in the machine.
  2039.  
  2040.     Syntax:
  2041.     mem=0  :  CALL ramfree(mem%)
  2042.     PRINT "Free memory amount is: ";mem
  2043.  
  2044.  
  2045.     Name: READSCRN             Type: Video             Level: BIOS
  2046.  
  2047.        This is like BASIC's SCREEN function except that it is much faster
  2048.     (on an order of magnitude) way to read text from the screen.  READSCRN
  2049.     uses the current cursor location as the starting point and reads as many
  2050.     characters as you have spaces in the passed string.  This is critical,
  2051.     since ASM routines cannot alter string lengths, if you want 13
  2052.     characters, text$ must be initialized to SPACE$(13).
  2053.  
  2054.     Syntax:
  2055.        scrntext$=SPACE$(13)
  2056.        locate 12,15
  2057.        CALL readscrn(scrntext$)
  2058.  
  2059.  
  2060.  
  2061.     Name: RINSTR               Type: String            Level: DOS
  2062.     FUNCTION
  2063.  
  2064.        Returns the LAST occurance of a character in a string.  This works
  2065.     conversely to DOS's INSTR, which returns the first occurance, and is
  2066.     faster and much more code efficient than a loop to keep testing INSTR
  2067.     until the end of the string is reached.  The character location however
  2068.     is still returned from the left.
  2069.        Note: RINSTR works only on character seeks, not on sub strings
  2070.     like BASIC's INSTR does.  That is, in the case of
  2071.     j=rinstr("ABCDEFG","A@B")
  2072.     RINSTR will only seek and match on "A", not "A@B".  Multiple passes thru
  2073.     RINSTR, however seeking each successive character in a sub string could
  2074.     be accomplished.
  2075.  
  2076.     Syntax:
  2077.         DECLARE FUNCTION rinstr(searched$, seek$)
  2078.         ..
  2079.         ..
  2080.         test$="123456x890" : char$="x"
  2081.         l = rinstr(test$, char$)                   ' returns 7
  2082.  
  2083.  
  2084.  
  2085.  
  2086.     Name: SVSCRN / RSTSCRN     Type: Video             Level: BIOS
  2087.  
  2088.       The SVSCRN routine saves the current screen display to an integer
  2089.     array then via RSTSCRN you can restore that saved screen to the
  2090.     display.  This is very handy in a routine in situations where you might
  2091.     want to pop a help window to the display.  You could save the current
  2092.     screen, display a help window or screen, then upon command redisplay
  2093.     the original screen.
  2094.        The array which we save to and from MUST be DYNAMIC, ie it must be
  2095.     allocated off of the far heap.  This is done via any of the three
  2096.     following ways:
  2097.     1) REM $DYNAMIC
  2098.        DIM scrnarry(2000)
  2099.  
  2100.     2) REDIM scrnarry(2000)
  2101.  
  2102.     3) j=2000 : DIM scrnarry(j)
  2103.  
  2104.     Parameters:
  2105.     In telling SVSCRN or RSTSCRN where to put or get screen contents, we
  2106.     do not pass the entire array, but a a pair of pointers pointing to
  2107.     the segment and the offset of the array.
  2108.  
  2109.     In QB4 this is done with the keywords VARPTR and VARSEG:
  2110.     segment=VARSEG(scrnarry(1)) )  : offset=VARPTR(scrnarry(1)) )
  2111.  
  2112.     We now have determined the segment and offset of the array and can
  2113.     continue with the call.
  2114.  
  2115.     Next, understand that each screen will require 2000 bytes to store;
  2116.     the array to hold the screens would need to be in multiples of 2000 for
  2117.     each screen.  To save 3 screens, dimension the array to 6000, if you
  2118.     plan to be swapping 2 screens, dimension it to 4000.
  2119.  
  2120.        Once you have the space set aside for the screen elements, before we
  2121.     can store a screen there, we need to set a pointer to the array.  That
  2122.     is, if we DIM sarry% to 6000, there is room for 3 screens, but before
  2123.     we can store a screen there, we need to tell the routine WHERE in the
  2124.     array to store the screen.  The idea is to point a variable at 2000
  2125.     byte intervals in the array for the different screens.
  2126.  
  2127.     Variable pointing to:                                Points to:
  2128.     ---------------------                               -----------
  2129.     Scrnarry(0)                                         Screen number 1
  2130.     Scrnarry(2000)                                      Screen number 2
  2131.     Scrnarry(4000)                                      Screen number 3
  2132.  
  2133.     (If using OPTION BASE 1, use scrnarry(1), scrnarry(2001) etc)
  2134.  
  2135.     One other thing to remember is that the being a DYNAMIC array, BASIC
  2136.     will move the array around in memory as it sees fit depending on what
  2137.     your code is doing.   Therefore, prior to EACH call to SVSCRN or
  2138.     RSTSCRN you must set or reset the segment and offset pointers.  I
  2139.     suggest that you do this via a GOSUB type subroutine:
  2140.  
  2141.  
  2142.  
  2143.     GOSUB SetPointers
  2144.     CALL svscrn(segment, offset)
  2145.     ...
  2146.     ...
  2147.     ...
  2148.  
  2149.     SetPointers:                   ' QB 4 version
  2150.       segment=VARSEG(scrnarry(1)) )
  2151.       offset =VARPTR(scrnarry(1)) )
  2152.     RETURN
  2153.  
  2154.  
  2155.     Syntax:
  2156.     -------
  2157.     CALL svscrn(segptr, offset)       ' save current screen to position one
  2158.     CALL rstscrn(segptr, offset)     ' restores screen from position 3
  2159.  
  2160.     Alternatively, for QB4:
  2161.     CALL svscrn(VARSEG(scrnarry(1)), VARPTR(scrnarry(1)) )
  2162.  
  2163.     For more information, examine the demo source code, as these 2 routines
  2164.     are used quite a bit.  In the demo, a deliberate delay is used in
  2165.     some cases to slow down the save and restore process to allow you time
  2166.     to perceive the process.
  2167.  
  2168.  
  2169.  
  2170.     Name: SETFATTR             Type: Disk             Level: DOS
  2171.     FUNCTION
  2172.  
  2173.       SETFATTR allows you to change or modify the file attributes for any
  2174.     disk file that exists.  For a table of the attributes, see GETFATTR.
  2175.     SETFATTR is also a function and will return any error code in the
  2176.     function name allowing you to use it in a statement or assign it.
  2177.        SETFATTR checks for, and allows only valid file attributes, volume
  2178.     labels and directories are not supported.
  2179.  
  2180.  
  2181.     Syntax:
  2182.     DECLARE FUNCTION setfattr%(fil$, attrib%)
  2183.     .
  2184.     .
  2185.     fil$="myprog.sys" : attrib=3             ' make it Read Only, Hiddden
  2186.     IF setfattr(fil$, attrib) THEN
  2187.        PRINT "Error - possible invalid file attribute."
  2188.     ELSE
  2189.        PRINT "Change succeeded."
  2190.     END IF
  2191.  
  2192.  
  2193.  
  2194.  
  2195.  
  2196.     Name: SYSTIME              Type: System            Level: BIOS
  2197.  
  2198.        Rather than tearing apart BASIC's TIME$ with MID$ to determine the
  2199.     current hour, minute, second, SysTime allows instant access to all that
  2200.     PLUS the hundredths of a second with no string garbage generated.  Note
  2201.     that not all Clone BIOSes support hundredths of a second in the BIOS,
  2202.     so it may not be accurate on all systems.
  2203.  
  2204.     Syntax:
  2205.     CALL systime(hrs, min, sec, hunds)
  2206.  
  2207.  
  2208.  
  2209.     Name: USCROLL / DSCROLL    Type: Video             Level: BIOS
  2210.  
  2211.     These 2 routines scroll a portion (or all) of the current display
  2212.     up or down a user defined number of times.  SCROLL allows for you to
  2213.     set the parameters for all four boundaries: top, bottom, left and right
  2214.     Additionally, you designate the number of lines to scroll.  Designating
  2215.     0 as the number of lines to scroll, clears the screen.
  2216.  
  2217.  
  2218.     Parameters:
  2219.     Top, left, bottom and right, relate to the bounds of the area to scroll,
  2220.     and they are listed in the same order as are used in WDW for uniformity.
  2221.  
  2222.  
  2223.     Syntax:
  2224.     num=12 : top%=1 : lft=1 : bttm=12 : rght=79
  2225.     CALL DSCROLL(num%, top%, lft%, bttm%, rght%)
  2226.         ' scrolls lines 1 to 12 down 12 lines - lines 13 to 25 are lost
  2227.  
  2228.     CALL uscroll(12, 13, 1, 25, 79)
  2229.         ' scrolls lines 12 to 25 up 12 lines -  with 13-25 becoming blank.
  2230.  
  2231.     CALL dscroll(25, 1, 1, 25, 79)
  2232.         ' Clears the screen with the display scrolling down off the screen
  2233.  
  2234.  
  2235.  
  2236.     NAME: SCROLLER             Type: Video             Level: BIOS
  2237.  
  2238.        This routine scrolls the entire screen left or right a designated
  2239.     number of lines.  For simplicity, the entire screen is scrolled or
  2240.     shifted eliminating the need for top, bottom etc co-ordinates.  A
  2241.     positive number scrolls the screen to the left, a positive number
  2242.     scrolls to the right.  Note that this is not a true scroll, but rather
  2243.     a creative implementation of the quick print algorithm.  Regardless, in
  2244.     the demo you will see that the result is so fast, especially on 286
  2245.     machines, that the insertion of a very short delay sometimes ADDS to
  2246.     the effect of the display.
  2247.  
  2248.     Syntax:
  2249.  
  2250.     CALL scroller(4)
  2251.     CALL scroller(-6)
  2252.  
  2253.  
  2254.  
  2255.     Name: SCRLON / SCRLOFF     Type: Keyboard          Level: BIOS
  2256.  
  2257.     Toggles the scroll lock key on or off.  If the keyboard is equipped
  2258.     with LED's, they are also toggled to the appropriate state.
  2259.  
  2260.     Syntax:
  2261.  
  2262.     CALL scrlon
  2263.     CALL scrloff
  2264.  
  2265.  
  2266.  
  2267.  
  2268.     Name: SCRNDUMP            Type: Video, Printer    Level: QB
  2269.  
  2270.     This does just what the name implies - it sends the screen display to
  2271.     a disk file.  In many cases, your program may adequately be able to
  2272.     send output to disk, but if you have a graphic display that you want to
  2273.     send to disk, or your application has a screen dump function, you might
  2274.     find this of help.
  2275.  
  2276.     You have control of the file mode: the screen dump can append to an
  2277.     existing file or you can let it be the only thing in the file. SCRNDUMP
  2278.     neither opens or closes any file.
  2279.  
  2280.     Parameters:
  2281.     You need to pass the file handle (number) to SCRNDUMP.
  2282.  
  2283.     Syntax:
  2284.     OPEN "scrndump.fil" FOR APPEND AS #6       ' tacks current display to
  2285.     CALL scrndump(6)                           ' file if it exists.
  2286.     CLOSE #6
  2287.  
  2288.     num=4
  2289.     OPEN "screen.fil" FOR OUTPUT AS #num       ' Kills existing file
  2290.     CALL scrndump(num%)                        ' then puts screen display
  2291.     CLOSE #num                                 ' to that file
  2292.  
  2293.  
  2294.  
  2295.     NAME: SETDRV               Type: DOS               Level: Assembler
  2296.  
  2297.     Sets or resets the default drive.  To set the drive, simply pass it the
  2298.     letter, upper or lower case, to log into.  This removes the ambiguity
  2299.     of drive numbers (Hmm, is drive 1 A: or B: in this case....).  SETDRV
  2300.     returns nothing and if passed a bad parameter, DOS simply rejects it
  2301.     leaving the default drive unchanged.
  2302.  
  2303.     Syntax:
  2304.     drv$="d"
  2305.     CALL setdrv(drv$)
  2306.  
  2307.  
  2308.  
  2309.     Name: SETERR               Type: DOS Terminate     Level: DOS
  2310.  
  2311.        Sets return code upon program termination.  These can be read from
  2312.     DOS via as "ERRORLEVELs" in batch files.  This routine MUST be CALLed
  2313.     at the VERY END of a program, as the DOS interrupt used to set return
  2314.     codes (the so-called ERRORLEVELs) WILL terminate your program.  It is
  2315.     also not possible to CALL this routine from inside the compiler
  2316.     environment as it will drop you to DOS after the call.  For this reason,
  2317.     it is not included in the environment libraries as prepared by me.
  2318.  
  2319.  
  2320.     Syntax:
  2321.     ------
  2322.     CALL seterr(code)                 ' terminate and set "ERRORLEVEL"
  2323.  
  2324.     Example:
  2325.     IF x=0 THEN PRINT "Normal ";: ELSE PRINT "End of job."
  2326.  
  2327.     IF x<>0 THEN PRINT "ERRORLEVEL set to ";x
  2328.     CALL seterr(x)
  2329.  
  2330.  
  2331.  
  2332.     NAME: SETVERFY             Type: DOS/System        Level: Assembler
  2333.  
  2334.     Sets or resets the DOS VERIFY switch (see GETVERFY for an explanation
  2335.     of VERIFY).  Note that if you intend to alter such a system switch, it
  2336.     is good programming practice to restore it to its original setting when
  2337.     your program terminates, this switch can be determined via GETVERFY.
  2338.     In calling SETVERFY, 0 turns VERIFY OFF, 1 turns it ON.
  2339.  
  2340.     CALL setverfy(0)
  2341.     CALL setverfy(1)
  2342.  
  2343.  
  2344.  
  2345.     Name: SINFO                Type: MISC              Level: BIOS
  2346.  
  2347.     Returns some simple, basic hardware or system info.
  2348.  
  2349.     Parameters
  2350.     RAM - Returns the amount of DOS memory installed
  2351.     SER - Returns number of serial ports installed
  2352.     PAR - Returns number of parallel ports installed
  2353.     EGA - Returns KB of installed EGA memory, 64, 128 or 256KB
  2354.           If no EGA is available, ega will return 0.
  2355.     VGA - Returns 0/1 if VGA is installed.
  2356.  
  2357.     Syntax:
  2358.     CALL sinfo(RAM, SER, PAR, EGA, VGA)
  2359.  
  2360.  
  2361.  
  2362.     Name: TFRMAT               Type: String            Level: QB
  2363.  
  2364.     TFRMAT allows for Time string formatting similar to that in DFRMAT.
  2365.     There is no error checking for the correct time being set, (how can there
  2366.     be?), but if the mode parameter is not set right, an error message of:
  2367.     " Invalid mode specified" will be returned in T$, also m will be set
  2368.     to 50.
  2369.  
  2370.     Parameters:
  2371.     label 0 = OFF   (none)
  2372.           1 = am/pm
  2373.  
  2374.     nutime$ = Returned, formatted time string.
  2375.  
  2376.     Syntax:                                  Output:
  2377.     PRINT TIME$                              13:01:01
  2378.     CALL tfrmat(nutime$,1)
  2379.     PRINT nutime$                             1:01 pm
  2380.  
  2381.  
  2382.  
  2383.     Name: VFNAME               Type: Disk/String       Level: DOS
  2384.     FUNCTION and SUB
  2385.  
  2386.         VFNAME checks a string you pass it to determine if the string indeed
  2387.     is capable of bing a valid filename.   Pre testing a string that you may
  2388.     have gotten from end user input, helps avoid runtime errors later on and
  2389.     in the case of novice end users allows considerable feedback from your
  2390.     program on what is wrong with a filename typed in.
  2391.  
  2392.         The process is twofold - it tests for characters such as ,[>< and
  2393.     also attempts to open the file and returns an error code.  In the case
  2394.     of the character test, the FUNCTION returns 0 if it finds no offending
  2395.     characters, or the ASCII value of any invalid filename character.  This
  2396.     allows you to be able to give apparently intuitive feedback to a users
  2397.     on valid filename characters.
  2398.  
  2399.         A second pass is needed to test drive and path validity.  The colon
  2400.     and backslash are not tested for as invalid chars since they ARE valid
  2401.     IF in the right spot.  To test this, VFNAME attempts to open or create
  2402.     the file thus returning info on the path, access and if the file already
  2403.     exists.  Any DOS feedback is returned as a formal parameter:
  2404.     3 - Drive or path not found
  2405.     4 - No handle available ("Too Many Files")
  2406.     5 - Access denied (already opened on multi system)
  2407.     80 - file exists.
  2408.  
  2409.         Note: VFNAME does NOT actually create or open the file!  It just
  2410.     pre-tests for any possible runtime error in trying to do so.
  2411.  
  2412.         Note: VFNAME requires DOS 3.x
  2413.  
  2414.  
  2415.  
  2416.  
  2417.     Syntax:
  2418.     DECLARE FUNCTION vfname%(fil$, DOScode%)
  2419.     ..
  2420.     ..
  2421.     getfname:
  2422.        LINE INPUT "File to Write Data to: ",fil$
  2423.  
  2424.        CharCode = vfname(fil$, DOSCode)
  2425.        IF CharCode THEN
  2426.           PRINT "Sorry, but '";CHR$(CharCode);"' is an illegal in filenames!"
  2427.        END IF
  2428.  
  2429.        SELECT CASE DOSCode
  2430.            CASE 0                   ' no DOS error or was not tested
  2431.                                     ' because fil$ had CharCode - do nothing
  2432.  
  2433.            CASE 3                   ' goofy path/drive
  2434.              PRINT fil$;" has an invalid drive or path in it.  Try again."
  2435.  
  2436.            CASE 4                   ' handles exceeds FILES= in config.sys
  2437.              GOSUB close.some.files
  2438.              DOSCode = 0            ' clear error for below
  2439.  
  2440.            CASE 5                   ' no access rights!
  2441.              PRINT "Pick a new name.  You do not have access to ";fil$
  2442.  
  2443.            CASE 80                  ' file already exists
  2444.              PRINT fil$;" exists. Overwrite it?"
  2445.              INPUT "",yorn$
  2446.              IF UCASE$(yorn$)="Y" THEN DOSCode=0     ' clear error
  2447.  
  2448.            CASE ELSE
  2449.              GOSUB something.really.weird.happened
  2450.  
  2451.        END SELECT
  2452.  
  2453.        IF DOSCode THEN GOTO getfname     ' loops if DOSCODE = 3, 5 or 80
  2454.                                          ' with no overwrite
  2455.     ..
  2456.     ..
  2457.  
  2458.  
  2459.     Name: VIDOFF/VIDON         Type: Video/hardware    Level: BIOS
  2460.  
  2461.         Similar to a screen saver program, this routine will turn off any
  2462.     monitor (we hope - tested on CGA, EGA and Composite so far).  If a
  2463.     timing loop in your long running program senses no activity for x
  2464.     minutes, a call to VIDOFF will trun off the display, then once you sense
  2465.     activity again, VIDON restores the display.
  2466.         This should accurately detect mono, CGA and EGA systems and
  2467.     correctly turn them on or off, I do not have any or info on VGA systems
  2468.     to tell if it will work on them (though I doubt it is necessary on
  2469.     them).
  2470.  
  2471.     Syntax:    CALL VIDOFF : PRINT "Hi, Pal" : BEEP : CALL VIDON
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.     Name: WDW                  Type: Video             Level: BIOS
  2478.  
  2479.        An extensive windowing routine, allows for frames, sound, color
  2480.     control and a growing effect.  The routine requires numerous arguments
  2481.     passed, but be warned that NO error checking takes place as to accurate
  2482.     or misplaced coordinates.  Really far out coordinates can lock up the
  2483.     machine (such as locating the bottom of the window ABOVE the top
  2484.     etc...) so be sure to save your work BEFORE test running a program with
  2485.     a window call.
  2486.        This routine offers a "growing" effect and a sound effect, both of
  2487.     which are optional thru the use of the parameters sent.  The grow
  2488.     effect is most effective on narrower windows as opposed to wider ones.
  2489.        Previous versions allowed your application to chirp or not chirp
  2490.     based on an environment switch ( SET GWDW=/Q ).  This implementation
  2491.     no longer recognizes this switch, however hope reigns supreme that it
  2492.     will again in the future.  On the other hand, being in assembler, the
  2493.     grow effect is MUCH more acceptable.
  2494.  
  2495.  
  2496.     Parameters
  2497.  
  2498.     top   - Top row of window to be displayed.
  2499.     lside - Left border of window to be displayed.
  2500.     bttm  - Bottom row of window to be displayed.
  2501.     rside - Right border of window.
  2502.     sfx   - Sound effects toggle, 0=OFF 1=ON
  2503.     grow  - Grow switch, 0=OFF 1=ON
  2504.     frame - Style of frame to use for the window:
  2505.             1 - Double Lines Horizontal  / Double Lines Vertical
  2506.             2 - Double Lines Horizontal  / Single Lines Vertical
  2507.             3 - Single Lines Horizontal  / Single Lines Vertical
  2508.             4 - Single Lines Horizontal  / Double Lines Vertical
  2509.     attr  - Attribute of window to be displayed
  2510.             Calculated by (BACK_COLOR * 16)+FORE_COLOR
  2511.     label - String to display centered across the top of the window.
  2512.             If no label is desired initialize to "".
  2513.  
  2514.     Syntax
  2515.     ------
  2516.     top%=2 : lside%=2 : bttm%=5 : rside%=79 : sfx%=1 : gro%=1 : frame%=1
  2517.     attr%=78 : label$=" A long window across the top of the screen "
  2518.  
  2519.     CALL wdw(top%, lside%, bttm%, rside%, sfx%, gro%, frame%, attr%, l$)
  2520.  
  2521.     Puts a window to the screen from 2,2 to 5,79, with a chirp sound
  2522.     effect, with a double / double line frame with a yellow foreground on a
  2523.     red background.
  2524.