* Power BASIC v3.5 On-Line Help
INTRODUCTION - Power BASIC v3.5 Help File - McDonald 20000722
      This Help file is for Power BASIC v 3.5 and includes my
      MLIB Library help file and several other useful info sections.
PROGRAMMING INFO


  ASCII Key Codes

      Keypress      Plain   +Shift  +Ctrl   +Alt        +Ctrl  +Alt
     ---------------------------------------------   ---------------
      Backspace     8               127     0+14      A   1    0+30
      Tab           9       0+15    0+148   0+165     B   2    0+48
      Enter         13              10         28     C   3    0+46
      ESC           27                                D   4    0+32
      F1            0+59    0+84    0+94    0+104     E   5    0+18
      F2            0+60    0+85    0+95    0+105     F   6    0+33
      F3            0+61    0+86    0+96    0+106     G   7    0+34
      F4            0+62    0+87    0+97    0+107     H   8    0+35
      F5            0+63    0+88    0+98    0+108     I   9    0+23
      F6            0+64    0+89    0+99    0+109     J   10   0+36
      F7            0+65    0+90    0+100   0+110     K   11   0+37
      F8            0+66    0+91    0+101   0+111     L   12   0+38
      F9            0+67    0+92    0+102   0+112     M   13   0+50
      F10           0+68    0+93    0+103   0+113     N   14   0+49
      F11           0+133   0+135   0+137   0+139     O   15   0+24
      F12           0+134   0+136   0+138   0+140     P   16   0+25
      Up Arrow      0+72            0+141   0+152     Q   17   0+16
      Down Arrow    0+80            0+145   0+160     R   18   0+19
      Left Arrow    0+75            0+115   0+155     S   19   0+31
      Right Arrow   0+77            0+116   0+157     T   20   0+20
      PgUp          0+73            0+132   0+153     U   21   0+22
      PgDn          0+81            0+118   0+161     V   22   0+47
      Insert        0+82            0+146   0+162     W   23   0+17
      Delete        0+83            0+147   0+163     X   24   0+45
      Home          0+71            0+119   0+151     Y   25   0+21
      End           0+79            0+117   0+159     Z   26   0+44


  BOXCHART
      Ŀ
           218   196   191     180  185    201   205    187    
            Ŀ       194  203      ͻ      
         179          179    197  206   186          186   
                   193  202      ͼ      
           192   196   217     195  204    200   205   188     
                                                                 
             
              176          177          178          219         
                                                                 
           214   196   183     182  198     213   205   184    
            ķ       199  208      ͸      
         186          186    215  207   179          179   
            Ľ       216  209      ;      
          211   196    189     181  210     212   205   190    
      

                BOX CHARACTER ASCII CODES

       218     194     191     213     209     184
          Ŀ           ͸
                                         
                                         
       195Ĵ180     198͵181
               197                  216  
           196      179         205      179
                     ;
       192     193     217     212     207     190



       214     210     183     201     203     187
          ķ           ͻ
                                         
                                         
       199Ķ182     204͹185
               215                  206  
           196      186         205      186
          Ľ           ͼ
       211     208     189     200     202     188


  DBF FILE STRUCTURES
    BASIC STRUCTURE
      BYTES   DESCRIPTION
      00      FoxBase+, FoxPro, dBaseIII+, dBaseIV, no memo - 0x03
              FoxBase+, dBaseIII+ with memo - 0x83
              FoxPro with memo - 0xF5
              dBaseIV with memo - 0x8B
              dBaseIV with SQL Table - 0x8E

      01-03   Last update, format YYYYMMDD
      04-07   Number of records in file (32-bit number)
      08-09   Number of bytes in header (16-bit number)
      10-11   Number of bytes in record (16-bit number)
      12-13   Reserved, fill with 0x00
      14      dBaseIV flag, incomplete transaction
              Begin Transaction sets it to 0x01
              End Transaction or RollBack reset it to 0x00

      15      Encryption flag, encrypted 0x01 else 0x00
              Changing the flag does not encrypt or decrypt the records

      16-27   dBaseIV multi-user environment use
      28      Production index exists - 0x01 else 0x00
      29      dBaseIV language driver ID
      30-31   Reserved fill with 0x00
      32-n    Field Descriptor array
      n+1     Header Record Terminator - 0x0D

      FIELD DESCRIPTOR ARRAY TABLE
      BYTES   DESCRIPTION
      0-10    Field Name ASCII padded with 0x00
      11      Field Type Identifier (see table)
      12-15   Displacement of field in record
      16      Field length in bytes
      17      Field decimal places
      18-19   Reserved
      20      dBaseIV work area ID
      21-30   Reserved
      31      Field is part of production index - 0x01 else 0x00

      FIELD IDENTIFIER TABLE
      ASCII   DESCRIPTION
      C       Character
      D       Date, format YYYYMMDD
      F       Floating Point
      G       General - FoxPro addition
      L       Logical, T:t,F:f,Y:y,N:n,?-not initialized
      M       Memo (stored as 10 digits representing the dbt block number)
      N       Numeric
      P       Picture - FoxPro addition

      Note all dbf field records begin with a deleted flag field.
      If record is deleted - 0x2A (asterisk) else 0x20 (space)
      End of file is marked with 0x1A

    dbase III PLUS
      *****************************************************************
      The data file header structure for dBASE III PLUS table file.
      *****************************************************************

      The table file header:
      ======================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0     1 byte      Valid dBASE III PLUS table file (03h without a memo
                        (.DBT file; 83h with a memo).

      1-3   3 bytes     Date of last update; in YYMMDD format.
      4-7   32-bit      Number of records in the table.
            number
      8-9   16-bit      Number of bytes in the header.
            number
      10-11 16-bit      Number of bytes in the record.
            number
      12-14 3 bytes     Reserved bytes.
      15-27 13 bytes    Reserved for dBASE III PLUS on a LAN.
      28-31 4 bytes     Reserved bytes.
      32-n  32 bytes    Field descriptor array (the structure of this array is
            each        shown below)
      n+1   1 byte      0Dh stored as the field terminator.

      n above is the last byte in the field descriptor array. The size of the
      array depends on the number of fields in the table file.

      Table Field Descriptor Bytes
      ============================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0-10  11 bytes    Field name in ASCII (zero-filled).
      11    1 byte      Field type in ASCII (C, D, L, M, or N).
      12-15 4 bytes     Field data address (address is set in memory; not useful
                        on disk).
      16    1 byte      Field length in binary.

      17    1 byte      Field decimal count in binary.
      18-19 2 bytes     Reserved for dBASE III PLUS on a LAN.
      20    1 byte      Work area ID.
      21-22 2 bytes     Reserved for dBASE III PLUS on a LAN.
      23    1 byte      SET FIELDS flag.
      24-31 1 byte      Reserved bytes.

      Table Records
      =============

      The records follow the header in the table file. Data records are
      preceded by one byte, that is, a space (20h) if the record is not
      deleted, an asterisk (2Ah) if the record is deleted. Fields are
      packed into records without field separators orrecord terminators.
      The end of the file is marked by a single byte, with the
      end-of-file marker, an OEM code page character value of 26 (1Ah).
      You can input OEM code page data as indicated below.

      Allowable Input for dBASE Data Types
      ====================================

      Data Type      Data Input
      -------------- -----------------------------------------------------------
      C (Character)  All OEM code page characters.
      D (Date)       Numbers and a character to separate month, day, and year
                     (stored internally as 8 digits in YYYYMMDD format).
      N (Numeric)    - . 0 1 2 3 4 5 6 7 8 9
      L (Logical)    ? Y y N n T t F f (? when not initialized).
      M (Memo)       All OEM code page characters (stored internally as 10
                     digits representing a .DBT block number).

      Binary, Memo, and OLE Fields And .DBT Files
      ===========================================

      Memo fields store data in .DBT files consisting of blocks numbered
      sequentially (0, 1, 2, and so on). The size of these blocks are
      internally set to 512 bytes. The first block in the .DBT file,
      block 0, is the .DBT file header.

      Memo field of each record in the .DBF file contains the number of
      the block (in OEM code page values) where the field's data
      actually begins. If a field contains no data, the .DBF file
      contains blanks (20h) rather than a number.

      When data is changed in a field, the block numbers may also change
      and the number in the .DBF may be changed to reflect the new
      location.

      This information is from the Using dBASE III PLUS manual, Appendix C.

    dBASE IV
      ***********************************************************************
      The data file header structure for dBASE IV 2.0 table file.
      ***********************************************************************

      File Structure:
      ===============

      Byte     Contents       Meaning
      -------  ----------     -------------------------------------------------
      0        1byte          Valid dBASE IV file; bits 0-2 indicate version
                              number, bit 3 the presence of a dBASE IV memo
                              file, bits 4-6 the presence of an SQL table, bit
                              7 the presence of any memo file (either dBASE III
                              PLUS or dBASE IV).
      1-3      3 bytes        Date of last update; formattted as YYMMDD.
      4-7      32-bit number  Number of records in the file.
      8-9      16-bit number  Number of bytes in the header.
      10-11    16-bit number  Number of bytes in the record.
      12-13    2 bytes        Reserved; fill with 0.
      14       1 byte         Flag indicating incomplete transaction.
      15       1 byte         Encryption flag.
      16-27    12 bytes       Reserved for dBASE IV in a multi-user environment.
      28       1 bytes        Production MDX file flag; 01H if there is an MDX,
                              00H if not.
      29       1 byte         Language driver ID.
      30-31    2 bytes        Reserved; fill with 0.
      32-n*    32 bytes each  Field descriptor array (see below).
      n + 1    1 byte         0DH as the field terminator.

      * n is the last byte in the field descriptor array. The size of the array
      depends on the number of fields in the database file.

      The field descriptor array:
      ===========================

      Byte     Contents       Meaning
      -------  ------------   --------------------------------------------------
      0-10     11 bytes       Field name in ASCII (zero-filled).
      11       1 byte         Field type in ASCII (C, D, F, L, M, or N).
      12-15    4 bytes        Reserved.
      16       1 byte         Field length in binary.
      17       1 byte         Field decimal count in binary.
      18-19    2 bytes        Reserved.
      20       1 byte         Work area ID.
      21-30    10 bytes       Reserved.
      31       1 byte         Production MDX field flag; 01H if field has an
                              index tag in the production MDX file, 00H if not.

      Database records:
      =================

      The records follow the header in the database file. Data records
      are preceded by one byte; that is, a space (20H) if the record is
      not deleted, an asterisk (2AH) if the record is deleted. Fields
      are packed into records without field separators or record
      terminators. The end of the file is marked by a single byte, with
      the end-of-file marker an ASCII 26 (1AH) character.

      Allowable Input for dBASE Data Types:
      ====================================

      Data  Type           Data Input
      ----  ----------     -----------------------------------------------------
      C     (Character)    All OEM code page characters.
      D     (Date)         Numbers and a character to separate month, day, and
                           year (stored internally as 8 digits in YYYYMMDD
                           format).
      F     (Floating      - . 0 1 2 3 4 5 6 7 8 9
            point binary
            numeric)
      N     (Binary        - . 0 1 2 3 4 5 6 7 8 9
            coded decimal
            numeric)
      L     (Logical)      ? Y y N n T t F f (? when not initialized).
      M     (Memo)         All OEM code page characters (stored internally as 10
                           digits representing a .DBT block number).

      Memo Fields And .DBT Files
      ===========================================

      Memo fields store data in .DBT files consisting of blocks numbered
      sequentially (0, 1, 2, and so on). SET BLOCKSIZE determines the
      size of each block. The first block in the .DBT file, block 0, is
      the .DBT file header.

      Each memo field of each record in the .DBF file contains the
      number of the block (in OEM code page values) where the field's
      data actually begins. If a field contains no data, the .DBF file
      contains blanks (20h) rather than a number.

      When data is changed in a field, the block numbers may also change
      and the number in the .DBF may be changed to reflect the new
      location.

      This information is from the dBASE IV Language Reference manual,
      Appendix D.

    dBASE V - DOS
      *********************************************************************
      The data file header structure for dBASE 5.0 for DOS table file.
      *********************************************************************

      The table file header:
      ======================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0     1 byte      Valid dBASE for Windows table file; bits 0-2 indicate
                        version number; bit 3 indicates presence of a dBASE IV
                        or dBASE for Windows memo file; bits 4-6 indicate the
                        presence of a dBASE IV SQL table; bit 7 indicates the
                        presence of any .DBT memo file (either a dBASE III PLUS
                        type or a dBASE IV or dBASE for Windows memo file).
      1-3   3 bytes     Date of last update; in YYMMDD format.
      4-7   32-bit      Number of records in the table.
            number
      8-9   16-bit      Number of bytes in the header.
            number
      10-11 16-bit      Number of bytes in the record.
            number
      12-13 2 bytes     Reserved; filled with zeros.
      14    1 byte      Flag indicating incomplete dBASE transaction.
      15    1 byte      Encryption flag.
      16-27 12 bytes    Reserved for multi-user processing.
      28    1 byte      Production MDX flag; 01h stored in this byte if a prod-
                        uction .MDX file exists for this table; 00h if no .MDX
                        file exists.
      29    1 byte      Language driver ID.
      30-31 2 bytes     Reserved; filled with zeros.
      32-n  32 bytes    Field descriptor array (the structure of this array is
            each        shown below)
      n+1   1 byte      0Dh stored as the field terminator.

      n above is the last byte in the field descriptor array. The size
      of the array depends on the number of fields in the table file.

      Table Field Descriptor Bytes
      ============================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0-10  11 bytes    Field name in ASCII (zero-filled).
      11    1 byte      Field type in ASCII (B, C, D, F, G, L, M, or N).
      12-15 4 bytes     Reserved.
      16    1 byte      Field length in binary.
      17    1 byte      Field decimal count in binary.
      18-19 2 bytes     Reserved.
      20    1 byte      Work area ID.
      21-30 10 bytes    Reserved.
      31    1 byte      Production .MDX field flag; 01h if field has an index
                        tag in the production .MDX file; 00h if the field is not
                        indexed.

      Table Records
      =============

      The records follow the header in the table file. Data records are
      preceded by one byte, that is, a space (20h) if the record is not
      deleted, an asterisk (2Ah) if the record is deleted. Fields are
      packed into records without field separators orrecord terminators.
      The end of the file is marked by a single byte, with the
      end-of-file marker, an OEM code page character value of 26 (1Ah).
      You can input OEM code page data as indicated below.

      Allowable Input for dBASE Data Types
      ====================================

      Data Type      Data Input
      -------------- -----------------------------------------------------------
      C (Character)  All OEM code page characters.
      D (Date)       Numbers and a character to separate month, day, and year
                     (stored internally as 8 digits in YYYYMMDD format).
      F (Floating    - . 0 1 2 3 4 5 6 7 8 9
        point binary
        numeric)
      N (Numeric)    - . 0 1 2 3 4 5 6 7 8 9
      L (Logical)    ? Y y N n T t F f (? when not initialized).
      M (Memo)       All OEM code page characters (stored internally as 10
                     digits representing a .DBT block number).

      Memo Fields And .DBT Files
      ===========================================

      Memo fields store data in .DBT files consisting of blocks numbered
      sequentially (0, 1, 2, and so on). SET BLOCKSIZE determines the
      size of each block. The first block in the .DBT file, block 0, is
      the .DBT file header.

      Each memo field of each record in the .DBF file contains the
      number of the block (in OEM code page values) where the field's
      data actually begins. If a field contains no data, the .DBF file
      contains blanks (20h) rather than a number.

      When data is changed in a field, the block numbers may also change
      and the number in the .DBF may be changed to reflect the new
      location.

      Unlike dBASE III PLUS, if you delete text in a memo field, dBASE
      5.0 for DOS may reuse the space from the deleted text when you
      input new text.  dBASE III PLUS always appends new text to the end
      of the .DBT file. In dBASE III PLUS, the .DBT file size grows
      whenever new text is added, even if other text in the file is
      deleted.

      This information is from the dBASE for DOS Language Reference
      manual, Appendix C.

    dBASE V - Windows
      ************************************************************************
      The data file header structure for dBASE 5.0 for Windows table file.
      ************************************************************************

      The table file header:
      ======================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0     1 byte      Valid dBASE for Windows table file; bits 0-2 indicate
                        version number; bit 3 indicates presence of a dBASE IV
                        or dBASE for Windows memo file; bits 4-6 indicate the
                        presence of a dBASE IV SQL table; bit 7 indicates the
                        presence of any .DBT memo file (either a dBASE III PLUS
                        type or a dBASE IV or dBASE for Windows memo file).
      1-3   3 bytes     Date of last update; in YYMMDD format.
      4-7   32-bit      Number of records in the table.
            number
      8-9   16-bit      Number of bytes in the header.
            number
      10-11 16-bit      Number of bytes in the record.
            number
      12-13 2 bytes     Reserved; filled with zeros.
      14    1 byte      Flag indicating incomplete dBASE IV transaction.
      15    1 byte      dBASE IV encryption flag.
      16-27 12 bytes    Reserved for multi-user processing.
      28    1 byte      Production MDX flag; 01h stored in this byte if a prod-
                        uction .MDX file exists for this table; 00h if no .MDX
                        file exists.
      29    1 byte      Language driver ID.
      30-31 2 bytes     Reserved; filled with zeros.
      32-n  32 bytes    Field descriptor array (the structure of this array is
            each        shown below)
      n+1   1 byte      0Dh stored as the field terminator.

      n above is the last byte in the field descriptor array. The size
      of the array depends on the number of fields in the table file.

      Table Field Descriptor Bytes
      ============================

      Byte  Contents    Description
      ----- --------    --------------------------------------------------------
      0-10  11 bytes    Field name in ASCII (zero-filled).
      11    1 byte      Field type in ASCII (B, C, D, F, G, L, M, or N).
      12-15 4 bytes     Reserved.
      16    1 byte      Field length in binary.
      17    1 byte      Field decimal count in binary.
      18-19 2 bytes     Reserved.
      20    1 byte      Work area ID.
      21-30 10 bytes    Reserved.
      31    1 byte      Production .MDX field flag; 01h if field has an index
                        tag in the production .MDX file; 00h if the field is not
                        indexed.

      Table Records
      =============

      The records follow the header in the table file. Data records are
      preceded by one byte, that is, a space (20h) if the record is not
      deleted, an asterisk (2Ah) if the record is deleted. Fields are
      packed into records without field separators orrecord terminators.
      The end of the file is marked by a single byte, with the
      end-of-file marker, an OEM code page character value of 26 (1Ah).
      You can input OEM code page data as indicated below.

      Allowable Input for dBASE Data Types
      ====================================

      Data Type      Data Input
      -------------- -----------------------------------------------------------
      B (Binary)     All OEM code page characters (stored internally as 10
                     digits representing a .DBT block number).
      C (Character)  All OEM code page characters.
      D (Date)       Numbers and a character to separate month, day, and year
                     (stored internally as 8 digits in YYYYMMDD format).
      G (General     All OEM code page characters (stored internally as 10
                     digits or OLE) representing a .DBT block number).
      N (Numeric)    - . 0 1 2 3 4 5 6 7 8 9
      L (Logical)    ? Y y N n T t F f (? when not initialized).
      M (Memo)       All OEM code page characters (stored internally as 10
                     digits representing a .DBT block number).

      Binary, Memo, and OLE Fields And .DBT Files
      ===========================================

      Binary, memo, and OLE fields store data in .DBT files consisting
      of blocks numbered sequentially (0, 1, 2, and so on). SET
      BLOCKSIZE determines the size of each block. The first block in
      the .DBT file, block 0, is the .DBT file header.

      Each binary, memo, or OLE field of each record in the .DBF file
      contains the number of the block (in OEM code page values) where
      the field's data actually begins. If a field contains no data, the
      .DBF file contains blanks (20h) rather than a number.

      When data is changed in a field, the block numbers may also change
      and the number in the .DBF may be changed to reflect the new
      location.

      Unlike dBASE III PLUS, if you delete text in a memo field (or
      binary and OLE fields), dBASE for Windows (unlike dBASE IV) may
      reuse the space from the deleted text when you input new text.
      dBASE III PLUS always appends new text to the end of the .DBT
      file. In dBASE III PLUS, the .DBT file size grows whenever new
      text is added, even if other text in the file is deleted.

      This information is from the dBASE for Windows Language Reference
      manual, Appendix C.


  DOS Error Codes

       0  - No Error                         21  - Drive Not Ready
       1  - Function Number Invalid          24  - Seek Error
       2  - File Not Found                   26  - Unknown Media Type
       3  - Path Not Found                   27  - Sector Not Found
       4  - Too Many Open Files              28  - Printer Out Of Paper
       5  - Access Denied                    29  - Write Fault
       6  - Handle Invalid                   30  - Read Fault
       8  - Insufficient Memory              31  - General Failure
      15  - Disk Drive Invalid               32  - Sharing Violation
      16  - Attempt to Remove Current Dir    33  - Lock Violation
      17  - Not Same Device                  34  - Disk Change Invalid
      18  - No More Files                    35  - FCB Unavailable
      19  - Disk Write Protected             36  - Sharing Buffer Full


  DOS File Attributes

      Hex    Dec    Description
              
       0      0    Normal File
       1      1    Read Only
       2      2    Hidden
       4      4    System
       8      8    Volume Label
      10     16    Subdirectory
      20     32    Archive

      Attributes can be  combined, such as 18 (12h)  which would be
      a hidden subdirectory (16+2; 10h+02h).  DOS versions prior to
      3.1 may return the volume label attribute in combination with
      another attribute which is a bug.  The true volume label will
      only have an attribute of 8.


POWERBASIC DOS Compiler

  Character Set
      PowerBASIC's character set includes A to Z, a to z, and 0 to 9.
      The numbers 0 to 9; the symbols ., +, and -; and the letters E, e,
      D, and d, as well as the type declaration characters %, &, !, #,
      ?, and @, can be used to form numeric constants.

      These symbols have specific meaning in PowerBASIC:

        Symbol   Function
        
        &        string concatenation operator
        *        multiplication operator, flex string name/length separator
        +        addition and string concatenation operator
        -        subtraction and negation operator
        /        division operator
        =        assignment operator, relational operator
        \        integer division operator
        ^        exponentiation operator

        Symbol   Function
        
        @x       32-bit pointer to target data
        ?        byte unsigned integer and substitute for PRINT
        ??       word unsigned integer
        ???      double-word unsigned integer
        %        integer and named constant type declaration
        &        long integer type declaration and non-decimal base descriptor
        &&       quad integer type declaration
        !        single-precision type declaration
        #        double-precision type declaration
        ##       extended-precision type declaration
        @        BCD fixed-point type declaration
        @@       BCD floating-point type declaration
        $        string type declaration and metastatement prefix
        $$       flex-string type declaration

        Symbol   Function
        
        ()       function/procedure arguments, arrays, expression precedence
        ,        all-purpose delimiter
        .        decimal point and file-name extension separator
        '        comment delimiter
        ;        all-purpose delimiter
        :        statement delimiter
        <        relational operator
        >        relational operator
        "        string constant delimiter
        _        line continuation
        !        ASM substitute

        Symbol   Function
        
        &B &b    binary radix (supports up to 64 bits)
        &H &h    hexadecimal radix (supports up to 64 bits)
        &O &o    octal radix (supports up to 64 bits)

        In order to maintain compatibility with other versions of BASIC, it
        is generally assumed that radix format numbers represent signed (+-)
        values.  However, you can override this assumption by inserting a
        leading zero, or by appending an appropriate type identifier.

           Example:   &hFFFF  is -1        &hFFFF%  is -1
                      &h0FFFF is 65535     &hFFFF?? is 65535

        This is especially important when using radixes with DEF SEG, PEEK,
        and POKE which treat signed and unsigned values differently.

        See Also:   $OPTION


  Compiler Directives
      Syntax is:  PBC  [options]  file  [options]
      (* = default    -x- = turn x off)
       -CE     *compile to .EXE           -FEMU  *emulator float
       -CU      compile to .PBU           -FNPX   NPX ('87) float
       -CC      compile to .PBC           -FP     procedural float
       -ODA     declare arrays            -G86   *generate 8086
       -ODV     declare vars/arrays       -G286   generate 80286
       -OD      attach PBD debug info     -G386   generate 80386
       -OG      gosub preserve            -OZF   *optimize faster
       -OM      debug map file            -LS    *serial com lib
       -OP      path names in unit debug  -LP    *printer lib
       -OU      unit full debug           -LB    *ctrl-break lib
       -RExxx   find run-time error       -LG    *graphics libs
       -ES      stack error test          -LC    *CGA graphics lib
       -EB      bounds error test         -LE    *EGA graphics lib
       -EO      overflow error test       -LV    *VGA graphics lib
       -EN      numeric error test        -LH    *Hercules lib
       -DExxx   executable directory      -LA     All libs
       -DUxxx   unit directory            -LI     interpreted print
       -DSxxx   source directories        -LF     full float emulate
       -DLxxx   link directories

  Compiler Metastatements
    $ALIAS metastatement
      $ALIAS lets you rename the segments of an externally linked
      module so they're compatible with PowerBASIC.

      $ALIAS DATA AS "external segment name"

      PowerBASIC expects the data segment to be DATA.  If you want to
      link in a object module (.OBJ) with a different data segment name,
      use $ALIAS. See also $CODE and $LINK.

      Example:

      'import this example to your program
      $ALIAS DATA AS "DGROUP"
      $LINK "mymodule.obj"

      $CODE metastatement

      $CODE SEG specifies the code segment name for a unit

      $CODE SEG "name"

      PowerBASIC combines all the code from units, libraries, and .OBJ
      modules into one or more segments, based on their segment names.

      You can also assign code segment names for your PowerBASIC units
      and libraries using $CODE SEG.  The code from units and libraries
      whose code segments are not explicitly named is combined into a
      segment named CODE.  To allow more than 64k of code from multiple
      units to be linked into your main program, put a $CODE SEG
      metastatement in your unit source code, using a name other than
      CODE.

      As long as the total amount of code $LINKed in is less than 64k, using
      $CODE SEG is optional, since the code segment CODE won't overflow.
      See also $LINK


    $COM metastatement

      Allocates space for the serial port receive buffers.

      Syntax:  $COM [size]

      'size' is an integer constant defining the buffer capacity in
      bytes (0 to 32767) for each communications adapter and must be in
      increments of 16 bytes. If 'size' is not specified, a buffer of
      the default size (256 bytes) is allocated.


    $COMPILE metastatement

      Purpose: Determines whether code is compiled to memory, an .EXE
                file, a chain (.PBC) file, or a unit (.PBU) file.

      Syntax:  $COMPILE MEMORY
               $COMPILE EXE   {"newname.EXE"}
               $COMPILE CHAIN {"newname.PBC"}
               $COMPILE UNIT  {"newname.PBU"}

      This information can also be partially specified by using the
      Compiler/Destination menu.

      $CPU metastatement

      Purpose: Controls generation of processor-specific code.

      Syntax:  $CPU {8086|80286|80386}

      Specifies whether to generate code for the 8086/8088,80286 or the
      80386 CPU. If you have a 80486 CPU, select 80386 to produce more
      efficient code.

      This information can also be specified using the Options/Compiler/
      Generated code menu.

      $DEBUG metastatement

      Purpose: Controls generation of debugging information.

      Syntax:  $DEBUG MAP [ON|+|OFF|-]
               $DEBUG PBDEBUG
               $DEBUG PATH
               $DEBUG UNIT

      (1) Specifies whether to generate a .MAP file containing symbol
          information for an external debugger when compiling to an .EXE
          file.  This information can also be specified using the
          Debug/MAP File item.
      (2) Attach debug information for use in the PowerBASIC debugger,
          PBD.
      (3) Full source path included in unit debug info.
      (4) Unit includes all symbol info, even local/static.


    $DIM metastatement

      Purpose: Controls how strictly the compiler requires declarations.

      Syntax:  $DIM ALL | ARRAY | NONE

      $DIM NONE is for compatibility with most BASIC interpreters.
      Variables are not required to be dimensioned before they can be
      used and any static arrays referenced are automatically
      dimensioned from 0 to 10 if a corresponding DIM statement is not
      found.

      $DIM ARRAY requires all static arrays to be dimensioned using DIM
      or REDIM before you can use them.  This is the recommended minimum
      setting.

      $DIM ALL requires all variables and arrays to be dimensioned
      before you can use them, and all SUBs and FUNCTIONs to be declared
      before you can call them.

      For compatibility with GW-BASIC, dynamic arrays are not checked
      when $DIM ARRAY is specified.  To catch the invalid use of array
      elements in dynamic arrays, use $ERROR BOUNDS.


    $DYNAMIC metastatement

      Purpose: Declares default array allocation to be dynamic when they
               are DIMmensioned.

      Syntax:  $DYNAMIC

      Space for dynamic arrays is allocated at run time and can be
      deallocated with the ERASE statement, which frees up memory for
      other purposes.  This is in contrast to static arrays which are
      allocated at compile time and cannot be deallocated.  Applying the
      ERASE statement to a static array will only result in the elements
      being zeroed.


    $ERROR metastatement

      Purpose: Controls generation of error test code.

      Syntax:  $ERROR test [state] [,test [state]]...

      'test' is one of BOUNDS, NUMERIC, OVERFLOW, STACK, or ALL. 'state'
      is one of ON, +, OFF, or -. If 'state' is not specified, ON is
      assumed.  This metastatement is used to specify whether a module
      is to generate code which tests for certain types of errors
      wherever they may occur.

      This information can also be specified using the Options/Compiler/
      Error Tests menu.


    $EVENT metastatement

      Purpose: Controls generation of event-trapping code.

      Syntax:  $EVENT {ON|+|OFF|-}

      If your program contains an event trap of some sort (for example,
      ON KEY, ON COM(n)) then the compiler default is to generate event
      checking code.  This code causes the program during execution, to
      check for the event(s) being trapped between statements.  If your
      program doesn't do trapping, then $EVENT is automatically set to
      OFF and no event checking code is generated.

      Event-checking code slows execution slightly.  $EVENT gives you
      control over what parts of your program will do event checking. If
      there is an area where maximum speed is important or you can be
      certain no events will occur, then bracket this code with $EVENT
      OFF and $EVENT ON statements.


    $FLOAT metastatement

      Purpose: Selects a floating-point math package.

      Syntax:  $FLOAT {EMULATE|NPX|PROCEDURE}

      This metastatement is used to select which math package to use for
      numeric computations at any point in your code. You can use it as
      often as you like to take advantage of the different math packages
      throughout your program; you are not restricted to specifying it
      once per module or once per program.

      This information can also be specified using the Options/Compiler/
      Floating Point menu.


    $HUGE metastatement

      Purpose: Declares array allocation to be huge by default

      Syntax:  $HUGE

      The $HUGE metastatement takes no argument.  It declares the
      default array allocation type to be huge.  Huge arrays are
      dynamic, but their data can also be larger than 64k.  The default
      array allocation is static.

      You can override default array allocation types within the DIM and
      REDIM statements using the DYNAMIC, STATIC, and HUGE keywords.

      See also $DYNAMIC, $STATIC, DIM, REDIM

      $HUGE
      DIM I(10000) AS LONG 'I() array is HUGE

      $IF, $ELSE, $ENDIF metastatements

      Purpose: Defines portions of a source program to skip or compile.

      Syntax:  $IF [NOT] const
               ... statements
               [$ELSEIF const
               ... statements
               [$ELSE
               ... statements]
               $ENDIF

      'const' is a named constant or constant value.  If 'const' is
      nonzero (True), then the statements between $IF and $ENDIF are
      compiled and the statements between $ELSE and $ENDIF are not.  The
      $ELSEIF and $ELSE clauses are optional, but $ENDIF is required.


    $INCLUDE metastatement

      Purpose:  Instructs the compiler to read a text file from disk during
                compilation.

      Syntax:   $INCLUDE filespec

      Includes a text file.  Use it to compile the text of another file
      along with the current file.  The $INCLUDE mechanism causes the
      compiler to treat the included file as though it were physically
      present in the original text.  This is especially useful when you
      need to compile a program with more than 64K (the editor's maximum
      size) of source code.


    $INLINE metastatement

      Purpose: Inserts inline machine (assembly) code into your program.

      Syntax:  $INLINE {byte list}

      byte list is a list of bytes of machine code to be included in
      your program at the current location.


    $LIB metastatement

      Purpose: Includes or removes library code from programs compiled to
                .EXE files

      Syntax:  $LIB libraryname [state] [,libraryname [state]]...

      libraryname is one of COM (serial communications), LPT (printer),
      GRAPH (all graphics), CGA (CGA graphics), EGA (EGA graphics), VGA
      (VGA graphics), FULLFLOAT (full floating-point emulation), IPRINT
      (interpreted print), or ALL (all libraries).  state is one of ON,
      +, OFF, or -. If state is not specified, ON is assumed. Use $LIB
      to specify which internal code libraries should be included or
      stripped out of your program when it is compiled to an .EXE file.

      This information can also be specified using the Options/Linker
      menu.


    $LINK metastatement

      Purpose: Links an object file or a unit into your main program.

      Syntax:  $LINK "filename"

      The $LINK metastatement is used to link an object module (.OBJ
      file) a unit (.PBU file), or a library (.PBL file) into your main
      program. It may only appear in your main program, never in a unit.
      Each $LINK metastatement may include only one file name, with
      optional path.

      You must include the appropriate extension as part of the file
      name.  $LINK metastatements can appear anywhere in your main
      program.

      Library files are linked into a PowerBASIC program in the same way
      as unit or object modules, however, PowerBASIC applies a smart
      linking algorithm in this case:  it analyzes each component module
      in the library, and includes only those actually required.


    $OPTIMIZE metastatement

      Purpose:  $OPTIMIZE controls how PowerBASIC optimizes your programs
                as it compiles them.

      Syntax:   $OPTIMIZE SIZE | SPEED

      You can have PowerBASIC generate code that is faster than normal
      using $OPTIMIZE SPEED.  The default (OPTIMIZE SIZE) is to generate
      code that is smaller at the expense of speed.  Remember that you
      can also use the $CPU metastatement to decrease size and increase
      speed for certain processors.

      Because optimizations are global, you can only have one $OPTIMIZE
      metastatement per module.


    $OPTION metastatement

      Purpose: $OPTION enables and disables compiler options.

      Syntax:  $OPTION {CNTLBREAK | GOSUB | SIGNED} [state] [,...]

      The $OPTION metastatement is used to specify which compiler
      options should be enabled or disabled during code generation.
      'state' is one of ON, +, OFF, or -.  If 'state' is not specified
      then ON is assumed. ON and + are synonymous as are OFF and -.

       CNTLBREAK:   When enabled, you can press Ctrl+Break to interrupt
                    an .EXE program while it is running.
       GOSUB:       When enabled, the GOSUB stack is preserved when a
                    run-time error occurs.
       SIGNED:      When enabled, addresses returned by CODEPTR, CODESEG,
                    STRPTR, STRSEG, VARPTR, VARSEG are signed integers
                    (+-32k) for compatibility with other compilers.  The
                    default is to return unsigned values (0-64k).


    $SEGMENT metastatement

      Purpose: Declares a new code segment.

      Syntax:  $SEGMENT

      Use this to break up your source program when the compiler reports
      that the 64K segment limitation has been exceeded.


      $SOUND metastatement

      Purpose: Sets the capacity of the background music buffer.

      Syntax:  $SOUND size

      'size' is a numeric constant, indicating the capacity of the PLAY
      statement's background buffer (1 to 4096 notes).  Each note
      requires 8 bytes of memory; the default capacity is 32 notes or
      256 bytes.  An invalid 'size' will select the default of 32.


    $STACK metastatement

      Purpose: Declares the size of the run-time stack.

      Syntax:  $STACK size

      'size' is a numeric constant from 2048 to 32766 (bytes); the
      default is 2048 (800 hex).  The stack is used for return
      addresses, parameter passing, local variables, and within
      structured statements.  You may want to allocate more stack space
      if your program is heavily nested, uses many local variables, or
      performs recursion.  If you suspect that a program is running out
      of stack space, recompile it with stack testing enabled (use the
      Options/Compiler/Error Tests/Stack Test menu item or the $ERROR
      STACK metastatement).


    $STATIC metastatement

      Purpose: Declares the default array allocation to be static when
               arrays are DIMensioned.

      Syntax:  $STATIC

      Space for static arrays is allocated at compile time.

      $STRING metastatement

      Purpose: Declares the string segment allocation size.

      Syntax:  $STRING {1|2|4|8|16|32}

      This setting refers to the size of newly-allocated string segments
      in Kilobytes.  The size can be either 1, 2, 4, 8, 16, or 32, which
      translates to 1006, 2030, 4078, 8174, 16366, or 32750 bytes per
      segment.  The default size is 32 (32750 bytes).  This size affects
      the maximum length of strings in your programs, as well as
      PowerBASIC's ability to allocate string space when more is needed.

INTERNAL PROCEDEURES
    INTRODUCTION
      PowerBASIC offers a large set of Internal Procedures, to allow the
      more advanced programmer access to the dynamic string memory
      manager, and other important run-time tools.  Internal Procedures
      may be called from BASIC code or ASM statements by first declaring
      them just as shown in the following descriptions.  In order to
      call them from external .obj modules, you must declare them in the
      external source code as a far external.  When calling Internal
      Procedures from assembler code, keep in mind that the
      AX,BX,CX,DX,SI,DI,ES registers may be altered.

      Arrays:
        ArrayCalc, ArrayInfo

      Strings:
        GetStrAlloc, GetStrLen, GetStrLoc, RlsStrAlloc

      Events:
        SetOnExit, SetUevent


      GETSTRALLOC (or GET$ALLOC)

      Used to allocate a new block of dynamic string space.  It returns
      the integer handle (AX) used to identify the string, or the value
      zero if sufficient string space is not available.

      'Example
      DECLARE FUNCTION GetStrAlloc(BYVAL AllocSize%) AS INTEGER

      Tmp$ = ""                  ' null (zero length string)
      !  mov  AX, 30             ; we want a 30 bytes string
      !  push AX                 ; push it on the stack
      !  call GetStrAlloc        ; allocate a new string
      !  mov  Tmp$, AX           ; store the handle in Tmp$
      PRINT LEN(Tmp$)            ' the length is now 30


    GETSTRLEN (or GET$LEN)
      Returns the length (AX) of the designated string.

      DECLARE FUNCTION GetStrLen(BYVAL AllocHandle%) AS INTEGER

      DIM l AS INTEGER
      x$ = "Hello!"

      ! mov  AX, x$              ; put string handle in AX
      ! push AX                  ; push it on the stack
      ! call GetStrLen           ; get its length
      ! mov  l, AX               ; put length in 'l'

      PRINT LEN(x$), l           'print length using LEN() and 'l'


    GETSTRLOC (or GET$LOC)
      Returns a pointer (DX:AX) to the string data, and the length (CX).

      'Example
      DECLARE FUNCTION GetStrLoc(BYVAL AllocHandle%) AS LONG

      a$ = SPACE$(20)
      ! mov  AX, a$              ; put string handle in AX
      ! push AX                  ; push it on the stack
      ! call GetStrLoc           ; find where the data is located
      ! mov  ES, DX              ; put segment in ES
      ! mov  DI, AX              ; put offset in DI
      ! mov  AL, 65              ; value for "A" in AL
      ! rep  stosb               ; fill the string (CX holds the length)
      PRINT A$


    RLSSTRALLOC (or RLS$ALLOC)
      Used to release a block of dynamic string space.  It returns a
      true or false integer value (AX) to reflect the success of the
      operation.

      'Example
      DECLARE FUNCTION RlsStrAlloc%(BYVAL StringHandle%)

      Tmp$ = SPACE$(30)          ' 30 byte long string
      !  mov  AX, Tmp$           ; put handle in AX
      !  push AX                 ; push it on the stack
      !  call RlsStrAlloc        ; release the string
      !  xor  AX, AX             ; clear the handle
      !  mov  Tmp$, AX           ; store the new handle in Tmp$
      PRINT LEN(Tmp$)            ' the length is now 0 bytes


    SETONEXIT
      PowerBASIC can be instructed to call as many as eight separate
      user procedures just before the program is exited.  The procedure
      is added to the list, and a true/false integer value is returned
      (AX) to reflect the success of the operation.  A false value
      indicates that eight procedures have already been defined.  If
      your program terminates abnormally (when an error occurs) all
      SetOnExit routines are called.

      'Example
      DECLARE FUNCTION SetOnExit%(BYVAL ProcedurePointer???)

      Pointer??? = CODEPTR32(HereWeAre)
      CALL SetOnExit(Pointer???)
      END
      SUB HereWeAre()     'no parameters are passed
        PRINT "Sorry to see you go!"
      END SUB


    SETUEVENT
      This procedure is called to inform the run-time library that a
      user defined event (UEVENT) has occurred.  If ON UEVENT is active,
      the specified subroutine will be executed at the first
      opportunity.

      'Example
      DECLARE SUB SetUevent()

      ON UEVENT GOSUB HereWeAre
      $EVENT ON
      CALL SetUEvent()
      END

      HereWeAre:
        PRINT "A UEVENT has occurred!"
        RETURN

  Internal Variables
      PowerBASIC offers a large set of special Internal Variables, to
      allow the more advanced programmer access to important internal
      information in the run-time library.  Internal variables may be
      referenced directly in PowerBASIC code, with no special
      declarations necessary.  In order to reference them from external
      .obj modules, you must declare them in the external source code as
      an external in the segment DATA.  It is the programmer's
      responsibility to respect read-only status of an internal
      variable, or unpredictable side effects may result.
      
      pbvBinBase     int  read only   OPTION BINARY BASE - current value
      pbvCpu         byt  read only   cpu type: 1=86/88/186, 2=286, 3=386+
      pbvCursor1     byt  read only   first cursor scan line
      pbvCursor2     byt  read only   last cursor scan line
      pbvCursorVis   byt  read only   True/False: cursor visibility
      pbvDefSeg      wrd  read write  Def Seg = current value for peek/poke/etc.
      
      pbvErr         byt  read only   Use this variable to display the current
                                      status of ERR in the IDE watch window
      pbvFixDigits   byt  read only   Fixed point BCD fractional digits
      pbvFlexChr     $*1  read only   Flex string fill character
      pbvHost        int  read only   Host environment descriptor:
                                      bit0=snowchk reqd    bit3=101-key keyboard
                                      bit4=101-key bios    bit5=executing in IDE
                                      bit7=DesqView active bit8=Win 3.1+ active
      pbvMinusOne    lng  read only   Predefined constant -1
      pbvNpx         byt  read only   NPX type: 0=none, 1=87, 2=287, 3=387+
      pbvOne         lng  read only   Predefined constant +1
      pbvRevision    wrd  read only   PowerBASIC revision number (hex)
      pbvRevltr      byt  read only   Ascii sub-revision letter
      pbvScrnApage   byt  read only   Active screen page
      pbvScrnBuff    dwd  read only   32-bit pointer to the video screen buffer
      
      pbvScrnCard    byt  read only   Screen video card descriptor:
                                      bit0=mono   bit1=cga  bit2=egamono
                                      bit3=egaclr bit5=vga  bit6=hercules
      pbvScrnCols    byt  read only   Screen columns
      pbvScrnMode    byt  read only   Screen mode
      pbvScrnPxlAttr int  read only   Screen graphics default pixel attribute
      pbvScrnRows    byt  read only   Screen rows
      pbvScrnTxtAttr int  read only   Screen text attribute
      pbvScrnVpage   byt  read only   Visible screen page
      pbvSwitch      int  read/write  If bit 0=0 then the normal restoration of
                                      video mode, cursor size, and visibility is
                                      suppressed upon termination or POPUP SLEEP
                                      if bit 1=0 then the screen is not erased
                                      upon a video mode change.  This switch is
                                      not valid with all video cards or modes.
      
      pbvUserArea    $32  read write  32-byte buffer which may be used to pass
                                      any data to the next RUN/CHAIN module
      pbvUsingChrs   $*4  read write  Default: "*$,." numeric format characters
                                      for PRINT USING/USING$ to allow numerics
                                      with leading zeros, non-USA currency, etc.
      pbvVTxtX1      byt  read only   X1 coordinate for the text viewport
      pbvVTxtX2      byt  read only   X2 coordinate for the text viewport
      pbvVTxtY1      byt  read only   Y1 coordinate for the text viewport
      pbvVTxtY2      byt  read only   Y2 coordinate for the text viewport
      pbvZero        lng  read only   Predefined constant  0
      

  Numeric Expression Order of Evaluation
      ^                             Exponentiation
      -                             Negation
      *  /                          Multiplication, Floating point division
      \                             Integer Division
      MOD                           Modulo
      +  -                          Addition, Subtraction
      =  <>  <  >  <=  =>  >=  =>   Relational operators
      NOT  ISFALSE  ISTRUE          Bitwise NOT, Logical false, Logical true
      AND                           Bitwise AND
      OR  XOR                       Bitwise OR, Bitwise XOR
      EQV                           Bitwise EQV
      IMP                           Bitwise IMP

  Scancode Chart
      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      Esc        1        27        27        27         *
      1 !        2        49        33         *       120
      2 @        3        50        64         3       121
      3 #        4        51        35         *       122
      4 $        5        52        36         *       123
      5 %        6        53        37         *       124
      6 ^        7        54        94        30       125
      7 &        8        55        38         *       126
      8 *        9        56        42         *       127
      9 (       10        57        40         *       128
      0 )       11        48        41         *       129
      -_        12        45        95        31       130
      =+        13        61        43         *       131
      Backspace 14         8         8       127         *
      Tab       15         9        15         *         *

      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      Q         16       113        81        17        16
      W         17       119        87        23        17
      E         18       101        69         5        18
      R         19       114        82        18        19
      T         20       116        84        20        20
      Y         21       121        89        25        21
      U         22       117        85        21        22
      I         23       105        73         9        23
      O         24       111        79        15        24
      P         25       112        80        16        25
      [{        26        91       123        27         *
      ]}        27        93       125        29         *
      Enter     28        13        13        10         *
      Ctrl      29         *         *         *         *
      A         30        97        65         1        30

      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      S         31       115        83        19        31
      D         32       100        68         4        32
      F         33       102        70         6        33
      G         34       103        71         7        34
      H         35       104        72         8        35
      J         36       106        74        10        36
      K         37       107        75        11        37
      L         38       108        76        12        38
      ;:        39        59        58         *         *
      '"        40        39        34         *         *
      `~        41        96       126         *         *
      Left shft 42         *         *         *         *
      \|        43        92       124        28         *
      Z         44       122        90        26        44
      X         45       120        88        24        45

      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      C         46        99        67         3        46
      V         47       118        86        22        47
      B         48        98        66         2        48
      N         49       110        78        14        49
      M         50       109        77        13        50
      ,<        51        44        60         *         *
      .>        52        46        62         *         *
      /?        53        47        63         *         *
      Rght shft 54         *         *         *         *
      PrtSc     55        42        **        16         *
      Alt       56         *         *         *         *
      Spacebar  57        32        32        32        32
      Caps lock 58         *         *         *         *
      F1        59        59        84        94       104
      F2        60        60        85        95       105

      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      F3        61        61        86        96       106
      F4        62        62        87        97       107
      F5        63        63        88        98       108
      F6        64        64        89        99       109
      F7        65        65        90       100       110
      F8        66        66        91       101       111
      F9        67        67        92       102       112
      F10       68        68        93       103       113
      Num Lock  69         *         *         *         *
      Scroll Lk 70         *         *         *         *
      Home      71        71        55       119         *
      Up Arrow  72        72        56         *         *
      Page up   73        73        57       132         *
      Gray -    74        45        45         *         *
      Left Arw  75        75        52       115         *

      key    scan code unshifted  +shift   +control    +alt
     ------------------------------------------------------
      Numpad 5  76        53        *          *         *
      Right Arw 77        77       54        116         *
      Gray +    78        43       43          *         *
      End       79        79       49        117         *
      Down Arw  80        80       50          *         *
      Page Down 81        81       51        118         *
      Insert    82        82       48          *         *
      Delete    83        83       46          *         *
      F11      217       133      135        137       139
      F12      218       134      136        138       140

  Sub/Function Parameters
      In order to create the most efficient PowerBASIC programs, it is
      important to understand the principles of parameter types and the
      methods of declaring them.  The most important rule: it is the SUB
      or FUNCTION (called procedures) definition which declares the
      number of parameters, the type of each, and finally whether each
      is passed by reference or by value. This information is absolute;
      it may never change, since the procedure must know the format of
      the data it is using.  It is therefore up to the compiler (and the
      programmer) to make certain that when the procedure is called, the
      data is in the format the procedure expects. If it isn't, it must
      be converted.

      By default, parameters are passed "by reference".  When the
      procedure is called, the compiler passes a 32-bit pointer to the
      variable, and the procedure uses the pointer to access it as
      needed.  So, if a parameter by reference is altered, it's the
      original copy which is altered, and this change persists even
      after the procedure is exited.  Any variable type or full array
      may be passed by reference.

      'Example of Parameter by Reference
      x = 1         : PRINT "Before:"; x
      CALL MySub(x) : PRINT "After:"; x
      SUB MySub(ParameterByReference)
        INCR ParameterByReference 'add one to passed variable
      END SUB

      Optionally, a parameter may be declared "by value" by preceding
      the parameter name with the word BYVAL.  In this case, the
      compiler actually places a copy of the value on the stack for
      procedure access.  The size may range from two to ten bytes,
      depending upon the type.  If a parameter BYVAL is altered, it's
      only this local copy which is changed.  The original copy is
      untouched, and the local copy is discarded when the procedure is
      exited.  Execution speed is generally faster with parameters
      passed BYVAL, since a level of indirection is removed.  Any
      numeric variable, dynamic string or flex string may be passed
      BYVAL.  Fixed length strings, user-defined types, and full arrays
      may not as size makes it impractical to transfer to the stack.

      'Example of Parameter by Value
      x = 1         : PRINT "Before:"; x
      CALL MySub(x) : PRINT " After:"; x
      SUB MySub(BYVAL ParameterByValue)
        INCR ParameterByValue  'add one to passed variable
      END SUB

      It is possible to pass parameters "by copy" which is kind of a
      hybrid of the above two forms.  This method is used when the
      procedure expects the parameter by reference (a 32-bit pointer),
      but the compiler can't precisely oblige.  The "caller" might pass
      a different type, or an expression, or a constant, or the
      programmer might simply enclose the variable in parentheses to
      fool the compiler into thinking it's an expression, not just a
      simple variable.  In each of these cases, the compiler evaluates
      the parameter, stores the result in a temporary buffer (in the
      expected/converted format), then passes a 32-bit pointer to this
      temporary buffer.  Since the value is a temporary one, the
      original copy is untouched by the function, and it's discarded
      upon procedure exit. This is the least efficient method of the
      three.

      'Example of Parameter by Copy
      x = 1             : PRINT "Before:"; x
      'Note the extra set of parenthesis in the CALL statement
      CALL MySub( (x) ) : PRINT " After:"; x
      SUB MySub(ParameterByCopy)
        INCR ParameterByCopy  'add one to passed variable
      END SUB

      Declaring a procedure as CDECL allows you to specify optional
      parameters which can be passed by reference, by value, or by copy.
      However, you may not pass a dynamic or flex string BYVAL to a
      CDECL SUB or FUNCTION which is written in BASIC. PowerBASIC
      automatically generates code to release temporary strings in your
      procedure, including those which have been passed by value. If you
      specify a string as an optional parameter, code is generated at
      compile time to release that string when the procedure ends. This
      works fine when you actually pass the optional string parameter.
      However, PowerBASIC has no way of determining whether or not the
      parameter was passed. And if you do not pass it, it will assume
      that any value which may be present on the stack is a string
      handle and attempt to release it. If it is not a valid string
      handle, an error 208 will be generated. If it is a valid string
      handle, then a string which is used elsewhere in your application
      will have been released causing an error 208 when you attempt to
      access it later in your program. You can pass an optional string
      parameter BYVAL to a procedure written in assembler or C because
      PowerBASIC does not generate any code to release the string.  It
      is the responsibility of your assembler or C code to release any
      temporary strings that it uses.

      When passing a parameter by reference to a SUB or FUNCTION, you
      must use the BYVAL keyword to pass the target of a pointer.  If
      you pass the pointer itself, PowerBASIC would reference the
      location in memory where the pointer itself resides.  Not the
      target of the pointer.  By using the BYVAL keyword as an override
      you achieve the proper result of referencing the target.

      'Example
      DECLARE SUB MySUB(x AS INTEGER)
      DIM z AS INTEGER PTR
      z = &HB800000
      CALL MySUB(BYVAL z)   'pass target integer to MySUB

      See Also:  CALL   DECLARE   FUNCTION   SUB

  Variable Types and Definitions
      TYPE                 KEYWORD  IND  SIZE  RANGE
              
      Byte                 BYTE     ?      1   0 to 255
      Word                 WORD     ??     2   0 to 65,535
      Integer              INTEGER  %      2   -32,768 to 32,767
      Double Word          DWORD    ???    4   0 to 4,294,967,295
      Long Integer         LONG     &      4   -2,147,483,648 to 2,147,483,647
      Quad Integer         QUAD     &&     8   9.22x10^18
      Single Precision     SINGLE   !      4   8.43x10^-37  to 3.37x10^38
      Double Precision     DOUBLE   #      8   4.19x10^-307 to 1.67x10^308
      Extended Precision   EXT      ##    10   3.4x10^-4932 to 1.2x10^4932
      BCD Fixed Point      FIX      @      8   9.99x10^-63  to 9.99x10^63
      BCD Float Point      BCD      @@    10   9.99x10^-63  to 9.99x10^63
      Pointer              PTR      @      4   n/a

      Dynamic String       STRING   $          32750 bytes (see $STRING)
      Flex String          FLEX     $$         32750 bytes
      Fixed-length String  STRING*n            32750 bytes
      ASCIIZ String        ASCIIZ*n            32750 bytes

  PBLIB
      PBLIB is the PowerBASIC Librarian Utility.  It allows you to
      combine many modules of pre-compiled object code into a single
      library file.  The library files you create will have the
      extension .PBL and may consist of any combination of PowerBASIC
      units (.PBU) and/or object modules (.OBJ)

      PBLIB is meant to be used interactively.  That is, it's expected
      that you will type a series of commands to instruct it to open a
      library file, ADD or DELETE component modules, and finally close
      the library file and QUIT.  However, you can use the IDE to type
      in a series of commands and save it as a text file.  Then, when
      you invoke PBLIB from the DOS command line, you can add the name
      of this response file to execute PBLIB in a batch mode of
      operation:
           PBLIB command.fil

                      See also $ALIAS, $SEGMENT
      'Example
      $LINK "math.pbl"

PowerBASIC Error Codes
  Information
      There are two fundamental types of errors in PowerBASIC:  compile
      time and run time.

      Run-time errors

      Run-time errors occur when a compiled program is executed.
      Examples include file system errors like #61, improper function
      calls like #13 and memory errors like #14.  HELPFUL HINT: Import
      the example at the end of the error listing to have symbolic error
      names for your ON ERROR (optional) routine.

                  2   3    4    5    6    7    9   10   11   13
                 14  15   19   20   24   25   27   50   51   52
                 53  54   55   57   58   59   61   62   63   64
                 67  68   69   70   71   72   73   74   75   76

            Run-time errors dealing with linking variables or chaining

                      201   202   203   204   205   206
                      207   208   209   210   211   241
                      242   243   244   245   246   256
                      257   258   259   260

                                  Compiler errors

                       401 402 403 404 405 406 407 408 409 410
                       411 412 413 414 415 416 417 418 419 420
                       421 422 423 424 425 426 427 428 429 430
                       431 432 433 434 435 436 437 438 439 440
                       441 442 443 444 445 446 447 448 449 450
                       451 452 453 454 455 456 457 458 459 460
                       461 462 463 464 465 466 467 468 469 470
                       471 472 473 474 475 476 477 478 479 480
                       481 482 483 484 485 486 487 488 489 490
                       491 492 493 494 495 496 497 498 499

                                More Compiler errors

                       500 501 502 503 504 505 506 507 508
                       509 510 511 512 513 514 515 517 518
                       519 520 521 522 523 524 525 526 527
                       528 529 530 531 532 533 534 535 536
                       537 538

                                  Internal errors

                      601 602 603 604 605 606 607 608 609
                      610 611

      ' Predefined equates for all trappable run-time errors.  Programs are more
      ' readable if you reference symbols instead of literal numbers.
      '
      %SyntaxError        =2 : %ReturnWithoutGOSUB =3 : %OutOfData          =4
      %IllegalFunctionCall=5 : %OverFlow           =6 : %OutOfMemory        =7
      %SubscriptOutOfRange=9 : %DuplicateDefinition=10: %DivisionByZero     =11
      %TypeMismatch       =13: %OutOfStringSpace   =14: %StringTooLong      =15
      %NoRESUME           =19: %ResumeWithoutError =20: %DeviceTimeOut      =24
      %DeviceFault        =25: %OutOfPaper         =27: %FieldOverflow      =50
      %InternalError      =51: %BadFileNumber      =52: %FileNotFound       =53
      %BadFileMode        =54: %FileAlreadyOpen    =55: %DeviceIOError      =57
      %FileAlreadyExists  =58: %BadRecordLength    =59: %DiskFull           =61
      %InputPastEnd       =62: %BadRecordNumber    =63: %BadFileName        =64
      %TooManyFiles       =67: %DeviceUnavailable  =68: %ComBufferOverflow  =69
      %PermissionDenied   =70: %DiskNotReady       =71: %DiskMediaError     =72
      %FeatureUnavailable =73: %RenameAcrossDisks  =74: %PathFileAccessError=75
      %PathNotFound       =76: %OutOfStackSpace    =201:%MismatchedCommons  =203
      %MismatchedOptions  =204:%MismatchedRevisions=205:%InvalidProgramFile =206
      %ArrayIsStatic      =207:%InvalidStringHandle=208:%IncompatibleMouse  =209

  ERROR2    Syntax error
      A READ statement attempted to load string data into a numeric
      variable.
  ERROR3    RETURN without GOSUB
      There is nothing to RETURN from.
  ERROR4    Out of data
      A READ statement ran out of DATA statement values.
  ERROR5    Illegal function call
      The wrong argument type, or range for the argument, was passed to
      a function or statement.  Some examples of things that could cause
      it are:

        Too large a color or screen-mode argument

        Issuing a graphics statements without a graphics adapter or
        setting the improper mode with a SCREEN statement.

        Trying to perform invalid mathematical operations, such as
        taking the square root of a negative number.

        Attempting to use the WIDTH statement on a sequential file.

        Attempting to CHDIR to an invalid drive.

  ERROR6    Overflow
      The result of a calculation is too large to put in the variable of
      the indicated type.

  ERROR7    Out of memory
      Can be caused by dimensioning too large an array or using up all
      string space.

  ERROR9    Subscript out of range
      The subscript is larger than the value used when the array was
      dimensioned.  If this error occurs on DIM or REDIM, an attempt was
      made to allocate more than 64K of memory without including the
      HUGE option.

  ERROR10   Duplicate definition
      You did not ERASE an array before dimensioning it again.

  ERROR11   Division by zero
      Cans also be generated by raising zero to a negative power.
  ERROR13   Type mismatch
      You used a string value where a numeric value was expected or
      vice-versa.
  ERROR14   Out of string space
      String storage space is exhausted.
  ERROR15   String too long
      The string is longer than the current string segment size.
  ERROR19   No RESUME
      Execution ran to the physical end of the program while in an
      error trapping routine.
  ERROR20   RESUME without error
      Execution was not in an error trapping routine when a RESUME statement
      was encountered.
  ERROR24   Device timeout
      The timeout value for DSR, CTS or CD was exceeded.
  ERROR25   Device fault
      A hardware error has occurred with the communications adapter or
      printer interface.
  ERROR27   Out of paper
      The printer device failed to respond within the timeout period.
      It may not be attached or have some other problem.
  ERROR50   Field overflow
      Given the file's record length, you attempted to define a set of
      variables too long in a FIELD statement.
  ERROR51   Internal error
      There is a malfunction within the PowerBASIC run-time system.
      Please save all information about your program and the machine
      it is running on and call the PowerBASIC Technical Support
      group at the telephone number in the printed manual.

  ERROR52   Bad file name or number
      The file number you gave in a file statement doesn't match one
      given in an OPEN statement, or the file number may be out of the
      valid range of file numbers.  Error 53  File not found

  ERROR53   File not found
      The file name specified could not be found on the designated
      drive.

  ERROR54   Bad file mode
      You attempted a PUT or GET (or PUT$ or GET$) on a sequential file.
  ERROR55   File is open
      You attempted to open a file that was already open or you tried to
      delete an open file.

  ERROR57   Device I/O error
      A serious hardware problem occurred when trying to carry out some
      command.
  ERROR58   File already exists
      The new name argument specified in your NAME statement already
      exists.
  ERROR59   Bad record length
      The length specified in a  GET or PUT statement doesn't match
      that specified in an OPEN statement.
  ERROR61    Disk full
      There isn't enough free space on the indicated or default disk to
      carry out a file operation.  Create some more free disk space and
      retry your program.
  ERROR62   Input past end
      You tried to read more data from a file than it had to read.  Use
      the EOF function to avoid this problem.  This error can also be
      caused by trying to read from a sequential file opened for output
      or append.
  ERROR63   Bad record number
      A negative number or a number larger than 16,777,215 was specified
      as the record argument to a random file PUT or GET statement.
  ERROR64    Bad file name
      The file name specified in a FILES, KILL, or NAME statement
      contains invalid characters.
  ERROR67   Too many files
      Caused either by trying to create too many files in a drive's root
      directory, or by an invalid file name that affects the performance
      of the DOS Create File system call.
  ERROR68   Device unavailable
      You tried to OPEN a device file on a machine without that device;
      for example, COM1 on a system without a serial adapter or modem.
  ERROR69   Communication buffer overflow
      The serial port received more characters than available space in
      the communications buffer.  Your program should check and empty
      the buffer more often, or use a larger buffer.
  ERROR70   Permission denied
      You tried to write to a write protected disk.
  ERROR71   Disk Not ready
      The door of a floppy disk drive is open or there is no disk in the
      drive.
  ERROR72   Disk media error
      The controller board of a floppy or hard disk indicates a hard
      media error in one or more sectors.
  ERROR73   Feature unavailable
      You tried to perform an operation that requires DOS 3.0 or
      greater, but your system is using an earlier version.
  ERROR74   Rename across disks
      You cannot rename a file from one disk drive to another.
  ERROR75   Path/file access error
      During a command capable of specifying a path name, you used the
      path inappropriately; trying to open a sub-directory or to delete
      a directory in-use.
  ERROR76   Path not found
      The path you specified during an OPEN can't be found.
  ERROR201  Out of stack space
      Try increasing the stack space available by using the $STACK
      metastatement, or reducing the amount of recursion by your
      functions and procedures.
  ERROR202  Expansion memory error
      Not enough EMS memory was available to perform the operation.
  ERROR203  Mismatched common variables
      You attempted to CHAIN between two program segments which did not
      contain matching COMMON statements.  PowerBASIC checks the type
      and number of variables in COMMON statements.  Stack size (set
      with $STACK) must be identical in both modules.
  ERROR204  Mismatched program options
      You attempted to CHAIN between two program segments that were
      compiled with different program options. (Different graphics
      library, math co-processor required, etc.)
  ERROR205  Mismatched program revisions
      You attempted to CHAIN between two programs segments compiled
      under different versions of the PowerBASIC compiler.
  ERROR206  Invalid program file
      You attempted to CHAIN or RUN a program segment that was not
      compiled with PowerBASIC.
  ERROR207  Array is static
      This occurs if you try to DIM or REDIM a static array referenced
      as a parameter or an external.
  ERROR208  Invalid string handle
      An invalid dynamic or flex string handle was found.  It is likely
      that something overwrote memory to corrupt it. This is similar to
      an error 242.
  ERROR209  Incompatible mouse driver
      Your driver required more than 2048 bytes to "save its state",
      therefore it was not possible to pop down with POPUP SLEEP.
  ERROR210  Huge Array Not Allowed
      This statement does not support huge arrays.
  ERROR211  Pointer is null
      You attempted to access the target of an uninitialized pointer.
      You must give your pointer a target address.
  ERROR241  Far heap corrupt.
      The far heap has been improperly overwritten.  Similar to the
      causes of error 242.
  ERROR242  String space corrupt
      The string memory area has been improperly overwritten.  This can
      be caused by a stray assembler program, too small a stack,
      accessing arrays out of dimensions, or an error within the
      PowerBASIC run time system.
  ERROR243  CHAIN/RUN from .EXE file only
      You attempted to CHAIN or RUN programs while the parent program
      was executing with the PowerBASIC integrated development
      environment.
  ERROR244  Missing library
      You excluded a library in the library stripping menu and you used
      a function in your program that is contained in that library.
  ERROR245  CHAIN/RUN too big
      You attempted to CHAIN or RUN a .PBC or .EXE program that will not
      fit in memory.
  ERROR246  Invalid stack frame
      The stack is a problem in trying to execute an EXIT FAR or LOCAL
      error handler.  Likely caused by an intervening assembler routine
      which did not create a proper stack frame.
  ERROR256  Requires DOS 3.0 or later
      DOS 3.0 is the minimum required to run PowerBASIC.  DOS 3.0 is
      Required for file locking features.
  ERROR257  Missing numeric co-processor.
      You compiled the program to require a coprocessor.  To ensure that
      the program can run on machines without a numeric coprocessor, use
      the Emulation or Procedure floating-point library.
  ERROR258  Program too big to fit in memory
      The program requires more conventional memory (below 640k) than is
      available.  Try unloading popup programs or other resident
      programs or drivers.  Or use CHAIN.
  ERROR259  80286 cpu or above required
      You directed PowerBASIC to generate code which took advantage of
      the more powerful 80286 instruction set.  Now you are trying to
      run the program on an 8088 machine.
  ERROR260  80386 cpu or above required
      You directed PowerBASIC to generate code which took advantage of
      the more powerful 80386 instruction set.  Now you are trying to
      run the program on an 8088 or an 80286 machine.
  ERROR401  Expression too complex
      The expression contained too many operators/operands; break it
      down into two or more simplified expressions.
  ERROR402  Statement too complex
      The statement complexity caused an overflow of the internal
      compiler buffers; break the statement down into two or more
      simplified statements.
  ERROR403  $IF nesting overflow
      Conditional compilation blocks are nested over 16 levels deep.
  ERROR404  File nesting overflow
      $INCLUDE file nesting is limited to four levels  the main program
      and three included files.  This limit has been exceeded.
  ERROR405  Block nesting overflow
      PowerBASIC block structures (Loops, Subs, Functions, etc.) are
      nested more than 64 levels deep.
  ERROR406  Out of main memory
      The available compiler memory for symbol space, buffers, and so on
      has been exhausted.  A few ways to gain extra space are

       1.  Remove unnecessary line numbers and labels
       2.  Shorten your variable and procedure names
       3.  Reboot your computer without AUTOEXEC.BAT or CONFIG.SYS
           files which may load other programs which take memory.

  ERROR407  Too many segments.
      Your program contains more than 16 segments.
  ERROR408  Segment exceeds 64k
      Your program compiles to overflow a segment.  Try adding a
      $SEGMENT directive to your program to force code generation into
      other segments.
      
      If you are linking units into your program you may need to add the
      $CODE metastatement to the source code for one or more units.  In
      this case, surrounding your $LINK statement with $SEGMENT
      directives will not help the segment overflow.
      
  ERROR409  Variables exceed 64k
      Get rid of unused variables or split your program into separate
      main and CHAIN modules.
  ERROR410  Literals exceed 64k
      String literals (such as the hello in PRINT "hello") are limited
      to 64k.  Reduce the number or length of literals, or restructure
      your program to read data files.
  ERROR411  "," expected
      The statement's syntax requires a comma.
  ERROR412  ";" expected
      The statement's syntax requires a semicolon.
  ERROR413  "(" expected
      The statement's syntax requires a parenthesized
      argument, or you left out the opening parenthesis.
  ERROR414  ")" expected
      The statement's syntax requires a parenthesized
      argument, or you left out the closing parenthesis.
  ERROR415  "=" expected
      The compiler was expecting an assignment and found
      no operator.
  ERROR416  "-" expected
      The statement's syntax requires a hyphen.
  ERROR417  "*" expected
      The statement's syntax requires an asterisk.
  ERROR418  Statement expected
      Some character could not be identified as
      a statement, meta statement, or variable.
  ERROR419  Label/line number expected
      A valid label or line number was not found in an IF, GOTO, GOSUB,
      or ON statement.
  ERROR420  Relational operator expected
      The compiler found a string operand in a position where a numeric
      operand should be.
  ERROR421  String operand expected
      The compiler expected a string expression and found something
      else; for example, X$ = A$+3.
  ERROR422  Scalar variable expected
      The compiler did not find a scalar variable as a formal parameter
      to a user-defined function.  Scalar variables include strings,
      flex-strings, integers, long integers, quad integers, single
      precision, double precision, extended precision, and BCD fixed and
      floating point reals.
  ERROR423  Array variable expected
      None was found in a DIM statement, or in the GET and PUT graphics
      statements.
  ERROR424  Numeric variable expected
      None was found in a INCR, DECR, or CALL ABSOLUTE statement.
  ERROR425  String variable expected
      None was found in a FIELD, GET$, PUT$, or LINE INPUT statement.
  ERROR426  Variable expected
      None was found as the argument to a VARPTR, VARSEG, or VARPTR$
      function.
  ERROR427  Integer constant expected
      An integer constant was expected in a named constant assignment or
      conditional compilation $IF metastatement.
  ERROR428  Positive integer constant expected
      You did not have one in the array bounds for a
      DIM STATIC array or in the $COM, $SOUND, or $STACK metastatements.
  ERROR429  String constant expected
      You must use a constant for the file name in the $INCLUDE
      metastatement.
  ERROR430  Integer variable expected
      None was found as a parameter in a statement such as ARRAY SCAN.
  ERROR431  Numeric scalar variable expected
      A numeric scaler variable (byte, word, integer, etc.) is expected.
      Such as the target of a FOR/NEXT loop.  You may not use a variable
      passed as a parameter to a SUB or FUNCTION in a FOR/NEXT loop.
  ERROR432  Integer scalar variable expected
      A non-array variable was expected as a parameter in a CALL
      ABSOLUTE statement.
  ERROR433  Integer array variable expected
      An example of this might be in the PALETTE statement.
  ERROR434  End of line expected
      For example, on a metastatement, END SUB, or a statement label
      there were characters other than a comment.
  ERROR435  $IF expected
      A $ENDIF conditional compilation metastatement is missing its
      opening $IF.
  ERROR436  $ENDIF expected
      A $IF conditional compilation metastatement is missing its closing
      $ENDIF.
  ERROR437  AS expected
      This reserved word is missing in either a variable or field buffer
      declaration statement.
  ERROR438  FROM expected
      The reserved word is missing in either a FIELD or MAP statement.
  ERROR439  GOSUB expected
      An ON statement is missing its accompanying GOSUB part.
  ERROR440  GOTO expected
      An ON statement is missing its accompanying GOTO part.
  ERROR441  IN expected
      This reserved word is missing in a REPLACE statement.
  ERROR442  THEN expected
      An IF is missing the accompanying THEN part.
  ERROR443  TO expected
      A FIELD, FOR, or MAP statement is missing its accompanying TO part.
  ERROR444  WITH expected
      The WITH reserved word is missing in a REPLACE
      statement. Check the syntax of the REPLACE statement.
  ERROR445  DEF FN expected
      The compiler found an END DEF or EXIT DEF without a DEF FN
      function defined.
  ERROR446  FUNCTION expected
      The compiler found an END FUNCTION or EXIT FUNCTION without a
      FUNCTION function defined.
  ERROR447  IF expected
      The compiler found an END IF or EXIT IF without a beginning IF
      statement defined.
  ERROR448  DO loop expected
      The compiler found a LOOP or EXIT LOOP without a beginning DO statement
      defined.
  ERROR449  SELECT expected
      When defining a SELECT CASE statement, you either forgot to include
      the reserved word SELECT or the compiler ran into an END SELECT or EXIT
      SELECT without a beginning SELECT CASE statement.  This error can also
      occur if you try to use the reserved word CASE as a variable.
  ERROR450  CASE expected
      When defining a SELECT CASE statement, you forgot to include the
      reserved word CASE.  This error can also occur if you try to use
      the reserved word SELECT as a variable in your program.
  ERROR451  FOR loop expected
      The compiler found an EXIT FOR statement without
      a beginning FOR statement defined.
  ERROR452  SUB expected
      The compiler found an END SUB or EXIT SUB statement without a procedure
      defined.  You must define a procedure by beginning it with a SUB
      statement.
  ERROR453  END DEF expected
      A DEF FN function was not terminated with a
      corresponding END DEF statement
  ERROR454  END FUNCTION expected
      A FUNCTION function was not terminated with a matching END
      FUNCTION statement.
  ERROR455  END IF expected
      An IF block is not terminated with a corresponding END IF.
  ERROR456  LOOP/WEND expected
      A DO or WHILE loop was not terminated with a corresponding
      LOOP or WEND statement.
  ERROR457  END SELECT expected
      A SELECT CASE statement was not properly terminated.
  ERROR458  END SUB expected
      A procedure was not properly terminated.
  ERROR459  NEXT expected
      A FOR loop was started and a matching NEXT was not found.
  ERROR460  Undefined equate
      You used a named constant in your program without defining it.
      Define the named constant or use a literal constant in the
      statement.
  ERROR461  Undefined FN reference
      You used a FN name in an expression without defining the DEF FN
      function.  Check the name of the function for mistakes or provide
      a definition for the function.  Error 461  Undefined FN reference

      You used a FN name in an expression without defining the DEF FN
      function.  Check the name of the function for mistakes or provide
      a definition for the function.
  ERROR462  Undefined SUB/FUNCTION reference
      You used CALL to a procedure, but you did not define the
      procedure.  Check the name of the procedure for mistakes or
      provide the procedure.  This error also occurs when you reference
      a procedure which is in a unit or .OBJ module but has no
      corresponding DECLARE statement in the main program, or is not
      declared to be PUBLIC in its module.
  ERROR463  Undefined label/line reference
      You used a line number or label in an IF, GOTO, GOSUB, or ON
      statement, but you did not define the label or number.  Check the
      label or line number for mistakes or provide a label.
  ERROR464  Undefined array reference
      An array was referenced but was never defined in a DIM statement.
      Check the array name for mistakes or provide a DIM statement for
      it.
  ERROR465  Duplicate definition
      A program element which should only appear once was duplicated in
      your code. (two $COMPILE meta-statements, or two $STRING
      metastatements, for example)
  ERROR466  Duplicate name definition
      A SUB name, FUNCTION name, DEF FN name, label name, or variable
      name was defined more than once in your code.  Check your program
      and any INCLUDE files for duplicate names and change one or both
      of them.
  ERROR467  Duplicate line number
      The same line number was used twice.  Check your program and any
      INCLUDE files for duplicate numbers and change one or both of
      them.
  ERROR468  Duplicate equate
      Two constants were defined with the same name.  Check your program
      and any INCLUDE files for duplicate names and change one or both
      of them.
  ERROR469  Duplicate common variable
      Two variables with the same name were listed in a COMMON
      statement.  Check your program and INCLUDE files for duplicate
      names and change one or both of them.
  ERROR470  Duplicate variable declaration
      Two variables with the same name have been declared with a LOCAL,
      STATIC, or SHARED statement.  Check your program and INCLUDE files
      for duplicate names and change one or both of them.
  ERROR471  Invalid line number
      The line number was not in the range 0 to 65535.
  ERROR472  Invalid label
      A label in your code contains invalid
      characters.
  ERROR473  Invalid numeric format
      Your program declared a number with more than 18 digits or a
      floating-point number with an E component--but without the
      exponent value.
  ERROR474  Invalid name
      A function, procedure, or label has an invalid name.  In the case
      of a DEF FN function, FN must be followed by a letter and then
      other letters,digits, and periods, optionally ended with a type
      identifier (?, %, &, !, #, or $).  In the case of a SUB procedure
      or FUNCTION, the name must begin with a letter and can be followed
      by other letters, digits, and periods but must not include a type
      identifier.
  ERROR475  Meta-statements not allowed here
      A meta statement was not the first statement on a line.
  ERROR476  Block/scanned statements not allowed here
      A WHILE/WEND, DO/LOOP, or SELECT/CASE was on a single line IF
      statement.  Also, you cannot have a procedure or function
      definition nested within the body of another definition.
  ERROR477  Syntax error
      Something is incorrect on the line and the compiler could not
      interpret it enough to give a more specific message.
  ERROR478  Array subscript error
      You dimensioned an array with a number of subscripts and used it
      with a different number of subscripts.
  ERROR479  Array bounds error
      In the case of a static dimensioned array, your program referenced
      the array with a literal value that was out of range.
  ERROR480  Type mismatch is generated
      You attempted to use an invalid variable type, such as using a
      TYPE variable in an INPUT statement.
  ERROR481  Parameter mismatch
      The parameters passed to a procedure or function are not of the
      same type that was defined in the corresponding definition or
      declare statement.  This error also occurs when variable types in
      a SWAP statement are not the same.
  ERROR482  CLEAR parameters not allowed
      The additional parameters available to the CLEAR statement in
      interpretive BASIC are not available in PowerBASIC.
  ERROR483  CLEAR not allowed here
      It was found within a procedure or function.
  ERROR484  Requires FUNCTION/SUB/DEFFN
      You attempted to declare LOCAL variables any other place.
  ERROR485  Fixed length string expected
      You tried to define a dynamic of flex string as a member of a TYPE
      or UNION.  Only fixed strings are allowed.
  ERROR486  COMMON must be dynamic
      Arrays used in the common statement were not declared dynamic.
  ERROR487  LOCAL must be dynamic
      Arrays defined as LOCAL cannot be defined as STATIC.  Get rid of
      the STATIC specifier or move the array definition out of the
      procedure or function and into your main program.
  ERROR488  Array is already dynamic/huge.
      If you have two DIM statements in a program for the same array, or
      if you DIMensioned an array using variables as indices, the array
      is automatically declared to be DYNAMIC.  You get this error
      message if you try to declare such an array STATIC.
  ERROR489  Array is already static
      You issued a DIM STATIC statement to DIMension a static array,
      then later attempted to dimension that array again.  Static arrays
      my be dimensioned only once in a program.
  ERROR490  Static array exceeds 64k
      The size of a STATIC array exceeds 64k.
  ERROR491  Array exceeds eight dimensions
      You exceeded the internal limit of the compiler on dimensions.
  ERROR492  No params with INLINE SUB.
      You cannot specify a formal parameter list in an INLINE SUB
      procedure declaration.  The assembly language program is
      responsible for knowing the number and type of parameters being
      passed to it.  No type checking is done by the compiler.
  ERROR493  Compiler file not found
      An $INCLUDE, or $LINK file could not be found in the specified
      directory path, current directory, or the path specified by the
      appropriate OPTIONS/DIRECTORIES menu item.  Check the directory
      paths or make sure the specified file exists.
  ERROR494  ASM not allowed here.
      ASM (or the shortcut '!') must be the only statement on a line.
  ERROR495  Compiler file read error
      When PowerBASIC tried to open the $INCLUDE, $INLINE, or $LINK file
      a disk error was reported during compilation.
  ERROR496  Destination file write error.
      While compiling to disk (an .EXE, .PBC, or .PBU file), the
      compiler received a disk write error.  There could be a bad disk,
      a bad drive, or an invalid .EXE file path in the Options menu.
  ERROR497  Assembler syntax error
      This occurs on any ASM statement which is not constructed
      correctly.  One thing to check is that you use PowerBASIC syntax
      for all numbers used as immediate operands.
  ERROR498  INLINE Expected
      This SUB/FUNCTION was previously declared without a set of empty
      parentheses.  That syntax is only legal for INLINE subs.
  ERROR499  ASE not allowed here.
      CASE must be the first statement on a line.
  ERROR500  EXTERNAL only in units
      EXTERNAL is legal only in UNIT (.PBU) files.
  ERROR501  Nested $LINK files
      A unit contains a $LINK metastatement; this is not allowed.  Only
      the main program may contain $LINK units and .obj files.  This
      error commonly occurs when you compile a file to a unit in the
      PowerBASIC environment, then forget to set the Compile/Destination
      menu item to Memory or EXE file when compiling the main program,
      which contains a $LINK statement.
  ERROR502  One Data Segment per Module
      This external .OBJ module included more than one data segment, as
      defined by your $ALIAS meta-statements.  It is not possible to
      link this module accurately.
  ERROR503  Unresolved EXTERNAL.
      A variable declared EXTERNAL in a unit was not present in the main
      program which the unit was $LINKed to.
  ERROR504  Flex variable expected
      A flex string variable was expected in a FIELD or MAP statement.
      Check the syntax of the FIELD or MAP statements.
  ERROR505  Flex array expected.
      A flex string array variable was expected in a MAP statement.
      Check the syntax of the MAP statement.
  ERROR506  Declaration must precede statements
      A meta statement such as $COMPILE, $CPU, etc was preceded by some
      executable code.  You must rearrange the statements in your
      program so that these metastatements come first.
  ERROR507  Invalid $LINK file
      There is something wrong with a file $LINKed into your program.
      If the file is a unit file, it may have been created with a
      different version of the PowerBASIC compiler.  If the file is a
      .obj file it may contain code or declarations which violate
      PowerBASIC's rules for .obj files.
  ERROR508  Duplicate label
      The name of a label which appears in a file $LINKed into your
      program is the same as a label in your main program.  Change one
      or both of the names.
  ERROR509  Invalid segment name
      You attempted to link a UNIT in which you specified a $CODE SEG
      name of DATA, or by a data name specified by $ALIAS.
  ERROR510  Invalid alignment
      You tried to specify 32 bit alignment.
  ERROR511  $LINK buffer overflow
      You don't have enough real memory available to buffer a unit or
      .obj for $LINK.  Split the modules up.  If the code segment(s) in
      a module are under 16k, they will always fit.  If they are larger,
      there must be main memory available to buffer them.
  ERROR512  Nested brackets not allowed
      You attempted to use nested brackets in an optional parameter
      declaration.
  ERROR513  "]" expected
      The statement's syntax requires a closing bracket (]).
  ERROR514  Invalid fixup
      You tried to $LINK an .OBJ file which contains an invalid fixup
      requirement.  For example, while it is legal to define initialized
      data in the 'DATA' segment (or one equated with $ALIAS), it must
      contain only static constants (numbers or characters).  It may not
      include any "pointers" which reference a code or data label, thus
      requiring a link-time "fixup".  Such pointers may only appear in a
      segment other than 'DATA.
  ERROR515  Fixup overflow
      You tried to $LINK an .obj file containing a reference to a code
      or data item which is not in the segment where PowerBASIC expected
      it to be.  A NEAR reference to an item which is in a different
      segment will cause this error.
  ERROR517   Expansion memory fault
      EMS or XMS reported an error.
  ERROR518  "[...]" requires CDECL
      You attempted to define optional parameters in a SUB or FUNCTION
      without declaring it as CDECL (using "C" style calling
      conventions).
  ERROR519  Missing declaration
      You specified that variables and/or arrays should be declared
      before use, but didn't declare a variable or array.  Use DIM a
      variables type or an array's dimensions.
  ERROR520  TYPE expected
      PowerBASIC found an END TYPE statement without a preceding TYPE
      statement.
  ERROR521  UNION expected
      PowerBASIC found an END UNION statement without a preceding UNION
      statement.
  ERROR522  END TYPE expected
      An TYPE statement was started but not closed with an END TYPE.
  ERROR522  END TYPE expected
      An TYPE statement was started but not closed with an END TYPE.
  ERROR523  END UNION expected
      A UNION statement was found but an END UNION to match was never
      located.
  ERROR524  Undefined type
      Means you specified an undefined type/member name like abc.qqq
      where qqq was not defined as a member.
  ERROR525  Type id (?%&!#$) not allowed
      You included a type id on a member in a TYPE / UNION definition.
  ERROR526  Period not allowed
      You included a period within a member name in a TYPE / UNION
      definition.
  ERROR527  End of statement expected
      There is an extra character at the end of a statement or line of
      source.
  ERROR528  Type too large
      TYPE /UNION definitions must be less than 16k.
  ERROR529  Pointer Variable Error
      You attempted to use a pointer variable incorrectly, such as using
      the leading at-sign (@) with a variable which is not a pointer, or
      attempted to DECLARE a target pointer as a parameter in a SUB or
      FUNCTION.
  ERROR530  Invalid member name
      Could be a duplicate of an ID or something else.
  ERROR531  Too many SUBS
      This is amazing.  The limit is 16000 subs.
  ERROR532  Too many externals
      The limit is 32000.
  ERROR533  Only valid in units
      Can be caused by using $CODE SEG or EXTERNAL which can only
      appear in a unit.
  ERROR534  Not valid in units
      RUN or COMMON may not appear in a UNIT.
  ERROR535  Dyn/flex string variable expected
      Some statements (like FIELD) require variable length or flex strings.
  ERROR536  Virtual Array Error
      Occurs when you attempt to use ARRAY SORT/SCAN/INSERT/DELETE or
      SWAP with a virtual array.  Or you attempted to pass a virtual
      array element to a Sub or Function by reference.
  ERROR537  Invalid debug file
      You tried to load a program in PBD that has no debugging
      information or has debugging information that is corrupted or from
      a different version.
  ERROR538  Out of expansion memory
      Not enough EMS, XMS, or VMS to complete compilation.
  ERROR601  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR602  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR603  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR604  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR605  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR606  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR607  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR608  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR609  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR610  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.
  ERROR611  Internal system error
      If this error occurs, report it immediately to the
      PowerBASIC Technical Support Group.

POWERBASIC Keywords

  ABS function
      Purpose: Returns the absolute value of its argument.

      Syntax:  y = ABS(numeric expression)


  CALL ABSOLUTE statement
      Purpose: Invokes an assembly language routine.

      Syntax:  CALL ABSOLUTE addressvar(parameter list)

      'addressvar' is an integer variable containing the offset in
      memory within the current segment where the routine is located.
      'parameter list' is a list of parameters to be passed to the
      routine; only integer parameters are allowed.


  ACCESS statement
      Purpose:  Prepares a file or device for reading or writing.

      Syntax:   OPEN filespec [FOR mode] [ACCESS access] [lock] AS [#]filenum
                            [LEN = recordsize]

                OPEN modestring, [#]filenum, filespec [, recordsize]

      Opens a file or device whose name is filespec as file number
      'filenum', and whose mode is described by a mode keyword (OUTPUT,
      INPUT, APPEND, RANDOM, or BINARY) or a string (modestring)
      containing "O", "I", "A", "R", or "B".  Files opened in BINARY
      mode may only be accessed with GET$, PUT$, PUT, and GET.  Files
      opened in OUTPUT or APPEND mode may only be accessed with PRINT,
      PUT, or WRITE.  Files opened in INPUT mode may only be accessed
      with INPUT, INPUT$, or LINE INPUT.  RANDOM-mode files may be
      accessed with GET, INPUT, INPUT$, LINE INPUT, PRINT, PUT, or
      WRITE.  'recordsize' is an integer expression from 1 to 32767
      which specifies the length of each record in a random file.

      The keyboard, screen, printers, and communications ports may be
      opened as files using filenames "KYBD:", "SCRN:", "CONS:",
      "LPT1:", "LPT2:", "LPT3:", "COM1:", "COM2:", "COM3:", and "COM4:".
      "KYBD:" and "CONS:" use DOS for all I/O, allowing both input and
      output to be redirected.  "SCRN:" writes to the screen memory
      directly, preventing redirection.  Access and Lock network modes
      may be specified when using DOS 3.0 or later. 'access' is one of
      READ, WRITE, or READ WRITE. lock is either SHARED, LOCK READ, LOCK
      WRITE, or LOCK READ WRITE. Specifying ACCESS READ means that only
      subsequent read operations will be allowed on this file;
      attempting a write operation will cause an error. ACCESS WRITE
      allows only write operations, while ACCESS READ WRITE allows both.
      LOCK WRITE means that this file cannot be written to by other
      users while you have it open; an attempt to do so will generate an
      error for the other user. The file can still be read by another
      user, however.


  AND operator
      Purpose:  AND works as a logical and a bitwise arithmetic operator

      Syntax:   p AND q

      Remarks:  AND returns TRUE if and only if both of its operands are
      TRUE.

                p     q     p AND q
                -------------------
                T     T        T
                T     F        F
                F     T        F
                F     F        F

      AND masks clear selected bits of an integer quantity.

      themask = &H3F00 : thevalue = &H9700
      thevalue = thevalue AND themask   'clear the high order bits


  ANY
      This is a reserved word.  It is used as a part of:

         DECLARE
         EXTRACT$
         FUNCTION
         INSTR
         LTRIM
         REMOVE$
         REPLACE
         RTRIM
         SUB
         TALLY


  ARRAY Statement
      The ARRAY statement allows you to sort an array, scan for a
      particular value, insert an element or delete one, in an array of
      any data type.  Each of the four forms is described below:

  ARRAY SORT
      Syntax for numeric array:

      ARRAY SORT darray([index]) [FOR count] [,TAGARRAY tarray()]
                [,{ASCEND|DESCEND}]

      Syntax for string array:

      ARRAY SORT darray([index]) [FOR count] [,FROM start TO end]
                [,COLLATE {UCASE|string}] [,TAGARRAY tarray()]
                [,{ASCEND|DESCEND}]

      ARRAY SORT allows you to sort all or part of a data array (darray)
      in ascending or descending order.  You may also specify one
      tag-along array (tarray), whose elements are sequenced in the same
      order as those in the main data array.  The tag-along array must
      have at least as many elements as the main data array, but it may
      be of any data type.  You use 'index' to specify the first element
      to sort.  If 'index' is omitted, the array is sorted from the
      first element.  You use 'count' to specify the total number of
      elements to sort.  If 'count' is omitted, the array is sorted
      through the last element.  If both are omitted, the entire array
      is sorted.

      By default, arrays are sorted in ascending sequence.  To sort in
      descending order, include the optional DESCEND keyword.  COLLATE
      UCASE is used with string arrays to treat all lowercase alphabetic
      characters as equal to their uppercase counterparts, while COLLATE
      string is used to specify an entirely new sorting order, such as
      for an international character set.  The collate string is
      described in detail below.

      When a string array is sorted, every character from each element
      is normally considered when performing comparisons.  Use the FROM
      and TO options to specify starting and ending character positions
      if you wish to restrict the comparisons to a subset of each
      string.  The options for ARRAY SORT can be listed in any order, as
      long as the FOR option, if specified, directly follows the name of
      the data array.

      It is possible to sort a multi-dimensional array, but the elements
      are sequenced just as they appear in memory.  Since PowerBASIC
      stores multi-dimensional arrays in column-major order, the array
      x(2,2) would appear in memory as follows:

                  x(0,0)  x(1,0)  x(2,0)  x(0,1)  x(1,1)  x(2,1)

      Use care in sorting multi-dimensional arrays, to avoid disrupting
      your data organization.  Since column-major order may not be
      compatible with your specific sort needs, it may be necessary to
      copy array elements to a temporary array, sort them, and copy them
      back to the original.


  COLLATE String
      The optional COLLATE string can be used to specify an entirely new
      sorting order for string arrays.  This can be useful for a variety
      of needs, the most obvious of which is the case of international
      character sets.  The collate string must be exactly 256 bytes long
      - one byte for each of the ASCII codes (0 to 255).  Please read
      the following sections carefully, as it is very easy to
      misunderstand the definitions.

      Each position in the string represents the ASCII code with that
      value.  The contents of the byte at that position tells the ARRAY
      SORT procedure the "weight" or importance factor for that
      particular ASCII code.  The default is that position 0 has a
      weight of 0, position 1 has a weight of 1, etc., so that chr$(0)
      sorts first, chr$(1) sorts second, and so on, through chr$(255).
      Suppose you wish to have the special character "" sort with
      exactly the same weight as the standard character "a".  It's easy:
      construct a string of 256 characters, 0 to 255, then go to the
      position of "" (ASCII code 132) in the string, and change the
      contents of that byte so it is exactly equal to the code for "a"
      (ASCII code 97).  The following Basic source code constructs just
      such a collate string.  Of course, since the MID$ statement
      considers the first byte to be position 1, not 0, the example
      modifies position 132+1 to be accurate.

                           FOR i% = 0 TO 255
                             c$ = c$ + chr$(i%)
                           NEXT
                           MID$(c$,132+1) = chr$(97)

      It is most important to remember the rule for creating a collate
      string, as many programmers intuitively jump to the wrong
      conclusion.  Each position in the string (0 to 255) represents the
      ASCII code with that value.  The contents of the byte at that
      position tells the ARRAY SORT procedure the new "weight" or
      importance factor for that particular code.  This is exactly the
      technique used by the 8086 assembler opcode XLAT.  Suppose you
      just wanted chr$(0) to sort at the very end of the sequence.  To
      do that, you would set the byte at position 0 to chr$(255), then
      set the bytes at position 1 through 255 to the values 0 to 254.

      To sort upper case and lower case alphabetic letters as exactly
      equal, just set positions 97 through 122 (ASCII a-z) to the values
      65 through 90 (ASCII A-Z).  This is precisely the technique used
      internally when you specify the COLLATE UCASE option.  Remember,
      with the collate method implemented by this procedure in
      PowerBASIC, it is possible for two or more ASCII codes to have
      equal "weight".

      As mentioned earlier, many programmers make a common, fatal
      mistake by intuitively creating a collate string which is a list
      of ASCII codes in the sequence they wish to sort.  That is, they
      expect the byte which appears first in the string to sort first,
      the byte which appears next to sort second, so that creating a
      collate string from the Basic code CHR$(65)+CHR$(66)+CHR$(67)+...
      might cause the characters "ABC..." to be sorted first.  This
      technique will never work with ARRAY, and must be carefully
      avoided.  We describe it here only because it is such a common
      error.  While it is arguably more intuitive than the technique
      implemented in PowerBASIC, it could never be used as it does not
      allow two or more ASCII codes to have equal "weight".

      The following code builds a collate string compatible with the IBM
      ASCII character set for European characters.  For best results,
      you should execute this code at the beginning of your program and
      make the collate string public:

                     PUBLIC c$
                     FOR x% = 0 TO 255
                       c$ = c$ + CHR$(x%)
                     NEXT x%
                     MID$(c$,129+1,6) = "ueaaaa"      '
                     MID$(c$,136+1,9) = "eeeiiiAAE"   '
                     MID$(c$,147+1,8) = "ooouuyOU"    '
                     MID$(c$,161+1,5) = "iounN"       '
                     MID$(c$,168+1,1) = "?"           '

                     {your code here}

                     ARRAY SORT MyArray$(), COLLATE c$

      The following code builds an upper case collate string compatible
      with the IBM ASCII character set for European characters:

                     PUBLIC cu$
                     FOR x% = 0 TO 255
                       cu$ = cu$ + CHR$(x%)
                     NEXT x%
                     MID$(cu$,97+1,26) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                     MID$(cu$,129+1,6) = "UEAAAA"      '
                     MID$(cu$,136+1,9) = "EEEIIIAAE"   '
                     MID$(cu$,147+1,8) = "OOOUUYOU"    '
                     MID$(cu$,161+1,5) = "IOUNN"       '
                     MID$(cu$,168+1,1) = "?"           '

                     {your code here}

                     ARRAY SORT MyArray$(), COLLATE cu$

      If you need to capitalize a collate string for non-American or
      European character sets, starting with DOS 5.0, DOS provides an
      interrupt call which will capitalize strings for you based on your
      country code:

                  $INCLUDE "REGNAMES.INC"
                  FUNCTION DosUcase$(BYVAL Text$) PUBLIC
                    REG %AX, &H6521    'function 65h, subfunction 21h
                    REG %DS, STRSEG( Text$ )
                    REG %DX, STRPTR( Text$ )
                    REG %CX, LEN( Text$ )
                    CALL INTERRUPT &H21
                    FUNCTION = Text$
                  END FUNCTION

      Multiple Tag Arrays
      The ARRAY SORT statement allows you to specify one tag-along
      array, whose elements are sequenced in the same order as those in
      the main data array.  Obviously, there are situations where it
      would be desirable to have two, three, or even more tag-along
      arrays.  However, the high ratio of internal data movements
      required per sorted element makes this feature impractical, as the
      relative execution speed would quickly deteriorate.  Fortunately,
      there is an elegant solution, easily implemented by the PowerBASIC
      programmer.  It is highly efficient, and executes far faster than
      any intrinsic method.

      For purposes of this example, we'll presume a main data array
      a(n), and a desire to have the arrays b(n) and c(n) tag-along.  To
      implement this concept, we simply dimension one additional array
      tag%(n), set each element equal to the element number, and sort it
      as the tag-along, as is shown in the example which follows.

      Upon completion of the sort, the tag-along array tag%(n) now
      specifies the desired order for any number of multiple tag arrays.
      However, the task was completed in a much shorter time than if
      multiple tag arrays were supported directly.  To reference the
      first element of b(n) in the new order, simply use b(tag%(0)).
      It's that simple.  The example which follows would print b(n) and
      c(n) in the new, sorted sequence:

                           DIM tag%(n)
                           FOR i% = 0 TO n
                             tag%(i%) = i%
                           NEXT
                           ARRAY SORT a(), TAGARRAY tag%()
                           FOR i% = 0 TO n
                             PRINT b(tag%(i%)), c(tag%(i%))
                           NEXT


  ARRAY SCAN
      Syntax for numeric array:

      ARRAY SCAN darray([index]) [FOR count] ,operator expression, TO
      ivar

      Syntax for string array:

      ARRAY SCAN darray([index]) [FOR count] [,FROM start TO end]
                [,COLLATE {UCASE|string}] ,operator expression, TO ivar

      ARRAY SCAN allows you to scan all or part of a data array
      (darray), to find the first element which satisfies the condition
      specified by operator expression.  The operator expression
      consists of a relational operator (=, >, <, <>, >=, =>, <=, =<)
      followed by an expression of the same type as darray.  The
      relative index position of the first match (indexed to 1) is
      stored in ivar, which must be an integer or long integer variable.
      It's important to note that this value is not the array subscript
      index, but rather a number relative to the first array element
      scanned: 1 if the first element, 2 if the second, etc.  If no
      match is found, then 0 is stored in ivar.

      Together, index and count specify the portion of darray to be
      scanned.  You use index to specify the first element to scan.  If
      it is omitted, the array is scanned from the first element.  You
      use count to specify the total number of elements to scan.  If
      count is omitted, the array is scanned through the last element.
      If both are omitted, the entire array is scanned.

      COLLATE UCASE may be used with string arrays to treat all
      lowercase alphabetic characters as equal to their uppercase
      counterparts, while COLLATE string is used to specify an entirely
      new collate sequence, such as for an international character set.
      The collate string is described in greater detail under the
      description of ARRAY SORT.

      When a string array is scanned, all characters from each element
      are normally considered when performing comparisons.  Use the FROM
      and TO options to specify starting and ending character positions
      if you wish to restrict the comparisons to a subset of each
      string.  The options for ARRAY SCAN can be listed in any order, as
      long as the FOR option, if specified, directly follows the name of
      the data array.

      It is possible to scan a multi-dimensional array, but the elements
      are scanned sequentially just as they appear in memory.  Since
      PowerBASIC stores multi-dimensional arrays in column-major order,
      the array x(2,2) would appear in memory as follows:

                  x(0,0)  x(1,0)  x(2,0)  x(0,1)  x(1,1)  x(2,1)

      Use care in scanning multi-dimensional arrays, to avoid a
      misleading result.  Every array element is scanned sequentially,
      just as it is found in memory.  There is no method provided to
      "skip over" any elements, regardless of the multi-dimensional
      structure.


  ARRAY INSERT
      Syntax:  ARRAY INSERT darray([index]) [FOR count] [,expression]

      ARRAY INSERT allows you to insert a single element into a data
      array (darray), while shifting other elements up to make room for
      the new one.  You use index to specify the position where the new
      element is to be inserted.  If index is omitted, it is inserted as
      the first element.  You use count to limit the number of elements
      which will be shifted up.  If count is omitted, all higher
      elements are shifted up.  If the highest element of the array is
      to be shifted up, the value is discarded.  You use expression to
      assign a value to the new element.  If expression is omitted, 0 is
      used for numerics, while null is used for strings.


  ARRAY DELETE
      Syntax:  ARRAY DELETE darray([index]) [FOR count] [,expression]

      ARRAY DELETE allows you to delete a single element from a data
      array (darray), while shifting other elements down to compress the
      list of values.  You use index to specify the element to be
      deleted.  If it is omitted, the first element of the array is
      deleted.  You use count to limit the number of elements which will
      be shifted down.  If it is omitted, all higher elements are
      shifted down.  You use expression to assign a value to the
      highest, vacated element.  If expression is omitted, 0 is used for
      numerics, while null is used for strings.


  AS
      This is a reserved word.  It is used as part of:
        $ALIAS
        DIM
        FIELD
        MAP
        NAME
        OPEN
        TYPE
        UNION


  ASC function
      Purpose: Returns the ASCII code of a character in a string.

      Syntax:  y = ASC(string expression[, n])

      The string passed to ASC may not be a null (empty) string.  Use
      the ASCII function instead.  The optional parameter 'n' specifies
      which character in the 'string expression' whose ASCII code you
      want.  If 'n' is out of range, a run-time error occurs.

      ASC statement
      Purpose: Place a byte into an existing string.

      Syntax:  ASC(stringvariable, n) = bytevalue

      Using the ASC statement, you can change the ASCII code of any byte
      in a string.


  ASCII function
      Purpose: Returns the ASCII code of a character in a string.

      Syntax:  y = ASCII(string expression[, n])

      If the string passed to ASCII is a null (empty) string, ASCII
      returns -1, unlike ASC which will generate a run-time error.  If
      the option parameter 'n' is not specified, the ASCII code of the
      first character in the string expression is returned. If 'n' is
      out of range, a -1 is returned.


  ASM statement
      Purpose: Allows direct entry of assembler statements

      Syntax:  ASM   opcode  [operand] [,operand]
               !     opcode  [operand] [,operand]

      PowerBASIC supports assembly of all 8086/8088 opcodes directly
      from your BASIC source code.  You may reference variables, labels,
      and SUB/FUNCTION names directly, but any variables so referenced
      must be declared either explicitly (with DIM) or implicitly (by
      use in a BASIC statement).

      Any reference to a static or shared variable is assumed to be DS
      relative, while local or parameter variables are assumed to be SS
      relative.  Lastly, all references to labels or SUB/FUNCTION names
      are assumed to be CS relative, regardless of the segment.
      References to labels are assumed to be near, while SUB/FUNCTION
      calls are assumed far.

      It is possible to override segment or type assumptions with an
      explicit reference in the operand (cs/ds/es/ss, byte/word/dword,
      short/near/far):

        MOV    AL, BYTE X%[01]
        CALL   WORD PTR X&
        LES    DI, DWORD ES:X&&[BX]
        JMP    SHORT