* ZBASIC 4.7 Help File - by Mark McDonald 941022
            Dedicated to Harry Gish at ZBASIC, Thanks For ZBASIC 4.7.

Note:  This page will display properly in a browser that can use the PC-8 character set.
       Unfortunately, the Internet has declared that UNICODE is best and will not allow
       modern browsers to properly display DOS characters sets on the internet.

       Internet Explorer (IE) will properly display file on your PC.  Otherwise, you may download
       this file and display it in your editor.

ZBASIC is a great DOS interpreter and compiler.  Wrote hundreds of programs using ZBASIC including
Micro-Mapper.  ZBASIC compiled code has a maximum size of 64k.  If your code is too large to compile,
remove the comments.  ZBASIC variables can be specified with a size parameter which allows the programmer
tight control of memory usage.

ZBASIC runs in MSDOS, DOSBox and DOSEmu.

DOS Command Line Commands:
      ZB source.bas result.com [/C]
      source.bas is the program to compile.
      result.com is the name of the compiled program.
      /C compile as a chain program.

ZBASIC Interpiler Commands:
      LOAD filename.ext - loads source file
      LOAD*filename.ext - loads source file, deleting comments
      RUN               - compiles and executes program.
      RUN filename.ext  - loades/compiles/executes program.
      RUN*              - compiles program and prompts for .COM name.
      RUN+       - compiles program and prompts for .CHN name.(chain file).

ZBASIC COMMANDS and FUNCTIONS


  ABS(expression)
      Returns the absolute value.
      The result will always be a positive number or 0.

      Example: A = - 15
               PRINT ABS(A)
               RUN
               15

  AND
      Used to determine if BOTH conditions are true. Returns
      -1 for true and 0 for false.


  ASC(string)
      Returns the ASCII code value(decimal) of the first character
      of string.


  ATN(expression)
      Returns the angle, in radians, for the inverse tangent of
      expression.


  BEEP
      Sounds the speaker.

      Example: FOR X = 1 TO 5
                  BEEP
                NEXT X
                RUN
                BEEP BEEP BEEP BEEP BEEP


  BIN$(expression)

      Returns a 16 character string which represents the binary
      (BASE 2) value of integer expression

      Example: A$ = BIN$("3")
               PRINT A$
               RUN
               0000000000000011


  BLOAD filespec[,[offset][,segment]]

      Loads a block of memory that was saved as filespec using
      the BSAVE statement.

      The optional offset is the position in memory to load the
      block into the current segment as defined using DEF SEG (or
      the segment option if used).

      If the offest and/or the segment is omitted, the information
      that was stored in the file with BSAVE is used.

      Example: MODE 7
               BLOAD "CGASCRN.MEM"
               DELAY 4000


  BOX [TO]exprx1,expry1 [TOexprx2, expry2 ...]

      BOXFILL [TO]exprx1,expry1 [TOexprx2, expry2 ...]

      Draws a box from th coordinates defined by the first corner(x1,y1)
      to the coordinates defined by the opposite corner (x2,y2) in the
      current color.

      If the BOX TO x,y is used the first corner will be the last graphic
      position used. If undefined then 0,0 will be used.

      If the optional FILL appears directly after the command, the  BOX
      will be painted as a solid BOX in the current color.

      The default screen positions are givne using Device Independent
      Coordinates of 1024 across by 768 down.


  BSAVE filespec, offset, length [,segment]

      Saves a block of memory as filespec so that it may be loaded later
      with BLOAD. It saves an exact image of memory.

      The optional offset is the position in memory to load the block
      and will save the current segment as defined using the DEF SEG
      statement(or the segment option if used).

      If DEF SEG is not used, the DATA SEGMENT(MEMD) is used.

      Remark: MODE    TYPE       ADDRESS       LENGTH
              0-15    CGA        &HB800        2048-16,384
              2       MDPA       &HB800        4096
              20      Hercules   &HB000        32,767
              20      Hercules   &HB800        32,767

      EGA, VGA and MCGA graphics are stored in memory in a
      different format than other graphic cards. To save images
      in EGA, VGA and MCGA modes 16-19 and 21-23 you should GET
      the screen. Save the screen to disk using:
      BSAVE filespec, VARPTR(var%(n)), number of elements/2
      BLOAD the integer array back into memory using
      BLOAD filespec, VARPTR(var%(n))
      and then PUT the image back to the screen.


  CALL address[, segment]

      This statement is used to execute a subroutine located in memory
      at the segment given by segment with an offest of address.

      If segment is not given, then ZBASIC code segment is used.

      Example: CALL LINE "Routine"
               Calls a ZBASIC routine starting at "Routine"(same as GOSUB but
               slower).
               CALL &H100, &H0BD7
               Calls a subroutine located at &HBD7 with an offset of &H100.

      Remark: Any subroutine called by specifying the segment must return from
              the subroutine with a far return. Otherwise, unpredictable results
              will occur.

      Format: CALL string

         Def: The CALL statement followed by a string will load and execute
              another program or DOS command specified by string. IF a null
              string is specified, then DOS will be loaded and executed, in
              which case typing EXIT in DOS will return to ZBASIC-PC.
              This is identical to the "SHELL" statement and is retained to
              remain compatible with other BASICs. See Shell.
              string must be either a string variable or a quoted string.

      Example: CALL "DISKCOPY A: B:"

               This will perform a diskcopy as if it was typed in from the DOS
               command line.

               CALL ""

               Gives control to DOS, displays DOS prompt. Type EXIT in DOS to
               return to ZBASIC-PC.

               A$ = "DIR A:*.BAS"
               CALL A$

               This will get the directory of all .BAS files on drive A.

      Remark:  There must be at least 17k of memory free to use the CALL
               statement. If COMMAND.COM is not found, the message "File not
               found" will be echoed to the display and control will return to
               ZBASIC-PC.


  CARDTYPE

      Returns type of graphic hardware connecto the current system.

      Example: A = CARDTYPE
               PRINT A

      Table: Single Monitor  Dual Monitor         Dual Monitor
        CGA          0  CGA+MDA        16  CGA+HERCULES          32
        EGA COLOR    1  EGA COLOR+MDA  17  EGA COLOR+HERCULES    33
        EGA MONO     2  EGA MONO+MDA   18  EGA MONO+HERCULES     34
        HERCULES     3
        VGA COLOR    4  VGA COLOR+MDA  20  VGA COLOR+HERCULES    36
        VGA MONO     5  VGA MONO+MDA   21  VGA MONO+HERCULES     35
        MCGA COLOR   6  MCGA COLOR+MDA 22  MCGA COLOR+HERCULES   36
        MCGA MONO    7  MCGA MONO+MDA  23  MCGA MONO+HERCULES    37
        VESA 256k    8
        VESA 512k    9
        VESA   1M   10
        VESA   2M   11
        VESA   4M   12
        VESA   8M   13
        VESA  16M   14
        VESA >16M   15
        MDA        255

      Some video cards do not follow the convention of identifying
      their type in the "BOIS footprint". In this case ZBASIC-PC makes
      an educated guess based upon factors such as amount of memory
      installed on the card. If the card is improperly identified the
      probably result will be a system lockup, scrambled graphics or a
      blank screen when graphics are attempted.


  SELECT [CASE][expression]
      CASE[IS] relational expression[, relational expression][,...]
               statement[:statement...]]
      CASE[IS] condition[,condition][,...]
               statement[:statement...]]
      CASE boolean expression
               statement[:statement...]]
      CASE ELSE
               statement[:statement...]]
      END SELECT

      When SELECT/CASE is encountered, the program checks the value of
      the controlling expression or variable, finds the CASE that
      compares true and executed the statements directly following
      the CASE statement. After these statements are preformed, the
      program continues a thte line after the END SELECT statement.

      Never exit a SELECT CASE structure using GOTO. This will
      introduce problems into the stack and cause unpredictable system
      errors. Always exit the structure at the END SELECT. Be sure to
      enclose loops and other contrucs completely within the SELECT-CASE
      and CASE ELSE constructs.


  CHDIR pathname

      Changes the current directory to the directory specified by
      pathname.

      Example: A$ = PATH$(0)           :' Get current path
               CHDIR "\ZBASIC\DATA"    :' Change Path
               OPEN"I",1,"MYDATA.TXT"  :' Opens file on new path
               CHDIR A$                :' Restores Path

      If an error is encountered, ZBASIC-PC returns an error(11).


  CHR$(expression)

      Returns a single character string with the ASCII value of
      expression. The range for expression is 0 to 255.
      Example: PRINT CHR$(65)


  CINT(expression)

      Truncates all digits to the right of decimal point of expression.


  CIRCLE

      Format: CIRCLE [FILL] expr1, expr2, exprR
              CIRCLE        expr1, expr2, exprR TO exprS, exprB
              CIRCLE        expr1, expr2, exprR PLOT exprS, exprB

       Draws a circle in the current color.

       If the optional FILL is used, the circle will be filled with the
       current color. If TO is used, a PIE segment will be displayed
       (shaped like pie slices). If PLOT is used, only the ARC segment
       will be displayed(a segment of the circumference).

       expr1   Horizontal center
       expr2   Vertical center
       exprR   Radius(diameter of circle) in graphic coordinates
       exprS   Start of angle in brads(0 starts at 3:00 o'clock)
       exprB   Number of brads to draw ARC or PIE(counter clockwise)
       Remark: CIRCLE uses the ZBASIC-PC Device Independent Graphic Coordinates
               1024 x 768.


  CLEAR
      CLEAR
      CLEAR number
      CLEAR END
      CLEAR INDEX$

      Used to reserve memory or clear all or specified variables (sets
      the value of the variables to null or zero).

      CLEAR          Sets all variables and INDEX$ to zero or null.
      CLEAR number   Sets aside number of bytes for INDEX$ array.
      CLEAR END      Clears all variables which have not yet been
                     assigned in the program. This form of CLEAR is
                     normally used to clear all variables not being used
                     when chaining.

      Only one CLEAR number is allowed in a program and must appear
      before any variables are encountered. Be sure to CLEAR one extra
      byte for each element in the INDEX$ array.

      A CLEAR is performed at the beginning of each program created
      with RUN or RUN*. RUN+ or warm start programs will not clear
      vriables at startup.


  CLOSE[[#]expression1[,[#]expression2...]]

      This statement is used to CLOSE one or more OPEN files or
      other devices.

      The parameter expression indicated a device or file number.
      If no file or device numbers are declared all OPEN devices will be
      closed.

      Note: All files should be closed before leaving a program to insure
      that data will not be lost or destroyed. If program exit is
      through END or STOP, all files will be closed.


  CLS

      Format: CLS
              CLS expression
              CLS LINE
              CLS PAGE

      These statements will clear all, or portions of the screen of text
      and graphics.

             CLS            Clears the entire screen of text and graphics.
                            Cursor ends up at the top left corner of screen.
             CLS expression In TEXT mode this fills the screen with the ASCII
                            character specified by expression and places the
                            cursor at the top left corner of the screen.
             CLS expression In GRAPHICS mode this will fill the screen with the
                            color specified by expression.
             CLS LINE       Clears from the cursor position to the end of the
                            line. Cursor will remain where it was.
             CLS PAGE       Clears from the cursor position to the end of the
                            screen. Cursor will remain where it was.

      CLS clears the current window(not the entire screen). CLS
      expression will clear the screen with white if expression = 0 and
      black if expression <> 0.


  COLOR [=][foreground][,[background][,[,border]]

      This statement controls the color of all output to the screen. All
      of the parameters are optional. Under all modes COLOR 0 will turn
      foreground off(black in B/W modes, space in character modes).

      Table:
        Character Modes 0,1,3,4,6,8,9,11,12,14
          Foreground 0-15  Background 0-7  Border 0-15

        Character Modes 2,10,18
          Foreground 0-15  Background 0-15 Not Used

        Graphics Modes 5,13,16
          Foreground       Background      Border
          0 - Black(invis) 0               0-15 (Normal)
          1 - Green
          2 - Brown
          0 - Black        1               16-31 (High Intensity)
          1 - Cyan
          2 - Magenta
          3 - White

          In this mode, background equals Palette, Border is a global
          background and border value.

        Graphics Modes 7,15,17,21
          Foreground 0-1   Background 0-7   Border
          Foregound values toggle display off/on, Border may provide
          different(or no) results on various EGA/VGA hardware in CGA
          mode; typically there is no effect on "pure" CGA cards.

        Graphics Modes 19,22
          Foreground 0-15  Background 0-15  Border 0-15

        Graphics Mode 20
          In Hercules mode there are only two colors; black and white.
          There are three character formats: Regular, Reverse and XOR.
          (See TFORMAT).

        Graphics Mode 23
          Foregound 0-255  Background 0-255  Border 0-255

        Mono Codes
          Attributes   Normal Bright Reverse
           Regular        7     15     112
           Blinking     135    143     240
           Underline      1      9
           UL Blinking  129    137
           Invisible    136

        CGA Color Codes
         0 = Black  4 = Red      8 = Gray     12 = Lt Red
         1 = Blue   5 = Magenta  9 = Lt Blue  13 = Lt Magenta
         2 = Green  6 = Brown   10 = Lt Green 14 = Yellow
         3 = Cyan   7 = White   11 = Lt Cyan  15 = Bright White

        2 Color Chart
         Background   Black Blue  Green Cyan Red Magenta Yellow White
         Colors
         Black         0    +16    +32   +48 +64  +80     +96    +112
         Blue          1
         Green         2    For blinking forground colors,add 128 to base.
         Cyan          3    EXAMPLE:
         Red           4             Blinking Brt Yellow on Black backgrnd
         Magenta       5             14 + 128 = 142
         Brown         6             ^     ^
         White         7             |     +---------- Blink Value
         Lt Black      8             +---------------- Foreground Color
         Lt Blue       9             Blinking Yellow on Blue background
         Lt Green     10             14 + 16 + 128 = 158
         Lt Cyan      11             ^    ^     ^
         Lt Red       12             |    |     +------- Blink Value
         Lt Magenta   13             |    +------------- Background Offset
         Lt Yellow    14             +------------------ Foreground Color
         Lt White     15

        16 COLOR Chart
         0=Black             22=Bright Light Green 44=Medium Fuchia
         1=Blue              23=Light Green Yellow 45=Medium Magenta
         2=Green             24=Blue Gray          46=Tan
         3=Cyan              25=Bright Light Blue  47=Light Lilac
         4=Red               26=Light Green        48=Olive Green
         5=Magenta           27=Light Cyan         49=Medium Purple Blue
         6=Yellow Brown      28=Light Brick Red    50=Neon Green
         7=Light Gray        29=Light Purple       51=Medium Mint Green
         8=Dark Blue         30=Yellow Green       52=Orange
         9=Bright Blue       31=Very Light Cyan    53=Medium Pink
        10=Medium Celery     32=Deep Red           54=Bright Yellow
        11=Sky blue          33=Purple             55=Light Manilla
        12=Dark Fuchia       34=Medium Green       56=Gray
        13=Lilac             35=Light GRay Cyan    57=Medium Blue
        14=Light Yellow      36=Bright Red         58=Green Yellow
        15=Light Blue Purple 37=Fuchia             59=Light Blue Cyan
        16=Kelly Green       38=Gold               60=Dark Peach
        17=Light Blue        39=Light Pink         61=Medium Lilac
        18=Bright Green      40=Deep Purple        62=Yellow
        19=Mint Green        41=Bright Purple      63=White
        20=Brown             42=Celery
        21=Light Magenta     43=Light Sky Blue


  COMBUFF (-port)

      Returns the number of bytes waiting in the communication buffer.

      The communication buffer is a first in, first out (FIFO) buffer.

      To read data out of the buffer use READ#, INPUT# or LINEINPUT#.

      OPEN "C" to set baud rate, buffer size, parity and handshaking.

      Table: Port   Device    Port    Device
              -1     COM1      -2      COM2
              -3     COM3      -4      COM4

      Remark:
      COM BUFF determines the size of the communications buffer in the
      following way:

      As bytes are read from the com port into the buffer the COM END
      pointer is positioned to the next available position in the buffer.

      When it gets to the end of the buffer it wraps around the
      beginning.

      As bytes are read out of the buffer using READ#, INPUT# or
      LINEINPUT#, the COM START pointer is incremented to the next
      available byte. When COM START = COM END then all data has been
      read out of the buffer.

      When either COM END or COM START get to the end of the buffer
      tye "wrap around" to the beginning. If COM END ever "catches
      up" to COM START (COM END = COM START minus one), no more space
      is available in the buffer and nay received characters are lost.


  COM ON/OFF

      Format: COM (port) ON
              COM (port) OFF

      Enables or disables the interrupt driven communications for a
      specified prot. While program execution is taking place between
      these statements, incoming data is from the serial device
      specified by port is loaded into a FIFO buffer. It may be
      read out of the buffer using the READ#, IPUT#, or LINEINPUT#
      statements.

      Table: Port    Device
              -1      COM1
              -2      COM2
              -3      COM3
              -4      COM4

       COM ON is assumed when OPEN "C" is used.


  COMMAND$

      This function returns the command line string used to start up a
      program from DOS(ie. a ZBASIC-PC program saved as a .COM file).
      The string does not include the name of the program.

      Example: Message$ = COMMAND$


  COMMON variable list ...

      Identical to the ZBASIC-PC DOM statement. Used to allocate memory
      for variables and for declaring variables common to chained
      programs.

      The order of the variables declared in COMMON is important when
      chaining programs. The COMMON statement must be exactly the same
      and in exactly the same order in other programs being chained.


  COORDINATE

      Format: COORDINATE horizontal, vertical
              COORDINATE WINDOW

      Allows you to change the coordinate system used for graphic
      functions and statements.

      ZBASIC-PC defaults to a coordinate system of 1024 x 768.
      COORDINATE horizontal, vertical  Sets the relative coordinate
                                       system to the specified
                                       limits minus one. COORDINATE
                                       100,100 would allow setting the
                                       coordinate from 0 to 99 for both
                                       the horizontal and vertical.
      COORDINATE WINDOW                Sets the system to pixel
                                       coordinates. This allows you to
                                       calculate the grphic position by
                                       the actual resolution on the
                                       screen.


  COS(expression)

      Returns the Cosine of the expression in radians.

      Remark:
      Using COS in an expression wil force ZBASIC-PC to calculate that
      expression in floating point. COS is a scientific function. You
      may configure BCD scientific accuracy separately from both Double
      and Sigle precision immediately after lodaing ZBASIC-PC.

      Integer Cosine may be accomplished with a predefined ZBASIC-PC
      USR function; UER9 (angle in Brads). This returns the integer
      cosine of an angle in the range = 255(corresponding to =1). The


  CSRLIN
      Returns the line where the cursor is positioned.


  CURSOR x

      Allows 1 of 5 alternate cursor characters for the mouse, in
      non-VESA graphics modes only.

      Example: CURSOR 2

      Remark: The alternate cursors are identical to ZEDCORE's Macintosh ZBASIC.


  CVB(string)

      Returns the binary floating point value of the first n characters
      of the condensed number in string(depending on whether Single or
      Double precision is used).

        Double Precision    Returns the digits of accuracy defined in
                            configure for double precision(default is 8
                            digits ie. the first 8 string characters).
        Single Precision    Returns the digits of accuracy defined in
                            configure for single precision(defualt is 4
                            digits ie. the first 4 string characters).

      This function is the compliment of MKB$.

      Null stings or 1 character strings return 0.

      Two character strings will return 2 digits accuracy. Four
      character strings will return four digits.


  CVI(string)

      Returns the binary integer value of the first 2 characters of
      string.  This funtion is the complement of MKI$.

      Null string returns 0. One character strings will return the ASCII
      value. Two character strings will return an integer value


  DATA dataitem[, dataitem[, ...]]

      The DATA statement is used to hold information that may be read
      into variables using the READ statement. Data items are a list of
      string or numeric constants separated by commas and may appear
      anywhere in a program.

      No other statements may follow the DATA statement on the same
      line.

      Items are read in the order they appear in a program. RESTORE will
      set the pointer back to the beginning of the first DATA statement.

      RESTORE n will set the pointer to the nth data item.

      Alphanumeric string information in a DATA statement need not be
      enclosed in quotes if the first character is not a number.

      Leading spaces wil be ignored(unless in quotes). DATA statements
      can be included anywhere within a program and will be read in
      order.


  DATE$

      DATE$ = [month][,[day][,year]]

      Returns an eight digit character string containing the system date
      using the format MM/DD/YY, wher MM=Month, DD=Day, and YY=Year. Can
      also be used to set the date.

      Any of the three parameters can be omitted, in which case the
      parameter will not be changed. The following values are accepted:

         month:  1-12
           day:  1-31
          year:  1980-2099

      Note: If any of the specified parameters are not in the accepted range
            range, the date will not be changed.


  DEF INT SNG DBL STR
      Format: DEFINT   letter[-letter][,letter[-letter],...]
              DEFSNG   letter[-letter][,letter[-letter],...]
              DEFDBL   letter[-letter][,letter[-letter],...]
              DEFSTR   letter[-letter][,letter[-letter],...]

      These statements define which variable type ZBASIC-PC will assume
      when encountering a variable name with letter as a first character
      and not followed by a type declaration symbol (% integer,! single,
      # double, $ string).

      DEFINT   Integer
      DEFSGL   Single Precision
      DEFDBL   Double Precision
      DEFSTR   String

      ZBASIC-PC will assume that all variables are integers unless
      followed by type delcaration symbol or defined by a DEF type
      statement.

      See configure in manual for another way of defining default
      variable types.

      letter         Letter from A to Z. Case is not significant.

      letter-letter  Defines an inclusive range of letters.


  DEF COLOR color, RED var, GREEN var, BLUE var

      This statement allows the user to define displayable colors by
      altering the pallette value in text or graphics with EGA, VGA,
      MCGA, or VESA video cards. The displayed color is defined as to
      RED, GREEN, BLUE levels of intensity by any of the three
      following variables.  Values omitted leave that intensity level
      unaltered.

      Example: MODE 23
               DEF COLOR 240, 10,,30
               COLOR 240
               CIRCLE FILE 100, 100, 50

      The example defines COLOR 240 to have a RED intensity level of 10,
      leaves GREEN intensity unaltered, and changes the BLUE intensity
      to 30.  Each intensity level can be 0 - 63.


  DEF FN name [(variable[,variable[,...]])] = expression

      This statement allows the user to define a function that can be
      called by FN name.
      The expression may be a numeric or string expression and must be
      used to pass values to the function. The variable should be of
      the right type used in the function.

      Remark: One function may call another function as long as the function was
              called was defined first.



  DEF LEN [=] number

      The DEF LEN statement is used to reset the default length of
      string variables until the next DEF LEN statement is encountered.
      The number must be from 1 to 255.
      If DEF LEN is not used string length default is 255 characters
      each. Each string will consume 256 bytes; 1 byte for length, the
      rest for characters.

      Remark: DEF LEN will allocate the specfied amount of memory to every
              string that is defined after it(unless defined differently in DIM
              or other DEF LEN).
              Strings that appear before DEF LEN statement are not affected.

        Always allocate one extra character for strings used with INPUT.
        Never use a one character string for INPUT. The extra character
        position is needed for the carriage return.


  DEF MOUSE [=] expression

      This statement sets the MOUSE function to return information from
      any one of four device drivers define by expression.
        DEF MOUSE = 0  Mouse
                    1  Joystick A
                    2  Joystick B
                    3  Light Pen

      If the DEF MOUSE statement is not used, the mouse driver is used
      as the default.

      If expression is not 0 to 3, then the MOUSE(n) function will
      always return 0.

      ZBASIC-PC must be configured to support a mouse.


  DEF PAGE x1,y1 TO x2,y2

      This statement defines the size of the screen used in print
      operations where the parameters are as follows:
      x1,y1  = the upper left character position of the screen.
      x2,y2  = the lower right character position of the screen.
      ZBASIC-PC uses the screen size in scrolling the characters on the
      screen and in the CLS statement.
      To change the color of a portion of a screen:
      DEF PAGE 0,0 to 39,12
      COLOR 14,1
      CLS

      Remark:
      This statement is most useful for displaying information and
      status on the screen that will not be erased by a CLS or by
      scrolling the characters. The area outside the defined screen can
      be accessed using LOCATE or PRINT @ to locate the cursor in this
      area. Then normal printing can be done, except that none of the
      screen will be scrolled. When done printing in this area, a
      LOCATE or PRINT@ is again used to go back to the normal area(CLS
      will also home the cursor inside the normal area).

      In VGA graphics screens there are 30 lines of text rather than
      25. ZBASIC-PC automatically adjusts to DEF PAGE 0,0 to 79,29. It
      is possible to use various EGA and VGA fonts to allow screen text
      widths greater than 80 and lines greater than 25. In this case
      you should issue a matching DEF PAGE command.


  DEF PAGE READ/WRITE

      DEF PAGE READ [=] expression
      DEF PAGE WRITE [=] expression

      ZBASIC-PC can access extra pages of memory available in TEXT MODES
      on the IBM PC. The number of pages varies according to the video
      employed and memory installed.
      ZBASIC-PC can write to and display any of the available screens.

        DEF PAGE READ = 0   Set display page to 0.
        DEF PAGE WRITE = 0  Set write page to 0.

      Remark:
      When the screen being displayed is not the same as the screen
      being written, the CLS statement does not work. Also, the auto
      scrolling feature does not work.
      However, CLS expression will work regardless of the displayed
      page.


  DEF SEG [=] [address]

      Defines the current segement in memory. The address is an integer
      number between 0 and 65,535.
      Any subsequent use of a BLOAD, BSAVE, CALL, PEEK or POKE defintion
      specifies the offest into the segment(if the ZBASIC-PC segment
      option is not used in these commands).


  DEF TAB [=] expression

      The DEF TAB statement is used to define the number of characters
      between tab stops for use in PRINT, PRINT# or LPRINT statements.
      Tab stops are the number of spaces to move over when the comma is
      encountered in a PRINT statement.
      The expression must be a number from 1 to 256. Tab default is 16.


  DEF USR n [=] address[, segment]

      This statement is used to tell ZBASIC-PC where a user function is
      to be located in memory. Address is used as the offset into the
      segment given by segemnt. If the segment is not given then
      ZBASIC's code segment is used.

      Example: DEFUSR1 = LINE 100
               Defines the subroutine at line 100 as user function 1.


  DELAY expression

      The DELAY statement will cause a program to pause a specified
      amount of time.
      The expression sets the delay in milliseconds or thousandths of a
      second.

      The BREAK key is not scanned during DELAY. Any negative expression
      will cause delays in excess of 32 seconds(the unsigned value).
      Note that DELAY -1 will delay over 65 seconds(unsigned -1 = 65535.
      There may be a slight variation from machine to machine due to
      processor speed, interrupts, hardware differences, etc.


  DIM [len]var[type][(number[,number..])][,...]

      The DIM statement is used to allocate memory for variables and
      array variables and to define common variables for chained
      programs.
        len      Defines the length of a string(how many characters it may
                 hold). This is optional and defines the length of all the
                 following string variables in that DIM statement or until
                 a new length is encountered in that statement. The
                 default is 255 characters unless changed by a previous
                 DEF LEN.
                 Example:
                    DIM 9A$, 3ADY$, 9C$, 2CRLF$, 6D$, 3EF$, 5EX$, 15FA$, 2LT$, 3LY$
        var      The name of a variable(any variable type).
        type     Forces the variable to be that of type.
                 % integer           ! Single Precision
                 # Double Precision  $ String
        number   The maximum number of elements that a dimension may
                 contain from 1 to 32,767 elements(add one if array base
                 option is set to zero(default)). Only numbers may be used
                 not variables.
        If no len is defined, the last given length in that DIM statement
        is used.


  DO

      DO
      .
      .
      until expression

      The DO statement is used to define the beginning of a loop with
      the UNTIL statement defining the end.
      Program functions and statements appearing between the DO and
      UNTIL will be executed until the expression at the UNTIL statement
      is TRUE.

      Remark: The statements in a DO loop will be executed at least once.


  ELSE

      Format: IF-THEN-ELSE line or label
              IF-THEN-ELSE statement

      ELSE is used with an IF statement to route control on a false
      condition.
      ELSE may refer to a linenumber or label or it may be followed by
      one or more statements that will be executed if the condition in
      the IF statement is FALSE.


  END [= expression]

      The END statement is the normal way to exit a ZBASIC-PC program.
      An error return code can be sent using the END = expression. This
      value can then ne interrogated by the batch subcommands IF and
      ERRORLEVEL. To force a reset of the video mode to the state
      before the program was executed add 256 to expression.
      If the END = expression statement is not used to terminate a
      program, then the error code returned is 0.


  END FN

      Format: long fn
               .
               .
              END FN [= expression]

      Marks the end of a LONG FN statement.
      The optional expression MUST be numeric for numeric functions
      (!%#&) and MUST be string ($) for string functions.

      Remark: If an END FN is omitted in a LONG FN construct, a structure error
              will occur. You must exit a function from an END FN otherwise
              problems will occur internally.

      Loops like FOR-NEXT, DO-UNTIl or WHILE-WEND must be entirely
      contained within a LONG FN-END FN. Do NOT exit a function except
      at the END FN.


  END IF

      Format: long if expression
                .
              xelse
                .
              END IF

      This is an end marker for the LONG IF statement.
      Program execution will continue normally at the END IF after
      completion of a LONG IF or XELSE.

      Remark: If and END IF is omitted in a LONG IF construct, a structure
              error will occur.


  END SELECT

       Format:
         SELECT [CASE][expression]
           CASE[IS] relational expression[, relational expression][,...]
             statement[:statement...]]
           CASE[IS] condition[,condition][,...]
             statement[:statement...]]
           CASE boolean expression
             statement[:statement...]]
           CASE ELSE
             statement[:statement...]]
         END SELECT

      END SELECT is the end marker for the SELECT/CASE structure.
      When SELECT/CASE is encountered, the program checks the value of
      the controlling expression or variable, finds the CASE that
      compares true and executes the statements directly following
      the CASE statement. After these statements are performed, the
      program continues at the line after the END.


  EOF(number)

      Returns true if an end-of-file condition exists for filenumber,
      returns zero if the end-of-file has not yet been reached. With
      READ#, the check is for the physical end-of-file, with INPUT#
      the check is for the logical end of file.

      Some sequential file structures can cause problems with the EOF
      function. Normally sequential files are terminated with an
      ASCII character 1A(hex), however others may lack this(for example
      files created with COPY CON). In this case you may prefer the
      alternative method(see ERROR).


  ERRMSG$(expression)

      Returns the error message string for the number specified by
      expression. In most cases you will use the number returned by
      the ERROR function when a disk error has occured.

      ZBASIC-PC will display the errors for you unless you use the ON
      ERROR disk trapping options.
      The ERROR function is commonly used for error trapping and display
      purposes. The expression is stored as follows:
      The low byte is used for the ERROR    (ERROR AND 255)
      The high byte is used for the file#   (ERROR>8)or(ERROR/256)


  ERROR

      Returns the number of an ERROR condition, if any.
      Zero is returned if no error has occured.
      This function is available to proammers who wish to trap disk
      errors using the ON ERROR statement.
      ERROR=11  An error happened with RMDIR MKDIR or CHDIR.
      Errors encountered depend on the statement but usually are related
      to that statement, ie. if you get an error 11 doing RMDIR either
      the directory didn't exist, the wrong diskette was used, a write
      protect was on the disk or the wrong pathname was used.

      If you do disk error trapping. ERROR must be reset to zero after
      a disk error occurs or ERROR function will continue to return
      and error value.
      16 - Cannot create lock - network file error.
      17 - Fatal network error - network file error.


  ERROR [=] expression

      Allows the programmer to set or reset ERROR conditions for the
      purpose of disk error trapping.
      IMPROTANT NOTE: If you do the disk error trapping, ERROR must be
      reset to zero after a disk error occurs or ERROR function will
      continue to return an error value.
      ERROR may also be used as a function.


  EXP (expression)

      Returns e raised to the power of expression. This function is the
      compliment of LOG. The BCD internal constant of the value of e is
      2.71828182845904523536028747135266249775724709369995957
      The result will be rounded to the digits of precision configured
      for Double Precision accuracy.
      This is a scientific function. See Configure for information
      about configuring scientific accuracy.


  FILES [filespec]

      Prints a directory of the files in the directory specified by
      filespec.
      If filespec is not used the current directory contents are used.
      COMMAND.COM must be available.


  FILL expressionX, expressionY

      The purpose of FILL is to paint an area of the screen in the
      current color. The point defined by the expressions are:
      expressionX(Horizonal position) and expressionY(vertical pos)
      FILL will search for the uppermost point in the contained area
      that has the background color, then start filling from left to
      right and down. For this reason, irregular shapes may not fill
      completely with on fill command. It may be necessary to use a
      fill statement for each appendage.


  FIX(expression)

      Truncates the digits on the right side of the decimal point.
      FIX works the same as INT in ZBASIC-PC, except that FIX will
      consider an expression floating point.
      FRAC is the opposite of FIX. It returns the fraction part of the
      number.


  FN name [(expression1[, expression2[, ...]])]

      FN calls a function by name which was previously defined by
      DEF FN or LONG FN.
      The name of the function must follow the syntax of variable names,
      that is, a string FN must have a name with a $, an integer FN
      must have a name with a %, etc. FN may not be used before it is
      defined with DEF FN or LONG FN.
      The expressions must match the variable types as defined by DEF FN
      or LONG FN. Numeric expressions are not a problem, string
      allow only simple strings.

      This function is useful for saving program space and for making a
      program easier to read.


  FOR

      FOR variable = expression1 to expression2 [STEP expression3]
          .
          .
      NEXT [variable][,variable ...]

      Permits the repeated execution of commands within the loop.
      A FOR/NEXT loop will automatcially increment variable by the
      amount set by STEP and compare this to the end value, expression2,
      exiting the loop when var exceeds this value after adding STEP.
      Default for STEP is 1.
      Note the loop will be executed at least once with the value of
      expression1.

      If STEP is set to zero, the program will enter an endless loop.
      If the variable is an integer, do not allow the loop to exceed
      32,767 or you will enter an endless loop(unsigned integer).


  FRAC(expression)

      FRAC returns the fractional part of expression. THe digits to the
      left of the decimal point will be truncated.


  FRE(parameter)

      Returns the amount of free memory left in the system (divided by
      16). Multiply the number returned by 16 to get the amount of free
      memory in bytes. Also can be used to return the free or total
      space on a disk storage device.
        -1       Returns system free memory.
        -2       Returns DOS version.
         0       Returns free space on default drive.
         1-26    Returns free space on a given drive(1=A,2=B,3=C,4=D...)
      Returns a value of -1 for parameters 0-126 if device is not
      available.
      It is imperative that these variables be double precision to get
      the amount of free memory.
      Since there is no "Garbage Collection" in ZBASIC-PC, this function
      does not compact memory or return the remaining string space.
      String space is allocated at compile time.


  GET(x1,y1)-(x2,y2), variable[array(index[,index...,])]

      Stores a graphic image from the screen into a variable array so
      that it may be retrieved later and put ot the screen with PUT.
      GET and PUT are extremely fast and useful for graphic animation.
      x1,y1  Coordinates of the upper-left-corner of the graphic image.
        x2,y2  Coordinates of the lower-left-corner of the graphic image.
      Coordinates are pixel coordinates; use with COORDINATE WINDOW.
      The image is normally stored in memory specified by an integer
      array since it is easier to calculate how much memory is required
      this way but other variables may be used.
      To calculate the number of bytes to DIM for a graphic image, use
      this equation. Bits-per-pixel has to do with color available.
        6+((y2-y1)+1)*((x2-x1+1)*bpp+7)/8
        Type        Mode      Colors       Bits Per Pixel
        CGA         5         4            2
        CGA         7         2            1
        EGA         16-19     3-16         2(64k or less)
        EGA         16-19     16           4(more than 64k)
        VGA         21        2            1
        VGA         22        16           4
        MCGA        23        256          8
        HERCULES    20        1            1

      IMPORTANT NOTE: Failure to DIM enough memory for the variable
      storing the graphic images may result in unpredictable system
      problems.


  GOSUB line or label

      GOSUB will call that part of a program starting with line or label
      and return to the next statement following the GOSUB with RETURN
      is encountered.

      On multiple statment lines, a RETURN will return control to the
      next statement on the the line following the originating GOSUB.
      To avoid errors, be certain there is a line with the number or
      label that you GOSUB. All subroutines must be terminated with a
      RETURN statement.

      NOTE: If ZBASIC-PC encounters a RETURN without a matching GOSUB,
      it will return to the operating system or the editor. ZBASIC-PC
      does not check for stack overflow which may cause errors if
      subroutines do not end with a RETURN.


  GOTO line or label

      GOTO will transfer control to a line or label in a program.

      A line error will occur during compile if the destination line or
      label cannot be found.


  HEX$(expression)

      The HEX$ function converts a numeric expression to a four
      character HEXadecimal string.

      Floating point numbers will be truncated to integers.


  IF

      Format:
      IF expression THEN line[or label][ELSE line[or label]]
      IF expression THEN statement [:statement ...][ELSE statment ...]

      The IF statement allows a program to do a number of things
      based on the result of expressoin:
        1. Branch to  a line or lable after the THEN if a condition is
           true; expression -0
        2. Execute statement(s) after the THEN if a condition is true;
           expression -0
        3. Branch to a line or label after the ELSE if a condition is
           false; expression = 0
        4. Execute statement(s) after the ELSE if a condition is false;
           expression = 0.

      Complex strings will generate an error if used in an IF
      statement.


  INDEX$

      Format: INDEX$(expression) = string
              INDEX$I(expression) = string
              INDEX$D(expression)

      INDEX$ is a special array. expression indicates an element
             number.

      INDEX$(n)=simple string
        Assigns a value to INDEX$(n).

      INDEX$I(n)=simple string
        Move element n(and all consecutive
        elements) up and INSERT simple string at
        INDEX$ element n.

      INDEX$D(n)
        Delete element n and move all
        consecutive elements down to fill the
        space.


  INDEXF(string[,expression])

      INDEXF is a special INDEX$ array function used to FIND a leading
      string within an INDEX$ array quickly.
      If INDEX$(1000) equaled "hello", then X=INDEXF("hello") would
      return 1000.
      If X = INDEXF("llo") X would equal -1 since "llo" would not be
      found. The leading characters are significant.


  INKEY$

      INKEY$ returns the character of the last key pressed or an empty
      string if no key was pressed.

      Example: Y$ = INKEY$

      Remark:
      When using INKEY$ for character entry, avoid having the TRON
      function active as this may cause pressed keys to be missed.
      Certian keys return more than one character, such as the function
      left cursor, right cursor, etc.  In this case, the first
      character in the returned string will be a null"00HEX" and the
      second character will be the value of the key pressed.
      Key Codes Returned by INKEY$ for MSDOS
      A = Alternate  C = Control  S = Shift
      The characters below are the 2nd character.
      Key N A C S  Key N A C S  Key N A C S  Key N A C S
      --- - - - -  --- - - - -  --- - - - -  --- - - - -
      UpA H - - -  F1  ; h ^ T  F6  @ m c Y  Ins R - - 0
      DnA P - - -  F2  < i _ U  F7  A n d Z  End O - u 1
      LA  K - s    F3  = j ` V  F8  B o e [  Hme G - w 7
      RA  M   t    F4  > k a W  F9  C p f \  PUp I   o 9
                   F5  ? l b X  F10 D q g ]  PDn Q   v 3
                                             Del S     .
      N = Normal  A = Alt  C = Cntl  S = Shift


  INKEY$(expression)

      This statement is used to enable or disable function key
      interrupts.
      The function keys can be used to control program flow with
      ON INKEY$ GOTO(see ON INKEY$ statement).
      The expression does the following:
        0    disables function keys
        <> 0 enables function keys
      Enabling or disabling the function keys deos not destroy the
      previous ON INKEY$ key definitions, it simply decides whether or
      not ZBASIC-PC should check for function keys.

      Example: ON INKEY$(1) GOTO "F1"

      Remark: The ability to turn the function keys on and off iss


  INP(expression)

      The INP function is used to read an input port. The function
      returns the value that is currently at port expression.

      Remark: This function requires a knowledge of your computer hardware.


  INPUT[(@or%)(exprx,expry)][;][!][&expr,]["string";]var[,var...]

      The INPUT statement is used to input values(string or numeric)
      from the keyboard into variables.
      Multiple variables must be separated by commas. If not value is
      input, a zero or null string is returned.
      @(exprx,expry) Places the cursor at text location horizonal,
                     vertical or column(x) and row(y).
      %(exprx,expry) Places the cursor at graphics coordinate
                     horizonat, vertical.
      ;              Supresses carriage return/line feed
      !              Automatic Carrige return after maximun
                     characters entered. User does not need to
                     press ENTER.
      &expr,         Sets the maximum number of characters to be
                     input. Default is 255. Will not allow more
                     than expr characters.
      "string";      Optional user prompt will replace the question
                     mark(and supress it).
      var            May be any variable type integer, single or
                     double or string.
      If more than one variable is INPUT, commas must be included form
      the user to separate input. If all the variables are not input, the
      value of those variables will be null. Replace INPUT with LINEINPUT
      whenever there is a need to input quotes, commas and control
      characters(except with multiple variables). String lengths MUST be
      one greater than manimum INPUT length since a CHR$(13) is added
      (interally). Never define a string used in an INPUT or LINEINPUT
      as one.  The variable stack will become corrupted.
      Example: INPUT A$
               INPUT "Name";A$
               INPUT;A$
               INPUT &10,A$
               INPUT ;&3,I%
               INPUT !%&10,A$
               INPUT ;!&10,"Name:",A$
               LINE INPUT;!&5,"Name:",A$


  INPUT#expression, var[, var[,...]]

      This statement will read INPUT from a disk or other device
      specified by expression until a carriage return, comma, EOF or
      255 characters are encountered.
      Remember that DOS delimits each sequential record with a carriage
      return/linefeed combination. The carraige return/linefeed is not
      passed to var.
      Commans and leading spaces may be read into a string variable if
      the data on disk was enclosed in quotes, otherwise leading
      spaces and line feeds will be ignored.
      See LINEINPUT# for wasy of inputting commas, quotes and some
      control characters.


  INSTR(expression,string1,string2)

      Defines first occurrence of string2 in string1, starting at
      search position specified by expression.
      expression       Starting position of the search(default is 1).
      string1          String to be searched.
      string2          String  to search for.

      If string is not found, 0 is returned, otherwise the starting
      position is returned.


  INT(expression)

      Truncates all didgits to the right of the decimal point of
      expression.

      INT works the same as FIX in that expression will be restricted
      to the integer range of -32,768 to +32,767 only when the expression
      has not been defined as floating point.
      INT is simply a function that truncates an expression to a whole
      number.


  KILL simplestring

      Kill will erase a disk file specified by simplestring.
      KILL functions either as a command or from within a program. The
      use of "wildcards" is NOT allowed, thus KILL ".DOC" is not
      allowed.

      Use this statement with caution. When a file has been killed it is
      normally unrecoverable.


  LEFT$(string,expression)

      LEFT$ returns the left most characters of string defined by
      expression. THe string will not be altered.


  LEN(string)

      Returns the number of characters that are stored in a string
      constant or string variable. If 0 is returned it indicates a null
      (empty) string.

      The maximum length of a string is 255 characters. You may set the
      length of strings in ZBASIC-PC using DIM or DEF LEN.
      Since the first character of a string stored in memory is the
      length byte, PEEK(VARPTR(var$)) will also return the length of a
      string.
      The memory required for a string variable is the defined length,
      plus one for the length byte(256 bytes if not defined).


  [LET] variable = expression

      LET is an optional statement that may be used to assign an
      expression to a variable.


  LINE linenumber or label

      Returns the starting address of a compile line in memory.
      Normally used with CALL to execute machine language subroutines
      created with MACHLG.

      This statement is useful for calling machine language subroutines
      embedded in your program or for calculating the number of bytes
      used by program lines.


  LINE INPUT [(@or %)][;][!][&expr2,][&expr,]["string";]var$

      The LINE INPUT statement is used to input characters from the
      keyboard into a string variable. It is different from INPUT in
      that quotes, commas, and some control characters may also be
      entered. LINE INPUT is terminated when the ENTER key is pressed.
      @(exprx,expry)    Places the cursor at text location horizonal,
                        vertical or column(x) and row(y).
      %(exprx,expry)    Places the cursor at graphics coordinate
                        horizonat, vertical.
      ;                 Supresses carriage return/line feed
      !                 Automatic Carrige return after maximun
                        characters entered. User does not need to
                        press ENTER.
      &expr,            Sets the maximum number of characters to be
                        input. Default is 255. Will not allow more
                        than expr characters.
      "string";         Optional user prompt will replace the question
                        mark(and supress it).
      var$              Only string varaibles may used with LINE INPUT.
      String lengths must be at least one greater than the number of
      characters being input, otherwise a string overflow condition will
      destroy subsequent variables. Never use a one character string with
      LINE INPUT.


  LINE INPUT#expression, variable$

      This statement will input ASCII or TEXT data from a disk file
      specified by expression until ENTER, EOF, or 255 characters are
      encountered.
      Useful for accepting commas, quotes and other characters that
      INPUT# will not accept.


  LOC(expression)

      Returns the byte pointer within the current RECORD of the
      filenumber specified by expression.

      The LOC position is incremented to the next file position
      automatically when READ#, WRITE#, INPUT#, LINE INPUT# or PRINT#
      are used. REC(filenumber) returns the current RECORD. LOF returns
      the last record in the file.


  LOCATE [x,y][,[cursor on/off][,[startline][,stopline]]]

      This statement handles all of the cursor functions.
      x,y       Horizontal,vertical coordinate on the screen.
      on/off    0 = cursor off, not 0 = cursor on.
      startline start line for cursor character 0-13(how thick)
      stopline  stop line for cursor character 0-13.
      For the monochrome adapter, the values of these two parameters can
      be from 0 to 13. Zero specifies the top of the character block and
      13 specifies the bottom. With the graphics adaptor, 0 is the top
      and 7 is the bottom. The cursor can be turned on and off without
      affecting the start and stop lines.

      Example: LOCATE 0,20,0
               LOCATE 0,20
               LOCATE ,,1,3,4

      The x,y orientation can be reconfigured to be y,x(row,column).
      Also note that ZBASIC-PC defaults to accesing character cells
      using numbers from 0 to 79 across and 0 to 24 down.
      This function is also useful with CLS LINE and CLS PAGE for
      clearing the screen to the end of line and end of page.


  LOF(filenumber/-port[,record length])

      Returns the last valid RECORD number for the file specified by
      expression. LOF stand for Last-Of-File. If a record length of one
      is used it will return the length of the file in bytes.
      If a negative port number is used, it will return the nubmer of
      characters in the current serial buffer(see OPEN"C").
      Remark: LOF returns the last record in the file. The default record length
              is 256 and may need to be changed to make LOF function properly.


  LOG(expression)

      Returns the natural logarithm of expression (LN). LOG is the
      compliment of EXP.

      LOG is a scientific function. Scientific prescision may be
      configured by the use differently from both single and double
      precision.


  LONG FN

      Format: LONG FN name[(var[,var[,...]])]
                .
              END FN [= expression]

      LONG FN is similar to DEF FN but allows the function to span
      over several lines.
      The variables being passed to the function must not be arrays.
      The expression must be numeric for numeric and string for string
      functions.


  LONG IF

      Format: LONG IF expression
               .
              [XELSE]
               .
              ENDIF

      LONG IF allows multiple line IF-THEN-ELSE structures. Two things
      happen based on the result of expression:
      If the expression is TRUE     Executes all the statements up to
                                    the XELSE(if present) and then exits
                                    at the ENDIF.
      IF the expression is False    Executes all the statements between
                                    the XELSE and END IF and then exits
                                    at the END IF. If XELSE is not used
                                    it will simply end at the END IF.
      Remark: No loop may be executed within a LONG IF construct unless it is
              completely contained between a LONG IF and XELSE or between the
              XELSE and END IF. The entire LONG IF construct must be completely
              contained within loops or nested loops in order to compile
              properly.


  LPRINT[variables,constants...]

      The LPRINT statement sends output to a printer.
      An alternative to LPRINT is to open the printer(s) as a sequential
      outp file. Then use PRINT# statements rather than LPRINT. Due to
      lower handshaking requirements, this can produce faster thoroughput
      times, especially in situations like graphic output to dot matrix
      printers. Be sure to close the printer device when finished.
      To use more than one printer you may also use OPEN"O",1,"LPT2" and
      use PRINT#1,[variables, constants...].

      Many laser printers do not accept the above technique.


  MACHLG {[byes,...]}or{[words,...]}or{[variables][,...]}

      The MACHLG statement is used to insert bytes directly into a
      compiled program. These bytes may be machine language programs,
      variables or other items.
      It may be used to insert machine language into memory without
      using POKE.
      bytes     numbers from 0 to 255
      words     numbers from 0 to 65535. They are stored in standard
                format.
      variables Will create address where the variable is used.

      ZBASIC-PC uses registers when calculating elements of an array
      variable. Contents of these registers may be destroyed.


  MAYBE

      MAYBE is a random function that returns either a TRUE(-1) or
      FALSE(0) with equal probability.
      MAYBE is faster than RDN.
      Provides 50% random factor.


  MEM

      Format: MEM
              MEM letter
              MEM STR
              MEM BCD
              MEM ARR array(dummy)
      This function returns the segment address of specific portions of
      a ZBASIC-PC compiled program.
      The segments returned are as follows:
      MEM             Memory remaining in INDEX$ segment
      MEMC            Code segment
      MEMD            Data segment
      MEME            Extra segment
      MEMS            Stack segment
      MEMI            Index$ segement
      MEM STR         Simple strings
      MEM BCD         BCD variables
      MEM ARR A$(1)   Array A$ begins

      When using the MEM ARR function, the string array is given only one
      dummy argument regardless of the number of dimensions.


  MID$(string, expr1[, expr2])

      Returns the contents of string starting at position expr1 and
      expr2 characters long.
        string     The string from which the copy will occur
        expr1      The distance from the left where the copy will begin
        expr2      Optional prarameter that determines how many
                   characters will be copied. If omitted, all characters
                   from expr1 to the end of the string will be copied.


  MID$(string1,expr1[, expr2]) = string2

      Replace a portion of a string1 starting at expr1 with expr2
      characters of string2.
      string1   Target string. String2 will be insterted or laid over
                this string.
      string2   String to be inserted or laid over string1.
      expr1     Distance from the left of string1 where overlay is to
                begin.
      expr2     How many characters of string2 to insert into string1.
                Using 255 will assure that all characters are used.


  MKB$(expression)

      Returns a string which contains the compressed floating point
      value of a ZBASIC-PC BCD expression.
      This function works with either single or double precision. The
      amount of string space used will be in double precision and will
      vary depending on the digits of precision configured.


  MKDIR pathname

      Creates a new directory.
      When an error is encountered, ERROR is set to 11.


  MKI$(expression)

      Returns a two character string which contains a two byte integer
      specified by expression.


  MOD

      Format: expression1 MOD expression2

      MOD returns the remainder of an integer division with the sign of
      expression1.


  MODE(expression)

      MODE sets the system screen attributes. MODE can be set in the
      range 0-23.
      Color Graphics Adaptor (CGA)                  MODE 0-7
      Monochrome Dispaly & Printer Adaptor (MDPA)   MODE 2
      CGA Black and White                           MODE 8-15
      EGA                                           MODE 16-19
      Hercules Graphics Cards                       MODE 2 & 20
      VGA                                           MODE 21-22
      MultiColor Graphics (MCGA)                    MODE 23
       (1) CGA  (2) Hercules  (3) EGA  (4) VGA/MCGA

      To determine what board is installed, see CARDTYPE.

      MODE   TEXT Cols   Graphics    Pages    Colors  Type
       0       40x25     Character     8        16
       1       40x25     40x25         1        16
       2       80x25     Character     4        16
       3       80x25     80x25         1        16
       4       80x25     Character     4        16
       5       40x25     320x200 (1)   1         4
       6       80x25     Character     4        16
       7       80x25     640x200 (1)   1         2
       8       40x25     Character     8        B/W
       9       40x25     40x25         1        B/W
      10       80x25     Character     4        B/W
      11       80x25     80x25         1        B/W
      12       80x25     Character     4        B/W
      13       40x25     320x200 (1)   1        B/W
      14       40x25     Character     4        B/W
      15       80x25     640x200 (1)   1        B/W
      16       40x25     320x200 (3)   2/4/8    16
      17       80x25     640x200 (3)   1        16
      18       80x25     640x350 (3)   1/2       3
      19       80x25     640x350 (3)   1        4/16
      20       80x25     720x348 (2)   2         2
      21       80x30     640x480 (4)   1         B/W
      22       80x30     640x480 (4)   1        16
      23       40x25     320x200 (4)   1        356
      24       80x25     640x400       1        256     7
      25       80x30     640x480       1        256     8
      26      100x37     800x600       1        16      7
      27      100x37     800x600       1        256     8
      28      128x48    1024x768       1        16      8
      29      128x48    1024x768       1        256     9
      30      160x64    1280x1024      1        16      9
      31      160x64    1280x1024      1        256     10
      32       80x60    Character      1        16      7
      33      132x25    Character      1        16      7
      34      132x43    Character      1        16      7
      35      132x50    Character      1        16      7
      36      132x60    Character      1        16      7
      Types: 7=VESA 8=512k VESA 9=1024k VESA 10=2048k VESA

      MODE 18 is quite hardware specific and may perform unreliably on
      other video cards in EGA emmulation.
      In addition to card type, the USR0 command has been added for
      returning card and monitor capabilities for VESA.
      When addressing text in VGA and VESA modes, there can be more
      than 25 lines text.  To allow for this you may want to multiply
      the y position by an adjustment factor (1.2 for mode 22).  Thus
      to print at the bottom left of the screen use:
      Y = 24: MODE = M(24)
      IF M = 21 OR MODE = 22 THEN Y = Y * 1.2
      PRINT @ (0,4) "Here is the bottom line"


  MOUSE(expression)

      This function returns information from the current mouse driver
      as defined by the DEF MOUSE statement. expression will determine
      the value returned as follows:
        MOUSE(0)    Resets and returns true if installed.
        MOUSE(1)    Returns X position.
        MOUSE(2)    Returns Y position.
        MOUSE(3)    Returns button status.
        MOUSE(4)    Show mouse cursor.
        MOUSE(5)    Hide mouse cursor.
      The X and Y positions returnred are in terms of ZBASIC-PC's
      coordinate system.
      If expression is not 0 to 3, the 0 is returned. Alos, MOUSE(0) is
      supported only for the mouse driver (DEF MOUSE=0).

      The MOUSE function does not operate exactly the same for all
      DEF MOUSE types. Use the following for more specific information:
        DEF MOUSE=0     - MOUSE DRIVER
          MOUSE(0)   Resets the mouse hardware and software and returns
                     0(false) if hardware is not installed, otherwise
                     returns -1(true). ZBASIC-PC always initally resets
                     the mouse.
          MOUSE(1)   Returns the horizontal position of mouse.
          MOUSE(2)   Returns the vertical position of mouse.
          MOUSE(3)   Returns the button status from 0 to 7.
                     Left              = 1
                     Middle            = 4
                     Right             = 2
                     Left/Middle       = 5
                     Middel/Right      = 6
                     Left/Middle/Right = 7
      Note that ZBASIC-PC has to be configured to support the mouse.
        DEF MOUSE=1 or 2 - JOYSTICK DRIVER
          MOUSE(1)   Returns Horizontal position of Joystick.
          MOUSE(2)   Returns vertical position of Joystick.
          MOUSE(3)   Returns button status from 0 to 3. 0 if both
                     buttons up and 3 if both buttons down.
        DEF MOUSE=3       - LIGHT PEN DRIVER
          MOUSE(1)   Returns last horizontal position. If pen switch is
                     currently down,, the X and Y positions are updated
                     and the new X position is returned, else the last
                     position is returned.
          MOUSE(2)   Returns last vertical position, operating the same
                     as MOUSE(1).
          MOUSE(3)   Returns pen switch status from 0 to 1(0 if light
                     pen switch not down/not triggered, 1 if down or
                     triggered). If pen switch is down, the X an Y
                     position are updated.
      If a mouse driver is installed, the light pen driver will no
      longer work. The MOUSE function wil then return the mouse
      position and buttons instead of the light pen, still updating a
      position only when a button is pressed.
      MOUSE(4) and MOUSE(5) are used to show and hide the mouse cursor.

      It is important to note that the number of calls to one of the
      mouse statements must be equal to the number of calls to the
      other to get the cursor to the same states. For example, if
      MOUSE(5) is called 10 times to hide the cursor, then MOUSE(4)
      must be called 10 times to show the cursor.
      Also, ZBASIC-PC initially resets the mouse and leaves the cursor
      off. One call to MOUSE(4) will turn the cursor on.
      The cursor is seen in screen MODE 5,,7,,13,,15,16.


  NAME string1 AS string2

      Renames a file with a filename of string1 to string2. Sames as
      RENAME statment except for syntax.


  NEXT expression

      For var=expression1 TO expression2 [STEP expression3]
        .
      NEXT [variable[,variable...]]

      The NEXT statement is used as the end marker of a FOR loop. There
      must be a matching NEXT for every FOR, otherwise a structure
      Error will occur at compile time.

      The variable(s) following the NEXT statement are optional.
      However, if used they must match the corresponding FOR
      variable(s).

      A FOR loop will execute at least once.

      A structure error will specify the line number if there is an
      extra NEXT, or will specify 65535 if a NEXT is missing.


  NOT expression

      NOT returns the opposite of expression. True is False, False is
      True. This is equivalent to changing a logical true(-1) to a
      logical false(0) and vice versa.
      With Boolean(binary) operations, the NOT function will toggle all
      bits in expression. That is, all bits that are one will be changed
      to 0 and all 0 bits will be changed to 1.


  OCT$(expression)

      OCT$ returns a 6 character string which represents the Octal
      value(base 8) of the result of expression truncated to an
      integer. Octal digits are from 0-7.


  ON ERROR

      ON ERROR GOSUB line/label
      ON ERROR RETURN
      ON ERROR GOSUB 65535

      The ON ERROR allows the use to enable and disable disk error
      trapping. If ON ERROR is not used, ZBASIC-PC will display disk
      errors as they occur and give the user the option of continuing
      or stopping.  Options are:

        ON ERROR GOSUB 65535
          Enables user disk error trapping. Erros are returned using
          the ERROR function. You must check for errors after each
          disk operation.

        ON ERROR GOSUB line
          IF a disk error occurs the program does a GOSUB to line or
          label.

        ON ERROR RETURN
          Disable user disk error trapping. ZBASIC-PC will trap error
          and display message to user.

      See ERROR and ERRMSG$ and "Files". Always remember to set
      ERROR = 0 after a disk error occurs when you are doing the disk
      error trapping. Failure to do this will cause ZBASIC-PC to
      return an error.


  ON GOSUB

      ON expression GOSUB line[,line[,line...]]

      The ON GOSUB statement is used to call one of several subroutines
      depending on the value of expression.

      The ON statement will call the first subroutine if the expression
      evaluates to one, to the third subroutine if the expression
      evaluatges to three and so on.

      The RETURN statement at the end of a subroutine will return the
      program to the statement immediately following the ON GOSUB.

      ZBASIC-PC will truncate expression to an integer.
      If expression <=0 or > (number of line numbers listed), the
      program wil continue on to the next statement in the program.


  ON GOTO

      ON expression GOTO line[, line[, line...]]

      The ON GOTO statment is used to branch or jump to one of several
      portions of a program depending on the value of expression.
      The ON statment will jump to the first line if the expression
      evaluates to 0, to the third if the expression evaluates to 3 etc.

      ZBASIC-PC will truncate expression to an integer.
      If expression <=0 or > (number of line numbers listed), the
      program wil continue on to the next statement in the program.


  ON INKEY$

      ON INKEY$(expression) GOTO line#/label
      ON INKEY$(expression) RETURN

      This statement is used to control the action when a function key
      is pressed.
      When using the ON INKEY$ statement, expression determines which
      function key is being defined. The function key is not actually
      recognized until a ZBASIC-PC keyborad function is implemented,
      such as INPUT, LINE INPUT, and INKEY$ fucntion.
      When the GOTO is used, the line# specifies where the program will
      continue execution after the function key is hit. When RETURN is
      used, the function key is no longer implemented.
      All function keys are disabled until the INKEY$() statement is
      used.

      Remember to use the INKEY$(1) statment to enable function keys;
      otherwise, ZBASIC-PC doesn't check to see if the ON INKEY$()
      statement was used.
      When a GOTO is made from a function key, the current program
      execution is terminated and then restared at the location
      specified in the ON INKEY$() GOTO statement. Thus, this program
      cannot be nested in a subroutine. If a RETURN is executed before
      a GOSUB, the program will stop and ZBASIC-PC will return to the
      editor(or operating system).

      Function Key Codes:
        KEY              ON INKEY$        INKEY$
        F1               1                59
        F2               2                60
        F3               3                61
        F4               4                62
        F5               5                63
        F6               6                64
        F7               7                65
        F8               8                66
        F9               9                67
        F10              10               68
        HOME             13               71
        Cursor Up        14               72
        Page Up          15               73
        Cursor Left      17               75
        Cursor Right     19               77
        END              21               79
        Cursor Down      22               80
        Page Down        23               81
        INSERT           24               82
        DELETE           25               83


  OPEN

      OPEN"A[options]",[#]filenumber, filename[, record length]
      OPEN"E[options]",[#]filenumber, filename[, record length]
      OPEN"I[options]",[#]filenumber, filename[, record length]
      OPEN"O[options]",[#]filenumber, filename[, record length]
      OPEN"R[options]",[#]filenumber, filename[, record length]

      The OPEN statement is used to access a data file. Once a file is
      opened, information may be read from or written to the file
      depending on the way the file was opened. The first argument
      determines access:

        A          - Opens a file at the end for ASCII text operations.
                     If the file does not exist, it is created. If any
                     EOF markers (26) exist at the end of the file they
                     are removed.  Think of this as appending to the
                     end of the file.

        E          - Opens a file at the end for actual end of file
                     operations.  If the file does not exist, it is
                     created.

        R          - Read/Write file. Open file if it exists, create
                     the file if it doesn't.

        I          - Read only file. Open file for input. If file
                     doesn't exist, a disk error occurs.  ERROR > 0.

        O          - Write only file. Overwrites the old file if it
                     exists, if not it creates it. Remeber to close
                     the file or your writes will not be there.

        options    - The File/Record/Direcotry options are available:

          L          Specifies network record locking. This is automatic
                     and is activated by the input or ouput after a
                     RECORD statement is issued. For example, if you
                     RECORD#1,20
                     WRITE#1,A$;50
                     the record is automatically locked when the write
                     statement executes and remains locked until another
                     RECORD statement is executed.  Care must be taken
                     to unlock the record with a RECORD statement.
                     Further operations which take the record pointer
                     outside of the locked record do NOT effect its
                     locked status.  Be careful to not write a string
                     longer than the length of the locked record.  This
                     will cause the data in subsequent records to be
                     changed though they have not been locked.

          W          Specifies file locking for write operations. Only
                     the current user can write to the file.

          R          Specifies file locking for read operations. Only
                     the current user can read the file.

          D          Specfies Dynamic Directory Update.  This forces
                     the file's directory entry to be updated each time
                     a RECORD statement is executed. This slows write
                     operations but gives better directory entry
                     security in case of system lock-up or reboot.

        filenumber - The number you assign to a file for reference with
                     READ, WRITE, INPUT, PRINT, LOC, LINE INPUT, and
                     EOF.

        filename   - The filename as it appears in a directory. Drive
                     and optionally pathname can be specified.

        record     - Optional record length to be used with that

        length       file(default is 256).

      To configure ZBASIC-PC to have more than two files open at a
      time, see configure in manual. DOS limits you to a max of 15.
      ZBASIC-PC defaults to SHARE for network opertations.  This means
      a compiled program is automatically "network-capable".
      Common Disk ERROR Codes and Messages

      ERROR Code        Error Message
      0                 Operation Successful
      1                 End of file
      2                 Disk full
      3                 File NOT found
      4                 File NOT open
      5                 Bad File Name
      6                 Bad File Number(buffer not defined via OPEN)
      7                 Write only error
      8                 Read only error
      9                 Error
      10                Disk Error
      11                Path Does Not Exist
      12                Memory Allocation Error
      13                Write to a Read-Only file
      14                File already open
      15                DOS File limit error - close a file
      16                Lock error
      17                Unlock error
      18                Locking NOT supported
      19 - 255          Error
      257               EOF on File #1
      513               EOF on File #2

      Always close files with an explicit CLOSE#n statement to ensure
      data integrity.  This is especially important when disk cache
      programs are used.


  OPEN"C"

      OPEN"C",[-port],[baud],[stopbit],[wordlength],
         [port],[IRQ],[buffersize]

      This statement is used to set serial communications port
      parameters. If any of the parms are omitted, the defualt is used,
      but the commas should be included.

      -port      -1 Com1 through -8 Com8

      baud       110 150 300 600 1200(default) 2400 4800 9600 19200
                 38400 57600 115200. Baud is an integer, thus 1=115200.
                 A value of 2 through 65535 allows any rate rounded to
                 the nearest rate supported by 8250.  16550 series UART
                 buffering is automatic.

      parity   0 = none(default)   1 = odd   2 = even

      stopbit  0 = one(default)    1 = two

      wordlength 0 = 7 bits  1 = 8 bits(default)

      port     base port of UART. Value of -1 forces default.

      IRQ      1-7 (For IRQ0 use 8). -1 forces default.
               Defualts:  ZB  PORT  IRQ  Standard  ZB  PORT  IRQ
                          -1  3F8    4    COM1     -5   3F8   4
                          -2  2F8    3    COM2     -6   2F8   3
                          -3  2E8    4    COM3     -7   3E8   4
                          -4  2E8    3    COM4     -8   2E8   3
               IRQ's cannot be shared by more than 1 serial port. Some
               are reserved and accessing them can cause system
               problems.  IRQ0 (Clock tick), IRQ1 (Keyboard) and IRQ6
               (floppy drive) should be left alone. IRQ2 is used by some
               EGA and VGA cards. IR5 and 7 can often be used if the
               serial card allows it.

      buffersize is used for loading incoming data with COM ON and
      COM OFF. COM ON is automatically executed when OPEN"C" is used.
      The buffer defaults to 256 bytes but may be configured up to
      65535 bytes.

      Serial ports may be accessed using the same statements used in
      disk I/O, PRINT#, INPUT#, LINE INPUT#, READ#, and WRITE#. In all
      of these statements, the port is not read or written to until the
      status indicates that the port is ready.
      The one exception to the paragraph above is when READ# is used to
      read a string of zero length. In this case, the character will be
      returned if ready, otherwise null string will be returned.

      A port does not have to be opened in order to be accessed. The
      OPEN "C" statement is used only to set the current port parameter
      values. Without this statement, the port will simply use the
      parameters to which it was last set.

      Program termination does not close the port.  The buffer will
      continue to receive data.  CLOSE will drop DTR.


  OR expression OR expression

      Performs a logical OR on the two expressions for IF THEN testing
      and BINARY operations. If either or both conditions are true,
      the statement is true.
      In binary/boolean operations, if either bit is one then a one is
      returned.


  OUT port, data

      The OUT statement sends data to the specified port number.
      See INP for a way of reading data in from the port.


  PAGE

      Returns the current line position of the printer. The first line
      is 0.

      This function is simular to POS except the line position is
      returned instead of the character position.
      See CSRLN for getting the line position of the cursor.

      PAGE [[expression1][,[expression2][,[expression3]]]]

      PAGE is used to format output to the printer and to control the
      number of actual lines per page, printed lines per page and top
      margin. Following is a description of the parameters:
      PAGE without parameters will send a page feed to the printer.
           This forces the print head to move to the defined psosition
           of the top of the next page.
      expression1  The number of lines per page.
      expression2  The number of actual lines per page. Also set the
                   line count to 0.
      expression3  Lines for the top margin. This number is a subset of
                   expression1. If the line count is 0, this many
                   linefeeds wil be output immediately.

      WIDTH LPRINT should be used to set the printer's character width
      for proper PAGE operation when doing LLIST.


  PAGE LPRINT

      This statement dumps the screen to the printer.


  PAINT(x,y)

      Fills a section of the screen with the current color. Same as
      FILL statement.


  PALETTE register#, color

      Changes the color in the palette. This statement will only work
      with PC's equipped with a color card in GRAPHICS MODES only.


  PATH$(drive number)

      Returns a string containing the current path of drive number.
      drive numbers:

       0 = default drive
       1 = drive A
       2 = drive B
       3 = drive C
       4 = drive E
         etc.


  PEEK [word]( address[,segment])

      This statement is used to read a particular address in memory.
      The address is actually the offset into the segment given by
      segment. If the segment parameter is not given, the data segment
      used by ZBASIC-PC is used.
      By specifiying the segment, every address available can be
      accessed. The PEEK is done much faster, however, when the segement
      is not given.


  PLOT

      PLOT expr1, expr2 [TO expr3, expr4...]
      PLOT [TO] expr1, expr2 [TO expr3, expr4...]

      The PLOT statement is used to draw either one graphic point, or
      a line between two or more points, in the current COLOR.
      Works in graphic modes only.

      As with all other ZBASIC-PC graphic commands, device independent
      graphic coordinates of 1024 by 768 are the default. Expressions
      are truncated to an integer. Character type graphics will be
      substituted on computers, or modes, without graphic capabilities.


  PLOT USING x,y,string[,magnification]

      This statement is used to plot a set of pixels on the screen in
      a pattern defined by string starting at location x,y. The
      starting location x,y defines a point on the screen according to
      the ZBASIC-PC graphic coordinate system. The simple string string
      tells ZBASIC-PC whrer to plot each point corresponding to the one
      before it. The following characters are accepted "UDLRHIJK",
      which control direction, and "+" or "-", which turn plotting on
      and off. The "=" resets to background color(which in effect
      erases any plot) anda number is a repeating factor. Letters
      specify direction as follows:

        H U I
        L   R
        K D J

      Each pixel is plotted in the color last set by the COLOR
      statement; thus a pattern can be erased by setting COLOR = 0
      and replotting.
      When turning the plotting back on with a "+" imbedded in the
      string, note that the pixel at that point is plotted. Non-valid
      letters/symbols are ignored and could bes used as control values
      for other purposes.


  POINT(expression1, expression2)

      Point is available on many computers to inquire about the color
      of a specific screen graphic position. As with other commands,
      ZBASIC-PC device independent graphic coordinates may overlap
      pixels.

      If the coordinate is outside the screen coordinates, a -1 will
      be returned.


  POKE [WORD] address, data[,segment]

      This statement is used to set a particular address in memory to
      a value determined by data.
      The address is actually the offset into the segment given by
      segment. If the segement parameter is not given, the ZBASIC-PC
      data segment is used.


  POS(expression)

      Returns the current horizontal cursor position, from 0 to 255,
      for a screen, printer or disk file.
      The expression specifies a device as follows:
         0 = Default device, normally video.
         1 = Printer.
         2 = Disk file(DOS sequential-CR/LF delimited).

      A carriage return will set POS value to 0. PAGE will return the
      current line position for the printer.


  PRINT[{@ or %}](expr1, expr2)[list]

      The PRINT statement is used to output information to the current
      device, normally the video.
      @ (expr1,expr2) specifies text coordinates.
      % (expr1,expr2) specifies graphic coordinates.
      expr1           horizontal
      expr2           vertical

      PRINT followed by a semicolon ";" will disable the carriage
      return.
      A PRINT item followed by a comma will cause the next element to
      be printed at the next TAB stop defined by DEF TAB.
      See ROUTE for ways of sending PRINT data to another device like a
      printer, disk file or serial port.
      See "SCREEN PRINTER" for other ways of formating text, especially
      differences in PRINT@ when DEF PAGE is used with non-standard
      screen widths and heights with EGA/VGA fonts and text in VGA
      graphics Modes 21 and 22.


  PRINT#expression, var, var,...

      Used to PRINT information to a disk file or other device in text
      format. Numbers or strings will appear in the file or device
      similar to how they would look on the screen or printer.
      The expression is the file number assigned to the disk file or
      other device in an OPEN statement.
      INPUT# or LINE INPUT# are normally used to read back data created
      with PRINT#(although READ# may also be used).

      Be sure to see the entry on INPUT for more information about
      using PRINT# and INPUT#.


  PRINT[#filenumber,]USING formatstring;numeric expression;USING...

      This function permits formating numeric data in PRINT or PRINT#
      statements.

      The last numeric digit displayed will be rounded up by adding 5
      to the first digit on the right that is not displayed.
      The formatstring may be a quoted or variable using the following
      symbols:

      #  Hold place for a digit. More than one may be used.

      ,  Insert a comma in that place.

      .  Determines placement of decimal point.

      $  Prints a dollar sign on the left of the format.

      +  Prints a floating plus or minus sign on the left of the
         number.

      -  Prints a floating minus sign on the left of the number, only
         if the number is negative.

      *  Fills spaces before a number with asterisks.

      When error is printed in the format field, this indicates an
      occurance of an overflow condition and replaces the nuber that
      would have been printed. An overflow condition is when the value
      of the expression would have exceeded the boundries of the format.


  PSTR$

      PSTR$(var%)
      READ PSTR$(var%)
      PSTR$(var%) = "quoted string constant"

      Returns the string pointed to by var%.
      Loads the address of a string constant into var%.


  PUT(x1,y1) variable[(array index)[,array index[,...])[,mode]

      This statement places the graphic bit image stored in an array
      with the GET statement to the screen position at coordinates
      specified by x1,y1.

      If an array has been used then you MUST specifiy the index
      number of the array.

      Memory required for pixel images is calculated using this formula:
      6+((y2-y1)+1*((x2-x1+1)*bbp+7)/8

      The number of bits per pixel(bbp) depends on system colors or
      grey levels.

      MODE   XOR    XORs the pixels over the background pixels.
              OR    ORs the pixels over the existing pixels.
             AND    ANDs the picture with the background.
             PRESET Similar to PSET except the reverse image is shown.
             PSET   Draws image over background exactly as created.

      It is recommended that COORDINATE WINDOW be used when using GET.
      Bits-Per-Pixel(bbp) chart

      GRAPHIC TYPE      MODE(s)  COLORS  BITS PER PIXEL
      CGA               5        4       2
      CGA               7        2       1
      EGA               16-19    3-16    2
      EGA               16-19    16      4
      Hercules          20       1       1
      VGA               21       2       1
      VGA               22       16      4
      MCGA              23       256     8


  RANDOM[expression]


  RATIO byteexpression1,byteexpression2

      This statement will change the aspect ratio of graphics created
      with CIRCLE.

      byteexpression1  Horizontal ratio. A number between -128 and +127
                       that gives the relationship of the width of the
                       circle to normal(zero).

      byteexpression2  Vertial ration. A number between -128 and +127
                       that gives the relationship of the height of the
                       circle to normal(zero).

      VALUE     RELATIONSHIP TO NORMAL
      +127      = 2.0   times normal
       +64      = 1.5   times normal
       +32      = 1.25  times normal
         0      = 0     normal proportion
       -32      = 0.75  times normal
       -64      = 0.5   times normal
       -96      = 0.25  times normal
      -128      = 0     times normal(no width or height)

      RATIO settings are executed immediately and all CIRCLE commands,
      including CIRCLE TO and CIRCLE PLOT will be adjusted to the last
      RATIO.


  READ [variable{-or-PSTR$(var%)}[...]]

      The READ statement reads strings or numbers from a DATA statement
      into corresponding variables.
      The variable list can consist of any combination of variable types
      (string or numeric, including arrays).
      If no variable is given, the READ statement will skip one DATA
      item.

      Leading spaces in string data statements will be ignored unless
      contained in quotes.
      Do not read numeric data into string variables and vice versa
      (no error is generated). Don't read past the end of a data list.


  READ#filenumber,[var[var$;stringlength][,,...]

      Reads strings or numbers saved in compressed format with WRITE#
      and stores them into corresponding variables. The list may
      consist of any type string or numberic variables or array
      variables.

      filenumber    The filenumber to work from

      var           Any numeric type variable

      var$          String variable

      ;stringlength The number of characters to load into the string
                    variable

      IMPORTANT NOTE: A string variable must be followed by
                      ;stringlength to specify the number of characters
                      to be read into that string.

      Note: Do not mix variable types when using READ# and WRITE#.
      Reading string data into numberic variables, and vice-versa will
      create variables with incoherent data.
      READ# and WRITE# store and retrieve numeric data in a compressed
      format.


  READ# 128/129(LPT1:/LPT2:)

      Reports status of LPT1: and LPT2:. It is not necessary to OPEN#128
      or #129, however a "FILE NOT OPEN ERROR" is returend if hardware
      is not present.

      Status can either be read as READ#128,A$;1 or READ#1,A. The bit
      values are as follows:

      Bit 7   Printer NOT ready
      Bit 6   Acknowledged
      Bit 5   Out of Paper
      Bit 4   Selected
      Bit 3   I/O error
      Bit 2   Unused
      Bit 1   Unused
      Bit 0   Unused

      Example: READ#128,X$
               X = ASC(X$)
               IF X = 223 PRINT "Printer Ready"
               IF X = 103 PRINT "Paper Out"
               IF X = 71  PRINT "Printer Off Line"


  RECORD[#]filenumber,recordnumber[,location in record]

      The RECORD statement is used to position the file pointer
      anywhere in a file. Once the file pointer has been positioned you
      may read or write data from that position.
      RECORD can position both the RECORD pointer and location within
      a record.

      filenumber         Filenumber from 1 to 99

      recordnumber       RECORD number to point to. Defualt is 0.

      location in record Optional location in RECORD. Default is 0.

      The default RECORD length is 256 bytes. The maximum record length
      65535. The maximum number of records in a file is 65,535.
      If you need to access a record number greater than 65535, use a
      single or double precision number/variable.
      The location within a record is optional(0 is assumed if not
      given).
      If RECORD is not used, reading or writing starts from the current
      pointer position. If a file has just been opened, the pointer is
      positioned at the beginning.
      After each read or write, the pointer is moved to the next
      position in the file.


  REC(filenumber)

      Returns the current position of the record pointer for the file
      specified by filenumber. The first record in a file is record 0.
      Also often used with REC is LOC which returns the position within
      a record.

      The default record length is 256 bytes.


  REM followed by program remarks

      The REM statement is used for inserting comments or remarks into
      a program. ZBASIC-PC ignores everything following a REM statement
      to the end of the line.
      The apostrophe ' may be used at the beginning of a line.

      REM statements are not compiled and do not take up any memory in
      the object code.


  RENAME string1 TO string2

      This statement is used to rename the file string1 to string2.

      Path names can be specified in RENAME as a way of moving files
      from one subdirectory to another.


  RESET

      Closes all open files and devices. Functionally identical without
      parameters.


  RESTORE [expression]

             This statement resets the DATA pointer to the first DATA
             statement or optionally to the DATA item specified by expression.

             If expression is omitted, the first DATA item is assumed.
             ZBASIC-PC automatically set the pointer to the next item after
             each variable is READ.

             If an attempt is made to READ or RESTORE past the last DATA item,
             the result will be zeros or null strings. No error will be
             returned.


  RETURN [line]

      The RETURN statement is used to continue execution at the
      statement immediately following the last executed GOSUB or
      ON GOSUB statement.

      If optional line is used, the last GOSUB is POPPED off the stack
      and a GOTO line is performed.

      When ZBASIC-PC encounters a RETURN statement which was not called
      by a GOSUB, it will return to the program that executed it
      (either DOS or the editor).

      Using RETURN line WITHOUT A GOSUB or from the middle of a LONG FN
      will cause unpredictable system errors.


  RIGHT$(string,expression)

      Returns the right-most expression characters fo string.

      If expression is more than the characters available, all
      characters will be returned.


  RMDIR pathname

      Removes a directory. Only empty directories may be removed.

      If an error is encountered when using CHDIR, RMDIR or MKDIR
      ZBASIC-PC sets ERROR to 11.


  RND(expression)

      The RND function returns a random integer number from 1 to
      expression.

      The largest number you may use for a RND expression is 32,767.


  ROUTE[#] expression

      This statement is used to route PRINT or INPUT statements to a
      specified device. The following are values to be used as
      expression:

      -1 to -4       Serial ports 1 - 4
      0              Screen(default)
      1-99           Disk files specified by number
      128            Printer
      234            Redirect during program run through DOS. Useful
                     when displaying ANSI text files.

      Always re-route output back to the screen.


  SCREEN(row, column[,color])

      If color is 0 or not used, this function returns the ASCII code
      for the character at row/column when in text mode.

      If color is used and is not 0, the color of the text character at
      row/column is returned.
      row     expression from 0-24
      column  expression from 0-39 or 0-79 depending on current mode.

      The upper left corner is defined the same way as the LOCATE
      function.

      The number returned when using the color parameter may be
      converted into foreground/background numbers using this formula:

        foreground = (number MOD 16)
        background = (((number-foreground)/16)MOD128)


  SCREEN modenumber

      Allows changing from one graphic type to another. Similar to
      ZBASIC-PC MODE statement.

      ZBASIC-PC MODE       SCREEN MODE
            2                 0
            5                 1
            7                 2
           16                 7
           17                 8
           18                10
           19                 9
           21                11
           22                12
           23                13


  SELECT

      SELECT [expression or simplestring]
        CASE [IS] relational condition[, relational condition][,...]
          statements...
        CASE [IS] condition [,condition][,,...]
          statements...
        CASE [IS] boolean expression
          statements...
        CASE ELSE
      END SELECT

      Provides a structured way of doing multiple comparisons with a
      single expression.

      Always exit a SELECT at END SELECT.


  SGN(expression)

      Returns the sign of expression.


  SHELL string

      The SHELL statement followed by simple string will load and
      execute another program specified by string. If a null string is
      specified, the DOS will be loaded and excuted, typing EXIT will
      return to execute to ZBASIC-PC.
      This is identical to CALL string.
      STRING must be either a variable or a quoted string.

      There must be at least 17k of memory free to use SHELL.
      If COMMAND.COM is not found, the message "File not found" will be
      echoed to the display and control returned to the program.


  SIN(expression)

      The SIN function returns the sine fo the expression in radians.

      SIN is a scientific function. The precision for scientific
      functions are specified in configure.
      ZBASIC-PC provides a predefined USR function to do high-speed
      integer sines(up to 30 times the speed).
      USR(angle) returns the integer of sine of angle in the range +255
      (corresponding to 1). The angle must be in brads.


  SOUND Frequency, duration

      SOUND may be used to create sound effects or music.

      Frequency     120Hz to 10KHz

      duration      1 millisecond increments.

      Note  Octaves 1     2     3     4     5     6      7
       C            33    66    132   264   528   1056   2112
       C-           35    70    140   281   563   1126   2253
       D            37    74    148   297   594   1188   2376
       E-           39    79    158   316   633   1267   2534
       E            41    82    165   330   660   1320   2640
       F            44    88    176   352   704   1408   2816
       G-           46    93    187   375   751   1502   3004
       G            49    99    198   396   792   1584   3168
       A-           52    105   211   422   844   1689   3379
       A            55    110   220   440   880   1760   3520
       B-           57    115   231   462   924   1848   3696
       B            61    123   247   495   990   1980   3960

      Quality of sound may vary by machine.


  SPACE$(expression)

      Returns a string of spaces expression characters long(0-255).


  SPC(expression)

      SPC prints expression spaces from 0 to 256.
      Prints the number of spaces specified by expression.


  SQR(expression)

      The SQR function returns the square root of expression.

      SQR is a scientific funtion whose precision is set in configure.


  STEP

      FOR var = expr1 to expr2 [STEP expr3]
        .
      NEXT [var][,var]

      This parameter allows sets the increments used in a FOR-NEXT
      loop. If STEP is omitted then 1 is assumed.

      If STEP = 0 then an endless loop is executed.
      If expr1 or expr3 change while the loop is executed this change
      will be in effect when NEXT is encountered.


  STOP

      STOP halts execution of ZBASIC-PC and prints the line number
      where execution stopped if line numbers are used or a relative
      number if line numbers are not used.

      STOP closes all files.
      Use END when no number is desired.


  STR$(expression)

      STR$ returns the string exquivalent of expression(a number). This
      is used to convert numbers or numeric variables to a string.
      This function is the compliment of VAL which converts a string
      into a number.


  STRING$(expr1,string)

      STRING$(expr1,expr2)

      Returns a string of the length expr1 consisting of the characters
      specified by either the ASCII exquivalent of expr2 or the first
      character of string.


  SYSTEM

      Same as END.


  SWAP var1, var2

      SWAP exchanges the contents of var1 and var2. Variables cannot be
      INDEX$ type.

      var1 and var2 must be of the same type.


  TAB(expression)

      Tab will move the cursor to positions 0 through 255 designated by
      expression.
      Three devices may be used with TAB and are: SCREEN, PRINTER and
      DISK.


  TAN(expression)

      Returns the value of the tangent of the expression in radians.

      TAN is a scientific function whose accuracy may be configured.


  TFORMAT[=]expression

      The TFORMAT statement is used to set the text format when using a
      Hercules graphics MODE 20.
      The values for expression are:

        0    Reverse video
        1    Normal(PSET);Overlays graphics
        2    XOR mode. XOR text over background.


  THEN

      if-THEN-else line or label
      if-THEN-else statement(s)

      THEN is used with an IF statement to route control on a true
      condition.
      THEN may refer to a linenumber or a label or it may be followed
      by one or more statements that will be executed if the condition
      is true.

      All statements on a line following a THEN are conditional on that
      THEN.


  TIME$

      TIME$
      TIME$ = [hour][,[minute][,second]]

      Returns an eight character string which represents the sytem
      clock value in the format HH:MM:SS in 2400 hour format.
      The second form is used to set the system time. Any of the three
      parameters may be omitted in which case the parameter is not
      changed.


  TIMER

      Returns the number of seconds elapsed since midnight.

      Since the number of seconds elapsed since midnight can be
      greater than 65,535 the holding varaible should not be an
      integer.


  TROFF

      TROFF is used to turn off trace statements: TRON, TRON X, TRON B
      and TRON S.


  TRON [{B S X}]

      This statement is used for tracing program execution, single
      stepping through a program, and setting break points for
      monitoring the BREAK key so that you can break out of program.

      TRON   Prints the line numbers of hte program as each line is
             executed.

      TRON S Lets you single step through a program. Program execution
             will pause at the beginning of every line in the program
             following the TRON S. Press any key to continue or press
             CNTRL Z to enable/disable single stepping.

      TRON X Sets a break point at that line in a program and checks to
             see if the BREAK key has been pressed.

      TRON B Sets a break point at that the beginning of every line in
             the program.

      CTRL S will pause execution when encountered during execution of

      TRON B, TRON X, or TRON. Any key will restart.

      CTRL Z will toggle single stepping when any TRON is active.
      Note that INKEY$ may loose keys if TRON is used.

      Every line between TRON and TROFF may use up to 8 extra bytes per
      line. Use TRON sparingly to save memory and increase execution
      speed.


  UCASE$(string)
      Returns a string with all characters converted to upper case.


  UNS$(expression)
      Returns a string which equals the integer value of expression in
      an unsigned decimal format.
      This function is useful for displaying integers in an unsigned
      format(0 through 65,535 instead of -32,768 through 32,768).


  UNTIL
      DO
         .
      UNTIL expression

      UNTIL is used to mark the end of a DO loop.
      The DO loop repeats until the expression following UNTIL is
      true(non-zero).

      A DO loop will always execute at least once.

      DO
        X = X + 1
      UNTIL X = 100



  USRdigit(word expression)
      The USR function calls the user created routine, defined with
      DEFUSR, specified by digit(0-9), and returns the value of integer
      expression in the 16 bit accumulator.
      A machine language return is necessary at the end of USR routine.
      MACHLG  &8B,&C4,&C3


  USR0(mode)
      This returns a value of 2 if the installed VESA card is capable
      of displaying a given VESA graphics or text mode. If, for example
      you want to determine if your card can do MODE 29, issue a
      USR0(29).  A value of 0 returns if the card can display MODE
      29, 0 if NOT.


  USR1(filenumber)
      This is equivalent to EOF(filenumber). The result is -1 if end
      of file, 0 if not.
      Use EOF instead.


  USR2(expression) - NOTE used in ZBASIC 4.7 or above.
      USR2 is used to control the millisecond time constant used in the
      delay statement.

      The ZBASIC-PC delay statement should be delay a specified number
      of milliseconds(1/1000 of a second). This delay time is very
      dependant on the actual speed of the computer. The delay time
      constand defaults to a 1ms delay on the IBM PC(4.77MHz using the
      8088 microprocessor).

      If using ZBASIC-PC on a different speed computer, the use the
      USR2 statement to adjust the time constant.

      4.77 MHz           expression should be 300.

      faster computer    use a larger expression.

      slower computer    use a smaller expression.

      The delay time constant is also used in the SOUND statement to
      specify the duration.

      USR2(470)
      This will set the time constant to 470. This is the value used
      on an 80286 based PC at 6MHz to correct time delay times.

      This time constant can also be altered in configuration.


  USR3(expression)
      This function is used to control the keyboard input and status as
      follows:

      USR3(0)    Returns the next character struck from the keyboard.
                 The ASCII code is returned in the lower 8 bits. The
                 keyboard scan code is returned in the upper 8 bits.

      USR3(1)    Scans the keyboard buffer. 0 is returned if no key
                 was pressed. If there is a key in the buffer, the
                 ASCII and scan codes are returned same as USR3(0),
                 except the character will remain in the buffer.

      USR3(2)    Returns the current shift status. The bits returned
                 are as follows:
                 *Bit7 = Insert Key active
                 *Bit6 = Caps lock key toggle
                 *Bit5 = Num lock key toggle
                 *Bit4 = Scroll lock key toggle
                  Bit3 = Alternate key depressed
                  Bit2 = Control key depressed
                  Bit1 = Left Shift Key depressed
                  Bit0 = Right Shift key depressed

      Remember that USR3(1) does not take the character out of the
      buffer. This can be useful for checking the keyboard for a
      specific key before going into a standard input routine.


  USR4(address)
      USR4 is used to set the ctrl-break address (or ctrl-C) when one
      is detected. The address specified must be in ZBASIC-PC's code
      segement.

      USR4(Line 2000)

      This sets the ctrl-break address to be ZBASIC-PC's line 2000. In
      this case, if during program execution a ctrl-break is detected,
      a jump will be made to line 2000.

      When USR4 is used, program execution may not be resumed as the
      stack is not preserved. Note that ZBASIC-PC ignores the ctrl-C
      and ctrl-break keys unless this routine is used.


  USR5(port)

      USR5 is used to return the status of the communication port.

      -1 = COM1
      -2 = COM2
      -3 = COM3
      -4 = COM4

      The status bits returned are defined as follows:

       Bit15 = Time out
       Bit14 = Trans shift register empty
       Bit13 = Tran Holding register empty
       Bit12 = Break detect
       Bit11 = Framing error
       Bit10 = Parity error
       Bit9  = Overrun error
       Bit8  = Data ready
       Bit7  = Received line signal detect
       Bit6  = Ring indicator
       Bit5  = Data set ready
       Bit4  = Clear to send
       Bit3  = Delta recieve line signal detect
       Bit2  = Trailing edige ring detector
       Bit1  = Delta data set ready
       Bit0  = Delta clear to send

       J=USR5(-1)
       This gets the status of communications port 1(COM1).

       This function can be useful in investigating the RS-232 Control.
       If there is a problem with the 232 communication(such as
       mismatched baud rate, parity error, time out, or cable hookup),
       it can be evident by observing the status via the USR5 function.


  USR6(expression)

      Returns the last line number executed that used any of the TRON
      functions. expression is a dummy value.

      TRONX
      I = USR6(0)
      PRINT I


  USR7(expression)

      Returns ZBASIC-PC's random number seed used in the RND function.
      expression is a dummy value.


  USR8(angle)

      Returns the integer sine of angle in the range = 255
      corresponding to  = 1). The angle must be in brads.


  USR9(angle)

      Returns the integer cosine of angle in the range = 255
      (corresponding to = 1). Then angle must be in brads.


  VAL(string)

      Returns the numeric value of the first number in a string.
      The VAL function will terminate conversion at the first
      non-numeric character in string.
      This function is the compliment of STR$. STR$ will convert a
      numeric expression to a string.

      The numeric value returned by VAL will be in floating point
      format.


  VARPTR VARSEG

      VARPTR(variable)
      VARSEG

      This pair of functions is used to determine the memory address of
      a variable. VARPTR(variable) returns the offset of the variable.
      VARSEG returns the segement of variable.

      A = VARPTR(A$)
      B = VARSEG

      Because of the enhanced variable memory capability, the VARPTR
      function is slightly different from previous versions.
      Integers, BCD's, strings and BCD/string arrays are given their
      own dedicated block of memory so that more data can be stored.
      Therefore, two numbers are needed; one for the offset; one for
      the segment.
      The VARSEG function returns the segment of the last variable used
      with VARPTR. Its value is valid only immediately after a VARPTR
      has been executed.


  VIEW PRINT topline TO bottomline

      Used to set scrolling boundries.
      topline     The top line to be used for output.
      bottomline  The bottom line to used for output.
      This statement is very simular to the ZBASIC-PC DEF PAGE
      statement which also allows setting the column boundries as well.


  WAIT portnumber, AND expression [, XOR expression]

      Suspends program execution while checking the status of an input
      port.

      portnumber        numeric from 0-65535

      AND expression    integer from 0-255

      XOR expression    integer from 0-255

      WAIT PORT(x), 255,255

      The WAIT statement causes execution of the program to be
      suspended until a specified prot produces a certain bit pattern.
      The data read at the port is XORed with the XOR expression and
      ANDed with the AND expression. If the result is 0 the program
      loops back to read the port again.

      The computer may lock up if the requried bit pattern does not
      appear on the port.


  WEND

      WHILE expression
        .
      WEND

      This statement is used to terminate a WHILE loop. When expression
      becomes false the loop will exit at the first statement
      following the WEND.

      A structure error will occur if a WHILE exists without a matching
      WEND.


  WHILE expression

      In a WHILE statment, expression is tested for true before the
      loop is executed and will exit to the statement immediately
      following the matching WEND when expression becomes false.

      A structure error will occur if a WHILE exists without a WEND.


  WIDTH [LPINT] [=] byte expression

      Sets the allowable number of characters on a line before
      generating an automatic line feed.
      The optional LPRINT designates printer width.
      If byte expression is set to 0. ZBASIC-PC will not send an
      automatic CR/LF. The rang of byte expression is 0 to 255.

      The default setting fo the screen width is 0 which disables the
      auto LF/CR after the limit has been reached.
      To return WIDTH to normal, type WIDTH 79 (for 80 column screens)
      or WIDTH 0. When widths are set, listings are wrapped around
      nicely for easy reading.
      To effect a smaller width, set byte expression to the width
      desired. To assure valid results for the POS statement and to
      keep line position count used by tabs correct, be sure WIDTH is
      set to the actual screen width minus 1.


  WRITE#expression1, [var1%][var!][var#][var$;stringlength][,...]

      Writes the contents of string or numeric variables in compressed
      format to a disk file(or other device) specified by expr1. The
      list may consist of any variable type or types, string or numeric
      including arrays, in any order. Constants may NOT be used!
      A string variable MUST be followed by ;stringlength which
      specifies the number of characters of that string to be written.
      If the string is shorter than stringlength, the extra characters
      will be spaces.
      If the string is longer than stringlength, the extra characters
      will be truncated.
      READ# is the statement normally used to read back data written
      with WRITE# and will automatically read back the data written in
      compressed format.

      Do NOT mix variables types when using READ# and WRITE#. READ#
      and WRTIE# store and retrieve numeric data in compressed format.
      This saves disk space and speed program execution.

      WRITE#1, A$;4, B


  WRITE#128/129

      WRITE# expression

      This is a special "direct write to printer port" function which
      by-passes both DOS and BIOS, therefore it may not work with some
      quasi-copmatiable hardware. It is intended primarily for speeding
      up(as much as 200%) high quality printer output such as complex
      laser printer output or bit graphics with dot matrix printers.
      Low volume output, such as text pages,may show little speed
      advantage with this method. It is suggested that READ#128/129
      (read ports status) be used with WRITE# 128/129 for error
      handling routines. WRITE#128/129 will not time-out if the printer
      is not connected, however Control C can be used to break out of
      various printer error conditions.

      128 is LPT1
      129 is LPT2

      The variables written with WRITE#128/129 must be of specific
      length, and is a line-feed/cariage return is to be issued a
      CHR$(10) and CHR$(13) should be added to the STRING written.


  XELSE

      LONGIF expression
       .
      XELSE
       .
      ENDIF

      This statement is used to separate the FALSE from the TRUE
      section of a LONGIF structure.
      The statements following the XELSE will only be executed if the
      statement following the LONGIF is false.

      A structure error will occur if the XLESE does not have a
      matching LONGIF.


  XOR

      expression1 XOR expression2

      Provides a means of doing a logical EXLUSIVE OR on two
      expressions for IF-THEN testing and BINARY operations.
      This operator will return true if one condition is true and
      one condition is false. False will be returned if both conditions
      are true or false.

ZLIB FUNCTIONS - Written by Mark McDonald - 19970407


  B2D$(string$)

      Converts string of binary characters (0/1) to a decimal number.

      Returns as a string.

      '/*---------------------------------------------------------------*/
      '/* B2D$(BINARY$)                                                 */
      '/* Converts Binary String to Decimal String                      */
      '/*---------------------------------------------------------------*/
           LONG FN B2D$(X$)
             X$ = "&X" + X$
             XT = VAL(X$)
             RET$ = RIGHT$(STR$(XT),LEN(STR$(XT))-1)
           END FN = RET$
      '/*---------------------------------------------------------------*/
      '/* Test Program Below                                            */
      '/*---------------------------------------------------------------*/
      '/* A$ = "11000011"
      '/* PRINT FN B2D$(A$)



  B2H$(string$)

      Converts a string of binary characters (0/1) to a hexidecimal
      number returning as a string.

       '/*---------------------------------------------------------------*/
       '/* B2H$(BINARY$)                                                 */
       '/* Converts Binary String to Hexi-Decimal String                 */
       '/*---------------------------------------------------------------*/
           LONG FN B2H$(X$)
             X$ = "&X" + X$
             XT = VAL(X$)
             RET$ = HEX$(XT)
           END FN = RET$
       '/*---------------------------------------------------------------*/
       '/* Test Program Below                                            */
       '/*---------------------------------------------------------------*/
       '/* A$ = "11000011"
       '/* PRINT FN B2H$(A$)


  BLINK(OPT)
      Set the color blink or intensity setting.
      OPT:  0 = Blink or low intensity background.
            1 = No blink or high intensity background.
      EXAMPLE:  FN BLINK(0)

       '/*-------------------------------------------------------------------*/
       '/*  BLINK(OPTION)                                                   */
       '/*    Option: 0 = Bright                                             */
       '/*            1 = Blink                                              */
       '/*         Note: Changing video modes resets this bit to blinking    */
       '/*         mode.                                                     */
       '/*-------------------------------------------------------------------*/
           LONG FN BLINK(BLNK%)
             MACHLG &B8,&03,&10,&8A,&1E,BLNK%,&CD,&10
           END FN
       '/*-------------------------------------------------------------------*/
       '   COLOR 12,09
       '   PRINT "PRESS ENTER TO CHANGE TO BRITE"
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ = CHR$(13)
       '   FN BLINK(0)
       '   COLOR 12,09
       '   PRINT "PRESS ENTER TO CHANGE TO BLINK"
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ = CHR$(13)
       '   FN BLINK(1)
       '   INPUT Z


  BMOUSE

      Makes the mouse cursor blink.

       '/*------------------------------------------------------------------*/
       '/* BMOUSE                                                           */
       '/* MAKES MOUSE CURSOR BLINK                                         */
       '/*------------------------------------------------------------------*/
           LONG FN BMOUSE
               MACHLG &B8,&0A,&00,&BB,&01,&00,&CD,&33
           END FN
       '/*------------------------------------------------------------------*/
       '/* TEST PROGRAM BELOW                                               */
       '/*------------------------------------------------------------------*/
       '   "RESTART"
       '   DEF MOUSE=0                           :'/*DEFINE MOUSE DEVICE
       '   MOUSE(0)                              :'/*RESET MOUSE INTERFACE
       '   MOUSE(4)                              :'/*DISPLAY MOUSE CURSOR
       '   "LOOP"
       '   PRINT "PRESS B TO MAKE MOUSE CURSOR BLINK. "
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   IF Y$ = "B" THEN FN BMOUSE
       '   IF Y$ = CHR$(27) THEN END
       '   GOTO "LOOP"


  C2MOUSE(option,nbr)

      Convert mouse mickey to cursor value.

      Options:  1 = Convert nbr to cursor column
                2 = convert nbr to cursor row

       '/*------------------------------------------------------------------*/
       '/* C2MOUSE(OPTION,VALUE)                                            */
       '/*   WHERE OPTIONS: 1 = CONVERT VALUE TO CURSOR COLUMN              */
       '/*                  2 = CONVERT VALUE TO CURSOR ROW                 */
       '/* Convert Mouse Mickey Col or Row to Cursor Col or Row             */
       '/*------------------------------------------------------------------*/
           LONG FN C2MOUSE(NBR,XF)
             IF XF = 1 THEN XT! = (NBR * .07826)     :'/*COLUMN
             IF XF = 2 THEN XT! = (NBR * .0327868)   :'/*ROW
             RET = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
           END FN = RET
       '/*------------------------------------------------------------------*/
       '/* Test Program Below                                               */
       '/*------------------------------------------------------------------*/
       '/* PRINT FN C2MOUSE(166,1) "COLUMN - SHOULD BE 13"
       '/* PRINT FN C2MOUSE(430,2) "ROW - SOULD BE 14"


  CENTER$(string,length)

      Returns string centered in a string of length characters.

      The space character is used for padding.

       '/*------------------------------------------------------------------*/
       '/* CENTER$(STRING,LENGTH)                                           */
       '/* RETURNS A STRING CENTERED IN LENGTH SPACES                       */        */
       '/*------------------------------------------------------------------*/
           LONG FN CENTER$(X$,XN)
             XL = LEN(X$)
             LONG IF XL >= XN
               XX = 0
             XELSE
               XRET$ = STRING$(XN/2 - XL/2," ") + X$
             END IF
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/* TEST PROGRAM BELOW
       '/*------------------------------------------------------------------*/
       '/*A$ = "HELLO"
       '/*PRINT "         1         2         3         4         5         6"
       '/*PRINT "123456789012345678901234567890123456789012345678901234567890"
       '/*T$ = FN CENTER$(A$,30)
       '/*PRINT T$


  COPIES$(string, cnt)

      Returns string with string repeated cnt times.

       '/*-----------------------------------------------------------------*/
       '/* COPIES$(STRING,NCNT)                                           */
       '/* RETURNS NCNT COPIES OF XSTRING                                  */
       '/*-----------------------------------------------------------------*/
           LONG FN COPIES$(XSTR$,NCNT)
             LONG IF NCNT > 0 AND XSTR$ <> ""
                XRET$ = ""
                FOR CNT = 1 TO NCNT
                  XRET$ = XRET$ + XSTR$
                NEXT CNT
             END IF
           END FN = XRET$
       '/*-----------------------------------------------------------------*/
       '  CLS
       '  PRINT FN COPIES$("@",30)
       '  PRINT FN COPIES$("THIS IS A TEST",10)
       '  INPUT Z


  D2B$(decimal$)

      Convers a string of decimal characters to a binary string.

       '/*---------------------------------------------------------------*/
       '/* D2B$(DECIMAL$)                                                */
       '/* Converts Decimal to Binary String                             */
       '/*---------------------------------------------------------------*/
           LONG FN D2B$(X$)
             XT = VAL(X$)
             RET$ = BIN$(XT)
           END FN = RET$
       '/*---------------------------------------------------------------*/
       '/* Test Program Below                                            */
       '/*---------------------------------------------------------------*/
       '/* A$ = "195"
       '/* PRINT FN D2B$(A$)


  D2H$(decimal$)

      Convers a string of decimal characters to a hexidecimal
      number string.

       '/*---------------------------------------------------------------*/
       '/* D2H$(DECIMAL$)                                                */
       '/* Converts Decimal to Hex String                                */
       '/*---------------------------------------------------------------*/
           LONG FN D2H$(X$)
             XT = VAL(X$)
             RET$ = HEX$(XT)
           END FN = RET$
       '/*---------------------------------------------------------------*/
       '/* Test Program Below                                            */
       '/*---------------------------------------------------------------*/
       '/* A$ = "195"
       '/* PRINT FN D2H$(A$)


  DISPMSG(string$)

      Displays a string on the last (25th) line of the screen.

       '/*-----------------------------------------------------------------*/
       '/*  DISPMSG(STRING)                                                */
       '/*  DISPLAYS MESSAGE ON LAST LINE OF SCREEN                        */
       '/*-----------------------------------------------------------------*/
           LONG FN DISPMSG(X$)
             X$ = LEFT$(X$,78)
             PRINT @ (00,24) STRING$(79,32);
             PRINT @ (00,24) X$;
           END FN
       '/*-----------------------------------------------------------------*/


  EXIST(buffer, filename$)

      Determines if file filename$ exists using DOS handle buffer.

      Returns value of ERROR.

       '/*------------------------------------------------------------------*/
       '/*  EXIST(BUFFER,FILENAME)                                          */
       '/*  DETERMINES IF FILENAME EXISTS USING BUFFER                      */
       '/*  RETURNS VALUE OF ERROR                                          */
       '/*  RETURNS 0 IF FILE IS FOUND                                      */
       '/*------------------------------------------------------------------*/
           LONG FN EXIST(BUFFER,X$)
             ERROR = 0
             OPEN"I",BUFFER,X$
             CLOSE#BUFFER
           END FN = ERROR
       '/*------------------------------------------------------------------*/
       '   ON ERROR GOSUB 65535
       '   T = FN EXIST(1,"C:\BATCH\2MS.BAT")
       '   PRINT T
       '   INPUT Z


  FEDIT$(string,row,col,length)

      General purose field editor.

      Returns string equal to length.

       '/*-------------------------------------------------------------------*/
       '/*  FEDIT$(STRING,ROW,COL,LENGTH)                                    */
       '/*    Allows Editing of string starting at row, col.                 */
       '/*    Returns copy of STRING to LENGTH                               */
       '/*    If LENGTH = 0, Length of returned string = passed length       */
       '/*    Keys allowed are BACKSPACE, ENTER, ESC, HOME, END, INSERT,     */
       '/*    DELETE, and Arrow Keys.                                        */
       '/*-------------------------------------------------------------------*/
           LONG FN FEDIT$(EditLine$,Horizontal,Vertical,EditLength)
             IF EditLength = 0 THEN EditLength = LEN(EditLine$)
       '/*   --- Define Keys ---*/
             Backspace$ = CHR$(8)
             Enter$ = CHR$(13)
             Esc$ = CHR$(27)
             Home$ = CHR$(0) + CHR$(71)
             End$ = CHR$(0) + CHR$(79)
             Insert$ = CHR$(0) + CHR$(82)
             Delete$ = CHR$(0) + CHR$(83)
             LeftArrow$ = CHR$(0) + CHR$(75)
             RightArrow$ = CHR$(0) + CHR$(77)
             UpArrow$ = CHR$(0) + CHR$(72)
             DownArrow$ = CHR$(0) + CHR$(80)
       '/*   --- Initialize Flags ---*/
             EditPointer = 0
             Insert = 1
             TerminationStatus = 0
       '/*   --- Size String ---*/
             IF LEN(EditLine$) < EditLength THEN EditLine$ = EditLine$ + STRING$(EditLength - LEN(EditLine$),32)
       '/*   --- Edit Loop ---*/
             DO
               LOCATE Horizontal, Vertical, 0, 0,15
               PRINT EditLine$;
               LONG IF Insert
                 IF EditPointer >239 THEN LOCATE Horizontal + EditPointer-240, Vertical+3, 1, 6, 7
                 IF EditPointer >159 AND EditPointer < 240 THEN LOCATE Horizontal + EditPointer-160, Vertical+2, 1, 6, 7
                 IF EditPointer >79 AND EditPointer < 160 THEN LOCATE Horizontal + EditPointer-80, Vertical+1, 1, 6, 7
                 IF EditPointer < 80 THEN LOCATE Horizontal + EditPointer, Vertical, 1, 6, 7
               XELSE
                 IF EditPointer >239 THEN LOCATE Horizontal + EditPointer-240, Vertical+3, 1, 1, 7
                 IF EditPointer >159 AND EditPointer < 240 THEN LOCATE Horizontal + EditPointer-160, Vertical+2, 1, 1, 7
                 IF EditPointer >79 AND EditPointer < 160 THEN LOCATE Horizontal + EditPointer-80, Vertical+1, 1, 1, 7
                 IF EditPointer < 80 THEN LOCATE Horizontal + EditPointer, Vertical, 1, 6, 7
               END IF
       '/*     --- Get Keystroke ---*/
               DO
                 Inkey$ = INKEY$
               UNTIL LEN(Inkey$)
               SELECT CASE Inkey$
       '/*       --- Insert Key? ---*/
                 CASE Insert$
                   IF Insert THEN Insert = 0 ELSE Insert = 1
       '/*       --- Backspace Key? ---*/
                 CASE Backspace$
                   LONG IF EditPointer
                     EditLine$ = LEFT$(EditLine$, EditPointer - 1) + MID$(EditLine$, EditPointer + 1)
                     EditLine$ = EditLine$ + " "
                     EditPointer = EditPointer - 1
                   END IF
       '/*       --- Delete Character? ---*/
                 CASE Delete$
                   EditLine$ = EditLine$ + " "
                   EditLine$ = LEFT$(EditLine$, EditPointer) + MID$(EditLine$, EditPointer + 2)
       '/*       --- Left Arrow? ---*/
                 CASE LeftArrow$
                   IF EditPointer THEN EditPointer = EditPointer - 1
       '/*       --- Right Arrow? ---*/
                 CASE RightArrow$
                   IF EditPointer < EditLength THEN EditPointer = EditPointer + 1
       '/*       --- Enter Key? ---*/
                 CASE Enter$
                   TerminationStatus = 1
       '/*       --- ESC Key? ---*/
                 CASE Esc$
                   TerminationStatus = 2
       '/*       --- Up Arrow Key? ---*/
                 CASE UpArrow$
                   LONG IF EditPointer > 79
                     EditPointer = EditPointer - 80
                   XELSE
                     TerminationStatus = 3
                   END IF
       '/*       --- Down Arrow Key? ---*/
                 CASE DownArrow$
                   LONG IF EditPointer < EditLength-80
                     EditPointer = EditPointer + 80
                   XELSE
                     TerminationStatus = 4
                   END IF
       '/*       --- Home Key? - Goto Character #1 ---*/
                 CASE Home$
                   EditPointer = 0
       '/*       --- End Key? - Goto Last Character ---*/
                 CASE End$
                   EditPointer = EditLength - 1
                 CASE ELSE
                   LONG IF LEN(Inkey$) = 1
                     LONG IF Insert
                       EditLine$ = LEFT$(EditLine$, EditPointer) + Inkey$ + MID$(EditLine$, EditPointer + 1)
                       EditLine$ = LEFT$(EditLine$, EditLength)
                     XELSE
                       LONG IF EditPointer < EditLength
                         MID$(EditLine$, EditPointer + 1, 1) = Inkey$
                       END IF
                     END IF
                   XELSE
       '/*           EditPointer = EditPointer -1
                     TerminationStatus = 99
                   END IF
                   IF EditPointer < EditLength THEN EditPointer = EditPointer + 1
                 END SELECT
               UNTIL TerminationStatus
           END FN = EditLine$
       '/*------------------------------------------------------------------*/
       '/*  Test Progam Below                                               */
       '/*------------------------------------------------------------------*/
       '/* COLOR 10,0
       '/* CLS
       '/* Test$ = "This is a test "
       '/* 'Test$ = Test$ + " arrow to move inside the test edit line but if we move the"
       '/* 'Test$ = Test$ + " arrows up or down outside the edit line the edit is is "
       '/* 'Test$ = Test$ + "terminated. 4 termination codes are returned."
       '/* T$ = FN FEDIT$(Test$,0,10,20)
       '/* LOCATE 33,20
       '/* PRINT"Termination Status"TerminationStatus
       '/* PRINT"Key Returned is "Inkey$
       '/* PRINT"Length is of Key"LEN(Inkey$)
       '/* PRINT"Length of String"LEN(T$)
       '/* PRINT T$


  GKEY$

      Waits until ANY key is pressed.  Key string is returned.

       '/*------------------------------------------------------------------*/
       '/* WAIT UNTIL KEY IS PRESSED.                                       */
       '/*------------------------------------------------------------------*/
           LONG FN GETKEY$
             XRET$ = ""
             WHILE XRET$ = ""
               XRET$ = INKEY$
             WEND
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/*  TEST PROGRAM BELOW                                              */
       '/*------------------------------------------------------------------*/
       '  T$ = FN GETKEY$
       '  PRINT T$
       '  INPUT Z


  H2B$(hexstring$)

      Converts a string of hexidecimal characters to a string of
      binary characters.

       '/*---------------------------------------------------------------*/
       '/* H2B$(HEXSTRING)                                               */
       '/* Converts Hex String to Binary String                          */
       '/*---------------------------------------------------------------*/
           LONG FN H2B$(X$)
             X$ = "&H" + X$
             XT = VAL(X$)
             RET$ = BIN$(XT)
           END FN = RET$
       '/*---------------------------------------------------------------*/
       '/* Test Program Below                                            */
       '/*---------------------------------------------------------------*/
       '/* A$ = "C3"
       '/* PRINT FN H2B$(A$)


  H2D$(hexstring$)

      Converts a string of hexidecimal characters to a string of
      decimal characters.

       '/*---------------------------------------------------------------*/
       '/* H2D$(HEXSTRING)                                               */
       '/* Converts Hex String to Decimal String                         */
       '/*---------------------------------------------------------------*/
           LONG FN H2D$(X$)
             X$ = "&H" + X$
             XT = VAL(X$)
             RET$ = RIGHT$(STR$(XT),LEN(STR$(XT))-1)
           END FN = RET$
       '/*---------------------------------------------------------------*/
       '/*  Test Program Below                                           */
       '/*---------------------------------------------------------------*/
       '/* A$ = "00C3"
       '/* PRINT FN H2D$(A$)


  HMS2S!("hh:mm:ss")

      Converts a time string to seconds returning a floatin point
      number.

       '/*------------------------------------------------------------------*/
       '/* HMS2S!("HH:MM:SS")                                               */
       '/* CONVERTS TIME$ (HH:MM:SS) TO SECONDS (FLOATING POINT)            */
       '/*------------------------------------------------------------------*/
           LONG FN HMS2S!(XX$)
             XH$ = MID$(XX$,1,2)
             XM$ = MID$(XX$,4,2)
             XS$ = MID$(XX$,7,2)
             XH! = VAL(XH$)
             XM! = VAL(XM$)
             XS! = VAL(XS$)
             XRET! = (XH! * 3600) + (XM! * 60) + XS!
           END FN = XRET!
       '/*------------------------------------------------------------------*/
       '/*  TEST PROGRAM BELOW                                              */
       '/*------------------------------------------------------------------*/
       '/* A$ = "23:59:59"
       '/* SEC! = FN HMS2S!(A$)
       '/* PRINT SEC!
       '/* PRINT "SHOULD BE 86399"


  INSERT$(string1$, string2$, length)
      Insert string2 into string1 truncating at length.

       '/*------------------------------------------------------------------*/
       '/* INSERT$(ORIGINAL$, INSERT$, MAXLENGTH)                           */
       '/* INSERT A STRING INTO ANOTHER                                     */
       '/*------------------------------------------------------------------*/
           LONG FN INSERT$(XN$,X$,XN)
             XL = LEN(X$)
             LONG IF XL + XN > 255
               XRET$ = ""
             XELSE
               XRET$ = LEFT$(X$,XN) + XN$ + RIGHT$(X$,XL  - XN + 1)
             END IF
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/* TEST PROGRAM BELOW                                               */
       '/*------------------------------------------------------------------*/
       '/*A$ = "HELLO "
       '/*B$ = "THIS IS THE WORD"
       '/*PRINT "         1         2         3         4         5         6"
       '/*PRINT "123456789012345678901234567890123456789012345678901234567890"
       '/*T$ = FN INSERT$(A$,B$,5)
       '/*PRINT T$


  ISLEAPYR(CCYY)
      Returns 1 if CCYY is a leap year, 0 if not.
      EXAMPLE:  T = FN ISLEAPYR(1996)   1
                T = FN ISLEAPYR(1997)   0

       '/*------------------------------------------------------------------*/
       '/* ISLEAPYR(CENTURYYEAR)                                            */
       '/* IS IT A LEAP YEAR?  FORMAT OF X$ IS YYYY                         */
       '/* RETURNS:  0 = NOT LEAP YEAR                                      */
       '/*           1 = IS A LEAP YEAR                                     */
       '/*------------------------------------------------------------------*/
         LONG FN ISLEAPYR(X)
           IF (X) MOD 4 = 0 AND (X) MOD 100 <> 0 OR (X) MOD 400 = 0 THEN XRET = 1 ELSE XRET = 0
         END FN = XRET
       '/*------------------------------------------------------------------*/
       '  FOR CNT = 1970 TO 2017
       '    PRINT CNT;FN ISLEAPYR(CNT)
       '  NEXT CNT
       '  INPUT Z


  ISODD(NUMBER)
      Returns 1 if NUMBER is odd, 0 if NOT.
      EXAMPLE:  T = FN ISODD(11)      1
                T = FN ISODD(12)      0
                T = FN ISODD(13)      1

       '/*------------------------------------------------------------------*/
       '/* ISODD(NBR)
       '/*   RETURNS 1 IF NBR IS ODD, 0 IF NOT.
       '/*------------------------------------------------------------------*/
       LONG FN ISODD(NUMBER!)

         ' Returns True if odd number, False if not
         ' No modifications are made to Number

         LONG IF (NUMBER! / 2) - FIX(NUMBER! / 2) = 0
           XN = 0
         XELSE
           XN = 1
         END IF
        END FN = XN
       '/*------------------------------------------------------------------*/
       '  CLS
       '  PRINT "13 = " FN ISODD(13)
       '  PRINT "12 = " FN ISODD(12)
       '  PRINT "11 = " FN ISODD(11)
       '  INPUT Z


  LASTPOS(NEEDLE$, HAYSTACK$, START)
      Returns position last occurrence of NEEDLE in HAYSTACK.
      If NEEDLE is not found, 0 is returned.  If START = 0 then
      the search starts at the last character of HAYSTACK and scans
      backwards.  This may be overridden by specifying START as the
      point at which to start the backwards scan.
      EXAMPLE: PRINT LASTPOS(" ","abc def ghi",0)       8
               PRINT LASTPOS(" ","abcdefghi",0)         0
               PRINT LASTPOS(" ","ABC DEF GHI",7)       4
               PRINT LASTPOS("lt","deltaepsilon",0)     3

       '/*------------------------------------------------------------------*/
       '/* LASTPOS(NEEDLE$, HAYSTACK$)                                      */
       '/* RETURNS LAST LOCATION OF XF$ WITHIN X$                           */
       '/*------------------------------------------------------------------*/
           LONG FN LASTPOS(XNEEDLE$,XHAYSTACK$,XSTART)
             XLNEEDLE = LEN(XNEEDLE$)
             XLHAYSTACK = LEN(XHAYSTACK$)
             LONG IF XSTART = 0
               XSTART = XLHAYSTACK
               XS = XLHAYSTACK - XLNEEDLE + 1
             XELSE
               XS = XSTART
             END IF
             DO
               XRET = 0
               XT$ = MID$(XHAYSTACK$,XS,XLNEEDLE)
               IF XT$ = XNEEDLE$ THEN XRET = XS
               XS = XS - 1
             UNTIL XRET <> 0 OR XS = 0
           END FN = XRET
       '/*-------------------------------------------------------------------*/
       '    CLS
       '    PRINT FN LASTPOS(" ","ABC DEF GHI",0);"         8                "
       '    PRINT FN LASTPOS(" ","ABCDEFGHI",0);"         0                "
       '    PRINT FN LASTPOS(" ","ABC DEF GHI",7);"       4                "
       '    PRINT FN LASTPOS("LT","DELTAEPSILON",0);"     3                "
       '    PRINT FN LASTPOS("\","C:\TESTING\TEST\",0)"    16              "
       '    INPUT Z
       '/*------------------------------------------------------------------*/


  LOGGED$
      Returns letter of logged drive.
      EXAMPLE:  T$ = FN LOGGED$     "C"

       '/*------------------------------------------------------------------*/
       '/* LOGGED$                                                          */
       '/* Returns Letter of Logged Drive   0=A  1=B  2=C                   */
       '/*------------------------------------------------------------------*/
           LONG FN LOGGED$
             MACHLG &B4,&19,&CD,&21,&A2,XRET
             XRET$ = CHR$(XRET+65)
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '   PRINT FN LOGGED$
       '   INPUT Z


  PCURSOR(DUMMYINT)
      Positions text cursor to current mouse cursor.

       '/*-----------------------------------------------------------------*/
       '/* PCURSOR(DUMMYINT)                                               */
       '/* Positions Cursor to Current Mouse Location                      */
       '/*-----------------------------------------------------------------*/
           LONG FN PCURSOR(X)
             XMC = MOUSE(1)
             XMR = MOUSE(2)
             XT! = (XMC * .07826)                   :'/*COLUMN
             XC = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
             XT! = (XMR * .0327868)                 :'/*ROW
             XR = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
             PRINT @ (XC,XR) "";
           END FN
       '/*-----------------------------------------------------------------*/
       '   PRINT @ (00,00) "Move mouse and see cursor follow mouse.";
       '   DO
       '     FN PCURSOR(X)
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""


  PMOUSE(COL,ROW)
      Positions mouse to cursor COL/ROW.
      EXAMPLE:  FN PMOUSE(00,01)

       '/*-------------------------------------------------------------------*/
       '/* PMOUSE(COL, ROW)                                                  */
       '/* Puts mouse to Cursor location                                     */
       '/*-------------------------------------------------------------------*/
           LONG FN PMOUSE(XC,XR)
       '/*   XC = Cursor Column  XR = Cursor Row
             XX% = (XC * 8)                     :'/*Calculate Mouse Column
             XY% = (XR * 8)                     :'/*Calculate Mouse Row
             MACHLG &B8,&04,&00,&8B,&0E,XX%,&8B,&16,XY%,&CD,&33
           END FN
       '/*-------------------------------------------------------------------*/
       '/* DEF MOUSE=0                           :'/*Define Mouse Device
       '/* MOUSE(0)                              :'/*Reset Mouse Interface
       '/* MOUSE(4)                              :'/*Display Mouse Cursor
       '/* FN PMOUSE(00,01)
       '/* PRINT @ (01,01) "Line 1, Column 0 - Press ANY Key";
       '/* GOSUB "Wait"
       '/* FN PMOUSE(00,02)
       '/* PRINT @ (01,02) "Line 2, Column 0 - Press ANY Key";
       '/* GOSUB "Wait"
       '/* END
       '/* "Wait"
       '/* DO
       '/*   Y$ = INKEY$
       '/* UNTIL Y$ <> ""


  REVERSE(STRING$)
      Returns STRING$ swaped end for end.
      EXAMPLE:  T$ = FN REVERSE$("This is a test.")  "tset a si sihT"

       '/*------------------------------------------------------------------*/
       '/* REVERSE$(STRING$)
       '/* Returns string swaped end for end
       '/*------------------------------------------------------------------*/
          LONG FN REVERSE$(XX$)
            XL = LEN(XX$)
            X$ = ""
            FOR CNT = XL TO 1 STEP -1
              X$ = X$ + MID$(XX$,CNT,1)
            NEXT CNT
          END FN = X$
       '/*------------------------------------------------------------------*/
       '   CLS
       '   A$ = "This is a test"
       '   PRINT A$
       '   PRINT FN REVERSE$(A$)
       '   INPUT Z


  ROUND(NBR,PLACES)
      Rounds NBR to PLACES decimal positions.
      EXAMPLE:  T! = (153 * .07826)
                TT = FN ROUND(T!,0)

       '/*------------------------------------------------------------------*/
       '/* ROUND(NUMBER,PLACES)                                             */
       '/* ROUND NBR# UP KEEPING PLACES DECIMAL PLACES                      */
       '/*------------------------------------------------------------------*/
           LONG FN ROUND(NBR#,PLACES)
             NUMBER# = INT(NBR#*10^PLACES+.5)/10^PLACES
           END FN = NUMBER#
       '/*------------------------------------------------------------------*/
       '/* T! = (153 * .07826)
       '/* TT = FN ROUND(T!,0)
       '/* PRINT TT


  S2HMS$(SECONDS)
      Converts SECONDS to HH:MM:SS string.
      EXAMPLE:  T$ = FN S2HMS$(5400)   "01:30:00"

       '/*------------------------------------------------------------------*/
       '/* S2HMS$(SECONDS)                                                  */
       '/* CONVERTS SECONDS TO HH:MM:SS                                     */
       '/*------------------------------------------------------------------*/
           LONG FN S2HMS$(XX!)
             XH = INT(XX!/3600)
             XM = INT((XX! - (XH * 3600)) / 60)
             XS = INT(XX! - (XH * 3600) - (XM * 60))
             XH$ = RIGHT$(STR$(XH),LEN(STR$(XH))-1)
             XL = LEN(XH$)
             IF XL < 2 THEN XH$ = "0" + XH$
             XM$ = RIGHT$(STR$(XM),LEN(STR$(XM))-1)
             XL = LEN(XM$)
             IF XL < 2 THEN XM$ = "0" + XM$
             XS$ = RIGHT$(STR$(XS),LEN(STR$(XS))-1)
             XL = LEN(XS$)
             IF XL < 2 THEN XS$ = "0" + XS$
             XRET$ = XH$ + ":" + XM$ + ":" + XS$
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/* T! = 86399
       '/* PRINT FN S2HMS$(T!)
       '/* PRINT "SHOULD BE 23:59:59"
       '/* T! = 32708
       '/* PRINT FN S2HMS$(T!)
       '/* PRINT "SHOULD BE 09:05:08"


  SATTR(ATTR)
      Sets print color to ATTR.  Number may be 0 - 255.
      EXAMPLE:  FN SATTR(12)

       '/*-----------------------------------------------------------------*/
       '/* SATTR(ATTRIBUTE)
       '/* SET COLOR USING 1 DIGIT COLOR NUMBER 0-255
       '/*-----------------------------------------------------------------*/
           LONG FN SATTR(XN)
             CF = (XN MOD 16)
             CB = (((XN - CF) / 16) MOD 128)
             COLOR CF,CB
           END FN
       '/*-----------------------------------------------------------------*/
       '/*FN SATTR(12)
       '/*PRINT "THIS IS RED"
       '/*FN SATTR(14)
       '/*PRINT "THIS IS YELLOW"
       '/*FN SATTR(140)
       '/*PRINT "THIS IS BLINKING RED"


  SAY(ROW,COL,STRING$,ATTR)
      Prints STRING$ at ROW/COL using color ATTR.
      EXAMPLE:  SAY(10,0,"This is a test.",30)

       '/*-------------------------------------------------------------------
       '/*  SAY (ROW,COL,STRING$,ATTR)
       '/*    DISPLAYS STRING$ AT ROW/COL USING ATTR
       '/*-------------------------------------------------------------------
          LONG FN SAY(XROW,XCOL,XX$,XATTR)
            CF = (XATTR MOD 16)
            CB = (((XATTR - CF) / 16) MOD 128)
            COLOR CF,CB
            PRINT @ (COL,ROW) XX$;
          END FN
       '/*-------------------------------------------------------------------
       '  FN SAY(10,1,"THIS IS A TEST",31)
       '  INPUT Z


  SCRCLR(ATTR,CHARACTER$,ROW,COL,HEIGHT,WIDTH)
      Clears box defined by height and width starting at col/row
      using character$(1 character such as space), using color
      attr.
      EXAMPLE:  FN SCRCLR(0,0,80,24," ",31)
      EXAMPLE:  FN SCRCLR(10,15,45,10," ",33)
      EXAMPLE:  FN SCRCLR(10,15,45,10,"",31)

       '/*------------------------------------------------------------------*/
       '/* SCRCLR(XATTR,CHARACTER$,XROW,XCOL,XHEIGHT,WIDTH)                 */
       '/* Clear the Screen or Section of Screen with a character and XCOLor */
       '/*------------------------------------------------------------------*/
       '/* LONG FN SCRCLR(XATTR, XCH$, XROW, XCOL, XHEIGHT, XWDTH)
           LONG FN SCRCLR(XCOL, XROW, XWDTH, XHGHT, XCH$, XATTR)
       '/*   --- Break XATTR into Foreground/Background XCOLor Numbers ---/*
             XCF = (XATTR MOD 16)
             XCB = (((XATTR - XCF) / 16) MOD 128)
             COLOR XCF,XCB
       '/*   --- Build Character String ---*/
             XT$ = STRING$(XWDTH,XCH$)
       '/*   --- Clear Area ---*/
             FOR XX = XROW TO (XROW + XHGHT)
               PRINT @ (XCOL,XX) XT$;
             NEXT XX
           END FN
       '/*------------------------------------------------------------------*/
       '/*  Test Program Follows                                            */
       '/*------------------------------------------------------------------*/
       '  FN SCRCLR(0,0,80,24," ",31)
       '  GOSUB "WAIT"
       '  FN SCRCLR(10,15,45,10," ",33)
       '  GOSUB "WAIT"
       '  FN SCRCLR(10,15,45,10,"",31)
       '  GOSUB "WAIT"
       '  END
       '/*------------------------------------------------------------------*/
       '  "WAIT"
       '    DO
       '      Y$ = INKEY$
       '    UNTIL Y$ <> ""
       '    RETURN
       '/*------------------------------------------------------------------*/


  SCRRD$(ROW,COL,LENGTH,OPTION)
      Reads the screen starting at row/col for length characters.
      OPTIONS:  A = Attributes (color) only
                B = Both characters and attributes (text/color)
                T = Text only
      EXAMPLE:  T$ = FN SCRRD$(0,1,20,"A")

       '/*------------------------------------------------------------------*/
       '/* SCRRD$(ROW,COL,LENGTH,OPTION)                                    */
       '/*  Options: A = Attributes only                                    */
       '/*           B = Both Attributes and Text in Text/Attribute format  */
       '/*           T = Text only                                          */
       '/*------------------------------------------------------------------*/
           LONG FN SCRRD$(ROW,COL,LTH,OPT$)
             XRET$ = ""
             FOR XX = COL TO (LTH - 1)
       '/*     --- Get Text? ---*/
               LONG IF OPT$ = "T" OR OPT$ = "B"
                 XT = SCREEN(ROW,XX,0)
                 XRET$ = XRET$ + CHR$(XT)
               END IF
       '/*     --- Get Attribute ---*/
               LONG IF OPT$ = "A" OR OPT$ = "B"
                 XT = SCREEN(ROW,XX,1)
                 XRET$ = XRET$ + CHR$(XT)
               END IF
             NEXT XX
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/*  Test Program Follows                                            */
       '/*------------------------------------------------------------------*/
       '   CLS
       '   PRINT @ (0,10) "This is a test to see if this works";
       '   T$ = FN SCRRD$(10,0,10,"T")
       '   PRINT @ (0,20) T$;
       '   INPUT Z


  SFTATTR(ATTR)
      Returns a number that is offset of the original.  Used to set
      color to one other than one at current location.
      EXAMPLE:  FN SFATTR(12)

       '/*------------------------------------------------------------------*/
       '/* SFTATTR(ATTRIBUTE)                                               */
       '/* Shift Color like Mouse Does                                      */
       '/*------------------------------------------------------------------*/
           LONG FN SFTATTR(XATTR)
             XCF = (XATTR MOD 16)                             :'/*Foreground
             XCB = (((XATTR - XCF) / 16) MOD 128)             :'/*Background
             IF XCB < 8 THEN XCB = 7 - XCB ELSE XCB = 15 - XCB
             IF XCB = 0 THEN XCF = 12 ELSE XCF = 0
             COLOR XCF,XCB
           END FN
       '/*------------------------------------------------------------------*/
       '/* LONG FN SATTR(XN)  :'/*Used for Demo Only -
       '/*   CF = (XN MOD 16)
       '/*   CB = (((XN - CF) / 16) MOD 128)
       '/*   COLOR CF,CB
       '/* END FN
       '/* LONG FN PCURSOR(X) :'/*Used for Demo Only -
       '/*   XMC = MOUSE(1)
       '/*   XMR = MOUSE(2)
       '/*   XT! = (XMC * .07826)                   :'/*COLUMN
       '/*   XC = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
       '/*   XT! = (XMR * .0327868)                 :'/*ROW
       '/*   XR = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
       '/*   PRINT @ (XC,XR) "";
       '/* END FN
       '/* SHELL "COLOR /F"
       '/* HXMC = 0
       '/* XHMR = 20
       '/* XR = 0
       '/* XC = 0
       '/* HC = SCREEN(XR,XC,0)
       '/* HA = SCREEN(XR,XC,1)
       '/* DO
       '/*   XMC = MOUSE(1)
       '/*   XMR = MOUSE(2)
       '/*   LONG IF XMC <> HXMC AND XMR <> HXMR
       '/*     FN SATTR(HA)
       '/*     PRINT @ (XC,XR) CHR$(HC);
       '/*     FN PCURSOR(X)
       '/*     HC = SCREEN(XR,XC,0)
       '/*     HA = SCREEN(XR,XC,1)
       '/*     FN SFTATTR(A)
       '/*     PRINT @ (XC,XR) CHR$(HC);
       '/*   END IF
       '/*   Y$ = INKEY$
       '/* UNTIL Y$ <> ""


  SHADOW(SCOL,SROW,NCOLS,NROWS,ATTR,OPTION)
      Draw shadow using ATTR COLOR
      around two sides of a box defined as starting at startcol/row
      and NCOLS AND NROWS.
      OPTION:   1 = Bottom and right side
                2 = Bottom and left side
                3 = Top and left side
                4 = Top and right side

      If fcolor and bcolor both = 0 then the shadow is grey characters
      on a black background.
      EXAMPLE:  FN SHADOW(10,12,5,6,7,4)

       '/*-----------------------------------------------------------------*/
       '/* SHADOW(SCOL,SROW,#COLS,#ROWS,ATTR,OPTION)                       */
       '/* WHICHONE -  1 = RIGHT/BOTTOM SIDES                              */
       '/*             2 = LEFT/BOTTOM SIDES                               */
       '/*             3 = LEFT/TOP SIDES                                  */
       '/*             4 = TOP/RIGHT SIDES                                 */
       '/* IF FCOLOR = 0 AND BCOLOR = 0 THEN THE SHADOW IS GREY ON BLACK   */
       '/*-----------------------------------------------------------------*/
           LONG FN SHADOW(XCOL,XROW,XNCOLS,XNROWS,XATTR,XOPT)
             XECOL = XCOL + XNCOLS
             XEROW = XROW + XNROWS
             IF XATTR = 0 THEN XATTR = 7
             XCF = (XATTR MOD 16)
             XCB = (((XATTR - XCF) / 16) MOD 128)
             COLOR XCF,XCB
             SELECT XOPT
               CASE 1
                 GOSUB "FN-RIGHT-BOTTOM"
               CASE 2
                 GOSUB "FN-LEFT-BOTTOM"
               CASE 3
                 GOSUB "FN-LEFT-TOP"
               CASE 4
                 GOSUB "FN-TOP-RIGHT"
             END SELECT
             GOTO "FN-SHADOW-EXIT"
             "FN-RIGHT-BOTTOM"
               FOR XCNT = XROW + 1 TO XEROW + 1
                 XC = SCREEN(XCNT,XECOL + 1,0)
                 XC2 = SCREEN(XCNT,XECOL + 2,0)
                 PRINT @ (XECOL + 1,XCNT) CHR$(XC);CHR$(XC2);
               NEXT XCNT
               FOR XCNT = XCOL + 2 TO XECOL + 1
                 XC = SCREEN(XEROW + 1,XCNT,0)
                 PRINT @ (XCNT,XEROW + 1) CHR$(XC);
               NEXT XCNT
             RETURN
             "FN-LEFT-BOTTOM"
               FOR XCNT = XROW + 1 TO XEROW + 1
                 XC = SCREEN(XCNT,XCOL - 1,0)
                 XC2 = SCREEN(XCNT,XCOL - 2,0)
                 PRINT @ (XCOL -2,XCNT) CHR$(XC2);CHR$(XC);
               NEXT XCNT
               FOR XCNT = XCOL -2 TO XECOL -2
                 XC = SCREEN(XEROW + 1,XCNT,0)
                 PRINT @ (XCNT,XEROW + 1) CHR$(XC);
               NEXT XCNT
             RETURN
             "FN-LEFT-TOP"
               FOR XCNT = XCOL - 2 TO XECOL - 2
                 XC = SCREEN(XROW - 1,XCNT,0)
                 PRINT @ (XCNT, XROW - 1) CHR$(XC);
               NEXT XCNT
               FOR XCNT = XROW - 1 TO XEROW - 1
                 XC = SCREEN(XCNT,XCOL - 2,0)
                 XC2 = SCREEN(XCNT,XCOL - 1,0)
                 PRINT @ (XCOL - 2,XCNT) CHR$(XC);CHR$(XC2);
               NEXT XCNT
             RETURN
             "FN-TOP-RIGHT"
               FOR XCNT = XCOL + 2 TO XECOL + 2
                 XC = SCREEN(XROW - 1,XCNT,0)
                 PRINT @ (XCNT,XROW - 1) CHR$(XC);
               NEXT XCNT
               FOR XCNT = XROW - 1 TO XEROW - 1
                 XC = SCREEN(XCNT,XECOL + 1,0)
                 XC2 = SCREEN(XCNT,XECOL + 2,0)
                 PRINT @ (XECOL + 1,XCNT) CHR$(XC);CHR$(XC2);
               NEXT XCNT
             RETURN
             "FN-LEFT-BOTTOM"
               FOR XCNT = XROW + 2 TO XEROW + 1
                 XC = SCREEN(XCNT,XCOL - 2,0)
                 XC2 = SCREEN(XCNT,XCOL - 1,0)
                 PRINT @ (XCNT,SC -2) CHR$(XC);CHR$(XC2);
               NEXT XCNT
               FOR XCNT = XCOL - 2 TO XECOL - 2
                 XC = SCREEN(XNROWS + 1, XCNT,0)
                 PRINT @ (XCNT,XEROW+1) CHR$(XC);
               NEXT XCNT
             RETURN
             "FN-SHADOW-EXIT"
           END FN
       '/*-----------------------------------------------------------------*/
       '   FOR XT = 1 TO 4
       '     COLOR 09,0
       '     CLS(64)
       '     COLOR 12,0
       '     FOR X = 31 TO 41
       '       FOR Y = 10 TO 20
       '         PRINT @ (X,Y) "Z"
       '       NEXT Y
       '     NEXT X
       '     IF XT = 1 THEN PRINT @ (0,0) "RIGHT-BOTTOM";
       '     IF XT = 2 THEN PRINT @ (0,0) "LEFT-BOTTOM";
       '     IF XT = 3 THEN PRINT @ (0,0) "LEFT-TOP";
       '     IF XT = 4 THEN PRINT @ (0,0) "TOP-RIGHT";
       '     FN SHADOW(31,10,10,10,31,XT)
       '     DO
       '       Y$ = INKEY$
       '     UNTIL Y$ <> ""
       '  NEXT XT



  STRIP$(STRING,OPTION)
      Returns string with spaces removed.
      OPTIONS:  A = All spaces, including those between words are
                    removed.
                B = Both leading and trailing spaces.
                L = Leading (left) spaces only.
                R = Trailing (right) spaces only.
                Q = Same as all except for words between quotes.
      EXAMPLE:  T$ = FN STRIP$("  This is a test  ","A")   'Thisisatest'
                T$ = FN STRIP$("  This is a test  ","B")   'This is a test'
                T$ = FN STRIP$("  This is a test  ","L")   'This is a test  '
                T$ = FN STRIP$("  This is a test  ","T")   '  This is a test'

       '/*------------------------------------------------------------------*/
       '/* STRIP$(STRING,OPTION)                                            */
       '/* STRIP SPACES FROM STRING,           A=ALL B=BOTH L=LEFT R=RIGHT */
       '/*                                    Q=SAME AS ALL BUT NOT IN QUOTE*/
       '/*------------------------------------------------------------------*/
           LONG FN STRIP$(X$,XC$)
             IF XC$ = "" THEN XC$ = "B"
             SELECT XC$
               CASE "A"
                 GOSUB "FN-STRIP-ALL"
               CASE "B"
                 GOSUB "FN-STRIP-LEFT"
                 X$ = XRET$
                 GOSUB "FN-STRIP-RIGHT"
               CASE "L"
                 GOSUB "FN-STRIP-LEFT"
               CASE "R"
                 GOSUB "FN-STRIP-RIGHT"
               CASE "Q"
                 GOSUB "FN-STRIP-ALL-BUT-QUOTES "
             END SELECT
             GOTO "FN-STRIP-EXIT"
             "FN-STRIP-ALL-BUT-QUOTES "
               XL = LEN(X$)
               XRET$ = ""
               FOR XCNT = 1 TO XL
                 XT$ = MID$(X$,XCNT,1)                 :'/*Get Character
                 LONG IF XT$ = CHR$(34)                :'/*Is it a "
                   IF QF = 0 THEN QF = 1 ELSE QF = 0
                 END IF
                 LONG IF QF = 0                        :'/*Not Inside Quote
                   IF XT$ <> " " THEN XRET$ = XRET$ + XT$
                 XELSE                                 :'/*Inside Quote
                   XRET$ = XRET$ + XT$
                 END IF
               NEXT XCNT
             RETURN
             "FN-STRIP-ALL"
               XL = LEN(X$)
               XRET$ = ""
               FOR XCNT = 1 TO XL
                 XT$ = MID$(X$,XCNT,1)
                 IF XT$ <> " " THEN XRET$ = XRET$ + XT$
               NEXT XCNT
             RETURN
             "FN-STRIP-RIGHT"
               XCNT = LEN(X$) + 1
               DO
                 XCNT = XCNT - 1
                 XT$ = MID$(X$,XCNT,1)
               UNTIL XT$ <> " "
               XRET$ = LEFT$(X$,XCNT)
             RETURN
             "FN-STRIP-LEFT"
               XCNT = 0
               DO
                 XCNT = XCNT + 1
                 XT$ = MID$(X$,XCNT,1)
               UNTIL XT$ <> " "
               XRET$ = MID$(X$,XCNT)
             RETURN
             "FN-STRIP-EXIT"
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/* A$ = "      HELLO     "
       '/* PRINT "         1         2         3         4         5         6"
       '/* PRINT "123456789012345678901234567890123456789012345678901234567890"
       '/* T$ = FN STRIP$(A$,"B")
       '/* PRINT T$;"|"
       '/* PRINT "         1         2         3         4         5         6"
       '/* PRINT "123456789012345678901234567890123456789012345678901234567890"
       '/* T$ = FN STRIP$(A$,"L")
       '/* PRINT T$;"|"
       '/* PRINT "         1         2         3         4         5         6"
       '/* PRINT "123456789012345678901234567890123456789012345678901234567890"
       '/* T$ = FN STRIP$(A$,"R")
       '/* PRINT T$;"|"
       '/* A$ = "THIS IS A TEST TO SEE IF THE ALL SPACE REMOVE WORKS."
       '/* PRINT FN STRIP$(A$,"A")
       '/* A$ = "THIS IS A TEST TO SEE IF " + CHR$(34) + "THIS WORKS" + CHR$(34) + "HERE TODAY.
       '/* PRINT FN STRIP$(A$,"Q")


  SUBSTR$
      Returns a string from XSTR$ starting at SPOS for LENGTH columns
      padding right side of returned string with PADSTR as needed to
      meet LENGTH.

       '/*-----------------------------------------------------------------*/
       '/* SUBSTR$(STRING,SPOS,LENGTH,PADSTR)                              */
       '/* RETURNS LENGTH CHARACTERS FROM STRING FROM TO SPOS PADDED AS    */
       '/*-----------------------------------------------------------------*/
           LONG FN SUBSTR$(XSTR$,SPOS,XLEN,XPAD$)
             XRET$ = XSTR$ + STRING$(XLEN,XPAD$)
             XRET$ = MID$(XSTR$,SPOS,XLEN)
           END FN = XRET$
       '/*-----------------------------------------------------------------*/
          CLS
          PRINT FN SUBSTR$("1234567890",3,4," ")
          PRINT FN SUBSTR$("1234567890",5,30,"_")
          INPUT Z


  TBOX(COL,ROW,NCOLS,NROWS,ATTR,OPTION)

      Draws a box starting at COL/ROW for NCOLS/NROWS using ATTR color
      and OPTION box type.
      Options:  1 = Single line box
                2 = Double line box
                3 = Double line top, single line sides
                4 = Double line sides, single line top
                5 = Text Box (+-|)
                6 = Comment Box (*)
                7 = Thick Line Box
                6 = Space Box
      EXAMPLE:  FN TBOX(0,0,80,25,15,7)

       '/*------------------------------------------------------------------*/
       '/* TBOX(COL,ROW,WIDTH,HIEGHT,OPTION)                                */
       '/* Draws a Text Box                                                 */
       '/* OPTIONS: 1 = Single Line Box                                     */
       '/*          2 = Double Line Box                                     */
       '/*          3 = Double Top, Single Side                             */
       '/*          4 = Double Side, Single Top                             */
       '/*          5 = Text Box                                            */
       '/*          6 = Comment Box                                         */
       '/*          7 = Thick Line Box                                      */
       '/*          8 = Space Box                                           */
       '/*------------------------------------------------------------------*/
           LONG FN TBOX(XCOL,XROW,XCOLS,XROWS,XOPT,XATTR)
             XCF = (XATTR MOD 16)
             XCB = (((XATTR - XCF) / 16) MOD 128)
             COLOR XCF,XCB
       '/*     XCOLS = # COLUMNS
       '/*     XROWS = # ROWS
       '/*     XCOL = Start Column
       '/*     XROW = Start ROW
       '/*     XECOL = End Column
       '/*     XEROW = End Line(Row)
       '/*     XOPT = Box Type 1=Single 2=Double 3=Double Top 4=Double Side
               XECOL = XCOL + XCOLS
               XEROW = XROW + XROWS
       '/*     --- Draw Box Corners ---*/
               PRINT @(XCOL,XROW) MID$("+* ",XOPT,1); :'/*Left Upper Corner - Hex DA C9 D5 D6 2B 2A DC 20 - Dec 128 201 213 214 43 32
               PRINT @(XCOL,XEROW) MID$("+* ",XOPT,1); :'/*Left Lower Corner - Hex C0 C8 D4 D3 2B 2A DF 20 - Dec 223 200 212 211 43 42 223 32
               PRINT @(XECOL,XROW) MID$("+* ",XOPT,1); :'/*Right Upper Corner - Hex C0 C8 D4 D3 2B 2A DF 20 - Dec 192 200 212 211 43 42 223 32
               PRINT @(XECOL,XEROW) MID$("ټ+* ",XOPT,1); :'/*Right Lower Corner - Hex D9 BC BE BD 2B 2A DF 20 - Dec 217 188 190 189 43 42 223 32
       '/*     --- Draw Box Top ---*/
               XT$ = MID$("-* ",XOPT,1)            :'/*Horizontal Line - Hex C4 CD CD C4 2D 2A DC 20 - Dec 196 205 205 196 45 42 220 32
               PRINT @ (XCOL+1,XROW) STRING$(XECOL-XCOL-1,XT$);
       '/*     --- Draw Box Bottom ---*/
               XT$ = MID$("-* ",XOPT,1)            :'/*Horizontal Line - Hex C4 CD C4 2D 2A DF 20 - Dec 196 205 196 45 42 223 32
               PRINT @ (XCOL+1,XEROW) STRING$(XECOL-XCOL-1,XT$);
       '/*     --- Draw Box Sides ---*/
               XT$ = MID$("|* ",XOPT,1)            :'/*Vertical Line - Hex B3 BA B3 BA 7C 2A DB 20 - Dec 179 186 179 124 42 219 32
               XT$ = XT$ + STRING$(XECOL-XCOL-1,32) + XT$
               FOR XX = (XROW + 1) TO (XEROW - 1)        :'/*side lines
                 PRINT @ (XCOL,XX) XT$;
               NEXT XX
           END FN
       '/*------------------------------------------------------------------*/
       '  LOCATE,,,0
       '  FN TBOX(00,00,60,20,1,12)
       '  GOSUB "WAITER"
       '  FN TBOX(01,01,58,18,2,28)
       '  GOSUB "WAITER"
       '  FN TBOX(02,02,56,16,3,44)
       '  GOSUB "WAITER"
       '  FN TBOX(03,03,54,14,4,60)
       '  GOSUB "WAITER"
       '  FN TBOX(04,04,52,12,5,76)
       '  GOSUB "WAITER"
       '  FN TBOX(05,05,50,10,6,92)
       '  GOSUB "WAITER"
       '  FN TBOX(06,06,48,08,7,118)
       '  GOSUB "WAITER"
       '  FN TBOX(07,07,46,06,8,134)
       '  GOSUB "WAITER"
       '  DO
       '    Y$ = INKEY$
       '  UNTIL Y$ <> ""
       '  END
       '  "WAITER"
       '    DO
       '      Y$ = INKEY$
       '    UNTIL Y$ = CHR$(13)
       '  RETURN


  TMATH$(HH:MM:SS$1,HH:MM:SS$2,OPTION)
      Returns result of addition or subtraction on supplied strings.
      OPTION:   A = Add hh:mm:ss$1 to hh:mm:ss$2
                S = Subtract hh:mm:ss$2 from hh:mm:ss$1
      EXAMPLE:  T$ = FN TMATH$("16:30:00","07:30:00","S")  "09:00:00"
                T$ = FN TMATH$("07:30:00","09:30:00","A")  "17:00:00"

       '/* LONG FN S2HMS$(XX!)
       '/*   XH = INT(XX!/3600)
       '/*   XM = INT((XX! - (XH * 3600)) / 60)
       '/*   XS = INT(XX! - (XH * 3600) - (XM * 60))
       '/*   XH$ = RIGHT$(STR$(XH),LEN(STR$(XH))-1)
       '/*   XL = LEN(XH$)
       '/*   IF XL < 2 THEN XH$ = "0" + XH$
       '/*   XM$ = RIGHT$(STR$(XM),LEN(STR$(XM))-1)
       '/*   XL = LEN(XM$)
       '/*   IF XL < 2 THEN XM$ = "0" + XM$
       '/*   XS$ = RIGHT$(STR$(XS),LEN(STR$(XS))-1)
       '/*   XL = LEN(XS$)
       '/*   IF XL < 2 THEN XS$ = "0" + XS$
       '/*   XRET$ = XH$ + ":" + XM$ + ":" + XS$
       '/* END FN = XRET$
       '/* LONG FN HMS2S!(XX$)
       '/*   XH$ = MID$(XX$,1,2)
       '/*   XM$ = MID$(XX$,4,2)
       '/*   XS$ = MID$(XX$,7,2)
       '/*   XH! = VAL(XH$)
       '/*   XM! = VAL(XM$)
       '/*   XS! = VAL(XS$)
       '/*   XRET! = (XH! * 3600) + (XM! * 60) + XS!
       '/* END FN = XRET!
       '/*------------------------------------------------------------------*/
       '/* TMATH$("HH:MM:SS"1, "HH:MM:SS"2, OPTION)                         */
       '/* SUBTRACT OR ADD TWO TIMES                                        */
       '/* OPTIONS: "A" = ADD "HH:MM:SS"1 TO "HH:MM:SS"2                    */
       '/*          "S" = SUBTRACT "HH:MM:SS"2 FROM "HH:MM:SS"1             */
       '/*------------------------------------------------------------------*/
           LONG FN TMATH$(X1$,X2$,XTYPE$)
             XT1! = FN HMS2S!(X1$)
             XT2! = FN HMS2S!(X2$)
             IF XTYPE$ = "A" THEN XRET! = (XT1! + XT2!)
             IF XTYPE$ = "S" THEN XRET! = (XT1! - XT2!)
             XRET$ = FN S2HMS$(XRET!)
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/* PRINT "SUBTRACT TWO TIMES"
       '/* PRINT "START TIME = 07:30:00"
       '/* PRINT "  END TIME = 16:30:00"
       '/* PRINT "           = "FN TMATH$("16:30:00","07:30:00","S")
       '/* PRINT "SHOULD BE  = 09:00:00"
       '/* PRINT "ADD TWO TIMES"
       '/* PRINT "START TIME = 07:30:00"
       '/* PRINT "  END TIME = 09:30:00"
       '/* PRINT "           = "FN TMATH$("07:30:00","09:30:00","A")
       '/* PRINT "SHOULD BE  = 03:00:00"


  TRANSLATE(STRING,NEWCHAR,OLDCHAR,PAD)
      Returns a string where all occurances of OLDCHAR within STRING
      are changed to NEWCHAR.
      EXAMPLES: TRANSLATE('abcdef',' ',' ',' ')      = 'ABCDEF'
                TRANSLATE('abbc',&,'b',' ')          = 'a&&c'
                TRANSLATE('abcdef',12','ec',' ')     = 'ab2d1f'
                TRANSLATE('abcdef',12','abcd','.')   = '12..ef'
                TRANSLATE('4123','abcd','1234',' ')  = 'dabc'

       '/*------------------------------------------------------------------*/
       '/* TRANSLATE$(STRING,NEWCHAR,OLDCHAR,PAD$)                          */
       '/* TRANSLATE A CHARACTER IN X$ TO ANOTHER CHARACTER                 */
       '/*------------------------------------------------------------------*/
          LONG FN TRANSLATE$(XS$, XO$, XI$, XPAD$)
            LO = LEN(XO$)
            LONG IF XO$ = " " AND XI$ = " "
              XS$ = UCASE$(XS$)
            XELSE
              XSL = LEN(XS$)
              FOR CNT = 1 TO XSL
                XT$ = MID$(XS$,CNT,1) :'Get Source String Character
                XS = INSTR(1,XI$,XT$) :'Character matches Input string table?
                IF XS <= LO AND XS > 0 THEN MID$(XS$,CNT,1) = MID$(XO$,XS,1) :'Replace it
                IF XS > LO AND XS > 0 THEN MID$(XS$,CNT,1) = XPAD$:'REPLACE IT
              NEXT CNT
            END IF
          END FN = XS$
       '/*------------------------------------------------------------------*/
       '  A$ = "\H\E\L\L\O\"
       '  PRINT "         1         2         3         4         5         6"
       '  PRINT "123456789012345678901234567890123456789012345678901234567890"
       '  T$ = FN TRANSLATE$(A$," ","\"," ")
       '  PRINT A$
       '  PRINT T$
       '  A$ = "HELLO,THIS,IS,A,TEST"
       '  PRINT "         1         2         3         4         5         6"
       '  PRINT "123456789012345678901234567890123456789012345678901234567890"
       '  T$ = FN TRANSLATE$(A$," ",","," ")
       '  PRINT A$
       '  PRINT T$
       '  INPUT Z


  TSCREEN(option)

      Saves and restores the screen.

      Options:  1 = Copy screen (with colors) to SSAVE%(cols,rows)
                2 = Copy SSAVE%(cols,rows) to screen
                3 = Read TFILE$ file into SSAVE%(cols,rows)
                4 = Write SSAVE%(cols,rows) to TFILE$
                5 = Copy TFile$ to screen
                6 = Write screen to TFILE$

       '/*------------------------------------------------------------------*/
       '/* TSCREEN(OPTION)                                                  */
       '/* Screen Save and Restore Routine                                  */
       '/* OPTIONS: 1 = Copy screen to save array                           */
       '/*          2 = Copy save array to screen                           */
       '/*          3 = Read TFILE$ file into save array                    */
       '/*          4 = Write save array to TFILE$ file                     */
       '/*          5 = Put screen into array/write array to TFILE$         */
       '/*          6 = Put TFILE$ file to screen                           */
       '/*------------------------------------------------------------------*/
           DIM Addr%,SSAVE%(79,24)   :'/*For screen save
               Addr%=VARPTR(Addr%)+2 :'/*Calculates address of SSAVE array
           DIM 80TFILE$
               TFILE$ = "C:\TEMP\TSCREEN.MEM" :'/*Specify Temp file name
           TBUFFER = 1               :'/*Specify File Buffer to Use
       '/*--- Save Current Screen into SSAVE/Returns current cursor position ---
           LONG FN SaveScreen%(SaveAdr%,Seg%)
             MACHLG &1E              '/* PUSH DS         ;Save DS
             MACHLG &31,&F6          '/* XOR SI,SI       ;Clear SI
             MACHLG &8B,&3E,SaveAdr% '/* MOV DI,[SaveAdr%] ;Point to storage
             MACHLG &B9,2000         '/* MOV CX,2000     ;2000 Bytes in screen mem
             MACHLG &A1,Seg%         '/* MOV AX,[Seg%] ;Get screen segment
             MACHLG &8E,&D8          '/* MOV DS,AX       ;Put into DS
             MACHLG &F3,&A5          '/* REPZ MOVSW      ;Copy from screen to ARRAY
             MACHLG &1F              '/* POP DS          ;Restore DS
             MACHLG &B4,3            '/* MOV AH,3        ;Make BIOS call
             MACHLG &B7,0            '/* MOV BH,0        ;(Current page #)
             MACHLG &CD,&10          '/* INT 10h         ;To get cursor position
             MACHLG &89,&16,a%       '/* MOV [a%],DX     ;Save pos in a%
           END FN=a%
       '/*--- Restore the Screen From Array ---*/
           LONG FN PutScreen(SaveAdr%,Seg%,CursorPos%)
             MACHLG 6                '/* PUSH ES         ;Save ES
             MACHLG &8B,&36,SaveAdr% '/* MOV SI,[SaveAdr%] ;Point to ARRAY
             MACHLG &31,&FF          '/* XOR DI,DI       ;Clear DI
             MACHLG &B9,2000         '/* MOV CX,2000     ;2000 Bytes in screen
             MACHLG &A1,Seg%         '/* MOV AX,[Seg%] ;Get screen segment
             MACHLG &8E,&C0          '/* MOV ES,AX       ;Put into ES
             MACHLG &F3,&A5          '/* REPZ MOVSW      ;Restore screen memory
             MACHLG 7                '/* POP ES          ;Restore ES
             MACHLG &B4,2            '/* MOV AH,2        ;BIOS call
             MACHLG &B7,0            '/* MOV BH,0        ;(Current screen #)
             MACHLG &8B,&16,CursorPos%'/* MOV DX,[CursorPos%] ;Get saved cursor pos
             MACHLG &CD,&10          '/* INT 10h         ;Set cursor position
           END FN
       '/*--- Write Saved Screen to Disk ---*/
           LONG FN STSCRN(XN)
             ERROR = 0
             OPEN"O",TBUFFER,TFILE$
             LONG IF ERROR = 0
             FOR XC = 0 TO 79
               FOR XR = 0 TO 24
                 WRITE#TBUFFER,SSAVE%(XC,XR)
               NEXT XR
             NEXT XC
             END IF
             CLOSE#TBUFFER
           END FN
       '/*--- Retrieve Screen From Disk --- */
           LONG FN RTSCRN(XN)
             ERROR = 0
             OPEN"I",TBUFFER,TFILE$
             LONG IF ERROR = 0
               FOR XC = 0 TO 79
                 FOR XR = 0 TO 24
                   READ#TBUFFER,SSAVE%(XC,XR)
                 NEXT XR
               NEXT XC
             END IF
             CLOSE#TBUFFER
           END FN
       '/*--- Control Screen IO ---*/
           LONG FN TSCREEN(XN)
             IF XN = 1 THEN XCP%=FN SaveScreen%(Addr%,&B800) :'/*Save Screen
             IF XN = 2 THEN FN PutScreen(Addr%,&B800,XCP%)   :'/*Restore Screen
             IF XN = 3 THEN FN RTSCRN(XN)                    :'/*Retrieve Screen Array
             IF XN = 4 THEN FN STSCRN(XN)                    :'/*Save Screen Array
             LONG IF XN = 5                                  :'/*Save Screen/Save Screen Array
               XCP%=FN SaveScreen%(Addr%,&B800)
               FN STSCRN(XN)
             END IF
             LONG IF XN = 6                                  :'/*Retrieve Screen/Restore Screen
               FN RTSCRN(XN)
               FN PutScreen(Addr%,&B800,XCP%)
             END IF
           END FN
       '/*------------------------------------------------------------------*/
       '   ON ERROR GOSUB 65535
       '   COLOR 12,0
       '   CLS(88)
       '   COLOR 09,0
       '   PRINT @ (30,10) "This is the Before Screen";
       '   PRINT @ (30,11) "Press Any Key";
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   FN TSCREEN(1)
       '   CLS
       '   PRINT "Press Any Key ...";
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   FN TSCREEN(2)
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   PRINT @ (30,10) "Saving this screen to Disk";
       '   FN TSCREEN(4)
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   CLS
       '   PRINT "Press Any Key ...";
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""
       '   FN TSCREEN(6)
       '   DO
       '     Y$ = INKEY$
       '   UNTIL Y$ <> ""


  WAITKEY(string$)

      Waits until a key (character) in string$ is pressed.


  WAITKEYS$(string$)

      Waits until a key is press corresponding to one of those in
      string$.  Returns the keypressed as a string.

       '/*-------------------------------------------------------------------*/
       '/* WAITKEYS$(STRING)                                                 */
       '/* WAIT UNTIL ONE OF THE KEYS IN STRING IS PRESSED                   */
       '/*-------------------------------------------------------------------*/
           LONG FN WAITKEYS$(XY1$)
             DO
               XY$ = UCASE$(INKEY$) :'/*WAIT UNTIL 1 OF SPECIFIED KEY IS HIT
               XS = INSTR(1,XY1$,XY$)
             UNTIL XS > 0
           END FN = XY$
       '/*-------------------------------------------------------------------*/


  WEEKDAY$("ccyymmdd")
      Returns the day of the week.

       '/*------------------------------------------------------------------*/
       '/* WEEKDAY$("CCYYMMDD")                                             */
       '/* RETURNS THE DAY OF THE WEEK  FORMAT IS YYYYMMDD                  */
       '/*------------------------------------------------------------------*/
           LONG FN WEEKDAY$(X$)
            XL = LEN(X$)
            XRET$ = ""
            LONG IF XL > 0
              XY$ = MID$(X$,1,4)
              XM$ = MID$(X$,5,2)
              XD$ = MID$(X$,7,2)
              XY = VAL(XY$)
              XM = VAL(XM$)
              XD = VAL(XD$)
              XE = XM + 10
              XF = XY + (XM-14)/12
           XP = ((13*(XE-(XE/13)*12)-1)/5+XD+77+5*(XF-(XF/100)*100)/4+XF/400-(XF/100)*2) MOD 7
              XRET$ = MID$("SUNMONTUEWEDTHUFRISAT",XP*3+1,3)
            END IF
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '/*                12345678
       '  CLS
       '  PRINT FN WEEKDAY$("19970401");" 1"
       '  PRINT FN WEEKDAY$("19970402");" 2"
       '  PRINT FN WEEKDAY$("19970403");" 3"
       '  PRINT FN WEEKDAY$("19970404");" 4"
       '  PRINT FN WEEKDAY$("19970405");" 5"
       '  PRINT FN WEEKDAY$("19970406");" 6"
       '  PRINT FN WEEKDAY$("19970407");" 7"
       '  PRINT FN WEEKDAY$("19970408");" 8"
       '  PRINT FN WEEKDAY$("19970409");" 9"
       '  PRINT FN WEEKDAY$("20170105");"THURSDAY"
       '  INPUT Z


  WIN_MICE(startcol,startrow,endcol,endrow,option)
      Sets mouse boundries.
      EXAMPLE:  FN WIN_MICE(01,10,10,20,0)

       '/*-----------------------------------------------------------------*/
       '/* WIN_MICE(STARTCOL,STARTROW,ENDCOL,ENDROW,OPT)                   */
       '/* Set Mouse Boundries                                             */
       '/*-----------------------------------------------------------------*/
           LONG FN WIN_MICE(X1%,Y1%,X2%,Y2%,MOV%)
             RAX! = .125
             RAY! = .125
             X1%=X1%/RAX!
             Y1%=Y1%/RAY!
             X2%=X2%/RAX!
             Y2%=Y2%/RAY!
             MACHLG &B8,&07,&00,&8B,&0E,X1%,&8B,&16,X2%,&CD,&33
             MACHLG &B8,&08,&00,&8B,&0E,Y1%,&8B,&16,Y2%,&CD,&33
             IF MOV%<>0 THEN X1%=(X2%+X1%)/2
             Y1%=(Y2%+Y1%)/2
             MACHLG &B8,&04,&00,&8B,&0E,X1%,&8B,&16,Y1%,&CD,&33
           END FN
       '/*-----------------------------------------------------------------*/
       '/*      Test Program Follows                                       */
       '/*-----------------------------------------------------------------*/
       '/*     Ratios are as follows:  RAX!      RAY!
       '/*        MODE 22 (640X480)    1          1
       '/*        MODE 3  (80x25)     .125       .125
       '/*        MODE 19              1          1
       '/*        MODE 5              .5         .5
       '/*        MODE 23 (320x200)   .5          1
       '/*        MODE 17              1          1
       '/*-----------------------------------------------------------------*/
       '/* LONG FN PMOUSE(XC,XR)
       '/*   XX% = (XC * 8)                     :'/*Calculate Mouse Column
       '/*   XY% = (XR * 8)                     :'/*Calculate Mouse Row
       '/*   MACHLG &B8,&04,&00,&8B,&0E,XX%,&8B,&16,XY%,&CD,&33
       '/* END FN
       '/* LONG FN TBOX(XSC,XSL,XEC,XEL,XZ)
       '/*     PRINT @(XSC,XSL) MID$("",XZ,1);  :'/*Left Upper Corner
       '/*     PRINT @(XSC,XEL) MID$("",XZ,1);  :'/*Left Lower Corner
       '/*     PRINT @(XEC,XSL) MID$("",XZ,1);  :'/*Right Upper Corner
       '/*     PRINT @(XEC,XEL) MID$("ټ",XZ,1);  :'/*Right Lower Corner
       '/*     XT$ = MID$("",XZ,1)              :'/*Horizontal Line
       '/*     FOR XX = (XSC + 1) TO (XEC - 1)      :'/*Lines
       '/*       PRINT @ (XX,XSL) XT$;              :'/*  "
       '/*       PRINT @ (XX,XEL) XT$;              :'/*  "
       '/*     NEXT XX                              :'/*  "
       '/*     XT$ = MID$("",XZ,1)              :'/*Vertical Line
       '/*     FOR XX = (XSL + 1) TO (XEL - 1)      :'/*side lines
       '/*       PRINT @ (XSC,XX) XT$;              :'/*  "
       '/*       PRINT @ (XEC,XX) XT$;              :'/*  "
       '/*     NEXT XX                              :'/*  "
       '/* END FN
       '/* LONG FN PCURSOR(X)
       '/*   XMC = MOUSE(1)
       '/*   XMR = MOUSE(2)
       '/*   XT! = (XMC * .07826)                   :'/*COLUMN
       '/*   XPC = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
       '/*   XT! = (XMR * .0327868)                 :'/*ROW
       '/*   XPR = INT(XT!*10^0+.5)/10^0             :'/*ROUND NUMBER
       '/* END FN
       '/* DEF MOUSE=0                           :'/*Define Mouse Device
       '/* MOUSE(0)                              :'/*Reset Mouse Interface
       '/* MOUSE(4)                              :'/*Display Mouse Cursor
       '/* FN TBOX(00,09,11,21,1)
       '/* FN PMOUSE(00,02)
       '/* FN WIN_MICE(01,10,10,20,0)
       '/* PRINT @ (00,23) "MOUSE SHOULD STAY IN BOUNDS OF 01,10 AND 10,20"
       '/* DO
       '/*   FN PCURSOR(X)
       '/*   PRINT @ (50,23) "Col"XPC" Row"XPR;
       '/*   Y$ = INKEY$
       '/* UNTIL Y$ <> ""


  WORD$(string,n)
      Returns the nth space delimited word in string.
      EXAMPLE:  T$ = FN WORD$("This is a test",2)    = 'is'
                T$ = FN WORD$("This is a test",4)    = 'test'

       '/*------------------------------------------------------------------*/
       '/* WORD$(STRING,NTH)                                                */
       '/* RETURN NTH WORD IN STRING                                        */
       '/*------------------------------------------------------------------*/
           LONG FN WORD$(X$,XN)
             XL = LEN(X$)
             XCW = 0
             XRET$ = ""
             XCWC = 0
             FOR XX = 1 TO XL
               XT$ = MID$(X$,XX,1)
               LONG IF XT$ = " "
                 LONG IF XCW = 1
                   LONG IF XCWC = XN
                     XX = 300
                   XELSE
                     XRET$ = ""
                     XCW = 0
                   END IF
                 END IF
               XELSE
                 IF XCW = 0 THEN XCWC = XCWC + 1
                 XCW = 1
                 XRET$ = XRET$ + XT$
               END IF
             NEXT XX
             IF XCWC <> XN THEN XRET$ = ""
           END FN = XRET$
       '/*------------------------------------------------------------------*/
       '  A$ = "THIS IS A TEST OF THIS FUNCTION."
       '  PRINT FN WORD$(A$,4)
       '  PRINT "SHOULD BE TEST"


  WORDS(string)
      Returns the number of space delimited words in string.
      EXAMPLE:  NWRDS = FN WORDS("This is a test to   see if")  = 7

       '/*-----------------------------------------------------------------*/
       '/* WORDS(STRING)                                                   */
       '/* RETURNS THE NUMBER OF SPACE DELIMITED WORDS IN STRING           */
       '/*-----------------------------------------------------------------*/
           LONG FN WORDS(X$)
             XDELIMIT$ = " "
             XWCNT = 0
             XCWRD = 0
             XL = LEN(X$)
             IF XL = 0 THEN "EXIT-FN-WORDS"
             FOR XCNT = 1 TO XL
               XT$ = MID$(X$,XCNT,1)
               LONG IF XT$ <> XDELIMIT$ AND XCWRD = 0
                 XCWRD = 1
                 XWCNT = XWCNT + 1
               END IF
               IF XT$ = XDELIMIT$ AND XCWRD > 0 THEN XCWRD = 0
             NEXT XCNT
             "EXIT-FN-WORDS"
           END FN = XWCNT
       '/*-----------------------------------------------------------------*/
       '/*T$ = "THIS IS A TEST TO SEE"
       '/*PRINT T$
       '/*T =  FN WORDS(T$)
       '/*PRINT T
       '/*T$ = "THIS IS ANOTHER TEST TO SEE IF THIS WORKS"
       '/*PRINT T$
       '/*T =  FN WORDS(T$)
       '/*PRINT T
       '/*T$ = ""
       '/*PRINT T$
       '/*T =  FN WORDS(T$)
       '/*PRINT T


  XWORD$(string,n,char)
      Returns the nth char delimited word in string.
      EXAMPLE:  T$ = FN XWORD$("This is a test",2," ") = 'is'
                T$ = FN XWORD$("This, is a, test",2,",") = ' is a'
                T$ = FN XWORD$("This, is a, test",2,",") = ' is a'
       '/*------------------------------------------------------------------*/
       '/* WORD$(STRING,NTH)                                                */
       '/* RETURN NTH WORD IN STRING                                        */
       '/*------------------------------------------------------------------*/
           LONG FN XWORD$(X$,XN,XDELIMIT$)
             XL = LEN(X$)
             XCW = 0
             XRET$ = ""
             XCWC = 0
             FOR XX = 1 TO XL
               XT$ = MID$(X$,XX,1)
               LONG IF XT$ = XDELIMIT$
                 LONG IF XCW = 1
                   LONG IF XCWC = XN
                     XX = 300
                   XELSE
                     XRET$ = ""
                     XCW = 0
                   END IF
                 END IF
               XELSE
                 IF XCW = 0 THEN XCWC = XCWC + 1
                 XCW = 1
                 XRET$ = XRET$ + XT$
               END IF
             NEXT XX
             IF XCWC <> XN THEN XRET$ = ""
           END FN = XRET$
       '/*------------------------------------------------------------------*/
          A$ = "THIS IS A TEST OF THIS FUNCTION."
          PRINT A$
          PRINT FN XWORD$(A$,4," ")
          A$ = "SHOULD, BE, TEST"
          PRINT A$
          PRINT FN XWORD$(A$,2,",")


  XWORDS(string,char)
      Returns the number of char delimited words in string.
      EXAMPLE:  NWRDS FN XWORDS("This is a test to    see if) = 7
                NWRDS FN XWORDS("This, is a test, to  ,  see if) = 4

       '/*-----------------------------------------------------------------*/
       '/* WORDS(STRING)                                                   */
       '/* RETURNS THE NUMBER OF SPACE DELIMITED WORDS IN STRING           */
       '/*-----------------------------------------------------------------*/
           LONG FN XWORDS(X$,XDELIMIT$)
             XWCNT = 0
             XCWRD = 0
             XL = LEN(X$)
             IF XL = 0 THEN "EXIT-FN-XWORDS"
             FOR XCNT = 1 TO XL
               XT$ = MID$(X$,XCNT,1)
               LONG IF XT$ <> XDELIMIT$ AND XCWRD = 0
                 XCWRD = 1
                 XWCNT = XWCNT + 1
               END IF
               IF XT$ = XDELIMIT$ AND XCWRD > 0 THEN XCWRD = 0
             NEXT XCNT
             "EXIT-FN-XWORDS"
           END FN = XWCNT
       '/*-----------------------------------------------------------------*/
       '  CLS
       '  T$ = "THIS IS A TEST TO SEE"
       '  PRINT T$
       '  T =  FN XWORDS(T$," ")
       '  PRINT T
       '  T$ = "THIS IS,ANOTHER,TEST TO,SEE,IF,THIS,WORKS"
       '  PRINT T$
       '  T =  FN XWORDS(T$,",")
       '  PRINT T
       '  T$ = ""
       '  PRINT T$
       '  T =  FN XWORDS(T$," ")
       '  PRINT T
       '  INPUT Z