home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / chasm1.zip / CHASM.DOC < prev   
Text File  |  1989-10-01  |  180KB  |  6,931 lines

  1.  
  2.  
  3.                                           READ
  4.                                           THIS
  5.                                          BEFORE
  6.                                         PRINTING!!!!
  7.  
  8.         This document has been formatted in a special way. Virtually all dot
  9.         matrix printers have a condensed mode which prints 132 characters
  10.         across a standard 8 1/2 inch page.  When this file is printed out in
  11.         condensed mode, the resulting printed pages can be cut down to 5 1/2 X
  12.         8 1/2 inches.  The cut pages will fit nicely in the back of your
  13.         DOS manual for storage.
  14.  
  15.         Typically, you can turn on this mode by sending a special control
  16.         sequence to the printer from BASIC.  For example, you can turn on the
  17.         condensed mode of the IBM/Epson printer with the BASIC statement:
  18.         LPRINT chr$(15).  If your printer has such a condensed mode, turn it
  19.         on now, before printing the rest of this document.
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.                                            (tm)
  76.                                       CHASM
  77.  
  78.                                  Cheap Assembler
  79.                           for the IBM Personal Computer
  80.  
  81.                                   User's Manual
  82.                     (c) 1985, 1986, 1987, 1989 by David Whitman
  83.                                   Version 4.14
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.     David Whitman
  109.     P.O. Box 1157
  110.     North Wales, PA 19454
  111.     (215) 234-4084 (evenings)
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.                       Table of Contents
  137.  
  138.  
  139.     Why CHASM?.....................................................4
  140.     What can CHASM do?.............................................5
  141.     What WON'T it do?..............................................6
  142.     System Requirements............................................7
  143.     Advanced and Subset CHASM......................................8
  144.     Modifiying CHASM's I/O Defaults................................9
  145.     Syntax........................................................14
  146.     Labels........................................................16
  147.     Operands......................................................19
  148.     Operand Expressions...........................................25
  149.     Resolution of Ambiguities.....................................28
  150.     Pseudo-Operations.............................................32
  151.     Macros........................................................41
  152.     Structures....................................................51
  153.     8087 Support..................................................55
  154.     Outside the Program Segment...................................57
  155.     Running CHASM.................................................58
  156.     Error and Diagnostic Messages.................................62
  157.     Execution of Assembled Programs...............................67
  158.     Notes for Those Upgrading to This Version of CHASM............79
  159.     Miscellaneous and A Word From Our Sponsor.....................83
  160.     Appendix A: 8088 Mnemonic List................................88
  161.     Appendix B: 8087 Mnemonic List................................90
  162.     Appendix C: Differences Between CHASM and TOA.................91
  163.     Appendix D: Description of Files..............................95
  164.     Appendix E: Bug Reporting Procedure...........................96
  165.     Appendix F: Using CHASM on "Compatible" Systems...............97
  166.     Advanced Version Order Form...................................99
  167.     Index........................................................103
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.     `.PGNO01
  202.     >>Why CHASM?<<
  203.  
  204.     Why go to the trouble to write an assembler, when one already
  205.     exists?  The IBM Macro Assembler is a very powerful software tool
  206.     available off the shelf.  It supports features such as macros,
  207.     multiple segments, and linking to external procedures.
  208.  
  209.     Unfortunately, the cost of all this power is complexity. The
  210.     Macro Assembler is so complicated that IBM warns beginners it is
  211.     only suitable for "experienced assembly language programmers".
  212.  
  213.     For most users, this sophistication is more of a hindrance than
  214.     an aid.  Even when writing short, simple programs, the user is
  215.     saddled with a set of confusing pseudo-ops only appropriate for
  216.     large, multi-segment programs.  Producing a fast loading
  217.     executable file requires running three separate programs (MASM,
  218.     LINK and EXE2BIN) before you can get down to testing.
  219.  
  220.     The macro assembler is totally unsuitable for use with BASIC.
  221.     Although it is *possible* to produce machine language BASIC
  222.     subroutines with the Macro Assembler, the process is incredibly
  223.     convoluted and confusing.
  224.  
  225.     To top it all off, the Macro Assembler costs an overpriced $125.
  226.  
  227.     CHASM is, I hope, a more reasonable compromise between power and
  228.     accessibility.  CHASM is simple to use and understand.  Unlike
  229.     the Macro Assembler, CHASM doesn't require a second LINK step to
  230.     produce a working program.  CHASM also produces fast loading
  231.     programs without the use of the utility EXE2BIN.
  232.  
  233.     CHASM supports several different simple mechanisms for getting
  234.     machine language routines into BASIC and Turbo Pascal versions 2
  235.     and 3. (Turbo Pascal versions 4 and higher require OBJ files,
  236.     which CHASM does not support.  For use with Turbo 4 or later, use
  237.     the Turbo Assembler, or MASM.)
  238.  
  239.     Finally, the suggested payment for CHASM is a modest $40.
  240.  
  241.     A Note for Beginners:
  242.  
  243.     Before going on, you might find it useful to print and read the
  244.     file PRIMER.DOC, included on your CHASM disk.  PRIMER is a gentle
  245.     introduction to assembly language, which will teach you some of
  246.     the vocabulary and key concepts you will need to start out with.
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.                                                                     6
  332.  
  333.     >>What can CHASM do?<<
  334.  
  335.     CHASM is a tool for translating assembly language into the native
  336.     machine language of the 8088 microprocessor.  Using CHASM, you
  337.     can write down easy to remember "mnemonics" which are then
  338.     converted into the relatively incomprehensible series of ones and
  339.     zeros that your PC prefers to work with.
  340.  
  341.     In addition to simple mnemonic translation (such as provided by
  342.     the mini-assembler in DEBUG), CHASM provides a great many
  343.     "convenience" features which make writing machine language much
  344.     easier.
  345.  
  346.     CHASM allows you to define labels for branching, rather than
  347.     requiring you to figure out offsets or addresses to jump to.
  348.     CHASM also lets you give symbolic names to any constants or
  349.     memory locations you use, to make your program easier to
  350.     understand.
  351.  
  352.     You can instruct CHASM to make your file "BLOADable" so that
  353.     BASIC can load it as a subroutine.   A utility is also provided
  354.     to convert machine language into BASIC "DATA" statements, so that
  355.     BASIC can "POKE" routines into memory.  Similarly, for Turbo
  356.     Pascal, CHASM can produce external procedures and functions, or a
  357.     file of Turbo "INLINE" statements.
  358.  
  359.     CHASM has intelligent error and diagnostic messages which guide
  360.     you in correcting mistakes and ambiguities in your program.  A
  361.     nicely formatted listing is produced during assembly, to help
  362.     during debugging.
  363.  
  364.     In general, CHASM is designed to eliminate much of the confusion
  365.     and dirty work involved in writing machine language for the IBM
  366.     PC.
  367.  
  368.     Using CHASM, you can produce:
  369.  
  370.        1. Lightning fast "stand-alone" programs.
  371.  
  372.        2. Machine language subroutines for BASIC programs, both
  373.           interpreted and compiled.
  374.  
  375.        3. Machine language procedures and functions for Turbo Pascal
  376.          versions 2 and 3.
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.                                                                     7
  398.  
  399.     >>What WON'T it do?<<
  400.  
  401.     In the interest of simplicity, CHASM has the following
  402.     restrictions:
  403.  
  404.     1. Multiple segment definitions are not allowed. CHASM assumes
  405.        that your entire program fits in one segment, that the cs, ds,
  406.        and es registers all point to this same segment, and that the
  407.        ss register points to a valid stack area.  An equivalent
  408.        statement is that CHASM produces COM files, not EXE files.
  409.  
  410.     2. Linking to Microsoft or Borland languages is not supported.
  411.        You can't use CHASM to produce object modules for use with
  412.        IBM/Microsoft Pascal or FORTRAN, or Borland Turbo Pascal
  413.        version 4 or later.
  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.                                                                     8
  464.  
  465.     >>System Requirements<<
  466.  
  467.     Minimum system requirements to use CHASM are:
  468.  
  469.          IBM PC or true compatible (must emulate IBM BIOS)
  470.          128K of memory            (some systems need 192K)
  471.          1 disk drive
  472.          80 column display
  473.          DOS 2.0 or later.
  474.  
  475.     Note the DOS 2 requirement.  To provide *true* DOS 2 support, it
  476.     was necessary to give up DOS 1 compatibility.  If you're still
  477.     using DOS 1, you'll need to upgrade to DOS 2.0 or later to use
  478.     CHASM.
  479.  
  480.     IBM PCjrs, and some compatibles seem to require 192K of memory.
  481.     In general, adding more memory will allow you to assemble larger
  482.     programs.  CHASM can take advantage of all available memory, up
  483.     to a megabyte.
  484.  
  485.     CHASM will run faster if your source files and object files are
  486.     on a hard disk or RAM disk.
  487.  
  488.     If you have a non-IBM computer, please read about the /VIDEO
  489.     switch in "Modifying CHASM's I/O Defaults" and also the appendix
  490.     titled "Using CHASM on Compatible Systems"
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.                                                                     9
  530.  
  531.     >>Advanced and Subset CHASM<<
  532.  
  533.     CHASM is available in two flavors, Advanced and Subset.
  534.     The two versions vary in their capabilities and method of
  535.     distribution.
  536.  
  537.     The subset version is the budget release.  It may be freely
  538.     copied by individuals as "user-supported" software, and is
  539.     available from user groups and bulletin boards across the
  540.     country.  Every time the subset runs, it prints a banner page
  541.     suggesting a payment of $40 to the author.  As its name
  542.     suggests, Subset CHASM does not support all the features of
  543.     Advanced CHASM.
  544.  
  545.     Advanced CHASM is the deluxe release.  It runs twice as fast, and
  546.     has a number of features not supported by the subset:
  547.  
  548.           macros
  549.           conditional assembly
  550.           8087 support
  551.           include files
  552.           structures
  553.  
  554.     Advanced CHASM is only available directly from Whitman Software.
  555.     Users who make the suggested $40 payment receive an upgrade to
  556.     Advanced CHASM.  Details, and an order blank are given at the
  557.     end of this document.
  558.  
  559.     Throughout this document, features supported only by the
  560.     advanced version will be marked as follows:
  561.  
  562.       ==>Advanced version only.
  563.  
  564.     Attempts to use these features in the subset version will
  565.     generally result in error messages, with the advanced feature
  566.     otherwise being ignored; however, unpredictable behavior could
  567.     result in some instances.
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.                                                                    10
  596.  
  597.     >>Modifying CHASM's I/O Defaults<<
  598.  
  599.     CHASM supports the use of a configuration file, which can be used
  600.     to override some of CHASM's I/O defaults.  If you are willing to
  601.     accept CHASM's defaults, you may skip this section - on most
  602.     systems, CHASM will work perfectly well without the file
  603.     described below.
  604.  
  605.     The configuration process involves supplying a text file named
  606.     CHASM.CFG on your default drive.  You can create this file with
  607.     any text editor or word processor.
  608.  
  609.     You have some freedom in where you put the configuration file.
  610.     If CHASM.CFG is not found in the current directory, CHASM will
  611.     also try the following paths:
  612.  
  613.           \CHASM\CHASM.CFG
  614.           \CHASM.CFG
  615.  
  616.     The file should contain a series of text "switches" of the
  617.     following form:
  618.  
  619.     /SWITCH, xx [, yy, zz,...]
  620.  
  621.     Where "/SWITCH" is a reserved word, listed below, and xx, yy, zz
  622.     are numbers.  The brackets around yy and zz indicate that these
  623.     numbers are optional - don't put brackets in CHASM.CFG.
  624.  
  625.     Each switch should start a new line, and the switch and each of
  626.     the numbers should separated by one or more blanks or commas.
  627.  
  628.     The following switches are implemented:
  629.  
  630.     /VIDEO      Video access method.  With this switch, you can
  631.                 control the method CHASM uses to write data on your
  632.                 video screen.  Three settings are currently
  633.                 supported:
  634.  
  635.                 /VIDEO 0  Direct write to screen memory.
  636.  
  637.                 /VIDEO 1  Direct write to screen memory, but only
  638.                           during the horizontal retrace interval.
  639.  
  640.                 /VIDEO 2  Write using BIOS calls.
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.                                                                    11
  662.  
  663.     /VIDEO      (continued) In general, the lower a number you
  664.                 specify for /VIDEO, the faster CHASM will run.
  665.  
  666.                 /VIDEO 0 is the fastest mode, and is intended for use
  667.                 with either the IBM monochrome display adapter or the
  668.                 EGA adapter.  You can use /VIDEO 0 with the CGA
  669.                 adapter, but some annoying "snow" and flicker may
  670.                 result.
  671.  
  672.                 /VIDEO 1 is intended for use with the CGA adapter.
  673.                 It is almost as fast as /VIDEO 0, and the snow is
  674.                 eliminated.  /VIDEO 1 is CHASM's default mode.
  675.  
  676.                 /VIDEO 2 is intended for non-IBM systems that emulate
  677.                 the IBM BIOS, but have significantly different screen
  678.                 hardware.  If you have trouble running CHASM on a
  679.                 "compatible" system, try setting /VIDEO 2.  Use of
  680.                 /VIDEO 2 will slow CHASM down significantly.
  681.  
  682.     /FG         Foreground color.  Users with color monitors may
  683.                 select a foreground color from the following list:
  684.  
  685.                 0    Black               8    Gray
  686.                 1    Blue                9    Light Blue
  687.                 2    Green              10    Light Green
  688.                 3    Cyan               11    Light Cyan
  689.                 4    Red                12    Light Red
  690.                 5    Magenta            13    Light Magenta
  691.                 6    Brown              14    Yellow
  692.                 7    White              15    High Intensity White
  693.  
  694.                 Example: (Magenta)
  695.  
  696.                 /FG 5
  697.  
  698.     /BG         Background color.  Selections 0-7 above are
  699.                 available. Example: (Cyan)
  700.  
  701.                 /BG, 3
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.                                                                    12
  728.  
  729.  
  730.     /132        Printer 132 column mode.  The numbers following this
  731.                 switch are the ASCII codes for the characters which
  732.                 cause your printer to go into condensed mode.  You
  733.                 may specify as many characters as you like.  If you
  734.                 don't provide this switch, CHASM will truncate source
  735.                 lines in listings to avoid going over 80 columns. You
  736.                 can also include characters to activate any special
  737.                 features of your printer you want CHASM to use during
  738.                 printing.  Example: (for IBM printer)
  739.  
  740.                 /132, 15
  741.  
  742.     /80         Printer 80 column mode.  Similar to /132, but the
  743.                 numbers represent the characters to return your
  744.                 printer to normal.  Include the codes for any
  745.                 characters you want CHASM to send to your printer
  746.                 before returning you to DOS.  The following example
  747.                 turns off condensed mode and causes a Form Feed on
  748.                 the IBM printer:
  749.  
  750.                 /80, 18, 12
  751.  
  752.     /FF         Formfeed.  A value of zero tells CHASM that your
  753.                 printer doesn't recognize ASCII 12 as a formfeed
  754.                 command.  Any other value, and CHASM assumes that
  755.                 formfeeds will be recognized.  The default is no
  756.                 formfeed character.
  757.  
  758.                 If /FF is off, CHASM will simulate formfeeds with a
  759.                 series of linefeeds.  However, most printers respond
  760.                 quicker to a formfeed than to multiple line feeds, so
  761.                 set /FF on if possible.  Example: (on)
  762.  
  763.                 /FF 1
  764.  
  765.     /PAGELEN    CHASM assumes that there are 66 lines to each printed
  766.                 page.  If you use different sized paper, enter the
  767.                 number of lines per page after this switch.
  768.                 Example: (European standard)
  769.  
  770.                 /PAGELEN 72
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.                                                                    13
  794.  
  795.  
  796.     /LINES      By default, CHASM will print 58 lines on each printed
  797.                 page, then skip over the perforation to the next
  798.                 page.  You can change this number to suit your paper
  799.                 and personal taste.  Example:
  800.  
  801.                 /LINES 50
  802.  
  803.     /BEEP       Enables/Disables audible warning when errors are
  804.                 discovered in your source program.  The following
  805.                 values are supported: (default is 1)
  806.  
  807.                 /BEEP 0      (no beeping)
  808.                 /BEEP 1      (beep for all errors/diagnostics)
  809.                 /BEEP 2      (beep only for FIRST error/diagnostic)
  810.  
  811.      /DWIDTH    When listing to a disk file, CHASM normally truncates
  812.                 listing lines to 80 columns to prevent wrap-around
  813.                 when viewing the file.  In some instances, such as
  814.                 disk-based print spooling with DOS's PRINT utility,
  815.                 you may wish to override this truncation.  You can
  816.                 enter a new truncation limit after this switch.
  817.                 Example: (128 column lines)
  818.  
  819.                 /DWIDTH 128
  820.  
  821.      /DPAGE     For easier scanning, listings sent to disk files do
  822.                 not normally contain page breaks.   If you want to
  823.                 produce printable listing files, you can turn on page
  824.                 breaks by setting /DPAGE to any value other than
  825.                 zero.  Example: (page breaks on)
  826.  
  827.                 /DPAGE 1
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.                                                                    14
  860.  
  861.  
  862.       /PATH     Path Strategy.  Affects the way CHASM constructs the
  863.                 default file names for list and object files.  If
  864.                 /PATH is set to 0 (the default), any drive or path
  865.                 specified on the source file name will be included in
  866.                 the default file names.  If /PATH is set to anything
  867.                 else, path and drive info are removed, thus putting
  868.                 the default list and object files in the current
  869.                 directory of the logged drive.  The following table
  870.                 shows how this works:
  871.  
  872.                 /PATH | Source filename   | Default object file
  873.                 ------|-------------------|-------------------------
  874.                    0  | a:\chasm\test.asm |   a:\chasm\test.com
  875.                    1  | a:\chasm\test.asm |   test.com
  876.  
  877.                 /PATH only affects how the default file names are
  878.                 constructed - CHASM won't edit filenames that you
  879.                 explicitly type in.
  880.  
  881.      /TIMER     Enables/Disables reporting of total assembly time. A
  882.                 value of 0 turns off timing, anything else turns it
  883.                 on.  The default is off.  This switch is used
  884.                 internally at Whitman Software to benchmark new
  885.                 versions of CHASM.
  886.  
  887.     A sample CHASM.CFG file, suitable for use with the IBM dot matrix
  888.     printer, is included on your CHASM distribution disk.
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.                                                                    15
  926.  
  927.     >>Syntax<<
  928.  
  929.     CHASM accepts a standard DOS text file for input.  In this
  930.     context, "standard DOS text file" means:
  931.  
  932.         1. Lines are terminated with a CR/LF pair.
  933.  
  934.         2. The end of the file is marked with an EOF marker (cntl-Z).
  935.  
  936.     Virtually every word processor or editor produces files which
  937.     meet these criteria.  Some word processors have to be in a
  938.     special mode to produce standard DOS files.  (For example, in
  939.     WordStar, you have to be in "non-document" mode.) The user's
  940.     manual for your editor should inform you if any special mode
  941.     needs to be activated.
  942.  
  943.     Some users have reported problems with the user-supported word
  944.     processor PC-Write.  Under certain circumstances, older
  945.     versions of PC-Write can produce lines ending with just a LF
  946.     (violation of rule 1) or files which aren't terminated with an
  947.     EOF marker (violation of rule 2).  If you use PC-Write, make sure
  948.     you have the latest version.
  949.  
  950.     Lines may be any combination of upper and lower case characters.
  951.     CHASM does not distinguish between the two cases: everything
  952.     except single quoted strings are automatically converted to upper
  953.     case during the parsing process.  Thus, BUFFER, Buffer, buffer,
  954.     and bUFFer all refer to the same symbol.
  955.  
  956.     The characters  blank ( ), comma (,), single quote (') semi-colon
  957.     (;) and TAB are reserved, and have special meaning to CHASM (see
  958.     below).  The characters + - * / ) ( are reserved for use as
  959.     operators in expressions.
  960.  
  961.     Each line must be no more than 80 characters long and have the
  962.     following format:
  963.  
  964.        Label Operation Operand(s) ;comment
  965.  
  966.     The different fields of an input line are separated by the
  967.     delimiters blank ( ), comma (,) or TAB.  Any number of any
  968.     delimiter may be used to separate fields.
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.                                                                    16
  992.  
  993.     Explanation of Fields:
  994.  
  995.     Label: A label is a string of characters, beginning in column 1.
  996.        Depending on the operation field, the label might represent a
  997.        program location for branching, a memory location, or a
  998.        numeric constant (see the section titled "Labels" for more on
  999.        this topic). No reserved characters can appear within the
  1000.        label, and to ensure that CHASM can distinguish between labels
  1001.        and numeric constants, the first character of a label must
  1002.        *not* be a numeric (i.e. 0-9). Anything beginning in column 1,
  1003.        except a comment, is considered a label.
  1004.  
  1005.     Operation: Either a pseudo-op (see the section with the same
  1006.        name) or an instruction mnemonic as defined in "The 8086
  1007.        Book" by Rector and Alexy.  A list of acceptable mnemonics is
  1008.        given in Appendix A.
  1009.  
  1010.        Note 1: Except as modified below,"The 8086 Book" is the
  1011.           definitive reference for use with CHASM.
  1012.  
  1013.        Note 2: There are several ways to resolve some ambiguities in
  1014.           8086 assembly language.  Please read page 3-285 of The 8086
  1015.           Book, and "Resolution of Ambiguities" in this document.
  1016.  
  1017.     Operand(s): A list of one or more operands, as defined in
  1018.        the section titled "Operands", separated by delimiters.
  1019.  
  1020.     Comment: Any string of characters, beginning with a semicolon
  1021.        (;). Anything to the right of a semicolon will be ignored by
  1022.        CHASM.
  1023.  
  1024.     Note that except for the case of an operation which requires
  1025.     operands, or the EQU pseudo-op which requires a label, all of the
  1026.     fields are optional.  The fields MUST appear in the order shown.
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.                                                                    17
  1058.  
  1059.     >>Labels<<
  1060.  
  1061.     The symbol in the label field of an input line can be interpreted
  1062.     in four different ways by CHASM:
  1063.  
  1064.       1. A program location which may be branched to.
  1065.  
  1066.       2. A memory location for data storage.
  1067.  
  1068.       3. An equated symbol, which takes the place of a numeric
  1069.          constant.
  1070.  
  1071.       4. A macro name, which takes the place of a series of
  1072.          frequently used source code lines.
  1073.  
  1074.     The default interpretation of a symbol is a program location for
  1075.     branching.  This default is modified by the presence of one of
  1076.     the following pseudo-ops in the instruction field:
  1077.  
  1078.     DB, DS, or DW:
  1079.  
  1080.           Normal:  The symbol is a memory location.
  1081.  
  1082.           In a Structure: The symbol is a numeric constant.
  1083.  
  1084.     EQU:
  1085.  
  1086.           Normal:  The symbol is a numeric constant.
  1087.  
  1088.           Memory Option:  The symbol is a memory location.
  1089.  
  1090.     MACRO:
  1091.          The symbol is a macro name.
  1092.  
  1093.     A given symbol may have only ONE of the above interpretations!
  1094.     Attempts to branch into a memory location or an equated symbol
  1095.     will result in error messages.  Similarly, CHASM will not allow
  1096.     you to treat program code as a data area.  Examples:
  1097.  
  1098.     TEXT DB  'Hit any key when ready'  ;memory location
  1099.          MOV  AL,TEXT                  ;ok
  1100.          JMP  TEXT                     ;wrong!
  1101.     LOOP MOV  AX,CX                    ;program location
  1102.          JMP  LOOP                     ;ok
  1103.          MOV  AX, LOOP                 ;wrong!
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.                                                                    18
  1124.  
  1125.     If for some arcane reason you *need* to branch into a data area,
  1126.     you can fool CHASM by placing a label on an otherwise blank line,
  1127.     immediately before the data area.  Example:
  1128.  
  1129.           JNZ NPU
  1130.           RET
  1131.     NPU                                ;dummy label for jump
  1132.           DB  D8H, 00H                 ;an 8087 instruction
  1133.  
  1134.     If you have a masochistic urge to crash your system by writing
  1135.     self-modifying code, there are at least two ways you can defeat
  1136.     CHASM's injunction against using program code as a data area.
  1137.  
  1138.     The first way is to use DS to declare zero bytes of storage
  1139.     immediately before the code you want to access.  A label on the
  1140.     null DS will have the same offset as the immediately following
  1141.     code.  Example:
  1142.  
  1143.            MOV   JUNK1, 9090         ;change endless loop to NOP
  1144.     JUNK1  DS    0
  1145.     JUNK   JMP  JUNK
  1146.  
  1147.     A sneakier approach is to load the OFFSET of a program
  1148.     location into a register, then use the register for indirect
  1149.     addressing. Using the optional displacement field, you can even
  1150.     address the middle of an instruction.  Examples:
  1151.  
  1152.            MOV   BX, OFFSET(CALL)
  1153.            MOVB  1[BX], 00H          ;change interrupt number in code
  1154.     CALL   INT   0
  1155.  
  1156.     In general, I cannot recommend trying to get around CHASM's type
  1157.     restrictions.  If you find yourself in a situation where it
  1158.     seems necessary to fool CHASM, there's probably a safer, more
  1159.     direct way to legally program what you're trying to accomplish.
  1160.  
  1161.     Labels can be up to 80 characters long, but only the first 15
  1162.     characters are significant.  For example, CHASM considers the
  1163.     following labels identical:
  1164.  
  1165.        VERYLONGLABELOVER15CHARACTERS
  1166.        VERYLONGLABELOVER
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.                                                                    19
  1190.  
  1191.     To avoid ambiguity, a given string can legally appear in the
  1192.     label field of only ONE statement.  If the same string appears on
  1193.     more than one instruction, all instances after the first will
  1194.     receive an error message.  Remember that labels are only
  1195.     significant to 15 characters, and if the first 15 characters are
  1196.     identical, an error will occur.
  1197.  
  1198.     TWO   EQU  '2'      ;first use is ok
  1199.     TWO   PROC FAR      ;wrong! symbol already defined
  1200.  
  1201.     CHASM has a number of reserved strings which are "predefined" in
  1202.     the symbol table, and will generate an error message if used as
  1203.     labels.  All the register names are reserved, as are the indirect
  1204.     address mode combinations.  The only other reserved strings are
  1205.     the words "NEAR" and "FAR", and the symbol "$". Examples:
  1206.  
  1207.     AX   MOV  AX, DX      ;wrong! (register name)
  1208.     [DI] ADD  AX, BX      ;wrong! (indirect address)
  1209.     FAR  CALL GETINPUT    ;wrong! (reserved word)
  1210.     $    SUB  AX, DX      ;wrong! (reserved word)
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.                                                                    20
  1256.  
  1257.     >>Operands<<
  1258.  
  1259.     The following operand types are allowed.
  1260.  
  1261.     1. Immediate data: A number, stored as part of the program's
  1262.        object code.  Immediate data are classified as either byte,
  1263.        expressible as an 8 bit binary integer; or word, expressible
  1264.        as a 16 bit binary integer.  If context requires it, CHASM
  1265.        will left-pad byte values with zeroes to convert them to word
  1266.        values.  Attempts to use a word value where only a byte will
  1267.        fit will cause an error message to be printed.
  1268.  
  1269.        Immediate data may be represented in 9 ways:
  1270.  
  1271.           A. An optionally signed decimal number in the range -32768
  1272.              to 32767.  Examples:
  1273.  
  1274.              MOV AL, 21
  1275.              MOV BX, -6300
  1276.  
  1277.           B. A series of up to 4 hex digits, followed by the letter
  1278.              H.  The first digit must be non-alphabetic, i.e. in the
  1279.              range 0-9, to allow CHASM to distinguish between numbers
  1280.              and symbols. If necessary, a leading zero, which does
  1281.              not count in the four allowed digits, may be added to
  1282.              fulfill the non-alphabetic condition.
  1283.  
  1284.              If a hex number starts with a digit in the range A-F,
  1285.              without a leading zero, a syntax error will result, and
  1286.              CHASM will usually offer the following diagnostic:
  1287.  
  1288.              ***Diagnostic: Add leading zero to hex constant
  1289.  
  1290.              To correct the problem, just add a zero on the front of
  1291.              the number.
  1292.  
  1293.              If the RADIX pseudo-op has been used to change the
  1294.              default number base to 16, the final H can optionally be
  1295.              omitted.  Examples:
  1296.  
  1297.              ADD   CX, 0B123H   ;leading zero required
  1298.              RADIX 16           ;change default number base
  1299.              ADD   DL, 12       ;same as 12H
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.                                                                    21
  1322.  
  1323.          C.  A series of up to 16 binary digits, followed by the
  1324.              letter B.  Examples:
  1325.  
  1326.              MASK   EQU   00000111B
  1327.                     MOV   AL, 10000000B
  1328.  
  1329.           D. A symbol representing types A, B or C above, defined
  1330.              using the EQU pseudo-op.  Examples:
  1331.  
  1332.              MASK EQU 10H
  1333.              MAX  EQU 1000
  1334.                   AND  CL,MASK
  1335.                   SUB  AX,MAX
  1336.  
  1337.           E. The offset of a label or storage location returned by
  1338.              the OFFSET operator.  OFFSET always returns a word
  1339.              value. OFFSET is used to get the address of a named
  1340.              memory location, rather than its contents.  Example:
  1341.  
  1342.                     MOV DI,OFFSET(BUFFER)
  1343.              BUFFER DS  0FFH
  1344.  
  1345.           F. The ASCII value of a printable character, represented by
  1346.              the character enclosed in single quotes (').  Thus, the
  1347.              following lines will generate the same object code:
  1348.  
  1349.                 MOV AL,41H  ;ascii code for 'A'
  1350.                 MOV AL,'A'
  1351.  
  1352.           G. When producing Turbo Pascal INLINE code, the function
  1353.              TURBO(x) assembles as 16 bit immediate data.
  1354.  
  1355.           H. ==>Advanced version only:
  1356.              Labels within structures become immediate operands whose
  1357.              values equal their offset within the structure.  See the
  1358.              section titled "Structures" for more detail and
  1359.              examples.
  1360.  
  1361.           I. ==>Advanced version only:
  1362.              The length of a structure, returned either by the LENGTH
  1363.              operator, or simply the structure's name.  See the
  1364.              section titled "Structures" for more detail and
  1365.              examples.
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.                                                                    22
  1388.  
  1389.           J. An expression that evaluates out to type Immediate.
  1390.              Examples:
  1391.  
  1392.                     MOV AX, (3+2)*5
  1393.                     MOV DX, MEMLOC1-MEMLOC2
  1394.  
  1395.              See the "Operand Expressions" section for more details.
  1396.  
  1397.     Note: Certain word length 8088 instructions taking immediate data
  1398.     have a special "sign extended" version which saves one byte of
  1399.     object code if the immediate data can be expressed in 8 bits.
  1400.     You can add an "S" suffix to instructions ADC, ADD, CMP, SBB and
  1401.     SUB to force CHASM to use the shorter, sign extended version of
  1402.     these instructions.  A syntax error will occur if you use the "S"
  1403.     suffix with immediate data larger than FFH.
  1404.  
  1405.     Since the "S" suffix is only meaningful with word length
  1406.     instructions, you don't need a "W" suffix to resolve ambiguous
  1407.     memory references.
  1408.  
  1409.     Most users can safely ignore this note.  However, using the "S"
  1410.     suffix allows you to save a few bytes to pare your object code
  1411.     down to the absolute minimum size.
  1412.  
  1413.     Examples:
  1414.  
  1415.           ADD   CX, 10H    ;16 bit immediate data
  1416.           ADDS  CX, 10H    ;8 bit sign extended version saves 1 byte
  1417.           SUBW  [DI], 2FH  ;16 bit reference with 16 bit data
  1418.           SUBS  [DI], 2FH  ;no "W" needed: 16 bit ref, 8 bit data
  1419.  
  1420.     2. Register Operands
  1421.  
  1422.        A. An 8 bit 8088 register from the following list:
  1423.           AH    AL
  1424.           BH    BL
  1425.           CH    CL
  1426.           DH    DL
  1427.  
  1428.        B. A 16 bit 8088 register from the following list:
  1429.  
  1430.           AX   BX   CX   DX   SP   BP   SI   DI
  1431.  
  1432.        C. An 8088 segment register from the following list:
  1433.  
  1434.           CS   SS   DS   ES
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.                                                                    23
  1454.  
  1455.  
  1456.  
  1457.  
  1458.        D. An 8087 stack register from the following list:
  1459.  
  1460.           ST ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7)
  1461.  
  1462.           Note: ST can also be referenced as ST(0).
  1463.  
  1464.     3. Memory Operands: The contents of a memory location addressed
  1465.        by one of the following methods.  Note that none of the memory
  1466.        addressing options specifies the *size* of the operand.  8088
  1467.        instructions have word or byte sized operands, and 8087
  1468.        instructions can have word, short, long or temporary real
  1469.        operands.  See the section titled "Resolution of Ambiguities"
  1470.        for more on this topic.
  1471.  
  1472.        All memory operands can optionally be preceded with a segment
  1473.        override to specify the segment register to be used in
  1474.        accessing memory.  The override takes the form of a segment
  1475.        register, followed by a colon, followed by the memory operand.
  1476.        No intervening delimiters are allowed.  Examples:
  1477.  
  1478.             MOV AX, ES:[80H]   ;80H into the extra segment
  1479.             MOV CS:[DI], SI     ;indirect with DI in the code segment
  1480.  
  1481.        Segment overrides are also discussed in the section titled
  1482.        "Resolution of Ambiguities".
  1483.  
  1484.        A. Direct Memory Address.
  1485.  
  1486.           1. A number or other immediate operand, enclosed in
  1487.              brackets, indicating an offset into the data segment.
  1488.              Example:
  1489.  
  1490.              BUFFER EQU 5A5AH
  1491.                     MOV BH, [BUFFER]
  1492.                     MOV [80H], DI
  1493.                     MOV AX, CS:[TURBO(I)]
  1494.  
  1495.           2. A symbol, defined to be a variable (i.e. a named memory
  1496.              location) using the EQU pseudo-op.  Example:
  1497.  
  1498.              FCB EQU [80H]
  1499.                  MOV DI,FCB
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.                                                                    24
  1520.  
  1521.  
  1522.  
  1523.  
  1524.           3. A symbol, defined to be a variable by its use on a
  1525.              storage defining pseudo-op.  Examples:
  1526.  
  1527.                   MOV AX,FLAG
  1528.                   MOV DATE,BX
  1529.              FLAG DS 1
  1530.              DATE DB 31
  1531.  
  1532.           4. The special symbol '$'.  $ returns an address of value
  1533.              equal to the current setting of CHASM's location
  1534.              counter.  This address can be used as either a memory
  1535.              location or a program location for branching.  Used by
  1536.              itself, $ has little utility, but it is a very powerful
  1537.              tool when used in expressions.  Example:
  1538.  
  1539.                   MOV AX, $+4    ;get the byte after this instruction
  1540.  
  1541.           5. An expression that evaluates out to type address.
  1542.              Example:
  1543.  
  1544.                     MOV AX, buffer+3
  1545.              BUFFER DS 20
  1546.  
  1547.              See the "Operand Expressions" section for more details.
  1548.  
  1549.  
  1550.        B. Indirect Memory Address:  The address of the operand is the
  1551.           sum of the contents of the indicated register(s) and a
  1552.           displacement.  The register, or sum of registers, are
  1553.           enclosed in square brackets: []
  1554.  
  1555.           The displacement is optional, and takes the form of either
  1556.           an immediate operand or the label of a memory location,
  1557.           placed without intervening delimiters to the left of the
  1558.           first bracket.
  1559.  
  1560.           Immediate data written as decimal numbers, with values
  1561.           between 127 and -128 generate a signed 8 bit offset.
  1562.           Values outside this range, or those expressed in some
  1563.           other manner generate 16 bit offsets.
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.                                                                    25
  1586.  
  1587.           The following indirect modes are provided:
  1588.  
  1589.           1. Indirect through a base register (BX or BP).  Examples:
  1590.  
  1591.              ENTRYLENGTH EQU 6
  1592.                          MOV AX, ENTRYLENGTH[BP]
  1593.                          MOV DL, -2[BX]
  1594.                          MOV CX, TURBO(COUNT)[BP]
  1595.                          MOV MEMLOC[BX], AX
  1596.              MEMLOC      DB  00H
  1597.  
  1598.           2. Indirect through an index register (DI or SI).
  1599.              Examples:
  1600.  
  1601.              MOV [DI], CX
  1602.              MOV CX, -5[SI]
  1603.  
  1604.           3. Indirect through the sum of one base register and one
  1605.              index register.  Examples:
  1606.  
  1607.              MOV [BP+DI], SP      ;note that no spaces are
  1608.              MOV BX, 10H[BX+SI]   ;allowed within the
  1609.              MOV CL, [BP+SI]      ;brackets.
  1610.              MOV DH, -2[BX+DI]
  1611.  
  1612.     4. Labels
  1613.  
  1614.        A label on most instructions may be used as an operand for
  1615.        call and jump instructions.  See the section titled "Labels"
  1616.        for more information.  Examples:
  1617.  
  1618.        START    PROC NEAR
  1619.                 CALL GETINPUT
  1620.                 JMPS START
  1621.                 ENDP
  1622.        GETINPUT PROC NEAR
  1623.  
  1624.     5. Strings
  1625.  
  1626.        A string is any sequence of characters (including delimiters)
  1627.        surrounded by single quotes (').  If you want to use the
  1628.        single quote character inside a string, put two of them
  1629.        in a row for each one you want in the string. Example:
  1630.  
  1631.        DB 'This is a ''string'' with embedded quotes'
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.                                                                    26
  1652.  
  1653.     >>Operand Expressions<<
  1654.  
  1655.     CHASM can perform arithmetic calculations at assemble time, to
  1656.     help you generate memory addresses and immediate data constants.
  1657.  
  1658.     The following operand types can participate in operand
  1659.     expressions:
  1660.  
  1661.          immediate data
  1662.          program locations
  1663.          data storage locations
  1664.  
  1665.     Actually, for the purpose of expression evaluation, CHASM treats
  1666.     both program locations and data storage locations identically.
  1667.     Thus, really only two types of operands are allowed in
  1668.     expressions: immediate and address.
  1669.  
  1670.     Symbols standing for immediate operands must have been defined
  1671.     prior to use in an expression, or you may get Phase Errors (see
  1672.     the error message section for a discussion on this topic).  You
  1673.     should put all your EQU and STRUC pseudo-ops at the beginning of
  1674.     your program, before any machine instructions.
  1675.  
  1676.     The following arithmetic operators are available:
  1677.  
  1678.          +  addition
  1679.          -  subtraction
  1680.          *  multiplication
  1681.          /  integer division
  1682.  
  1683.     Note that / performs *integer* division.  5/2 evaluates to 2.
  1684.  
  1685.     The normal rules of precedence apply.  To force evaluation
  1686.     contrary to normal precedence, you can use parenthesis: ().
  1687.  
  1688.          MOV AX  2+5*3   ;means mov ax, 17 because * outranks +
  1689.          MOV AX, (2+5)*3 ;means mov ax, 21
  1690.  
  1691.     No delimiters can appear within an expression.  If you separate
  1692.     the parts of an expression with delimiters, CHASM will try to
  1693.     interpret each part as a separate operand.
  1694.  
  1695.          MOV [BX], BUFFER + 3    ;WRONG!!
  1696.          MOV [BX], BUFFER+3      ;ok
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.                                                                    27
  1718.  
  1719.     The type of an operand expression is determined by the individual
  1720.     operand types that are combined within it.  In evaluating each
  1721.     operation in an expression, the result type follows this rule:
  1722.  
  1723.          If the two operand types are the same, the result type is
  1724.          IMMEDIATE.
  1725.  
  1726.          If the two operand types are different, the result type is
  1727.          an ADDRESS.
  1728.  
  1729.     In expressions, both program locations and data storage locations
  1730.     are considered identical.  An expression which evaluates to type
  1731.     address can be used in either a MOV or a JMP.
  1732.  
  1733.     The result type of a complicated expression is determined by
  1734.     replacing individual binary operations with their result, and
  1735.     evaluating the (simpler) expression thus formed, following the
  1736.     above rules.
  1737.  
  1738.     Here's a program fragment with some expressions, and a discussion
  1739.     of their types and significance:
  1740.  
  1741.     EXPSAMPLE PROC  NEAR
  1742.               MOV   AX, 3+5         ;immediate, calculated value
  1743.               MOV   DX, STRING-END  ;immediate, length of string
  1744.               MOV   STRING+5, 'A'   ;address, fifth byte of string
  1745.               JMP   EXPSAMPLE+100H  ;address, used as program loc.
  1746.               JMP   STRING+100H     ;valid address syntax, but silly
  1747.     STRING    DB    'MESSaGE'       ;data area
  1748.     END                             ;marks position of end of string
  1749.  
  1750.  
  1751.     The special symbol '$' returns the current value of CHASM's
  1752.     location counter for use in expressions.  $ is of type address.
  1753.     Thus, $-1 is the address of the byte immediately prior to the
  1754.     instruction currently being assembled.
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.                                                                    28
  1784.  
  1785.     The rules for typing expressions were set up to produce the "most
  1786.     useful" result type, taking a guess as to why one would want to
  1787.     do a given calculation.  If the type isn't what you have in mind,
  1788.     you can coerce CHASM using square brackets or the OFFSET
  1789.     function:
  1790.  
  1791.           MOV AX, 3+5              ;immediate
  1792.           MOV AX, [3+5]            ;coerced to address
  1793.           MOV DX, $+4              ;address
  1794.           MOV DX, OFFSET($+4)      ;coerced to immediate
  1795.  
  1796.     Under certain circumstances, CHASM can get confused when you use
  1797.     OFFSET or LENGTH functions in expressions.  The problem occurs if
  1798.     the expression starts with a function, and ends with a close
  1799.     parenthesis:
  1800.  
  1801.           MOV AX, OFFSET(BUFFER)*(3+2)    ;will be misinterpreted
  1802.  
  1803.     CHASM will try to interpret this as the offset of "BUFFER)*(3+2",
  1804.     and you'll get the error message "Illegal or undefined argument
  1805.     for OFFSET".  The solution is to enclose the whole works in
  1806.     parenthesis, to force CHASM to recognize it as an expression:
  1807.  
  1808.           MOV AX, (OFFSET(BUFFER)*(3+2))  ;correct
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.                                                                    29
  1850.  
  1851.     >>Resolution of Ambiguities<<
  1852.  
  1853.     The language defined in "The 8086 Book" contains a number of
  1854.     ambiguities which must be resolved by an assembler.  This is
  1855.     discussed throughout the book, but pages 3-285 and 3-286
  1856.     specifically cover this topic.  CHASM's solutions of these
  1857.     problems are discussed in this section.
  1858.  
  1859.     A. 8088 Memory references:
  1860.  
  1861.     When one specifies the address of a memory location, it is
  1862.     unclear how large an operand is being referenced.  An operand
  1863.     might be a byte, or a word.
  1864.  
  1865.        1. If a register is present as an operand, it is assumed that
  1866.           the memory operand matches the register in size.  An
  1867.           exception to this rule are the shift and rotate
  1868.           instructions, where the CL register is used as a counter,
  1869.           and has nothing to do with the size of the other operand.
  1870.           Examples:
  1871.  
  1872.           MOV MASK, AX  ;mask is a word
  1873.           MOV DH, [BX]  ;BX points to a byte
  1874.           NEG [SI]      ;error, operand of unknown size
  1875.           SHR FLAG, CL  ;error, flag is of unknown size
  1876.  
  1877.        2. If no register is present, (or if the only register is CL
  1878.           being used as a counter) the size of the memory operand is
  1879.           specified by adding the suffix "B" or "W" to the
  1880.           instruction mnemonic.  Examples:
  1881.  
  1882.           NEGB [SI]        ;SI points to a byte
  1883.           SHRW FLAG, CL    ;flag is a word
  1884.           MOVW MASK, 0AH   ;mask is a word
  1885.           MOVB MASK, 0AH   ;mask is a byte
  1886.           MOVW MASK, 9A9AH ;must specify size even though
  1887.                            ;immediate operand implies word
  1888.  
  1889.     You don't need to use a "W" suffix if an "S" suffix was used to
  1890.     indicate a 16 bit operation which uses a sign extended 8 bit data
  1891.     byte.   See the Operand section of this manual for a discussion
  1892.     of the "S" suffix for assembling certain instructions in their
  1893.     sign extended form.
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.                                                                    30
  1916.  
  1917.     B. 8087 Memory References:
  1918.  
  1919.        All real and integer 8087 memory references are ambiguous as
  1920.        to the operand size.  Integer operands could be word, short,
  1921.        or long.  Reals can be short, long or temporary real.  As with
  1922.        8088 memory references, you specify the size using a suffix:
  1923.  
  1924.              W: word
  1925.              S: short
  1926.              L: long
  1927.              T: temporary real
  1928.  
  1929.        For more details and examples, see the section on 8087
  1930.        support.
  1931.  
  1932.     C. Indirect Branching.
  1933.  
  1934.     The 8088 supports two flavors of indirect branching: intra, and
  1935.     intersegment.  A register is set to point at a memory location
  1936.     which contains a new value for the program counter, and in the
  1937.     case of intersegment branching, a new value for the CS register
  1938.     as well.
  1939.  
  1940.     The syntax of "The 8086 Book" does not specify which flavor of
  1941.     branch is being invoked.  CHASM adds the suffixes "N" (for near,
  1942.     or intrasegment) and "F" (for far, or intersegment) to the
  1943.     indirect CALL and JMP mnemonics.  Examples:
  1944.  
  1945.        CALLN [BX]    ;intrasegment call
  1946.        JMPF  [DI]    ;intersegment jump
  1947.        JMP   [BP]    ;error, unspecified flavor
  1948.  
  1949.     D. Long and Short Jumps
  1950.  
  1951.     Two types of relative jumps are supported by the 8088: short
  1952.     (specified by a signed 8 bit displacement) and long (specified by
  1953.     a 16 bit displacement).  Both are implemented in CHASM as a jump
  1954.     to a label.
  1955.  
  1956.     The short jump is specified by mnemonic JMPS. Since one of the
  1957.     displacement bits is used to indicate direction, only seven are
  1958.     left to express the magnitude of jump.  JMPS (and similarly, all
  1959.     the jump on condition instructions) is thus limited to branching
  1960.     to labels within a range of -128 to +127 bytes.
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.                                                                    31
  1982.  
  1983.     CHASM reserves mnemonic JMP for the long jump.  JMP may be used
  1984.     to jump anywhere within the program segment, but the object code
  1985.     generated is less compact than that from JMPS.
  1986.  
  1987.     Examples:
  1988.  
  1989.        START PROC NEAR
  1990.              JMPS END     ;short jump
  1991.              JMP  START   ;long jump
  1992.        END   ENDP
  1993.  
  1994.  
  1995.     E. Instruction Prefixes.
  1996.  
  1997.     The 8088 supports three instruction prefixes:
  1998.  
  1999.        1. SEG: segment override. An alternate segment register is
  2000.           specified for a reference to memory.
  2001.  
  2002.        2. REP, REPE,REPNE,REPZ,REPNZ: repeat. A string primitive is
  2003.           repeated until a condition is met.
  2004.  
  2005.        3. LOCK: Turns on the LOCK signal. Only useful in
  2006.           multi-processor situations.
  2007.  
  2008.     SEG is implemented as a modifier attached to a memory operand.
  2009.     If you want to override the default segment register for a memory
  2010.     access, precede the memory operand with the segment register
  2011.     followed by a colon.  Examples:
  2012.  
  2013.        MOV AX, ES:FLAG     ;flag is in the extra segment
  2014.        MOV CS:[100H], DX   ;offset 100H in the code segment
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.                                                                    32
  2048.  
  2049.     The other prefixes are implemented as separate instructions. They
  2050.     appear on a separate line, immediately before the instruction
  2051.     which they modify.  For compatibility with earlier versions of
  2052.     CHASM, you can also specify segment overrides on a separate line,
  2053.     using the mnemonic SEG. Examples:
  2054.  
  2055.        REP
  2056.        MOVSB           ;move bytes until CX decremented to 0
  2057.        SEG SS
  2058.        MOV AX,BUFFER   ;buffer is in the stack segment
  2059.        LOCK
  2060.        MOV [8FFH], AX  ;lock bus to ensure data is transferred
  2061.                        ;before other processors try to access it
  2062.  
  2063.     Note for 8087 users:  You may get unexpected results using the
  2064.        separate instruction form of SEG on 8087 instructions.  Use
  2065.        the operand modifier form for segment overrides on 8087
  2066.        instructions.
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.                                                                    33
  2114.  
  2115.     >>Pseudo-Operations<<
  2116.  
  2117.     The following pseudo-ops are implemented:
  2118.  
  2119.     BSAVE: Generate object code in BSAVE format.
  2120.  
  2121.       Instructs CHASM to build a header in the format of BASIC's
  2122.       BSAVE command.  The resulting object code file may be BLOADed
  2123.       by BASIC programs.  No operands are required, and the pseudo-op
  2124.       may appear anywhere within the source code. Example:
  2125.  
  2126.             ORG    0     ;no psp
  2127.       SUBRT PROC   FAR   ;subroutine for BASIC program
  2128.             BSAVE        ;make BLOADable object file
  2129.  
  2130.     COUNT ...ENDC:  Count bytes.
  2131.  
  2132.       COUNT was available in earlier versions of CHASM. With the
  2133.       addition of operand expression support, COUNT became obsolete,
  2134.       and was eliminated to make room for new features.
  2135.  
  2136.       Existing programs using COUNT can be modified as in the
  2137.       following example.  The length of the string is calculated by
  2138.       subtracting two labels, one just before the string, one just
  2139.       after it:
  2140.  
  2141.       MESSAGE    COUNT
  2142.       MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2143.                  ENDC
  2144.                  MOV CX, LENGTH(MESSAGE)
  2145.  
  2146.       becomes:
  2147.  
  2148.       MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2149.       MSG_END
  2150.                  MOV   CX, MSG_END-MSG_TXT
  2151.  
  2152.  
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.                                                                    34
  2180.  
  2181.     DB: Declare Bytes
  2182.  
  2183.       Memory locations are filled with values from the operand list.
  2184.       Any number of operands may appear, but all must fit on one
  2185.       line. Acceptable operands are immediate data, or strings
  2186.       enclosed in single quotes (').  DB interprets strings as a
  2187.       series of ASCII bytes.
  2188.  
  2189.       If a label appears, it is redefined as a memory location, and
  2190.       the data area may be referred to using the label, rather than
  2191.       an address. Examples:
  2192.  
  2193.             MOV AX,MASK
  2194.       MASK  DB  00H,01H
  2195.       STG   DB  'A string operand'
  2196.  
  2197.       CHASM generates an error message ("Data too large") if word
  2198.       operands (such as OFFSETs, or numbers greater than 255) are
  2199.       found in the DB operand list. DW should be used for declaring
  2200.       words.
  2201.  
  2202.     DM: Declare Multiple Bytes
  2203.  
  2204.       Like COUNT, DM became obsolete when operand expressions became
  2205.       available, and has been eliminated to make room for new
  2206.       features.  Existing programs using DM can be modified as
  2207.       follows:
  2208.  
  2209.           DM  500, ENTRYLENGTH
  2210.  
  2211.       becomes:
  2212.  
  2213.           DS  500*ENTRYLENGTH
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.  
  2244.  
  2245.                                                                    35
  2246.  
  2247.     DS: Declare Storage
  2248.  
  2249.       Used to declare large blocks of identically initialized
  2250.       storage.  The first operand is required, a number specifying
  2251.       how many bytes are declared.  If a second operand in the form
  2252.       of a number 0-FFH appears, the locations will all be
  2253.       initialized to this value.  If the second operand is not
  2254.       present, locations are initialized to 0.   As with DB, any
  2255.       label is redefined as a memory location.  To save space, the
  2256.       object code does not appear on the listing.  Examples:
  2257.  
  2258.          DS 10         ;10 locs initialized to 0
  2259.          DS 100H,1AH   ;256 locs initialized to 1AH
  2260.  
  2261.     DW: Declare Words
  2262.  
  2263.       Used to unambiguously assign a word of storage for each item in
  2264.       the operand list.  Any number of immediate operands may appear,
  2265.       but all must fit on one line.  You can also put labels in the
  2266.       DW operand list; they will be replaced with the offset of the
  2267.       corresponding memory or code location.  As with DB, any label
  2268.       on the DW statement itself is redefined as a memory location.
  2269.       Example:
  2270.  
  2271.           DW 0012H, FFFFH       ;four bytes declared
  2272.  
  2273.     EJECT: Begin New Print Page
  2274.  
  2275.       When listing is enabled, causes CHASM to move to the top of the
  2276.       next listing page.  Normally has no effect on listings sent to
  2277.       the screen or to disk, although you can enable EJECTs in disk
  2278.       listings with CHASM's /DPAGE configuration switch.
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289.  
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.                                                                    36
  2312.  
  2313.     EJECTIF: Conditional Page Break
  2314.  
  2315.       Requires one immediate operand.  If listing is enabled and
  2316.       fewer than that many lines are left on the current page of the
  2317.       listing, CHASM will move to the top of the next page.
  2318.  
  2319.       If you put an appropriate EJECTIF at the beginning of each
  2320.       procedure or section of your programs, CHASM will keep them in
  2321.       one piece.  Like EJECT, EJECTIF normally has no effect on
  2322.       listings to the screen or disk.  You can enable EJECTIF for
  2323.       disk listings with CHASM's /DPAGE configuration switch.
  2324.       Example:
  2325.  
  2326.           EJECTIF 20    ;following procedure is 20 lines long
  2327.  
  2328.     ENDP: End of Procedure
  2329.  
  2330.       See PROC (below) for details.
  2331.  
  2332.     ENDSTRUC: End of Structure
  2333.  
  2334.       ==>Advanced version only.  See STRUC (below) for details.
  2335.  
  2336.     EQU: Equate
  2337.  
  2338.       Used to equate a symbolic name with a number. The symbol may
  2339.       then be used anywhere the number would be used.  Use of symbols
  2340.       makes programs more understandable, and simplifies
  2341.       modification.
  2342.  
  2343.       An alternate form of EQU encloses the number in square
  2344.       brackets: []. The symbol is then interpreted as a memory
  2345.       location, and may be used as an address for memory access. This
  2346.       version is provided to allow symbolic reference to locations
  2347.       outside the program segment. Examples:
  2348.  
  2349.          MOFFSET    EQU 0B000H
  2350.          MONOCHROME EQU [0000H]
  2351.  
  2352.       Warning: Difficult to debug errors may result from using a
  2353.       ======>  symbol prior to its being defined by EQU.  You are
  2354.       strongly urged to group all your equates together at the
  2355.       beginning of programs, before any other instructions. See
  2356.       "Phase Error" in the Error Message section.
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.  
  2376.  
  2377.                                                                    37
  2378.  
  2379.     INLINE: Generate Turbo Pascal inline statements
  2380.  
  2381.       Instructs CHASM to output object code in the form of a text
  2382.       file, suitable for including in Turbo Pascal inline statements.
  2383.       The resulting object file is not directly executable, but with
  2384.       minimal editing, can be compiled by Turbo Pascal as inline
  2385.       data.
  2386.  
  2387.       INLINE can appear anywhere in your source file, and requires no
  2388.       operands.
  2389.  
  2390.       See the "Execution of Assembled Programs" section of this
  2391.       document for examples, and more details.
  2392.  
  2393.     IFXX... [ELSE]... ENDIF: Conditional Assembly
  2394.  
  2395.       ===> Advanced version only.
  2396.  
  2397.       CHASM's conditional assembly pseudo-ops can be used to cause
  2398.       macros to expand differently according to the parameters
  2399.       supplied on the invocation.  Many different IF pseudo-ops are
  2400.       provided, to allow testing for (in)equality, relative size, and
  2401.       (non)existence of parameters.  You can also test whether a
  2402.       parameter is a register, and if so, what type.
  2403.  
  2404.       For more details and examples, see the Macro section of this
  2405.       document.
  2406.  
  2407.     INCLUDE: Include file
  2408.  
  2409.       ==>Advanced version only.
  2410.  
  2411.       INCLUDE requires one string operand, a filename enclosed in
  2412.       single quotes.  If desired, you can specify a drive and/or a
  2413.       path as part of the filename.
  2414.  
  2415.       The contents of the specified file are logically inserted into
  2416.       the source file at the point where the INCLUDE appears.
  2417.       INCLUDEs cannot be nested: an error message will be printed if
  2418.       the specified file itself contains an INCLUDE.  Example:
  2419.  
  2420.           INCLUDE '\ASM\STDIO.HDR'    ;bring in standard library
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.  
  2442.  
  2443.                                                                    38
  2444.  
  2445.     LIST: Enable listing output
  2446.  
  2447.       Output to the list device is enabled, presumably after a NOLIST
  2448.       was encountered.  No operands required.
  2449.  
  2450.     MACRO ...ENDM: Macro Definition
  2451.  
  2452.       ==> Advanced version only.
  2453.  
  2454.       Declares a macro.  MACRO requires no operands, and signals
  2455.       CHASM that the following lines constitute a macro definition,
  2456.       and are to be stored for later use, rather than assembled in
  2457.       place.  A label is required on the MACRO statement to name the
  2458.       defined macro.
  2459.  
  2460.       ENDM terminates the macro definition, and requires no operands.
  2461.  
  2462.       For more information and examples, see the section titled
  2463.       "Macros".
  2464.  
  2465.     MAP: Generate map file
  2466.  
  2467.       ==> Advanced Version Only.
  2468.  
  2469.       Generates a file with the same name as your source file but
  2470.       with extension .MAP, containing label information for use by
  2471.       symbolic debuggers.  Works with Advanced Trace86 by Morgan
  2472.       Computing, and maybe other debuggers.  See "Execution of
  2473.       Assembled Programs" for more details.
  2474.  
  2475.       The MAP pseudo-op can appear anywhere in your program, and
  2476.       requires no operands.
  2477.  
  2478.     NOLIST: Disable listing output
  2479.  
  2480.       Normal output to the list device is disabled.  Error messages
  2481.       are listed as usual.  No operands required.
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.  
  2508.  
  2509.                                                                    39
  2510.  
  2511.     ORG: Origin
  2512.  
  2513.       Allows direct manipulation of the location counter during
  2514.       assembly.  By default, CHASM assembles code to start at offset
  2515.       100H, thus leaving room for the program segment prefix normally
  2516.       built by COMMAND or DEBUG.  In situations where no PSP is
  2517.       provided, such as routines to be called from BASIC, you should
  2518.       override this default with ORG, or incorrect assembly may
  2519.       result.
  2520.  
  2521.       ORG requires one operand, a number between 0 and FFFFH, which
  2522.       represents the new setting of CHASM's location counter.
  2523.       Although the location counter may be reset anywhere within a
  2524.       program, generally this pseudo-op should be used before any
  2525.       machine executable instructions for meaningful results.
  2526.  
  2527.       Example:
  2528.  
  2529.          ORG 0   ;Code will be assembled for starting
  2530.                  ;offset of 0
  2531.  
  2532.     PROC ...ENDP: Procedure Definition
  2533.  
  2534.       Declares a procedure.  One operand is required on PROC, either
  2535.       the word NEAR, or the word FAR.  This pseudo-op warns CHASM
  2536.       whether to assemble returns as intra (near) or intersegment
  2537.       (far).  Procedures called from within the program being
  2538.       assembled should be declared NEAR.  Generally, all others
  2539.       should be FAR.  ENDP terminates the procedure, and requires no
  2540.       operands.  If a RET is encountered outside of a declared
  2541.       procedure, an error occurs.  Procedures may be nested, up to 10
  2542.       deep.  Example:
  2543.  
  2544.       MAIN  PROC  FAR
  2545.             ...
  2546.             ...      ;body of procedure
  2547.             ENDP
  2548.  
  2549.     RADIX:  Default Number Base
  2550.  
  2551.       CHASM's default radix is 10, meaning that numbers are assumed
  2552.       to be in base 10 unless they end in "B" or "H".  The RADIX
  2553.       pseudo-op allows you to change this default.  Allowed RADIX
  2554.       values are 16 and 10.  Setting RADIX 16 allows you to specify
  2555.       hex numbers without the trailing "H".
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.                                                                    40
  2576.  
  2577.       Note that when RADIX 16 is in effect, there is no way to
  2578.       specify numbers in base 1 (binary) or base 10 (decimal).  To
  2579.       write in either of these bases, shift back to RADIX 10.  For
  2580.       example:
  2581.  
  2582.          RADIX 16
  2583.          mov   ax, 1B     ;means 1B in hexadecimal
  2584.          mov   ax, 20     ;means 20 in hexadecimal
  2585.          mov   ax, 30H    ;trailing "H" allowed, but not necessary
  2586.          RADIX 10
  2587.          mov   ax, 1B     ;means 1 in binary
  2588.          mov   ax, 20     ;means 20 in decimal
  2589.          mov   ax, 30H    ;means 30 in hexadecimal
  2590.  
  2591.  
  2592.     STRUC ...ENDSTRUC: Structure Definition
  2593.  
  2594.        ==> Advanced version only.
  2595.  
  2596.       Declares a structure.  STRUC requires no operands, and signals
  2597.       CHASM that the following lines constitute a structure template,
  2598.       and not actual storage declaration.  If a label appears on the
  2599.       STRUC, the label is equated with the length of the structure.
  2600.  
  2601.       ENDSTRUC terminates the structure definition, and requires no
  2602.       operands.
  2603.  
  2604.       Inside the structure, storage defining pseudo-ops behave
  2605.       somewhat differently.  See the section titled "Structures" for
  2606.       more information. Example:
  2607.  
  2608.           DIRENTRY STRUC      ;disk directory entry
  2609.           NAME     DS    8
  2610.           EXT      DS    3
  2611.           ATRIB    DS    1
  2612.           RESERVED DS   10
  2613.           TIME     DS    2
  2614.           DATE     DS    2
  2615.           START    DS    2
  2616.           SIZE     DS    4
  2617.                    ENDSTRUC
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630.  
  2631.  
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637.  
  2638.  
  2639.  
  2640.  
  2641.                                                                    41
  2642.  
  2643.     WAITON / WAITOFF: Toggle Automatic WAIT Assembly
  2644.  
  2645.       CHASM normally assembles WAIT instructions before most 8087
  2646.       instructions.  After a WAITOFF pseudo-op is encountered, CHASM
  2647.       will not add WAITs.  This allows you to let the 8088 and 8087
  2648.       run in parallel for greater speed, putting in WAITs manually
  2649.       where synchronization is important.  WAITON turns automatic
  2650.       WAIT assembly back on.
  2651.  
  2652.     CHKJMP / NOCHKJMP
  2653.  
  2654.       Following a CHKJMP pseudo-op, CHASM will check each JMP
  2655.       instruction to see if it could have been coded as JMPS (to
  2656.       produce tighter code).  JMP instructions with displacements
  2657.       smaller than 128 bytes will be flagged with a diagnostic
  2658.       message ("Could Use JMPS").  NOCHKJMP turns off JMP checking.
  2659.  
  2660.     = : Assignment to Assembler Variable
  2661.  
  2662.       CHASM supports the use of "assembler variables", which can be
  2663.       dynamically redefined throughout your program.  The assignment
  2664.       operator "=" acts similarly to pseudo-op EQU.  A label on a "="
  2665.       line will be defined as equivalent to the operand, until it is
  2666.       redefined by another assignment statement.  Unlike EQU, with
  2667.       "=" you can assign any valid operand type (except string) to
  2668.       the assembler variable. These assignments do *NOT* result in
  2669.       object code generation - they simply redefine a symbol to have
  2670.       different meanings to CHASM in different parts of your program.
  2671.       For example:
  2672.  
  2673.        x    =   [80]
  2674.             mov ax, x      ;means mov ax, [80]
  2675.        x    =   bx
  2676.             mov ax, x      ;x  redefined, means mov ax, bx
  2677.        x    =   100H
  2678.             mov ax, x      ;redefined again, means mov ax, 100H
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.  
  2706.  
  2707.                                                                    42
  2708.  
  2709.     >>Macros<<
  2710.  
  2711.     ==>Advanced version only.
  2712.  
  2713.     Macros are an advanced feature.  Beginners may wish to skip this
  2714.     section until they become more experienced with CHASM and
  2715.     assembly language programming.
  2716.  
  2717.     A. Introduction
  2718.  
  2719.        Macros are a shorthand way of writing frequently used
  2720.        sections of code.  Using macros, you can write a code fragment
  2721.        once, then any time you want to use it, just reference it by
  2722.        name.  Once you define a macro and give it a name, anywhere
  2723.        CHASM sees the name will be automatically "expanded" into the
  2724.        previously defined code.
  2725.  
  2726.        For example, suppose you were writing a large program, and at
  2727.        the beginning of each subroutine you pushed all the general
  2728.        purpose registers onto the stack to save their contents.
  2729.        Every subroutine would start out something like this:
  2730.  
  2731.              push ax       ;save register contents
  2732.              push bx
  2733.              push cx
  2734.              push dx
  2735.  
  2736.        Before long, you'd get pretty sick of writing the same thing
  2737.        for each subroutine.  Macros are a way to put some of the
  2738.        boring, repetitive nature of assembly language into the hands
  2739.        of the assembler, freeing you up for the more creative
  2740.        aspects.  Here's how you define a CHASM macro to take the
  2741.        place of this code fragment:
  2742.  
  2743.        savestate  macro
  2744.                   push ax           ;save general purpose registers
  2745.                   push bx
  2746.                   push cx
  2747.                   push dx
  2748.                   endm
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758.  
  2759.  
  2760.  
  2761.  
  2762.  
  2763.  
  2764.  
  2765.  
  2766.  
  2767.  
  2768.  
  2769.  
  2770.  
  2771.  
  2772.  
  2773.                                                                    43
  2774.  
  2775.        Note the MACRO and ENDM statements.  These signal to CHASM
  2776.        that the enclosed code is a macro definition to be saved for
  2777.        later use, rather than code to be assembled at this point in
  2778.        your program.  The MACRO statement also gives a name
  2779.        (SAVESTATE) to the macro, which will take the place of the
  2780.        stored code.
  2781.  
  2782.        Now, at the beginning of each subroutine you can just write
  2783.        "SAVESTATE" when you want to push the general purpose
  2784.        registers. Here's an example:
  2785.  
  2786.        get_input  proc  near
  2787.                   savestate
  2788.                   ...
  2789.                   ...
  2790.                   endp
  2791.  
  2792.        Given the previous macro definition, the above example is
  2793.        *exactly* equivalent to:
  2794.  
  2795.        get_input  proc  near
  2796.                   push ax
  2797.                   push bx
  2798.                   push cx
  2799.                   push dx
  2800.                   ...
  2801.                   ...
  2802.                   endp
  2803.  
  2804.        The only difference is that less busy work is required on your
  2805.        part.
  2806.  
  2807.        Macros are NOT subroutines!  Subroutines are coded once, then
  2808.        called within your program at run time.  Macros are expanded
  2809.        in-line at assembly time, and the code is inserted into your
  2810.        program at the invocation point.  If you invoke the macro 20
  2811.        times in your program, you'll end up with 20 copies of the
  2812.        macro code.
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.                                                                    44
  2840.  
  2841.        Although this does waste some memory space, you save execution
  2842.        time by eliminating the subroutine call and return process.
  2843.        At a minimum, it takes 32 machine cycles to call a subroutine.
  2844.        The four instruction macro given above requires 40 cycles to
  2845.        execute.  If it were coded as a subroutine, the time to
  2846.        execute it would almost *double*.  Macros trade off space for
  2847.        speed.
  2848.  
  2849.     B. Macro Parameters
  2850.  
  2851.        CHASM's macros allow 9 user defined parameters, which are
  2852.        evaluated at expansion time.  The parameters work just like
  2853.        those in DOS batch files.  Here's an example of a macro with
  2854.        one parameter.  PRINT calls DOS function 9 to print a string
  2855.        on the console.  A parameter is used to specify the name of
  2856.        the string to be printed:
  2857.  
  2858.        print    macro
  2859.                 mov  ah, 09H          ;specify print string function
  2860.                 mov  dx, offset(%1)   ;point to string
  2861.                 int  21H              ;call DOS
  2862.                 endm
  2863.  
  2864.        Given this definition, when CHASM sees a line like:
  2865.  
  2866.              print title
  2867.  
  2868.        The following code gets inserted in its place:
  2869.  
  2870.              mov  ah, 09H
  2871.              mov  dx, offset(title)
  2872.              int  21H
  2873.  
  2874.        Note how the "%1" in the macro definition got replaced by
  2875.        "title" which was put as an operand on the invocation of the
  2876.        macro.  You can put up to 9 operands onto a macro invocation,
  2877.        and they will be substituted for the dummy parameters %1
  2878.        through %9.
  2879.  
  2880.  
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.  
  2904.  
  2905.                                                                    45
  2906.  
  2907.        If you put a label on a macro invocation, two things happen.
  2908.        As usual, the label represents a program location for
  2909.        branching, with offset equal to the beginning of the expanded
  2910.        macro.  You can branch into the expanded macro by using the
  2911.        label as an operand on a jump or call instruction.  In
  2912.        addition, if the special dummy parameter "%0" is used in the
  2913.        macro definition, it is replaced with the label text when the
  2914.        macro is expanded.  This feature is provided to facilitate
  2915.        writing loops within macros.
  2916.  
  2917.        If you fail to provide an operand for any dummy parameter used
  2918.        in the macro definition, CHASM substitutes a null string of
  2919.        length zero.  To leave one parameter blank, but provide
  2920.        replacements for parameters with higher numbers, use the
  2921.        special operand "%B" for the one you want blank.  For example:
  2922.  
  2923.             def_mem  macro
  2924.             %1       db  %2, %3
  2925.                      endm
  2926.  
  2927.                      def_mem twobytes, 128, FFH
  2928.                      def_mem %B, 'Hit any key when ready...'
  2929.  
  2930.        Expands to:
  2931.  
  2932.             twobytes  db 128, FFH
  2933.                       db 'Hit any key when ready...'
  2934.  
  2935.     C. Internal Labels
  2936.  
  2937.        A potential problem exists if you put a label on a statement
  2938.        within a macro.  The first time the macro gets invoked,
  2939.        everything works fine.  However, remember that a given label
  2940.        can only be used once.  The second time you invoke the macro,
  2941.        the line with the label will get a "Duplicate definition"
  2942.        error message.
  2943.  
  2944.        CHASM offers "internal labels" for use within macros.  When
  2945.        expanding macros, CHASM replaces these internal labels with a
  2946.        unique text, different for each invocation of the macro.
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.                                                                    46
  2972.  
  2973.        Macro internal labels are of the form:
  2974.  
  2975.            %Lx
  2976.  
  2977.        The "%L" signals CHASM that you want an internal label.  The
  2978.        "x" can be any character that isn't a delimiter.  By using
  2979.        different characters, you can define many different labels in
  2980.        each macro.
  2981.  
  2982.        Within the macro, you use the internal label symbol just like
  2983.        a normal label.  For example:
  2984.  
  2985.            INTLAB MACRO
  2986.            %LA    MOV AX, DX
  2987.                   JMPS %LA
  2988.                   ENDM
  2989.  
  2990.        Each time this macro is invoked, all occurrences of "%LA" will
  2991.        be replaced with a different text.  (The replacement text will
  2992.        be of the form "%LAnnnn" where "nnnn" is a number.)
  2993.  
  2994.        Using the symbol table dump on your listing, you can figure
  2995.        out what text CHASM used in any given invocation.  DON'T try
  2996.        to use this information to branch into the macro invocation
  2997.        from the outside.  Editing your source file can cause CHASM to
  2998.        use a different substitution text the next time you assemble.
  2999.        Internal labels are intended for macro INTERNAL use only.
  3000.  
  3001.     D. Macro Nesting
  3002.  
  3003.        Macro invocations can be nested, up to 10 deep.  Invocations
  3004.        are maintained on a stack, and each invocation has it's own
  3005.        set of parameters and internal labels.
  3006.  
  3007.        CHASM does not check for recursive macro calls.  If you call a
  3008.        macro from within itself, it's quite possible to get caught in
  3009.        an endless loop.  This can also happen indirectly, where a
  3010.        macro invokes another macro, which ends up calling the first.
  3011.        If you get caught, you can escape by hitting Ctrl-Break.
  3012.  
  3013.        Experienced programmers can use macro recursion along with
  3014.        expressions and conditional assembly to create some really
  3015.        elegant macros.  However, this is definitely not for beginners
  3016.        or the faint of heart.  Enter at your own risk.
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.                                                                    47
  3038.  
  3039.     E. Conditional Macro Expansion
  3040.  
  3041.        This advanced feature allows you to write general purpose
  3042.        macros which expand in different ways based on the parameters
  3043.        used on the invocation.
  3044.  
  3045.        For example, suppose you wanted to write a macro to do
  3046.        operating system calls.  Many of the DOS functions just load
  3047.        the function number into AH, then call DOS with an interrupt.
  3048.        Here's a macro to do this:
  3049.  
  3050.        doscall  macro
  3051.                 mov ah, %1
  3052.                 int 21H
  3053.                 endm
  3054.  
  3055.        Given the above definition, "DOSCALL 1" will expand into a
  3056.        call to DOS function #1, keyboard input.
  3057.  
  3058.        Unfortunately, not all DOS calls are quite so simple.  For
  3059.        example, the call for printing a string to the console
  3060.        requires that the offset of the string be loaded into DX.
  3061.        Different system calls are going to require somewhat different
  3062.        handling.  One approach would be to write separate macros for
  3063.        each function.  However, with 87 different functions in DOS 2,
  3064.        this starts to get unwieldy.
  3065.  
  3066.        A more general approach is to incorporate some "intelligence"
  3067.        into the macro, and let it expand differently for different
  3068.        DOS functions.  Here's a slightly more general macro, which
  3069.        loads DX whenever the "print string" function is requested:
  3070.  
  3071.        doscall  macro
  3072.                 mov ah, %1
  3073.                 ife %1 9
  3074.                    mov dx, offset(%2)
  3075.                 endif
  3076.                 int 21H
  3077.                 endm
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.  
  3091.  
  3092.  
  3093.  
  3094.  
  3095.  
  3096.  
  3097.  
  3098.  
  3099.  
  3100.  
  3101.  
  3102.  
  3103.                                                                    48
  3104.  
  3105.        "IFE" is short for "If Equal".  The "IFE" and "ENDIF" bracket
  3106.        a line of macro code which will be included during expansion
  3107.        only if the "IFE" statement is satisfied.  In this example,
  3108.        the MOV DX statement will be included only if the first
  3109.        parameter is equal to 9.  The enclosed line is indented in
  3110.        this example to help show the structure of the macro, but
  3111.        indentation is not required.
  3112.  
  3113.        Given the above definition, "DOSCALL 1" expands to only two
  3114.        lines:
  3115.  
  3116.           mov ah, 1
  3117.           int 21H
  3118.  
  3119.       However, "DOSCALL 9, STRING" expands to three lines:
  3120.  
  3121.           mov ah, 9
  3122.           mov dx, offset(string)
  3123.           int 21H
  3124.  
  3125.        CHASM supports twelve different conditional test statements.
  3126.        They are:
  3127.  
  3128.             IFE       "if equal"
  3129.             IFNE      "if not equal"
  3130.             IFGT      "if greater than"
  3131.             IFGE      "if greater than or equal"
  3132.             IFLE      "if less than or equal"
  3133.             IFLT      "if less than"
  3134.             IFB       "if blank"
  3135.             IFNB      "if not blank"
  3136.             IFREG     "if a register"
  3137.             IFREG8    "if an 8 bit register"
  3138.             IFREG16   "if a 16 bit register"
  3139.             IFSEGREG  "if a segment register"
  3140.  
  3141.        Most of the conditionals take two operands, and perform a
  3142.        comparison.  The operands are evaluated, and their values are
  3143.        compared according to the condition being tested.  Strings are
  3144.        compared in the normal alphabetical order sense.  Examples:
  3145.  
  3146.             IFE   15, 0FH       ;is true
  3147.             IFGT  'ABCD' 'EFGH' ;is false
  3148.             IFLE  20H, 128      ;is true
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.  
  3164.  
  3165.  
  3166.  
  3167.  
  3168.  
  3169.                                                                    49
  3170.  
  3171.        IFB and IFNB require only one operand, which should be a dummy
  3172.        parameter.  These conditionals test whether the parameter was
  3173.        left "blank" or if a replacement was provided on the
  3174.        invocation.
  3175.  
  3176.        The IFREG conditionals take one operand.  They return true if
  3177.        the operand is a register in the following sets:
  3178.  
  3179.             IFREG:    any register
  3180.             IFREG8:   AH, AL, BH, BL, CH, CL, DH, DL
  3181.             IFREG16:  AX, BX, CX, DX, DI, SI, BP, SP
  3182.             IFSEGREG: CS, DS, ES, SS
  3183.  
  3184.        You can place as many lines as you like between an IF
  3185.        statement and the ENDIF.  All will be included if the
  3186.        condition tested is true, and none will be included if it's
  3187.        false.
  3188.  
  3189.        An optional "ELSE" construct is also provided.  Statements
  3190.        after the ELSE get included only if the tested condition is
  3191.        false. CHASM's conditional assembly syntax can be summarized
  3192.        as follows:
  3193.  
  3194.            IF.....            ;if statement with parameter(s)
  3195.              s1                  ;statements included if true
  3196.              s2                  ;    "         "      "   "
  3197.            ELSE               ;end of "true" option, begin "false"
  3198.              s3                  ;statements included if false
  3199.              s4                  ;    "         "      "   "
  3200.            ENDIF              ;end of conditional assembly
  3201.  
  3202.        IF statements can be nested, up to 10 deep.  During nesting,
  3203.        CHASM assumes that ELSEs are paired with the latest unfinished
  3204.        IF statement.  For example:
  3205.  
  3206.        example macro
  3207.                ife %1, 1
  3208.                   db 'Outer IF is true'
  3209.                   ifb %2
  3210.                      'Inner IF is true'
  3211.                   else
  3212.                      'Where do I belong?'
  3213.                   endif
  3214.                endif
  3215.  
  3216.  
  3217.  
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.                                                                    50
  3236.  
  3237.        "EXAMPLE 1, 5" expands to:
  3238.  
  3239.               db 'Outer IF is true'
  3240.               db 'Where do I belong?'
  3241.  
  3242.        But "EXAMPLE 2" produces no expansion at all.
  3243.  
  3244.        This is easiest to follow if you use "structured" indenting
  3245.        when writing the macro, as in the example above. Remember,
  3246.        however, that CHASM ignores indenting and follows the
  3247.        "latest unfinished" rule in figuring out which IF gets the
  3248.        ELSE.  Don't fool yourself with improper indentation.
  3249.  
  3250.     F. Final Notes:
  3251.  
  3252.        The conditional assembly pseudo-ops are not restricted to use
  3253.        in macros, although there aren't that many useful non-macro
  3254.        applications.
  3255.  
  3256.        CHASM won't recursively expand parameters.  For example:
  3257.  
  3258.            RECUR MACRO
  3259.                  XOR %1, %2
  3260.                  ENDM
  3261.  
  3262.                  RECUR AX, %1
  3263.  
  3264.        expands to:
  3265.  
  3266.                 XOR AX, %1   ;actual expansion
  3267.  
  3268.        NOT to:
  3269.  
  3270.                 XOR AX, AX   ;won't happen
  3271.  
  3272.        Like equates and structures, macro definitions should all be
  3273.        placed at the beginning of your programs, before the macro
  3274.        gets invoked.  If you invoke a macro before it's defined, a
  3275.        phase error will occur.
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.                                                                    51
  3302.  
  3303.        Macro definitions are stored and expanded blindly by CHASM,
  3304.        with no syntax checking.  Dummy parameter symbols can appear
  3305.        in any of the input line fields.  Any errors in a macro
  3306.        definition will only become evident when CHASM expands the
  3307.        macro and attempts to assemble the result.
  3308.  
  3309.        In keeping with the "shorthand" philosophy of macros, the
  3310.        results of macro expansion don't normally appear on the
  3311.        listing.  If you want to see the expansion for debugging
  3312.        purposes, insert a LIST pseudo-op as the first line of the
  3313.        macro definition.
  3314.  
  3315.        Once you start writing macros, you might find it useful to
  3316.        gather them together into a single file.  You can then pull
  3317.        this file into the beginning of all your programs with an
  3318.        INCLUDE pseudo-op.  Macros which don't get invoked won't add
  3319.        anything to the object code produced, and you'll save yourself
  3320.        the trouble of typing in the ones you *do* need.  If you put a
  3321.        NOLIST at the beginning and a LIST at the end of your INCLUDE
  3322.        file, you don't even have to look at the definitions on your
  3323.        listings.
  3324.  
  3325.  
  3326.  
  3327.  
  3328.  
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.  
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.  
  3362.  
  3363.  
  3364.  
  3365.  
  3366.  
  3367.                                                                    52
  3368.  
  3369.     >>Structures<<
  3370.  
  3371.     ==>Advanced version only.
  3372.  
  3373.     Structures are an advanced feature.  Beginners may wish to skip
  3374.     this section until they become more experienced with CHASM and
  3375.     assembly language programming.
  3376.  
  3377.     CHASM's structure capability allows you to generate a "template"
  3378.     with which to organize repetitive data structures.  As an example
  3379.     of a repetitive data structure, consider a phone list.  Each
  3380.     entry in the list has three components:
  3381.  
  3382.          Name    - 20 characters
  3383.          Address - 50 characters
  3384.          Phone   - 10 characters
  3385.  
  3386.     Each entry thus uses a total of 80 bytes of storage.  To declare
  3387.     a list with 500 entries, you would declare 80 x 500 = 4000 bytes:
  3388.  
  3389.          PHONELIST  DS  4000   ;500 entries @ 80 bytes/entry
  3390.  
  3391.     That's easy enough, but now what's the offset of the 346th
  3392.     address field?  This is starting to get confusing, and time
  3393.     consuming to figure out.
  3394.  
  3395.     Furthermore, hard-coding numbers (like that 4000, above) into a
  3396.     program is never a good idea.  What's going to happen when you
  3397.     decide to add a zip code field, or make more room in the name
  3398.     field because you just met Alexandria Zbrievskivich?  You'd have
  3399.     to go through and change by hand each number which depended on
  3400.     the actual layout of your data.  Murphy's law guarantees that
  3401.     it'll take somewhere between "several" and "too many" assemblies
  3402.     to find them all.
  3403.  
  3404.     Structures allow you to set up a symbolic template which makes it
  3405.     much easier to manage structured data like this phone list.  By
  3406.     using symbols defined in the structure, rather than bare numbers,
  3407.     a change in data structure doesn't mean a frantic search
  3408.     throughout your entire program to make corrections.  If you
  3409.     change the structure definition, the symbols take on new values
  3410.     automatically.
  3411.  
  3412.  
  3413.  
  3414.  
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.  
  3428.  
  3429.  
  3430.  
  3431.  
  3432.  
  3433.                                                                    53
  3434.  
  3435.     Here's what the phone list structure looks like:
  3436.  
  3437.          LISTENTRY  STRUC
  3438.          NAME       DS 20
  3439.          ADDRESS    DS 50
  3440.          PHONE      DS 10
  3441.                     ENDSTRUC
  3442.  
  3443.     Note the STRUC and ENDSTRUC statements.  They mark the beginning
  3444.     and end of the structure, and give it a name (LISTENTRY).
  3445.  
  3446.     Within the structure are storage defining pseudo-ops.  DS is used
  3447.     in this example, but DB and DW could also be used.  ORG can be
  3448.     used within a structure, but any 8088 instruction will result in
  3449.     an diagnostic message and termination of the structure
  3450.     definition.
  3451.  
  3452.     Inside a structure, the storage defining pseudo-ops
  3453.     behave somewhat differently than normal.  No actual storage is
  3454.     set aside, but CHASM keeps track of how much space would normally
  3455.     be declared.
  3456.  
  3457.     Labels on pseudo-ops get assigned values equal to their offset
  3458.     within the *structure*, not within the program as a whole.  Also,
  3459.     CHASM will treat the labels as immediate operands, rather than
  3460.     memory locations.  The result of the structure given above is to
  3461.     generate three immediate operands, with the following values:
  3462.  
  3463.          NAME    =  0
  3464.          ADDRESS = 20
  3465.          PHONE   = 70
  3466.  
  3467.     CHASM does one other piece of useful book-keeping during
  3468.     structure definitions.  If a label appears on the STRUC
  3469.     pseudo-op, it gets treated as an immediate operand, whose value
  3470.     is equal to the total length of the structure.
  3471.  
  3472.     You can either use the STRUC label directly as an operand, or if
  3473.     you like "pretty" code, use the LENGTH operator on it.  In this
  3474.     example, both LISTENTRY and LENGTH(LISTENTRY) are immediate
  3475.     operands of value 80.
  3476.  
  3477.     (Inside note: LENGTH is a null operator, provided mainly for
  3478.     aesthetic reasons.  Using LENGTH will often make your code more
  3479.     readable, but is equivalent to using just the label itself.)
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494.  
  3495.  
  3496.  
  3497.  
  3498.  
  3499.                                                                    54
  3500.  
  3501.     Like equates and macros, structures should be placed at the
  3502.     beginning of your programs before any machine instructions,
  3503.     otherwise phase errors can occur.  If you *do* embed structures
  3504.     inside your program, you can eliminate any phase errors by using
  3505.     the LENGTH function to reference any of the immediate operands
  3506.     generated by the embedded structure.
  3507.  
  3508.     The immediate operands generated during a structure definition
  3509.     can be very useful in writing your program.  Following the phone
  3510.     list example, here's a better way to declare storage for the
  3511.     list:
  3512.  
  3513.        NUMENTRYS  EQU 500
  3514.        PHONELIST  DS  LISTENTRY*NUMENTRYS ;500 entries of length
  3515.                                           ;defined by the structure.
  3516.  
  3517.     Now if you add another field to the structure, PHONELIST will
  3518.     automatically increase in size.
  3519.  
  3520.     The 8088's indirect addressing modes, coupled with structures,
  3521.     make a very powerful combination for accessing structured data in
  3522.     memory.  Suppose AX contains the number of the entry you want to
  3523.     work on.  You can calculate the address of the entry as follows:
  3524.  
  3525.         MOV BX, LENGTH(LISTENTRY)    ;length per entry
  3526.         MUL AX, BX                   ;times entry number
  3527.         ADD AX, OFFSET(PHONELIST)    ;plus the starting offset
  3528.         MOV BX, AX                   ;BX <== frame pointer
  3529.  
  3530.     BX is now a "frame pointer" - it points to the beginning of the
  3531.     desired entry.  You can access the various parts of the entry
  3532.     using the optional displacement field in the indirect address.
  3533.     For example, here's how you would store the letter 'A' into the
  3534.     first byte of the address field:
  3535.  
  3536.          MOV  ADDRESS[BX], 'A'
  3537.  
  3538.     As another example, the following line reads the third letter of
  3539.     the name into the AL register:
  3540.  
  3541.          MOV  AL, NAME+3[BX]
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.  
  3561.  
  3562.  
  3563.  
  3564.  
  3565.                                                                    55
  3566.  
  3567.     The first entry in a structure almost invariably has value 0.
  3568.     CHASM "optimizes" indirect addresses with structure-generated
  3569.     constants equal to zero, generating the no-offset form of the
  3570.     address.  In this example:
  3571.  
  3572.         MOV AX, NAME[BX]
  3573.  
  3574.     actually assembles as MOV AX, [BX] rather than MOV AX, 0[BX]
  3575.     The resulting code is more compact, and runs faster.
  3576.  
  3577.     The more complicated indirect modes can be used to scan through
  3578.     or point within the fields.  The following program fragment gets
  3579.     the fourth digit in the phone number:
  3580.  
  3581.          MOV DI, 4             ;specify 4th digit
  3582.          MOV AL, PHONE[BX+DI] ;read it into AL
  3583.  
  3584.     Often times, you'll want to process entries sequentially.  To
  3585.     move to the next entry, you just add the length of the entry to
  3586.     the frame pointer:
  3587.  
  3588.          ADD   BX, LENGTH(LISTENTRY)    ;point to next entry
  3589.  
  3590.     The preceding examples should give you a feel for what you can
  3591.     do with structures, but do not exhaust all the possibilities.
  3592.     Experiment with this feature, and many of your programs will be
  3593.     both more readable and more easily modified.
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.                                                                    56
  3632.  
  3633.     >>8087 Support<<
  3634.  
  3635.     ===> Advanced version only.
  3636.  
  3637.     In addition to the normal 8088 instructions, CHASM's Advanced
  3638.     version supports all the 8087 mnemonics.  Look in the appendices
  3639.     for a list available instructions.
  3640.  
  3641.     Several books describing the functions of the 8087 instructions
  3642.     are available.  CHASM's 8087 support is based on Appendix D of
  3643.     Intel's 8087 Support Library, and the book "Assembly Language
  3644.     Programming for the IBM Personal Computer" by David J. Bradley
  3645.     (Prentice-Hall, 1984).
  3646.  
  3647.     ALL the 8087 instructions that reference memory for a real or
  3648.     integer quantity are ambiguous as to the size of operand.
  3649.     Integers can be Word (2 bytes), Short (4 bytes) , or Long (8
  3650.     bytes).  Reals can be Short (4 bytes), Long (8 bytes) or
  3651.     Temporary Real (10 bytes).
  3652.  
  3653.     As with 8088 memory references, CHASM resolves ambiguities using
  3654.     a suffix.  The following suffixes can be added to mnemonics to
  3655.     specify operand size:
  3656.  
  3657.        W: word
  3658.        S: short
  3659.        L: long
  3660.        T: temporary real
  3661.  
  3662.     Here are some examples of using suffixes:
  3663.  
  3664.        FADD   [200H]    ;wrong! ambiguous memory reference
  3665.        FADDT  [200H]    ;add 10 byte temporary real
  3666.        FILD   CS:[DI]   ;wrong! ambiguous memory reference
  3667.        FILDW  CS:[DI]   ;load 2 byte integer
  3668.  
  3669.     CHASM automatically generates a WAIT instructions prior to most
  3670.     8087 instructions.  The only exceptions are the "No Wait"
  3671.     instructions with a "N" as the mnemonic's second letter.
  3672.     Examples:
  3673.  
  3674.         FYL2X   ;automatically preceded by WAIT
  3675.         FNCLEX  ;no wait form of FCLEX
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.  
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.  
  3693.  
  3694.  
  3695.  
  3696.  
  3697.                                                                    57
  3698.  
  3699.     If you'd prefer to manually add WAITs only where needed to
  3700.     synchronize critical instructions, the WAITOFF pseudo-op disables
  3701.     CHASM's automatic WAIT assembly.  Using fewer WAITs allows the
  3702.     8088 and 8087 to run in parallel more often, giving better
  3703.     performance.  Make sure you synchronize with a WAIT before
  3704.     allowing the 8088 to access a location being modified by the
  3705.     8087.  You can turn CHASM's automatic WAIT assembly back on using
  3706.     a WAITON pseudo-op.
  3707.  
  3708.     You must use the operand modifier form for segment overrides on
  3709.     8087 instructions.  A separate SEG instruction will modify
  3710.     CHASM's automatically generated WAIT instruction, and won't
  3711.     affect the intended 8087 instruction.  Example:
  3712.  
  3713.         SEG CS
  3714.         FLDS [100H]     ;wrong!
  3715.         FLDS CS:[100H]  ;correct
  3716.  
  3717.  
  3718.  
  3719.  
  3720.  
  3721.  
  3722.  
  3723.  
  3724.  
  3725.  
  3726.  
  3727.  
  3728.  
  3729.  
  3730.  
  3731.  
  3732.  
  3733.  
  3734.  
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.  
  3744.  
  3745.  
  3746.  
  3747.  
  3748.  
  3749.  
  3750.  
  3751.  
  3752.  
  3753.  
  3754.  
  3755.  
  3756.  
  3757.  
  3758.  
  3759.  
  3760.  
  3761.  
  3762.  
  3763.                                                                    58
  3764.  
  3765.     >>Outside the Program Segment<<
  3766.  
  3767.     As mentioned previously, CHASM does not support multiple segment
  3768.     definitions.  Provision is made for limited access outside of the
  3769.     program segment, however.
  3770.  
  3771.     A. Memory References:
  3772.        To access memory outside the program segment, you move a new
  3773.        segment address into the DS register, then address using
  3774.        offsets in the new segment.  The memory option of the EQU
  3775.        pseudo-op allows you to give a variable name to offsets in
  3776.        other segments. For example, to access DOS's equipment flag:
  3777.  
  3778.           BIOS_DATA   EQU  40H
  3779.           EQUIP_FLAG  EQU  [0010H]
  3780.                       MOV  AX,BIOS_DATA  ;can't move immed. to DS
  3781.                       MOV  DS,AX
  3782.                       MOV  AX,EQUIP_FLAG ;get bios equipment flag
  3783.  
  3784.     B. Code Branching:
  3785.        CHASM supports 4 instructions for branching outside the
  3786.        program segment.
  3787.  
  3788.        1. Direct CALL and JMP
  3789.  
  3790.           New values for the PC and CS registers are included in the
  3791.           instruction as two immediate operands.  Example:
  3792.  
  3793.           BIOS         EQU  0F000H            ;RAM bios segment
  3794.           DISKETTE_IO  EQU  0EC59H            ;disk handler
  3795.                        JMP  DISKETTE_IO,BIOS
  3796.  
  3797.        2. Indirect CALLF and JMPF
  3798.  
  3799.           Four consecutive bytes in memory are initialized with new
  3800.           values for the PC and CS registers.  The CALLF or JMPF then
  3801.           references the address of the new values.  Example:
  3802.  
  3803.           BIOS        EQU   0F000H           ;RAM bios segment
  3804.           PRINTER_IO  EQU   0EFD2H           ;printer routine
  3805.                       MOV   [DI],PRINTER_IO
  3806.                       MOV   2[DI],BIOS
  3807.                       CALLF [DI]
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.                                                                    59
  3830.  
  3831.     >>Running CHASM<<
  3832.  
  3833.     A. Prompt Mode
  3834.  
  3835.        From DOS, type:
  3836.  
  3837.          CHASM
  3838.  
  3839.        If you're using the Subset version, a hello screen is printed,
  3840.        followed by the message:
  3841.  
  3842.          Hit Esc to exit, anything else to continue...
  3843.  
  3844.        Advanced CHASM skips the commercial message.
  3845.  
  3846.        You're now presented with a series of prompts:
  3847.  
  3848.           Source code file name? [.asm]
  3849.  
  3850.        Type in the name of the file which contains your program.  If
  3851.        you don't include an extension for the filename, CHASM
  3852.        assumes it to be .ASM.  If CHASM is unable to find the file,
  3853.        it will give you the option of naming another file, or
  3854.        returning to DOS.  Note that anywhere CHASM expects a
  3855.        filename, you can optionally include a drive and/or path.
  3856.  
  3857.        Assuming your file is present, CHASM prompts:
  3858.  
  3859.           Direct listing to Printer (P), Screen (S), or Disk (D)?
  3860.           [nul:]
  3861.  
  3862.        Respond with either an upper or lower case letter.  If you
  3863.        just press enter, no listing will be produced.  If you select
  3864.        "D", CHASM will prompt:
  3865.  
  3866.           Name for listing file? [fname.lst]
  3867.  
  3868.        Type in a name for the listing file.  If you just press ENTER,
  3869.        the name defaults to that of your source file, with an
  3870.        extension of .LST.
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.  
  3890.  
  3891.  
  3892.  
  3893.  
  3894.  
  3895.                                                                    60
  3896.  
  3897.        Listing Notes:
  3898.  
  3899.           1. The setting of the /PATH configuration switch controls
  3900.              the exact form of the default list file name.
  3901.  
  3902.           2. Regardless of where the listing is sent, error messages
  3903.              are always echoed to the screen.
  3904.  
  3905.           3. Suppressing the listing will result in faster assembly.
  3906.  
  3907.        The final prompt is:
  3908.  
  3909.           Name for object file? [fname.com]
  3910.  
  3911.        Type in a name for the assembled program.  If you just press
  3912.        ENTER, the name defaults to that of your source file, with an
  3913.        extension of .COM.
  3914.  
  3915.        Note: The setting of the /PATH configuration switch controls
  3916.              the exact form of the default object file name.
  3917.  
  3918.        CHASM now assembles your program.  A status line is maintained
  3919.        on the screen, showing how many lines have been processed,
  3920.        along with how many errors have been discovered.  CHASM makes
  3921.        two passes over your source file, outputting the listing and
  3922.        object code on the second pass.  You can pause assembly at any
  3923.        time by hitting Cntl-S (or just S).  Hitting any key then
  3924.        resumes assembly. You may abort assembly and return to DOS at
  3925.        any time by hitting Esc, Ctrl-C or Ctrl-Break.
  3926.  
  3927.        At the end of the second pass, a final summary of the assembly
  3928.        process is printed.  It will look something like:
  3929.  
  3930.           0 Error(s) detected
  3931.           0 Diagnostic(s) offered
  3932.  
  3933.        954 (3BAH) Bytes of object code generated
  3934.  
  3935.        This information should be self-explanatory.  The number of
  3936.        bytes is given in both decimal and hex format.
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.  
  3961.                                                                    61
  3962.  
  3963.        If labels appeared in your program, a dump of the symbol table
  3964.        will follow.  This lists each user-defined symbol, along with
  3965.        its value (in hex). The symbols are printed in alphabetical
  3966.        order.  Each value is preceded by a one-letter code, which
  3967.        tells the symbol's type:
  3968.  
  3969.                 P: a program location
  3970.                 M: a memory location for data
  3971.                 I: immediate data
  3972.  
  3973.        Upon exit, CHASM sets the system variable ERRORLEVEL to
  3974.        (surprise!) the total number of errors discovered in your
  3975.        source file. If you run CHASM from a batch file, you can use
  3976.        this feature to automatically invoke your text editor if
  3977.        errors were discovered.
  3978.  
  3979.     B. Expert Mode:
  3980.  
  3981.        This mode allows you to specify all i/o information on the
  3982.        command line which invokes CHASM.  The syntax is:
  3983.  
  3984.           CHASM sourcefile [p|s|d|/] [listfile|/] [objectfile]
  3985.  
  3986.        Items within brackets ([]) are optional. You may select *one*
  3987.        of any list of items separated by a bar (|).
  3988.  
  3989.        Basically, you just include on the command line all your
  3990.        responses to the normal prompts.  Each response must be
  3991.        separated from the others by either a space or comma.
  3992.  
  3993.        If you don't specify the list device/file or the object file,
  3994.        they default to NUL: and sourcename.COM respectively.  To
  3995.        represent a carriage return (to specify a default choice, but
  3996.        allow modifying a later response) use the character slash (/).
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.  
  4014.  
  4015.  
  4016.  
  4017.  
  4018.  
  4019.  
  4020.  
  4021.  
  4022.  
  4023.  
  4024.  
  4025.  
  4026.  
  4027.                                                                    62
  4028.  
  4029.        Expert mode examples:
  4030.  
  4031.           1. Source file is EXAMPLE.ASM, no listing, object file
  4032.              EXAMPLE.COM:
  4033.  
  4034.                 CHASM example
  4035.  
  4036.           2. Source file is SDIR.ASM, list to printer, object file
  4037.              SDIR.COM:
  4038.  
  4039.                 CHASM sdir p
  4040.  
  4041.           3. Source file is MYFILE.PRG, list to disk file MYFILE.LST,
  4042.              object file SUBR.COM:
  4043.  
  4044.                 CHASM myfile.prg d / subr.com
  4045.  
  4046.  
  4047.  
  4048.  
  4049.  
  4050.  
  4051.  
  4052.  
  4053.  
  4054.  
  4055.  
  4056.  
  4057.  
  4058.  
  4059.  
  4060.  
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066.  
  4067.  
  4068.  
  4069.  
  4070.  
  4071.  
  4072.  
  4073.  
  4074.  
  4075.  
  4076.  
  4077.  
  4078.  
  4079.  
  4080.  
  4081.  
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.  
  4088.  
  4089.  
  4090.  
  4091.  
  4092.  
  4093.                                                                    63
  4094.  
  4095.     >>Error and Diagnostic Messages<<
  4096.  
  4097.     Error messages generated on pass one appear on the listing before
  4098.     any source code is printed, and mention the line number to which
  4099.     they refer.  The majority of messages occur during pass two, and
  4100.     will appear in the listing immediately prior to the line which
  4101.     caused the message.  Unless the listing itself is going to the
  4102.     screen, messages and the source line which generated them will be
  4103.     echoed there.
  4104.  
  4105.     Add Leading Zero to Hex Constant: Diagnostic.  The unknown
  4106.        symbol could be interpreted as a hexadecimal number if a
  4107.        leading zero was added.
  4108.  
  4109.     CHASM Internal Error: XX PC: YYYY or
  4110.     CHASM I/O Error: XX PC: YYYY
  4111.        Sigh. You just discovered a problem in CHASM itself.  Please
  4112.        contact Whitman Software, following the procedure in the
  4113.        appendix on Bug Reporting.
  4114.  
  4115.     Could Use JMPS: Diagnostic.  The specified label requires an
  4116.        offset of less than 128 bytes; specifying the short jump would
  4117.        result in more compact code.  The assembled code is correct,
  4118.        however.
  4119.  
  4120.     Conditional Nested Too Deeply:  IF statements can only be nested
  4121.        10 deep.
  4122.  
  4123.     Data too Large:  You are attempting to use a word of immediate
  4124.        data where only a byte is allowed.
  4125.  
  4126.     Duplicate Definition of XXX in (linenum): Pass 1 error.  An
  4127.        attempt was made to define a symbol already present in the
  4128.        symbol table.
  4129.  
  4130.     ELSE without IF: An ELSE was encountered, but no corresponding
  4131.        conditional pseudo-op was found.
  4132.  
  4133.     ENDIF without IF: An ENDIF was encountered, but no corresponding
  4134.        conditional pseudo-op was found.
  4135.  
  4136.     ENDM without MACRO:  An ENDM was encountered, but no
  4137.        corresponding MACRO was found.
  4138.  
  4139.     ENDP without PROC: An ENDP was encountered, but no corresponding
  4140.        PROC was found.
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.  
  4154.  
  4155.  
  4156.  
  4157.  
  4158.  
  4159.                                                                    64
  4160.  
  4161.  
  4162.     ENDSTRUC without STRUC: An ENDSTRUC was encountered, but no
  4163.        corresponding STRUC was found.
  4164.  
  4165.     EQU Without Label: No symbol was found to equate with the
  4166.        operand.
  4167.  
  4168.     File not found: XXX in (linenum).  Pass one error.  CHASM was
  4169.        unable to find the file XXX, specified in the INCLUDE
  4170.        pseudo-op.
  4171.  
  4172.     Heap Full: Too many XXX.  Usually a Pass one error.
  4173.        You've run out of memory for the symbol and macro tables.  You
  4174.        shouldn't see this message unless you have only 128K and are
  4175.        assembling a very large program.
  4176.  
  4177.     Illegal Label: XXX in (linenum). Pass one error.  The symbol
  4178.        XXX begins in column one and has as its first character a
  4179.        number, or a plus or minus sign.  Alternatively, you tried to
  4180.        use a reserved word or symbol as a label.
  4181.  
  4182.     Illegal Operation for Structure - ENDSTRUC Implied: Diagnostic.
  4183.        The current line is within a structure, and is not a storage
  4184.        defining pseudo-op.  CHASM generates an ENDSTRUC, which
  4185.        terminates the structure definition, then assembles the line
  4186.        normally.
  4187.  
  4188.     Illegal or Undefined Argument for LENGTH:  The argument for the
  4189.        LENGTH  function was not present in the symbol table as an
  4190.        immediate operand on pass 2.
  4191.  
  4192.     Illegal or Undefined Argument for OFFSET: The argument for the
  4193.        OFFSET function was not present in the symbol table as a near
  4194.        label or memory location on pass 2.
  4195.  
  4196.     Missing ENDM:  The end of the input file was encountered, and at
  4197.        least one MACRO had not been terminated by an ENDM.
  4198.  
  4199.     Missing ENDP: The end of the input file was encountered, and at
  4200.        least one PROC had not been terminated by an ENDP.
  4201.  
  4202.     Missing ENDSTRUC: The end of the input file was encountered, and
  4203.        at least one STRUC had not been terminated by an ENDSTRUC.
  4204.  
  4205.  
  4206.  
  4207.  
  4208.  
  4209.  
  4210.  
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.  
  4224.  
  4225.                                                                    65
  4226.  
  4227.     Multiple Segment Overrides are Illegal:  Diagnostic.  You have
  4228.        specified more than one segment override on this instruction.
  4229.        The first override is used, and the other(s) ignored.
  4230.  
  4231.     Nested INCLUDE: An INCLUDE was encountered in an INCLUDEd file.
  4232.        The INCLUDE pseudo-op cannot be nested.
  4233.  
  4234.     Nested Structure: A STRUC was encountered inside a structure.
  4235.        Structures cannot be nested.
  4236.  
  4237.     No Name For Macro:  Diagnostic.  The macro statement did not have
  4238.        a label.  CHASM is unable to give a name to the macro, and you
  4239.        will be unable to reference it.
  4240.  
  4241.     Operands Not Compatible:  The size of the two operands does not
  4242.        match.
  4243.  
  4244.     Phase Error: A label or memory location is found to have
  4245.        different values on pass 1 and pass 2.  A difficult to debug
  4246.        error: generally the problem is not caused by the statement
  4247.        which received the error message. The problem is caused by an
  4248.        improper statement before this one, but after any other labels
  4249.        (otherwise *they* would have received the error message).
  4250.  
  4251.        When phase errors are discovered, CHASM prints this message,
  4252.        then resynchronizes the location counter to match the offset
  4253.        calculated on pass one.  If further phase errors are reported,
  4254.        the line responsable for each subsequent error will be located
  4255.        between two Phase Error messages, but after any unflagged
  4256.        labels.
  4257.  
  4258.        There are four documented ways to generate phase errors.
  4259.  
  4260.        1. A previous instruction used a symbolic immediate operand
  4261.           prior to the symbol's definition.
  4262.  
  4263.        2. A previous instruction made improper use of a forward
  4264.           referenced label, either an attempt to branch into a data
  4265.           area, or to access a code area as if it was data.
  4266.  
  4267.        3. The label on the flagged statement is defined more than
  4268.           once in the program.
  4269.  
  4270.        4. A previous instruction invoked a macro prior to its
  4271.           definition.
  4272.  
  4273.  
  4274.  
  4275.  
  4276.  
  4277.  
  4278.  
  4279.  
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.  
  4289.  
  4290.  
  4291.                                                                    66
  4292.  
  4293.        Whitman Software would appreciate hearing about any other
  4294.        situations which cause the Phase Error message to appear.
  4295.  
  4296.     Parameter Too Large for Expansion: Diagnostic. Replacement of the
  4297.        dummy parameter would cause the macro line to exceed CHASM's
  4298.        internal 255 character limit for manipulating strings.
  4299.        Generally this message will be accompanied by the "Source Line
  4300.        Truncated" message, warning that a line has exceeded the
  4301.        allowed 80 columns.
  4302.  
  4303.     Procedures Nested Too Deeply: Procedures may be
  4304.        nested no more than 10 deep.
  4305.  
  4306.     Source Line Truncated:  The length of the input line exceeded 80
  4307.        characters.
  4308.  
  4309.     Specify Word or Byte Operation: Diagnostic.  CHASM suggests that
  4310.        the Syntax Error might be resolved by adding the suffix "B" or
  4311.        "W" to the instruction mnemonic.  Most, but not all, ambiguous
  4312.        memory references are flagged with this diagnostic.
  4313.  
  4314.     Syntax Error: (OP) (DEST), (SOURCE).  CHASM was unable to find a
  4315.       version of the instruction (OP) which allows the operands
  4316.       (DEST) and (SOURCE).  Either the instruction doesn't exist, or
  4317.       it is an inappropriate choice for the given operands.  The (OP)
  4318.       (Dest), (Source) is a reconstruction of your source line based
  4319.       on how CHASM parsed it.  A comparison of the reconstruction and
  4320.       your original source code will sometimes help pinpoint the
  4321.       error.
  4322.  
  4323.       Syntax Error messages are followed by two diagnostics which
  4324.       spell out in words CHASM's best guess about the operands.
  4325.       Again, a comparison between CHASM's guesses and what you
  4326.       really meant can help find the problem.
  4327.  
  4328.     Too Far For Short Jump: The displacement to the specified label
  4329.        is not in the range -128 to +127.
  4330.  
  4331.     Undefined Operand for EQU: Any operands on an EQU statement must
  4332.        have been previously defined.
  4333.  
  4334.     Undefined Symbol XXX: The symbol XXX was used as an operand, but
  4335.        never appeared as a label, and is not a predefined symbol.
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.  
  4353.  
  4354.  
  4355.  
  4356.  
  4357.                                                                    67
  4358.  
  4359.     Unrecognized Operand XXX: XXX is used in the DB or DW operand
  4360.        list, but is not a valid immediate operand. (or string, in the
  4361.        case of DB).
  4362.  
  4363.  
  4364.  
  4365.  
  4366.  
  4367.  
  4368.  
  4369.  
  4370.  
  4371.  
  4372.  
  4373.  
  4374.  
  4375.  
  4376.  
  4377.  
  4378.  
  4379.  
  4380.  
  4381.  
  4382.  
  4383.  
  4384.  
  4385.  
  4386.  
  4387.  
  4388.  
  4389.  
  4390.  
  4391.  
  4392.  
  4393.  
  4394.  
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.  
  4416.  
  4417.  
  4418.  
  4419.  
  4420.  
  4421.  
  4422.  
  4423.                                                                    68
  4424.  
  4425.     >>Execution of Assembled Programs<<
  4426.  
  4427.     A. Object code format
  4428.  
  4429.        The object code file produced by CHASM is in the form of a
  4430.        memory image, exactly as will be present in your computer at
  4431.        run time.  No link step is required.  Provided that the segment
  4432.        registers are set correctly, the architecture of the 8088
  4433.        guarantees that code is self-relocating, and will run correctly
  4434.        loaded anywhere in memory.  Storing a program as an exact image
  4435.        of memory at run time is called the COM format by IBM.
  4436.  
  4437.        This COM format is *not* that produced by the IBM assembler.
  4438.        The output of the IBM assembler is in the form of an "object
  4439.        module" suitable for input to the linker.  The object module
  4440.        is not directly executable, but must first be "filtered"
  4441.        through the linker.  This adds an extra step to the process of
  4442.        producing a working program, but gives you the option of
  4443.        combining multiple object modules into one program.  The
  4444.        resulting linked program is *still* not a memory image, but
  4445.        has a header which is used to perform relocation during
  4446.        loading.  This linked program plus header is called the EXE
  4447.        format by IBM.
  4448.  
  4449.     B. Running Assembled Programs From DOS
  4450.  
  4451.        DOS provides a loader for running machine language programs.
  4452.        To run a program, you merely type its name, without the
  4453.        extension.  This is what you're doing every time you use a DOS
  4454.        external command such as FORMAT or CHKDSK.  In fact, the COM
  4455.        format is named after "external COMmand".
  4456.  
  4457.        When DOS loads a program, it examines the file extension to
  4458.        determine what format the file is in, either COM or EXE.  This
  4459.        is why CHASM defaults to using the extension .COM for your
  4460.        object file.  If you plan to run the program from DOS, don't
  4461.        change the extension.
  4462.  
  4463.        For COM programs, DOS builds a 255 byte long "program segment
  4464.     prefix" and sets the segment registers to point to this PSP. The
  4465.     contents of the file are then loaded verbatim right after the
  4466.     PSP, at offset hex 100 in the segment defined by the segment
  4467.     registers.  As soon as loading is complete, your program is
  4468.     executed starting with the instruction at hex 100.
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.  
  4479.  
  4480.  
  4481.  
  4482.  
  4483.  
  4484.  
  4485.  
  4486.  
  4487.  
  4488.  
  4489.                                                                    69
  4490.  
  4491.        Although you can totally ignore the PSP, you should read pages
  4492.     E-3 through E-11 of the DOS manual to see what DOS puts there for
  4493.     you.  It turns out there are some real goodies which your program
  4494.     might want to use.
  4495.  
  4496.        When your program is done, it must transfer control back to
  4497.        DOS, otherwise the 8088 will continue to fetch what it
  4498.        believes are instructions from whatever garbage or bit-hash
  4499.        happens to follow your program in memory.  The easiest way to
  4500.        return to DOS is to execute the instruction:
  4501.  
  4502.          INT 20H
  4503.  
  4504.        This is the vectored interrupt reserved by DOS for program
  4505.        termination.
  4506.  
  4507.        While we're on the topic of vectored interrupts, you would be
  4508.        well rewarded to study both the DOS Technical Reference and
  4509.        Hardware Technical Reference Manuals to find out what happens
  4510.        when you execute some of the other interrupts.  Some very
  4511.        useful functions, such as file handling and screen i/o, are
  4512.        available at the machine language level through this
  4513.        mechanism.  Information on interrupts is also available in
  4514.        Peter Norton's book "Programmer's Guide to the IBM PC", which
  4515.        is cheaper than buying both of IBM's reference manuals, and
  4516.        also more readable.
  4517.  
  4518.        Looking at things the other way, by changing the interrupt
  4519.        vector for a given function to point to your own code, you can
  4520.        override the way DOS or the BIOS does something, and do it
  4521.        your way.  DOS even provides a method (via interrupt 27H) by
  4522.        which your new code can be grafted onto DOS, and not be
  4523.        overwritten by other programs.
  4524.  
  4525.     C. Debugging Assembled Programs
  4526.  
  4527.        IBM provides an excellent utility with DOS, called DEBUG.COM.
  4528.        By specifying your program's name as a parameter when invoking
  4529.        DEBUG, you can observe your program execute with DEBUG's trace
  4530.        and other functions.  To debug your program, from DOS type:
  4531.  
  4532.           DEBUG progname.COM
  4533.  
  4534.  
  4535.  
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.  
  4544.  
  4545.  
  4546.  
  4547.  
  4548.  
  4549.  
  4550.  
  4551.  
  4552.  
  4553.  
  4554.  
  4555.                                                                    70
  4556.  
  4557.        DEBUG builds a PSP and loads your program just like DOS does,
  4558.        but you have the added power of the debugging commands to
  4559.        monitor your program while it runs.  See chapter 6 of the DOS
  4560.        manual for more details about using DEBUG.
  4561.  
  4562.        On the topic of debugging, I can recommend most highly a
  4563.        program called TRACE86, from Morgan Computing (10400 N.
  4564.        Central Expressway, Suite 210, Dallas, TX 75231).  The program
  4565.        replaces DEBUG, and although rather steeply priced, makes the
  4566.        IBM debugger look silly.  I've been using TRACE86 for some
  4567.        time now, and wouldn't be without it.
  4568.  
  4569.     D. Using Assembled Programs in BASIC
  4570.  
  4571.        To incorporate a machine language subroutine in a BASIC
  4572.        program, write it in assembly language, then assemble it with
  4573.        CHASM.  You should read page C-7 of the BASIC manual for some
  4574.        conventions to use in writing your subroutine.  In particular,
  4575.        note that you must declare the routine to CHASM as a FAR
  4576.        procedure using the PROC pseudo-op, and that the last
  4577.        instruction of the routine should be a RET.
  4578.  
  4579.        Unlike programs which are run directly from DOS, your routine
  4580.        will not be preceded by a program segment prefix.  You should
  4581.        prevent CHASM from leaving room for a PSP by putting an ORG 0
  4582.        pseudo-op at the beginning of your routine. If you don't
  4583.        include the ORG, memory references will not be assembled
  4584.        correctly.  Example:
  4585.  
  4586.             ORG  0    ;no psp
  4587.        SUBR PROC FAR  ;far procedure
  4588.             ...       ;body of subroutine
  4589.             RET
  4590.             ENDP
  4591.  
  4592.        CHASM supports two methods for getting assembled routines into
  4593.        BASIC programs.  The methods differ in whether the routine is
  4594.        included in the BASIC program file, or in a separate file.
  4595.  
  4596.        A utility program called COM2DATA is provided for including
  4597.        machine language within BASIC program files.  The program is
  4598.        distributed in source code form (file COM2DATA.ASM) and must
  4599.        be assembled with CHASM prior to use.  The program functions
  4600.        as a DOS 2 filter, reading a COM file in from the standard
  4601.        input, and writing a series of BASIC DATA statements to the
  4602.        standard output.
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.  
  4620.  
  4621.                                                                    71
  4622.  
  4623.  
  4624.        COM2DATA's syntax is as follows:
  4625.  
  4626.          COM2DATA [<infile] [>outfile] [linenum]
  4627.  
  4628.        You specify the input and output files as with any DOS 2
  4629.        filter.  The linenum parameter sets the starting line number
  4630.        used on the BASIC code produced.  If you don't specify
  4631.        linenum, it defaults to 1000.
  4632.  
  4633.        If you MERGE the file of DATA statements into your BASIC
  4634.        program, the program can then READ the data and POKE it into
  4635.        memory.  An example program to do this is given on page C-6 of
  4636.        the BASIC manual.  An alternative approach would be to store
  4637.        the routine in a string variable, which could later be located
  4638.        with the VARPTR function.
  4639.  
  4640.        If you would prefer to keep your machine language subroutine
  4641.        in a separate file, include a BSAVE pseudo-op somewhere within
  4642.        your assembly language source code.  CHASM will build a header
  4643.        on the object code produced, which will mimic that built by
  4644.        BASIC's BSAVE command.  The resulting file may be BLOADed by
  4645.        BASIC to any location in memory.
  4646.  
  4647.        You transfer control to your routine with either the USR
  4648.        function, or the CALL statement.  Syntax for these statements
  4649.        can be found in the BASIC manual.
  4650.  
  4651.  
  4652.  
  4653.  
  4654.  
  4655.  
  4656.  
  4657.  
  4658.  
  4659.  
  4660.  
  4661.  
  4662.  
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672.  
  4673.  
  4674.  
  4675.  
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.  
  4682.  
  4683.  
  4684.  
  4685.  
  4686.  
  4687.                                                                    72
  4688.  
  4689.  
  4690.     E. Using Assembled Programs with Turbo Pascal:
  4691.  
  4692.        CHASM and Turbo Pascal work splendidly together, complementing
  4693.        each other's strong points.  You can use CHASM to provide new
  4694.        functions you wish Turbo had, or to fine tune a critical
  4695.        procedure for optimum speed.   CHASM itself is written in a
  4696.        combination of Turbo Pascal and CHASM.
  4697.  
  4698.        CHASM supports two techniques for producing machine language
  4699.        code for Turbo Pascal: external procedures or functions, and
  4700.        Turbo INLINE code.
  4701.  
  4702.     1. External Procedures and Functions:
  4703.  
  4704.        Turbo loads external procedures and functions within the same
  4705.        segment as the rest of your Pascal program.  You have no
  4706.        control of the exact load location (more on this later), but
  4707.        on the other hand, you don't have to worry about setting aside
  4708.        a special location for your procedures (as in BASIC).  Since
  4709.        your external procedure is loaded in the same segment as the
  4710.        Pascal code, it should be declared NEAR to CHASM:
  4711.  
  4712.          EXTERNAL PROC NEAR
  4713.                   ...           ;body of procedure
  4714.                   ...
  4715.                   ENDP
  4716.  
  4717.        Turbo passes parameters to your procedure/function via the
  4718.        stack.  To work effectively, a good grasp of the stack
  4719.        structure is critical.  Read the Turbo manual for information
  4720.        on internal data formats and parameter passing, to see just
  4721.        what to expect on the stack.  Also, remember that the stack
  4722.        grows *down* from the top of memory.
  4723.  
  4724.        If you're going to access the stack in your procedure, the
  4725.        first thing you should do is set up BP as a stack pointer.
  4726.        Since Turbo also uses BP, you have to save the current value
  4727.        first.  The obvious place to save it is on the stack...
  4728.  
  4729.           PUSH BP           ;save old BP
  4730.           MOV  BP, SP        ;and set up to indirectly address stack
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744.  
  4745.  
  4746.  
  4747.  
  4748.  
  4749.  
  4750.  
  4751.  
  4752.  
  4753.                                                                    73
  4754.  
  4755.        You can now access the parameters on the stack using offsets
  4756.        relative to the BP register.  Note that since you PUSHed BP,
  4757.        everything is 2 bytes deeper onto the stack than what Turbo
  4758.        originally sent you.
  4759.  
  4760.        Here's an example.  Suppose you declare the following external
  4761.        function in Turbo:
  4762.  
  4763.           function Sum(x,y: int): int;
  4764.              external 'sum.com';
  4765.  
  4766.        After you've pushed BP, here's how the stack looks:
  4767.  
  4768.            stack contents           indirect address
  4769.         ----------------------------------------------
  4770.            <function result>             8[BP]
  4771.            <value of parameter y>        6[BP]
  4772.            <value of parameter x>        4[BP]
  4773.            <return address to Turbo>     2[BP]
  4774.            <old BP value>                 [BP]
  4775.  
  4776.        The indirect addresses go up two at a time, since each item on
  4777.        the stack is a word (two bytes) long. You can access the
  4778.        parameters using their indirect addresses. We'll talk more
  4779.        about the "function result" area later; ignore it for now.
  4780.        Here's the code for an external function to add two integer
  4781.        parameters:
  4782.  
  4783.        SUM  PROC NEAR
  4784.             PUSH BP          ;save old BP
  4785.             MOV  BP, SP      ;set up stack pointer
  4786.  
  4787.             MOV  AX,  4[BP]  ;get parameter x
  4788.             MOV  ADD, 6[BP]  ;add parameter y
  4789.                              ;leave sum in AX to return to Turbo
  4790.  
  4791.             POP  BP          ;restore old BP for Turbo
  4792.             RET  6           ;clear params and "result" off stack
  4793.             ENDP
  4794.  
  4795.  
  4796.  
  4797.  
  4798.  
  4799.  
  4800.  
  4801.  
  4802.  
  4803.  
  4804.  
  4805.  
  4806.  
  4807.  
  4808.  
  4809.  
  4810.  
  4811.  
  4812.  
  4813.  
  4814.  
  4815.  
  4816.  
  4817.  
  4818.  
  4819.                                                                    74
  4820.  
  4821.        A more elegant way to access the parameters is by using a
  4822.        CHASM structure to define their offsets on the stack:
  4823.  
  4824.        STACK    STRUC
  4825.        OLDBP    DW   0000H
  4826.        RETADDR  DW   0000H
  4827.        XPARAM   DW   0000H
  4828.        YPARAM   DW   0000H
  4829.                 ENDSTRUC
  4830.  
  4831.        With this structure added to the above example, you could
  4832.        access the parameters like this:
  4833.  
  4834.                 MOV  AX, XPARAM[BP]    ;get parameter X
  4835.  
  4836.        Functions return scalar results by having the value in AX upon
  4837.        return.  The function in the above example saves some time by
  4838.        calculating the value in AX in the first place.  Upon exit,
  4839.        the function POPs BP, to restore the value Turbo was using.
  4840.  
  4841.        Note the RET 4 in the example.  This returns to Turbo, while
  4842.        simultaneously POPing (and discarding) 4 bytes off the stack.
  4843.        This clears off the two parameters which Turbo passed.  If
  4844.        there were three parameters, you'd use a RET 6; if none, a
  4845.        simple RET would do. When Turbo receives control, it assumes
  4846.        that you've cleaned up the stack by removing all parameters.
  4847.        If you don't do this properly, a run-time error, or even a
  4848.        system crash will result.
  4849.  
  4850.        (Typical scenario:  Turbo tries to return from one of its own
  4851.        subroutines, thinking the top of the stack has the return
  4852.        address.  Unfortunately, the top is really an integer
  4853.        parameter, left over from your external function.  Turbo's
  4854.        RET sends control into some random area of memory, and boom -
  4855.        the system crashes.)
  4856.  
  4857.        It's easy to get confused about the exact contents of the
  4858.        stack.  If your procedure doesn't seem to be working right,
  4859.        the first thing to suspect is Turbo and you have different
  4860.        ideas about what's where on the stack.  A DEBUG session can
  4861.        usually straighten things out.
  4862.  
  4863.  
  4864.  
  4865.  
  4866.  
  4867.  
  4868.  
  4869.  
  4870.  
  4871.  
  4872.  
  4873.  
  4874.  
  4875.  
  4876.  
  4877.  
  4878.  
  4879.  
  4880.  
  4881.  
  4882.  
  4883.  
  4884.  
  4885.                                                                    75
  4886.  
  4887.        Boolean functions constitute a special case which is poorly
  4888.        documented in the Turbo Pascal manual.  Boolean functions must
  4889.        return their result in two ways:
  4890.  
  4891.            1. by setting the zero flag (Z = false, NZ = true)
  4892.  
  4893.            2. and by returning either 0 (false) or 1 (true) in AX
  4894.  
  4895.        The first return method is assumed by Turbo if you use the
  4896.        function in a conditional statement, the second if you assign
  4897.        the value of the function to a variable.  You need to return
  4898.        the result both ways to cover all possible uses of your
  4899.        function.
  4900.  
  4901.        When external functions are called, in addition to the normal
  4902.        parameters, Turbo passes something called the "function
  4903.        result" on the stack.  When the result is a scalar type (other
  4904.        than real), this seems to be intended just as a local work
  4905.        area for you to use, since Turbo ignores any value you store
  4906.        there.  (For non-real scalars, the result is actually
  4907.        returned in AX).
  4908.  
  4909.        In fact, like a parameter, the function result must be POPed
  4910.        off the stack when your function returns to Turbo. Unlike
  4911.        scalar parameters (which always occupy a word of stack memory,
  4912.        even if they are defined as byte), the function result is the
  4913.        exact length of the result type.  Thus for a boolean function,
  4914.        you have to POP off one extra byte above and beyond those for
  4915.        clearing off the parameters.
  4916.  
  4917.        Functions which return either a real or non-scalar result use
  4918.        the "function result" area to return their result, since it
  4919.        won't fit in AX.  For these types of functions, you shouldn't
  4920.        pop the "function result" area before returning, since Turbo
  4921.        is expecting to find it on top of the stack.
  4922.  
  4923.        A problem of addressability can crop up if your external
  4924.        procedure tries to maintain its own local variables and/or
  4925.        constants.  The problem is that you have no way of knowing
  4926.        just where Turbo is going to load your procedure within the
  4927.        shared segment.  As such, the address CHASM calculates for any
  4928.        memory locations are going to be offset from their real values
  4929.        by some unknown constant, the offset of the procedure within
  4930.        the shared segment.  This is called a relocation problem.
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944.  
  4945.  
  4946.  
  4947.  
  4948.  
  4949.  
  4950.  
  4951.                                                                    76
  4952.  
  4953.        Fortunately, there's a way around this problem, but it
  4954.        requires using a trick.  Your program has to figure out, *at
  4955.        run time*, just where it's located in memory.  If you could
  4956.        find out the offset of any known point in your procedure,
  4957.        you'd "have your bearings" so to speak, and could go on.
  4958.  
  4959.        The trick is as follows.  The 8088 CALL instruction pushes the
  4960.        address of the next instruction onto the stack, then branches
  4961.        to the location given in the CALL.  By performing a dummy
  4962.        CALL, then stealing the value off the stack, we have the
  4963.        location of a known spot in the procedure.   By subtracting
  4964.        the offset within the procedure of that known location, we get
  4965.        a pointer to the beginning of the procedure which can be used
  4966.        to access everything else.  Here's an example:
  4967.  
  4968.        LOCAL  PROC NEAR
  4969.               PUSH BP                     ;set up to access stack
  4970.               MOV  BP, SP                 ; ditto
  4971.  
  4972.               CALL DUMMY                  ;establish addressability
  4973.        DUMMY  POP  BX                     ;  "           "
  4974.               SUB  BX, OFFSET(DUMMY)
  4975.  
  4976.               MOV  AX, 4[BP]                ;get parameter
  4977.               SEG  CS                       ;offset relative to CS
  4978.               ADD  OFFSET(TOTAL)[BX], AX    ;maintain running total
  4979.  
  4980.               POP  BP
  4981.               RET  2
  4982.        TOTAL  DW   0000H
  4983.               ENDP
  4984.  
  4985.        We use indirect addressing here.  After the funny business
  4986.        with the CALL, POP, SUB sequence, BX has a pointer to the
  4987.        beginning of the procedure.  Using indirect addressing, we
  4988.        take that pointer and add in the offset of the memory location
  4989.        we want to access.  In this example we're using a local
  4990.        variable to maintain a running total of the parameter which
  4991.        gets passed.
  4992.  
  4993.  
  4994.  
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002.  
  5003.  
  5004.  
  5005.  
  5006.  
  5007.  
  5008.  
  5009.  
  5010.  
  5011.  
  5012.  
  5013.  
  5014.  
  5015.  
  5016.  
  5017.                                                                    77
  5018.  
  5019.        Note the SEG CS just before the ADD which accesses the
  5020.        location TOTAL.  Since we found our bearings by stealing the
  5021.        address of a program instruction, our offset is known relative
  5022.        to the CS register, NOT the DS which is normally used to
  5023.        access data.  The SEG CS forces the 8088 to calculate the
  5024.        address using CS rather than the default DS register.  Every
  5025.        time you access a memory location within your procedure, you
  5026.        *MUST* do it relative to CS by using a segment override.
  5027.  
  5028.        Turbo requires that you preserve the values of the following
  5029.        registers:
  5030.  
  5031.             BP, CS, DS, SS
  5032.  
  5033.        If you want to use these registers in your routine, the
  5034.        easiest way to preserve them is to PUSH them onto the stack at
  5035.        the beginning of your routine, then POP them just before
  5036.        returning.  As near as I can tell, you can safely trash the
  5037.        other registers.
  5038.  
  5039.  
  5040.     2. INLINE Code
  5041.  
  5042.        An alternative method of incorporating code into Turbo Pascal
  5043.        is through Turbo's inline statement.  The inline statement is
  5044.        intended for short routines or patches where you just give
  5045.        Turbo a list of numbers representing the code.  In addition to
  5046.        numbers, you can also include variable names in the inline
  5047.        list.  Turbo replaces them with their offsets at compile time.
  5048.  
  5049.        CHASM's INLINE pseudo-op is provided to facilitate producing
  5050.        Turbo inline code.  If you put an INLINE pseudo-op in your
  5051.        CHASM source file, rather than producing a normal object code
  5052.        file, CHASM produces a text file formatted to include in a
  5053.        Turbo inline statement.  For example:
  5054.  
  5055.            inline        ;shift to inline mode
  5056.            mov  ah, 0FH  ;call bios for video mode
  5057.            int  10H      ;  ditto
  5058.  
  5059.        produces the following object file:
  5060.  
  5061.                         {    inline       ;shift to inline mode    }
  5062.           $B4/$0F/      {    mov ah, 0FH  ;call bios for video mode}
  5063.           $CD/$10/      {    int 10H      ;  ditto                 }
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.  
  5073.  
  5074.  
  5075.  
  5076.  
  5077.  
  5078.  
  5079.  
  5080.  
  5081.  
  5082.  
  5083.                                                                    78
  5084.  
  5085.        Object code is output in text form, as hex constants.  A
  5086.        comment with the source code for each line is also generated.
  5087.  
  5088.        The INLINE pseudo-op can appear anywhere in your source file,
  5089.        and it requires no operands.
  5090.  
  5091.        Object files produced from source files with an INLINE
  5092.        pseudo-op are NOT executable!  They contain text suitable for
  5093.        inclusion in Turbo Pascal inline statements.  It's probably a
  5094.        good idea to override CHASM's default name for the object
  5095.        file, and specify something with an extension other than COM
  5096.        to prevent DOS from trying to run the program.
  5097.  
  5098.        Your inline code must preserve the BP, SP, DS and SS
  5099.        registers. If you need to modify these registers, you should
  5100.        PUSH the ones you need at the beginning of your code, and POP
  5101.        them at the end.
  5102.  
  5103.        Turbo's inline statement allows you to insert variable names
  5104.        in with the list of numbers.  At compile time, Turbo will
  5105.        replace the name with the 16 bit offset of the variable in its
  5106.        native segment.  (See the Turbo Pascal manual for a discussion
  5107.        of internal data formats and the native segment of variables.)
  5108.  
  5109.        CHASM supports this capability with the TURBO() function.
  5110.        CHASM treats TURBO() as 16 bit immediate data during assembly.
  5111.        However, in place of the two bytes of data, CHASM outputs the
  5112.        function argument literally for Turbo to evaluate:
  5113.  
  5114.           inline
  5115.           mov   bl, turbo(flag)[bp]     ;local variable "flag"
  5116.           mov   ax, cs:[turbo(maxcode)] ;typed constant "maxcode"
  5117.           lds   si, turbo(y)[bp]        ;pointer to var parameter "y"
  5118.  
  5119.        produces:
  5120.  
  5121.                               {      inline                        }
  5122.           $8A/$9E/FLAG/       {      mov   bx, turbo(flag)[bp]     }
  5123.           $2E/$A1/MAXCODE/    {      mov   ax, cs:[turbo(maxcode)] }
  5124.           $C5/$B6/Y/          {      lds   si, turbo(y)[bp]        }
  5125.  
  5126.  
  5127.  
  5128.  
  5129.  
  5130.  
  5131.  
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141.  
  5142.  
  5143.  
  5144.  
  5145.  
  5146.  
  5147.  
  5148.  
  5149.                                                                    79
  5150.  
  5151.     F. Symbolic Debugging
  5152.  
  5153.        ===> Advanced Version Only
  5154.  
  5155.        The MAP pseudo-op (available in CHASM's advanced version)
  5156.        generates a file containing label information that can be used
  5157.        by debugging software to show label names in your program
  5158.        during debugging.  This makes debugging *much* easier, since
  5159.        you don't have to keep looking at a listing to tell where you
  5160.        are in your program.
  5161.  
  5162.        The map file is formatted to be used by Advanced Trace86 from
  5163.        Morgan Computing, but may be usable by other debuggers.  If
  5164.        you're using CHASM's map files with another debugger, please
  5165.        write so that other's can share this information.
  5166.  
  5167.        In AT86, the following command sequence will load in a
  5168.        program, including labels:
  5169.  
  5170.            N program.MAP
  5171.            LL
  5172.            N program.COM
  5173.            L
  5174.  
  5175.        The LL (load labels) command has to come before you load the
  5176.        program, since AT86 uses the program area as a workspace when
  5177.        loading labels.
  5178.  
  5179.        The map file contains data about both program locations and
  5180.        data locations.  AT86 handles the program labels correctly, so
  5181.        the label appears both on the labeled line, and is referenced
  5182.        on any JMP or CALL to the labeled line.  Data locations get
  5183.        partial support.  The location is labeled, but only memory
  5184.        references with a CS: segment override use the symbolic name.
  5185.  
  5186.  
  5187.  
  5188.  
  5189.  
  5190.  
  5191.  
  5192.  
  5193.  
  5194.  
  5195.  
  5196.  
  5197.  
  5198.  
  5199.  
  5200.  
  5201.  
  5202.  
  5203.  
  5204.  
  5205.  
  5206.  
  5207.  
  5208.  
  5209.  
  5210.  
  5211.  
  5212.  
  5213.  
  5214.  
  5215.                                                                    80
  5216.  
  5217.     >>Notes for Those Upgrading to This Version of CHASM<<
  5218.  
  5219.     CHASM is not yet carved in stone - improvements and corrections
  5220.     are made fairly frequently, based on both my own experience in
  5221.     using the program, and the comments of outside users.  This
  5222.     section summarizes the changes which have been made since version
  5223.     1.2 was released.  Changes followed with an asterisk (*) denote
  5224.     modifications which could invalidate programs written under
  5225.     earlier versions of CHASM.
  5226.  
  5227.     Version   Notes
  5228.     4.14      "S" suffix allowed on ADC, ADD, CMP, SBB and SUB to
  5229.               generate sign extended versions of these instructions
  5230.               when used with immediate data which can be expressed in
  5231.               8 bits.  Sign extension saves 1 byte per instruction.
  5232.  
  5233.     4.13      Labels and memory locations now allowed in DW operand
  5234.               list without using OFFSET().
  5235.  
  5236.     4.12      FBLD now working.  Corrected bug in reporting number
  5237.               of object code bytes generated by DS with large
  5238.               numbers.
  5239.  
  5240.     4.11      "N" suffix now optional on JMP and CALL through a 16
  5241.               bit register.
  5242.  
  5243.     4.10      Fixed bug which caused lockup when using negative
  5244.               numbers with RADIX 16 in effect.  Document
  5245.               improvements, including index.
  5246.  
  5247.     4.09      Speed enhancement. MUL, IMUL, DIV, IDIV now accept more
  5248.               operand options.  Memory labels now allowed as indirect
  5249.               offsets.  Some bugs in COM2DATA fixed.
  5250.  
  5251.     4.08      New option in /BEEP switch.  MAP pseudo-op for use with
  5252.               symbolic debuggers.
  5253.  
  5254.     4.07      Speed enhancement.  Intersegment JMP and CALL fixed.
  5255.               Expressions now allowed in the subset.  Characters + -
  5256.               * / ) ( are now reserved for expressions only. (*)
  5257.  
  5258.     4.06      Speed enhancement.  Turbo Pascal INLINE facility.
  5259.               /VIDEO configuration switch.  New conditionals: IFREG,
  5260.               IFREG8, IFREG16, IFSEGREG.  New pseudo-ops: INLINE,
  5261.               RADIX, CHKJMP, NOCHKJMP.  New function: TURBO(). Single
  5262.               quotes now allowed in strings (use two).  Obsolete
  5263.  
  5264.  
  5265.  
  5266.  
  5267.  
  5268.  
  5269.  
  5270.  
  5271.  
  5272.  
  5273.  
  5274.  
  5275.  
  5276.  
  5277.  
  5278.  
  5279.  
  5280.  
  5281.                                                                    81
  5282.  
  5283.               COUNT, ENDC and DM pseudo-ops no longer supported. (*)
  5284.  
  5285.  
  5286.  
  5287.     4.05      Speed enhancement.  Characters now work in expressions.
  5288.               EJECT and EJECTIF appear *before* page breaks.  /DPAGE
  5289.               configuration switch.  Parameter collection on macro
  5290.               invocations now halts before comments.  SHL can now
  5291.               also be written as SAL.
  5292.  
  5293.     4.04      RET with displacement is now assembled correctly.
  5294.               Parser bug fixed which crashed on strings with '/'.
  5295.  
  5296.     4.03      Assembler variables.  Operand size incompatibility now
  5297.               reported. FSUB now assembles correctly.  Intermittent
  5298.               bug in expressions with forward references fixed.
  5299.               Indirect memory references with offsets and segment
  5300.               overides now assemble correctly.  Only the first
  5301.               occurrence of a phase error is now reported.
  5302.  
  5303.     4.02      DS storage assembly is now turned off during structure
  5304.               definitions.  Structures assemble faster. Intermittent
  5305.               problem with macro parameter expansion cleared up.
  5306.  
  5307.     4.01      8087 support.  WAITON and WAITOFF pseudo-ops. Internal
  5308.               labels for macros.  Corrects bug which caused crash on
  5309.               certain syntax errors.
  5310.  
  5311.     4.00      Total rewrite in Turbo Pascal.  Subset replaces
  5312.               interpreted version as free distribution release.
  5313.               Faster assembly.  Symbol and macro tables now use all
  5314.               available memory.  Nested macros permitted.  Operand
  5315.               expressions. $ now returns location counter value.  New
  5316.               syntax for segment overrides.  Conditional pseudo-ops
  5317.               now evaluate operands.  Improved error and diagnostic
  5318.               messages.  DOS 2 or later now required (*). DOS 2 path
  5319.               support for files. Setting of DOS 2 ERRORLEVEL. EJECTIF
  5320.               pseudo-op added. New configuration switches: /DWIDTH,
  5321.               /FF /TIMER, /PATH. CHASM.CFG must now have only one
  5322.               switch per line (*).
  5323.  
  5324.     3.15      Macros added. New pseudo-ops: MACRO, ENDM, IFE, IFNE,
  5325.               IFB, IFNB, ELSE, ENDIF.
  5326.  
  5327.  
  5328.  
  5329.  
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.  
  5339.  
  5340.  
  5341.  
  5342.  
  5343.  
  5344.  
  5345.  
  5346.  
  5347.                                                                    82
  5348.  
  5349.  
  5350.  
  5351.  
  5352.  
  5353.     3.14      Interpreted version frozen at version 2.13, further
  5354.               changes apply only to compiled version.  Memory
  5355.               requirement raised to 128K.  INCLUDE, STRUC, ENDSTRUC,
  5356.               DM, DW, LIST, NOLIST, COUNT and ENDC pseudo-ops added.
  5357.               Alternate mnemonics for the jump on condition
  5358.               instructions, and alternate syntax for the DIV and MUL
  5359.               instructions.  Binary numbers added.
  5360.  
  5361.     2.13      Assembly can now be aborted with the Esc key. Negative
  5362.               decimal numbers are working again.  Input lines now
  5363.               limited to 80 characters, and labels must begin with a
  5364.               non-numeral. (*)
  5365.  
  5366.     2.12      Listings can now be suppressed.  Error messages echoed to
  5367.               the console on non-screen listings. Expert mode added.
  5368.  
  5369.     2.11      Pagination improved.  Listings now time stamped. OFFSETs
  5370.               and word values now allowed in DB operand list.
  5371.  
  5372.     2.10      Equated symbols allowed in the DB operand list.  Status
  5373.               line improved.
  5374.  
  5375.     2.09      The first digit of hexadecimal constants must now be in
  5376.               the range 0-9. A leading zero is permitted on four digit
  5377.               hex constants, to allow fulfilling this condition. (*)
  5378.  
  5379.     2.08      Configuration process expanded.  CHASM now skips over
  5380.               perforations on printed listings.  EJECT pseudo-op added.
  5381.  
  5382.     2.07      Oops.  Configuration file now works as advertised.
  5383.  
  5384.     2.06      CHASM now supports reverse long jumps.
  5385.  
  5386.     2.05      Compiled version released.  BSAVE pseudo-op.
  5387.               Configuration process simplified.
  5388.  
  5389.     2.04      TABs are now expanded and replaced with blanks, for
  5390.               compatibility with IBM text editors.
  5391.  
  5392.     2.03      Two bugs corrected.  The first involved incorrect
  5393.               assembly of indirect memory references with
  5394.               displacements in the range 128-255.  The second caused
  5395.  
  5396.  
  5397.  
  5398.  
  5399.  
  5400.  
  5401.  
  5402.  
  5403.  
  5404.  
  5405.  
  5406.  
  5407.  
  5408.  
  5409.  
  5410.  
  5411.  
  5412.  
  5413.                                                                    83
  5414.  
  5415.               a crash if a hex number longer than 4 digits used.
  5416.  
  5417.     2.01      COM2DATA utility added.
  5418.  
  5419.     2.00      Corrected a bug in the DS and DB pseudo-ops which caused
  5420.               the last label in a program to be redefined as a memory
  5421.               location.  Also, the TAB character was added as a new
  5422.               delimiter, and PRIMER.DOC was added to the CHASM package.
  5423.  
  5424.     1.9       The short jump is now represented with mnemonic JMPS, for
  5425.               compatibility with DEBUG version 1.1. (*)
  5426.  
  5427.     1.8       The operand type "character" was added as a new way to
  5428.               represent immediate data.
  5429.  
  5430.     1.7       The DS operator now works for blocks larger than 255
  5431.               bytes.  Also, the OFFSET function now works properly in
  5432.               the displacement field of an indirect memory reference.
  5433.  
  5434.     1.6       A revision of this document.  Some sections were improved
  5435.               slightly, and in response to user requests, a section on
  5436.               execution of assembled programs was added.
  5437.  
  5438.     1.5       Corrected an error which generated the message "Data too
  5439.               Long" if the value FFH was used as 8 bit immediate data.
  5440.  
  5441.     1.4       User interface improved.  CHASM now traps some common
  5442.               input errors such as misspelling a file name, or
  5443.               forgetting to turn on your printer.
  5444.  
  5445.     1.3       A speed enhancement.  Version 1.3 benchmarks about 5
  5446.               times faster than version 1.2.
  5447.  
  5448.  
  5449.  
  5450.  
  5451.  
  5452.  
  5453.  
  5454.  
  5455.  
  5456.  
  5457.  
  5458.  
  5459.  
  5460.  
  5461.  
  5462.  
  5463.  
  5464.  
  5465.  
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472.  
  5473.  
  5474.  
  5475.  
  5476.  
  5477.  
  5478.  
  5479.                                                                    84
  5480.  
  5481.     >>Miscellaneous and A Word From Our Sponsor...<<
  5482.  
  5483.     A. Programming Notes:
  5484.  
  5485.        1. CHASM is written in a combination of Turbo Pascal and
  5486.           CHASM.  This is less incestuous than it sounds: the
  5487.           program was written in Turbo, then profiled to single
  5488.           out the critical routines.   The rate determining sections
  5489.           were rewritten in optimized assembly language, and
  5490.           assembled with the original Turbo Pascal version of CHASM.
  5491.           These routines were then incorporated as Turbo external
  5492.           procedures and functions in a new version of CHASM.
  5493.  
  5494.           The speed enhancements possible by "helping out" Turbo with
  5495.           CHASM can be quite dramatic.  Replacing four rate limiting
  5496.           routines out of over ten thousand lines of Pascal gave
  5497.           almost a four-fold speed increase!
  5498.  
  5499.           CHASM's source code is available to registered users by
  5500.           sending a formatted disk and stamped return mailer.  If you
  5501.           make any improvements, I'd like to hear about them for
  5502.           possible inclusion in future releases.
  5503.  
  5504.           Please note that although you can modify CHASM for your own
  5505.           use, under NO CIRCUMSTANCES may you distribute modified or
  5506.           translated versions, either in the public domain or for
  5507.           profit.
  5508.  
  5509.     B. Red Tape and Legal Nonsense:
  5510.  
  5511.        1. Disclaimer:
  5512.  
  5513.           CHASM is distributed as is, with no guarantee that it will
  5514.           work correctly in all situations.  In no event will the
  5515.           Author be liable for any damages, including lost profits,
  5516.           lost savings or other incidental or consequential damages
  5517.           arising out of the use of or inability to use these programs,
  5518.           even if the Author has been advised of the possibility of
  5519.           such damages, or for any claim by any other party.
  5520.  
  5521.           Despite the somewhat imposing statement above, it *is* my
  5522.           intention to fix any bugs which are brought to my attention.
  5523.           See the appendix on Bug Reporting for more details.
  5524.  
  5525.  
  5526.  
  5527.  
  5528.  
  5529.  
  5530.  
  5531.  
  5532.  
  5533.  
  5534.  
  5535.  
  5536.  
  5537.  
  5538.  
  5539.  
  5540.  
  5541.  
  5542.  
  5543.  
  5544.  
  5545.                                                                    85
  5546.  
  5547.        2. Copyright Information:
  5548.  
  5549.           The entire CHASM distribution package, consisting of the
  5550.           main program, documentation files, and various data and
  5551.           utility files, is copyright (c) 1983, 1984, 1985 and 1986
  5552.           by David Whitman.  The author reserves the exclusive right
  5553.           to distribute this package, or any part thereof, for
  5554.           profit. The name "CHASM (tm)", applied to a microcomputer
  5555.           assembler program, is a trademark of David Whitman.
  5556.  
  5557.           CHASM's Subset version and various subsidiary files may be
  5558.           copied freely by individuals for evaluation purposes.  It
  5559.           is expected that those who find the package useful will
  5560.           make a contribution directly to the author of the program.
  5561.           The Subset version identifies itself by displaying a banner
  5562.           page giving the author's address and inviting free copying.
  5563.           ONLY VERSIONS DISPLAYING THIS BANNER PAGE MAY BE COPIED.
  5564.  
  5565.           CHASM's Advanced version is only available to registered
  5566.           users who have made the $40 suggested payment.  Registered
  5567.           users may copy the program for backup purposes, but must
  5568.           restrict use of the program to either one user or one CPU,
  5569.           at their option.
  5570.  
  5571.           CHASM's source code is made available for educational
  5572.           purposes and to allow users to customize for their own
  5573.           personal use.  Under NO CIRCUMSTANCES may modified versions
  5574.           or translations into other computer languages be
  5575.           distributed, either in the public domain or for profit.
  5576.  
  5577.           User groups and clubs are authorized to distribute CHASM's
  5578.               Subset version under the following conditions:
  5579.  
  5580.           1.  No charge is made for the software or documentation.  A
  5581.               nominal distribution fee may be charged, provided that
  5582.               it is no more than $8 total.
  5583.  
  5584.           2.  Recipients are to be informed of the user-supported
  5585.               software concept, and encouraged to support it with
  5586.               their donations.
  5587.  
  5588.           3.  The program and documentation are not modified in ANY
  5589.               way, and are distributed together.
  5590.  
  5591.  
  5592.  
  5593.  
  5594.  
  5595.  
  5596.  
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.  
  5606.  
  5607.  
  5608.  
  5609.  
  5610.  
  5611.                                                                    86
  5612.  
  5613.           Interested manufacturers are invited to contact Whitman
  5614.           Software to discuss licensing CHASM for bundling with
  5615.           MS-DOS based computer systems.
  5616.  
  5617.           Distribution of CHASM outside the United States is through
  5618.           licensed distributors, on a royalty basis.  Interested
  5619.           distributors are invited to contact Whitman Software.
  5620.  
  5621.        3. Royalty Information:
  5622.  
  5623.           No royalties are required to distribute programs produced
  5624.           using CHASM.  However, if you send me a copy of any major
  5625.           program you have produced using CHASM, I'll give you a free
  5626.           page of advertising in this document.
  5627.  
  5628.        4. Educational Discount:
  5629.  
  5630.           Substantial discounts are available for multi-CPU licenses
  5631.           of CHASM's Advanced version to educational institutions.
  5632.           Contact Whitman Software for details.
  5633.  
  5634.     C. An Offer You Can't Refuse.
  5635.  
  5636.        CHASM is User-Supported software, distributed under a
  5637.        modification of the FREEWARE (tm) marketing scheme developed by
  5638.        the late Andrew Fluegelman, whose inspiration and efforts are
  5639.        gratefully acknowledged.
  5640.  
  5641.        Anyone may obtain a free copy of CHASM's Subset version by
  5642.        sending a blank, formatted diskette to the author. An
  5643.        addressed, postage-paid return mailer must accompany the disk
  5644.        (no exceptions, please).
  5645.  
  5646.        A copy of the program, with documentation, will be sent by
  5647.        return mail.  The program will carry a notice suggesting a
  5648.        payment to the program's author.  Making the payment
  5649.        is totally voluntary on the part of the user.  Regardless of
  5650.        whether a payment is made, the user is encouraged to
  5651.        share the program with others.  Payment for use is
  5652.        discretionary on the part of each subsequent user.
  5653.  
  5654.  
  5655.  
  5656.  
  5657.  
  5658.  
  5659.  
  5660.  
  5661.  
  5662.  
  5663.  
  5664.  
  5665.  
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.  
  5672.  
  5673.  
  5674.  
  5675.  
  5676.  
  5677.                                                                    87
  5678.  
  5679.        The underlying philosophy here is based on three principles:
  5680.  
  5681.        First, that the value and utility of software is best assessed
  5682.           by the user on his/her own system.  Only after using a
  5683.           program can one really determine whether it serves personal
  5684.           applications, needs, and tastes.
  5685.  
  5686.        Second, that the creation of independent personal computer
  5687.           software can and should be supported by those who benefit
  5688.           from its use.
  5689.  
  5690.        Finally, that copying and networking of programs should be
  5691.           encouraged, rather than restricted.  The ease with which
  5692.           software can be distributed outside traditional commercial
  5693.           channels reflects the strength, rather than the weakness,
  5694.           of electronic information.
  5695.  
  5696.       If you like this software, please help support it.  Your
  5697.       support can take three forms:
  5698.  
  5699.       1. Become a registered user.  The suggested payment for
  5700.          registration is $40.
  5701.  
  5702.       2. Suggestions, comments, and bug reports.  Your comments will
  5703.          be taken seriously - user feedback was responsible for most
  5704.          of the changes listed in CHASM's revision history.
  5705.  
  5706.       3. Spread the word.  Make copies of the Subset for friends.
  5707.          Write the editor of your favorite computer magazine.
  5708.          Astronomical advertising costs are one big reason that
  5709.          commercial software is so overpriced.  To continue offering
  5710.          CHASM this way, I need your help in letting other people
  5711.          know about CHASM.
  5712.  
  5713.  
  5714.  
  5715.  
  5716.  
  5717.  
  5718.  
  5719.  
  5720.  
  5721.  
  5722.  
  5723.  
  5724.  
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.  
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.  
  5742.  
  5743.                                                                    88
  5744.  
  5745.       Those who make the $40 payment to become registered users
  5746.       receive the following benefits:
  5747.  
  5748.       1. An upgrade to the Advanced version of the program. The
  5749.          Advanced version executes twice as fast as the Subset and
  5750.          supports macros, conditional assembly and other features.
  5751.          An order form for the Advanced version is given at the end
  5752.          of this manual.
  5753.  
  5754.       2. User support, by phone or mail. The phone number and address
  5755.          for help are given below.  SUPPORT IS ONLY AVAILABLE TO
  5756.          REGISTERED USERS.  If you call without registering, be
  5757.          prepared to listen to a Tanstaafl lecture (*).
  5758.  
  5759.       3. Notices announcing the release of significant upgrades.
  5760.  
  5761.      (*) Tanstaafl = There Ain't No Such Thing As A Free Lunch.  A
  5762.          basic truism of the universe, first expounded by R.A.
  5763.          Heinlein.  There is also no such thing as free user support.
  5764.  
  5765.     CHASM is copyrighted, and users are requested NOT to make copies
  5766.     of the Advanced version other than for their own use.  I am
  5767.     strongly opposed to copy protection, and would regret being
  5768.     forced to protect CHASM.  Please recognize the amount of time and
  5769.     money which went into producing CHASM, and respect the wishes of
  5770.     the author.
  5771.  
  5772.           David Whitman
  5773.           P.O. Box 1157
  5774.           North Wales, PA 19454
  5775.  
  5776.           (215) 234-4084 (evenings/weekends only)
  5777.  
  5778.  
  5779.  
  5780.  
  5781.  
  5782.  
  5783.  
  5784.  
  5785.  
  5786.  
  5787.  
  5788.  
  5789.  
  5790.  
  5791.  
  5792.  
  5793.  
  5794.  
  5795.  
  5796.  
  5797.  
  5798.  
  5799.  
  5800.  
  5801.  
  5802.  
  5803.  
  5804.  
  5805.  
  5806.  
  5807.  
  5808.  
  5809.                                                                    89
  5810.  
  5811.     Appendix A: 8088 Mnemonic List
  5812.  
  5813.     This appendix lists the mnemonics which CHASM will recognize,
  5814.     grouped roughly by function.  Consult "The 8086 Book" for
  5815.     definitions of these instructions, and for the operands each will
  5816.     accept.  Mnemonics marked with an asterisk (*) will accept a 'B'
  5817.     or 'W' suffix for ambiguous memory references.
  5818.  
  5819.     Arithmetic:
  5820.  
  5821.     AAA      AAD       AAM       AAS       ADC*      ADD*      CBW
  5822.     CWD      CMP*      CMPS*     DAA       DAS       DEC*      DIV*
  5823.     IDIV*    IMUL*     INC*      MUL*      NEG*      SBB*      SUB*
  5824.  
  5825.     Data Movement:
  5826.  
  5827.     LAHF     LDS       LEA       LES       LODS*     MOV*     MOVS*
  5828.     POP      POPF      PUSH      PUSHF     SAHF      XCHG     XLAT
  5829.  
  5830.     Logical:
  5831.  
  5832.     AND*     NOT*      OR*       TEST*     XOR*
  5833.  
  5834.     String Primitives:
  5835.  
  5836.     CMPS*    LODS*     MOVS*     SCAS*     STOS*
  5837.  
  5838.     Instruction Prefixes:
  5839.  
  5840.     LOCK     REP       REPE      REPNE     REPNZ     REPZ      SEG
  5841.  
  5842.     Program Counter Control: (unconditional)
  5843.  
  5844.     CALL     CALLN     CALLF     JMP       JMPF      JMPN      JMPS
  5845.     RET
  5846.  
  5847.     Program Counter Control: (conditional)
  5848.  
  5849.     JA       JAE      JB      JBE      JC        JCXZ       JE
  5850.     JG       JGE      JL      JLE      JNA       JNAE       JNB
  5851.     JNBE     JNC      JNE     JNG      JNGE      JNL        JNLE
  5852.     JNO      JNO      JNP     JNS      JNZ       JO         JP
  5853.     JPE      JPO      JS      JZ       LOOP      LOOPE      LOOPNE
  5854.     LOOPNZ   LOOPZ
  5855.  
  5856.  
  5857.  
  5858.  
  5859.  
  5860.  
  5861.  
  5862.  
  5863.  
  5864.  
  5865.  
  5866.  
  5867.  
  5868.  
  5869.  
  5870.  
  5871.  
  5872.  
  5873.  
  5874.  
  5875.                                                                    90
  5876.  
  5877.     Processor Control:
  5878.  
  5879.     CLC      CLD       CLI       CMC       HLT       NOP       STC
  5880.     STD      STI       WAIT
  5881.  
  5882.     I/O:
  5883.  
  5884.     IN       OUT
  5885.  
  5886.     Interrupt:
  5887.  
  5888.     INT      INTO      IRET
  5889.  
  5890.     Rotate and Shift:
  5891.  
  5892.     RCL*     RCR*      ROL*      ROR*      SAL*      SAR*      SHL*
  5893.     SHR*
  5894.  
  5895.  
  5896.  
  5897.  
  5898.  
  5899.  
  5900.  
  5901.  
  5902.  
  5903.  
  5904.  
  5905.  
  5906.  
  5907.  
  5908.  
  5909.  
  5910.  
  5911.  
  5912.  
  5913.  
  5914.  
  5915.  
  5916.  
  5917.  
  5918.  
  5919.  
  5920.  
  5921.  
  5922.  
  5923.  
  5924.  
  5925.  
  5926.  
  5927.  
  5928.  
  5929.  
  5930.  
  5931.  
  5932.  
  5933.  
  5934.  
  5935.  
  5936.  
  5937.  
  5938.  
  5939.  
  5940.  
  5941.                                                                    91
  5942.  
  5943.     Appendix B: 8087 Mnemonic List
  5944.  
  5945.     ===> Advanced version only.
  5946.  
  5947.     This appendix lists the 8087 mnemonics recognized by CHASM's
  5948.     Advanced version, grouped roughly by function.
  5949.  
  5950.     Arithmetic:
  5951.  
  5952.     FADD     FADDP    FCHS     FDIV     FDIVP     FDIVR    FDIVRP
  5953.     FIADD    FIDIV    FIDIVR   FIMUL    FISUB     FISUBR   FMUL
  5954.     FMULP    FPREM    FSUB     FSUBP    FSUBR     FSUBRP
  5955.  
  5956.     Mathematical Functions:
  5957.  
  5958.     F2XM1    FABS     FPATAN   FPTAN    FRNDINT   FSCALE   FSQRT
  5959.     FXTRACT  FYL2X    FYL2XP1
  5960.  
  5961.     Data Movement:
  5962.  
  5963.     FBLD     FBSTP    FILD     FIST     FISTP     FLD      FLD1
  5964.     FLDL2E   FLDL2T   FLDLG2   FLDLN2   FLDPI     FLDZ     FST
  5965.     FSTP     FXCH
  5966.  
  5967.     Comparison:
  5968.  
  5969.     FCOM     FCOMP    FCOMPP   FICOM    FICOMP    FTST      FXAM
  5970.  
  5971.     Processor Control:
  5972.  
  5973.     FCLEX    FDECSTP  FDISI    FENI     FFREE     FINCSTP   FINIT
  5974.     FNCLEX   FNDISI   FNENI    FNINIT   FNOP      WAIT
  5975.  
  5976.     Processor Status:
  5977.  
  5978.     FLDCW    FLDENV   FNSAVE   FNSTCW   FNSTENV   FNSTSW    FRSTOR
  5979.     FSAVE    FSTCW    FSTENV   FSTSW
  5980.  
  5981.  
  5982.  
  5983.  
  5984.  
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.  
  6002.  
  6003.  
  6004.  
  6005.  
  6006.  
  6007.                                                                    92
  6008.  
  6009.     Appendix C: Differences Between CHASM and That Other Assembler
  6010.  
  6011.     Virtually all magazine articles about assembly language
  6012.     programming on the IBM PC assume that the reader is using That
  6013.     Other Assembler - you know, the outrageously priced one.  This
  6014.     appendix will try to summarize the differences between the two
  6015.     programs.  Please note that I do not own a copy of That Other
  6016.     Assembler, and therefore this section is not complete, nor even
  6017.     guaranteed to be correct.  I continue to work on this section,
  6018.     and users of both products are invited to suggest additions or
  6019.     corrections, so that this section will continually improve with
  6020.     time.
  6021.  
  6022.     A. General Differences
  6023.  
  6024.     The biggest difference is philosophical.  The IBM assembler was
  6025.     designed for use by professional assembly language programmers,
  6026.     to write operating systems and other huge projects.  This is
  6027.     reflected in the large size and relative complexity of the macro
  6028.     assembler.
  6029.  
  6030.     On the other hand, CHASM was designed for use by beginners, to
  6031.     write relatively short programs.  This was done by leaving out
  6032.     some of the power offered by IBM's assembler, in exchange for
  6033.     simplicity and ease of use.  The main simplification involved
  6034.     producing object code in the COM format, rather than the EXE
  6035.     format chosen by IBM. There are two main consequences of this
  6036.     choice:
  6037.  
  6038.        1. You can't link routines assembled by CHASM to
  6039.           Microsoft languages. (Although you *can* include them in
  6040.           Turbo Pascal or BASIC programs.)
  6041.  
  6042.        2. Your program has to fit in one 64K segment.  If (shudder!)
  6043.           you want to write a 256K assembly language program, you're
  6044.           out of luck.
  6045.  
  6046.     Like Pascal, the IBM assembler is a strongly typed language.  By
  6047.     requiring you to specify the *type* of each memory location you
  6048.     will access in your program, the IBM assembler generally knows
  6049.     what size of memory operand you want.  If you don't like the
  6050.     declared size, you have to override the default with the PTR
  6051.     operator.  Thus, to loading the AL register from a location
  6052.     declared word is a syntax error, unless you specify BYTE PTR
  6053.     before the address.
  6054.  
  6055.  
  6056.  
  6057.  
  6058.  
  6059.  
  6060.  
  6061.  
  6062.  
  6063.  
  6064.  
  6065.  
  6066.  
  6067.  
  6068.  
  6069.  
  6070.  
  6071.  
  6072.  
  6073.                                                                    93
  6074.  
  6075.  
  6076.     In analogy to the C language, CHASM is weakly typed. CHASM is
  6077.     perfectly happy extracting a byte from where you originally set
  6078.     aside a word - CHASM can't tell the difference. In most cases,
  6079.     CHASM can tell what size you want from context:  for example, if
  6080.     you're using a word register, it *must* be a word memory access. On
  6081.     the other hand, for any access to memory which doesn't have a
  6082.     register as the other operand, you must add either a 'B' or a 'W'
  6083.     to the instruction mnemonic used by IBM.
  6084.  
  6085.     B. Miscellaneous Differences:
  6086.  
  6087.        1. Short Jumps:
  6088.  
  6089.           IBM uses the SHORT keyword, CHASM uses an 'S' suffix.
  6090.           Example:
  6091.  
  6092.           JMP   SHORT label    ;ibm
  6093.           JMPS  label          ;chasm
  6094.  
  6095.        2. Offset Function:
  6096.  
  6097.           Where IBM precedes an operand with the keyword OFFSET,
  6098.           CHASM has a *function* called OFFSET. CHASM requires
  6099.           parentheses around the operand. Example:
  6100.  
  6101.           MOV   AX, OFFSET FCB  ;ibm
  6102.           MOV   AX, OFFSET(FCB) ;chasm
  6103.  
  6104.        3. Declaring Storage:
  6105.  
  6106.           A.  If you don't care what value a memory location is
  6107.               initialized to, the IBM assembler allows you to specify
  6108.               '?' as its contents.  In CHASM, if you don't care what
  6109.               value the variable is initialized to, just put down a
  6110.               zero.  Example:
  6111.  
  6112.                  DB   ?      ;ibm
  6113.                  DB   0      ;chasm
  6114.  
  6115.  
  6116.  
  6117.  
  6118.  
  6119.  
  6120.  
  6121.  
  6122.  
  6123.  
  6124.  
  6125.  
  6126.  
  6127.  
  6128.  
  6129.  
  6130.  
  6131.  
  6132.  
  6133.  
  6134.  
  6135.  
  6136.  
  6137.  
  6138.  
  6139.                                                                    94
  6140.  
  6141.  
  6142.           B.  The IBM assembler allows the keyword DUP as an operand
  6143.               in storage declaring pseudo-ops.  This means to repeat
  6144.               the definition as many times as the number just before
  6145.               the DUP.  Example:
  6146.  
  6147.               DW   3 DUP(?)  ;ibm
  6148.               DW   0, 0, 0   ;chasm
  6149.  
  6150.     4. ASSUME Pseudo-op:
  6151.  
  6152.        IBM's ASSUME pseudo-op tells the assembler where the segment
  6153.        registers will be pointing.  CHASM always assumes that the CS,
  6154.        DS and SS registers point to the beginning of the code
  6155.        segment, and that the SS register has been set up to point to
  6156.        a valid stack area.  If you find an ASSUME pseudo-op with
  6157.        different assumptions for the CS, DS and ES registers you'll
  6158.        have to figure out the addresses for memory references in the DS
  6159.        and ES segments yourself.
  6160.  
  6161.     5. Segment Pseudo-op:
  6162.  
  6163.        This pseudo-op is used to set up multiple segments in the IBM
  6164.        assembler.  Since CHASM only allows one segment, there is no
  6165.        equivalent pseudo-op.  If there is only one segment definition
  6166.        in an IBM assembler program, everything is fine, just leave
  6167.        the pseudo-op out for CHASM.
  6168.  
  6169.        Often times the SEGMENT pseudo-op is used to provide
  6170.        addressing of an area in the BIOS, or perhaps the interrupt
  6171.        vector table at the beginning of memory.  For example, if a
  6172.        program needed to get at the BIOS data area, in the IBM
  6173.        assembler you would define a dummy segment with the same
  6174.        structure as that in the BIOS listing in Technical Reference:
  6175.  
  6176.          DATA          SEGMENT AT 40H
  6177.          RS232_BASE    DW    4 DUP(?)
  6178.          PRINTER_BASE  DW    4 DUP(?)
  6179.          EQUIP_FLAG    DW    ?
  6180.          MFG_TST       DB    ?
  6181.          MEMORY_SIZE   DW    ?
  6182.          IO_RAM_SIZE   DW    ?
  6183.  
  6184.        All this is really accomplishing is giving a name to some
  6185.        memory locations which are outside the actual program being
  6186.        written.
  6187.  
  6188.  
  6189.  
  6190.  
  6191.  
  6192.  
  6193.  
  6194.  
  6195.  
  6196.  
  6197.  
  6198.  
  6199.  
  6200.  
  6201.  
  6202.  
  6203.  
  6204.  
  6205.                                                                    95
  6206.  
  6207.        In CHASM, you can accomplish the same thing using a structure.
  6208.        This will generate a series of immediate operands whose values
  6209.        correspond to the offsets of the labels in the dummy segment.
  6210.        You can then reference the locations by enclosing the label
  6211.        names in square brackets, to coerce from type immediate to
  6212.        type address.
  6213.  
  6214.          DUMMY         STRUC            ;simulate dummy segment
  6215.          RS232_BASE    DW    0, 0, 0, 0
  6216.          PRINTER_BASE  DW    0, 0, 0, 0
  6217.          EQUIP_FLAG    DW    0
  6218.          MFG_TST       DB    0
  6219.          MEMORY_SIZE   DW    0
  6220.          IO_RAM_SIZE   DW    0
  6221.                        ENDSTRUC
  6222.                        MOV AX, [EQUIP_FLAG]
  6223.  
  6224.     6. Labels:
  6225.  
  6226.        The macro assembler indicates a local label by appending a
  6227.        colon (:).  The colon does not become part of the label, and
  6228.        is not included when referencing the label.  CHASM's labels
  6229.        are all global, and although they may end with a colon, the
  6230.        colon will become part of the label itself, and must then be
  6231.        used when referencing the label.  Example:
  6232.  
  6233.        a2:   mov ax,cx      ;ibm
  6234.              jmp a2         ; "
  6235.  
  6236.        a2:   mov ax,cx      ;chasm
  6237.              jmp a2:        ;  "
  6238.  
  6239.        CHASM does provide support for local labels in macros.  See
  6240.        the discussion on internal labels in the macro section of this
  6241.        document.
  6242.  
  6243.     7. Entry Point:
  6244.  
  6245.        The macro assembler allows you to specify the point within
  6246.        your program where execution will begin.  A label is put
  6247.        on the entry point, then to indicate entry, the same label is
  6248.        placed on the "END" pseudo-op.  Since COM programs must always
  6249.        start at offset 100H, CHASM doesn't allow setting an entry
  6250.        point, or use the END pseudo-op.
  6251.  
  6252.  
  6253.  
  6254.  
  6255.  
  6256.  
  6257.  
  6258.  
  6259.  
  6260.  
  6261.  
  6262.  
  6263.  
  6264.  
  6265.  
  6266.  
  6267.  
  6268.  
  6269.  
  6270.  
  6271.                                                                    96
  6272.  
  6273.     Appendix D: Description of Files
  6274.  
  6275.     Your CHASM distribution disk contains a number of files.  This
  6276.     appendix will give a brief statement of the purpose of each.
  6277.  
  6278.     FILE           DESCRIPTION
  6279.     ----------------------------------------------------------------
  6280.     CHASM.CFG       Sample configuration file, for IBM printer.
  6281.  
  6282.     CHASM.COM       The CHASM program (either subset or advanced)
  6283.  
  6284.     CHASMS.COM      This file may appear on the disk of advanced
  6285.                     version users.  It is the current subset version,
  6286.                     that can be shared with others.  Please rename it
  6287.                     CHASM.COM on their disk, to avoid confusion.
  6288.  
  6289.     CHASM.DOC       This document.
  6290.  
  6291.     EXAMPLE.ASM     Sample source file.
  6292.  
  6293.     COM2DATA.ASM    Source code for COM2DATA filter.
  6294.  
  6295.     COM2DATA.DOC    Documentation for COM2DATA.
  6296.  
  6297.     FREEWARE.DOC    References to other User Supported programs.
  6298.  
  6299.     PRIMER.DOC      Simple introduction to assembly language.
  6300.  
  6301.     Occasionally, various other sample source files for CHASM will be
  6302.     distributed.  These files will have extension ASM, and will be
  6303.     accompanied by a corresponding DOC file.
  6304.  
  6305.  
  6306.  
  6307.  
  6308.  
  6309.  
  6310.  
  6311.  
  6312.  
  6313.  
  6314.  
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323.  
  6324.  
  6325.  
  6326.  
  6327.  
  6328.  
  6329.  
  6330.  
  6331.  
  6332.  
  6333.  
  6334.  
  6335.  
  6336.  
  6337.                                                                    97
  6338.  
  6339.     Appendix E: Bug Reporting Procedure
  6340.  
  6341.     Although each version of CHASM is tested extensively prior to
  6342.     release, any program of this magnitude is bound to contain a few
  6343.     bugs.  It is the intention of Whitman Software to correct any
  6344.     genuine problem which is reported.
  6345.  
  6346.     If you think you have found a bug in CHASM, please take the time
  6347.     to report it for correction.  Although any report is helpful,
  6348.     correction of the problem will be easiest if you provide the
  6349.     following:
  6350.  
  6351.        1. The version of CHASM you are using.  Your problem may have
  6352.           been fixed already!
  6353.  
  6354.        2. A brief description of what you believe the problem to be.
  6355.  
  6356.        3. A printed listing of a source file which manifests the
  6357.           problem.
  6358.  
  6359.           * DON'T send a 5,000 line program which has one
  6360.             manifestation of the bug!  Isolate the problem area, or
  6361.             write a short sample routine that demonstrates the bug.
  6362.  
  6363.     Unlike normal commercial software, where corrections are saved up
  6364.     for a major revision, bugs in CHASM are fixed as soon as reported,
  6365.     with a new version released almost immediately (which is why there
  6366.     are so many versions in CHASM's revision history).
  6367.  
  6368.                    =====> BONUS <======
  6369.  
  6370.     If you send a copy of your problem source file on disk, it will
  6371.     be returned with either a new, corrected version of CHASM, or
  6372.     with an explanation of what you were doing wrong to *think* you'd
  6373.     found a bug.
  6374.  
  6375.  
  6376.  
  6377.  
  6378.  
  6379.  
  6380.  
  6381.  
  6382.  
  6383.  
  6384.  
  6385.  
  6386.  
  6387.  
  6388.  
  6389.  
  6390.  
  6391.  
  6392.  
  6393.  
  6394.  
  6395.  
  6396.  
  6397.  
  6398.  
  6399.  
  6400.  
  6401.  
  6402.  
  6403.                                                                    98
  6404.  
  6405.     Appendix F: Using CHASM on "Compatible" Systems
  6406.  
  6407.     CHASM was written specifically for the IBM PC, but should
  6408.     function normally on true "compatibles".  This appendix is a new
  6409.     section to summarize compatibility data for various systems.
  6410.  
  6411.     Please help make this document section useful to others.  If you
  6412.     are using (or are unable to use...) CHASM on a non-IBM computer,
  6413.     please write with your experiences.  Does CHASM work correctly on
  6414.     your system? Are there specific problem areas?  Can they be
  6415.     worked around?
  6416.  
  6417.     If you are using a non-IBM system, I strongly recommend that at
  6418.     least to start out, you include the line:
  6419.  
  6420.           /VIDEO 2
  6421.  
  6422.     in your CHASM.CFG file (see the section on "Modifying CHASM's I/O
  6423.     Defaults" for a discussion of the CHASM.CFG file).  This will
  6424.     force CHASM to use BIOS calls to access your video screen.  By
  6425.     default, CHASM writes directly to the screen hardware for maximum
  6426.     speed.  Without this line, if your hardware is not *strictly* IBM
  6427.     compatible, CHASM's output could be invisible, or your system
  6428.     could even hang up and require re-booting.
  6429.  
  6430.     The following systems are reported to run CHASM sucessfully:
  6431.  
  6432.            Artisoft XT
  6433.            AT&T 6300
  6434.            Chameleon
  6435.            Columbia 1600-1
  6436.            Compaq, Compaq DeskPro, Compaq Plus
  6437.            Corona PC-2
  6438.            Heath 151
  6439.            IBM PC, XT, AT, 3270 PC, 3270 PC/G
  6440.            ITT XTRA
  6441.            Kaypro 16
  6442.            Leading Edge Model D
  6443.            Mega XT
  6444.            PC Designs FD-1
  6445.            Sanyo 555
  6446.            Sun-ST
  6447.            Superior PC
  6448.            Tandy 1000, 2000
  6449.            Televideo 1605
  6450.            Zenith 150
  6451.  
  6452.  
  6453.  
  6454.  
  6455.  
  6456.  
  6457.  
  6458.  
  6459.  
  6460.  
  6461.  
  6462.  
  6463.  
  6464.  
  6465.  
  6466.  
  6467.  
  6468.  
  6469.                                                                    99
  6470.  
  6471.  
  6472.  
  6473.     The following systems have one or more problems:
  6474.  
  6475.     ================================================================
  6476.     Tandy 1200HD - CHASM crashes on some systems.  The problem seems
  6477.     to be related to the exact amount of free memory available on the
  6478.     system.  You can prevent the crash by slightly changing the
  6479.     amount of free memory, to either a higher or lower number.
  6480.     Probably the easiest way to do this is to change the number of
  6481.     disk buffers, or load an extra device driver such as ANSII.SYS.
  6482.     Call Whitman Software if you have trouble.
  6483.     ================================================================
  6484.     ================================================================
  6485.     IBM PCjr. - Several users report getting as far as the source file
  6486.     prompt, at which point the program crashes.  Several other users
  6487.     (invariably with more than 128K of memory) report that CHASM works
  6488.     fine.  The PCjr uses part of user memory for the screen buffer, and
  6489.     PCjr users probably need 192K to run CHASM.
  6490.     ================================================================
  6491.  
  6492.  
  6493.  
  6494.  
  6495.  
  6496.  
  6497.  
  6498.  
  6499.  
  6500.  
  6501.  
  6502.  
  6503.  
  6504.  
  6505.  
  6506.  
  6507.  
  6508.  
  6509.  
  6510.  
  6511.  
  6512.  
  6513.  
  6514.  
  6515.  
  6516.  
  6517.  
  6518.  
  6519.  
  6520.  
  6521.  
  6522.  
  6523.  
  6524.  
  6525.  
  6526.  
  6527.  
  6528.  
  6529.  
  6530.  
  6531.  
  6532.  
  6533.  
  6534.  
  6535.                                                                   100
  6536.  
  6537.           ********ADVANCED VERSION ORDER FORM********
  6538.  
  6539.     Please add me to the list of registered CHASM users, and send me
  6540.     an upgrade to Advanced CHASM.  I understand that CHASM is
  6541.     copyrighted, and agree not to distribute any unauthorized copies
  6542.     of this Advanced version.
  6543.  
  6544.     Note that version 4 requires DOS 2 (or later)
  6545.     and 128K of memory. (192K for PCjr)
  6546.  
  6547.     Computer Model: ____________________________________
  6548.  
  6549.     Diskette format:            Total Memory: _______K
  6550.  
  6551.        __ single sided/9 sector
  6552.  
  6553.        __ doubled sided/9 sector
  6554.  
  6555.     Check one:
  6556.  
  6557.            ___ I enclose a check for $40
  6558.  
  6559.            ___ I am a past customer.  The enclosed check brings my
  6560.                total payment up to $40.
  6561.  
  6562.  
  6563.     Where did you hear about CHASM? ________________________________
  6564.  
  6565.     Name:    _______________________________________________________
  6566.  
  6567.     Address: _______________________________________________________
  6568.  
  6569.     City, State, Zip: ______________________________________________
  6570.  
  6571.  
  6572.     ================================================================
  6573.          Send order form and check to:
  6574.  
  6575.               Whitman Software
  6576.               P.O. Box 1157
  6577.               North Wales, PA 19454
  6578.  
  6579.  
  6580.  
  6581.  
  6582.  
  6583.  
  6584.  
  6585.  
  6586.  
  6587.  
  6588.  
  6589.  
  6590.  
  6591.  
  6592.  
  6593.  
  6594.  
  6595.  
  6596.  
  6597.  
  6598.  
  6599.  
  6600.  
  6601.                                                                   101
  6602.  
  6603.       ==============PRINTER ENHANCEMENT===================
  6604.  
  6605.  
  6606.     Michael Hoyt, of Soft and Friendly Software, has produced a set
  6607.     of printer enhancement programs using CHASM, which is sold under
  6608.     the name Prowriter Utilities.  The package supports the following
  6609.     printers:
  6610.  
  6611.         NEC 8023A-C
  6612.         Prowriter I  (C. Itoh 8510)
  6613.         Prowriter II (C. Itoh 1550)
  6614.  
  6615.     The package contains three programs:
  6616.  
  6617.         PRINT_CHARACTERS
  6618.         PRINT_SCREEN
  6619.         PRINT_SET
  6620.  
  6621.     Once PRINT_CHARACTERS is run, it attaches itself to DOS, and
  6622.     makes your printer have exactly the same character set as your
  6623.     video monitor.  The conversion is very professionally done.
  6624.     Particularly impressive are the line drawing characters, which
  6625.     actually form connected lines, both horizontally and vertically.
  6626.  
  6627.     As if this wasn't enough, PRINT_CHARACTERS adds italics
  6628.     capability as well.  The italics make very effective emphasis in
  6629.     documents and letters, and look really good.
  6630.  
  6631.     PRINT_SCREEN is a graphics screen dump, activated by the normal
  6632.     Shift/PrtSc sequence.  Several options are available which trade
  6633.     off speed and print quality.  Since I have the mono card, I
  6634.     haven't tried PRINT_SCREEN, but Michael sent me a sample printout
  6635.     which looked quite nice.
  6636.  
  6637.     PRINT_SET is a menu-driven program to turn on and off the various
  6638.     special printing modes supported by these printers.  A simple but
  6639.     effective program.
  6640.  
  6641.     I've been using this package with my NEC 8023 for a few months
  6642.     now, and I like them quite a bit.  To get a copy, send $35 to:
  6643.  
  6644.         Soft and Friendly
  6645.         RR 2 Box 65
  6646.         Solsberry, IN 47459
  6647.  
  6648.  
  6649.  
  6650.  
  6651.  
  6652.  
  6653.  
  6654.  
  6655.  
  6656.  
  6657.  
  6658.  
  6659.  
  6660.  
  6661.  
  6662.  
  6663.  
  6664.  
  6665.  
  6666.  
  6667.                                                                   102
  6668.  
  6669.          ================= NEW PRODUCT ====================
  6670.     VPRINT version 2.00
  6671.  
  6672.     VPRINT traps printer output to create a "virtual printer".
  6673.     Normal printer output is sent to a disk file of your chosing.
  6674.     Redirection of printer output allows you to:
  6675.  
  6676.        * Produce formatted disk files with software packages that
  6677.          don't support "printing to disk".
  6678.  
  6679.        * Set up word processors and other software to work with your
  6680.          printer.  Using DEBUG to examine output trapped to disk
  6681.          allows you to see exactly what's being sent to your printer,
  6682.          to immediately pinpoint problems.
  6683.  
  6684.        * Capture output generated on one computer, to be printed on
  6685.          another system.
  6686.  
  6687.        * Take disk "snapshots" of your video screen.  With VPRINT
  6688.          enabled, the PrtSc key copies your screen to disk.
  6689.  
  6690.        * Delaying output for later printing.  VPRINT uses less memory
  6691.          than most print spoolers (only about 3K), but runs almost as
  6692.          fast.  If you can't afford lots of memory for a print
  6693.          spooler, you can VPRINT quickly, then print the file during
  6694.          a time when your computer is idle.
  6695.  
  6696.     VPRINT is distributed as User-Supported software, with a
  6697.     suggested payment of $15 from satisfied users.  VPRINT is written
  6698.     in CHASM, and registered users get access to VPRINT's heavily
  6699.     commented source code, which can be studied to learn about
  6700.     writing memory resident software.
  6701.  
  6702.     To get VPRINT, send a either $15 for a registered copy, or a disk
  6703.     and stamped return mailer for a evaluation copy to:
  6704.  
  6705.               Whitman Software
  6706.               P.O. Box 1157
  6707.               North Wales, PA  19454
  6708.  
  6709.     Be sure to specify that you're interested in VPRINT.
  6710.  
  6711.  
  6712.  
  6713.  
  6714.  
  6715.  
  6716.  
  6717.  
  6718.  
  6719.  
  6720.  
  6721.  
  6722.  
  6723.  
  6724.  
  6725.  
  6726.  
  6727.  
  6728.  
  6729.  
  6730.  
  6731.  
  6732.  
  6733.                                                                   103
  6734.  
  6735.  
  6736.          ================= ALSO AVAILABLE ==================
  6737.  
  6738.     If you use the IBM/Microsoft BASIC compiler, chances are your
  6739.     programs are bigger and slower than they have to be.  If all
  6740.     unreferenced line numbers are removed from your source program,
  6741.     and the /N switch is used, BASCOM will "optimize" your program.
  6742.     The result is tighter, more efficient code.
  6743.  
  6744.     NUMZAP is a utility which carefully scans your source file, and
  6745.     deletes all the non-essential line numbers.  Performing this task
  6746.     by hand would be prohibitively time consuming and you'd probably
  6747.     introduce errors into your program in the process.  NUMZAP will
  6748.     do the job in minutes, 100% error free.
  6749.  
  6750.     The old BASIC version of CHASM was passed through NUMZAP, and the
  6751.     resulting compiled code shrank by a factor of 10% (!).  That 10%
  6752.     reduction could make the difference between your program running
  6753.     in 64K, or having users with minimal systems get "Out of Memory"
  6754.     messages just before your program crashes.
  6755.  
  6756.     An added advantage to using NUMZAP is that bigger programs can be
  6757.     compiled.  You may not be aware that there is a limit on the size
  6758.     of program which the compiler can handle.  BASCOM uses up space
  6759.     remembering the offset of each line number in your program. If
  6760.     you have too many numbered lines, BASCOM will run out of room and
  6761.     you'll get a unending series of "TC" (Too Complex) error
  6762.     messages.  By eliminating the unneeded line numbers, you give
  6763.     BASCOM more elbow room.  The free space available to compile
  6764.     CHASM increased 27% (!) after using NUMZAP.
  6765.  
  6766.     NUMZAP is distributed as User-Supported software, with a
  6767.     suggested payment of $15 from satisfied users.  To get NUMZAP,
  6768.     send a either $15 for a registered copy, or a disk and stamped
  6769.     return mailer for a evaluation copy to:
  6770.  
  6771.        Whitman Software
  6772.        P.O. Box 1157
  6773.        North Wales, PA  19454
  6774.  
  6775.     Be sure to specify that you're interested in NUMZAP.
  6776.  
  6777.  
  6778.  
  6779.  
  6780.  
  6781.  
  6782.  
  6783.  
  6784.  
  6785.  
  6786.  
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.  
  6793.  
  6794.  
  6795.  
  6796.  
  6797.  
  6798.  
  6799.                                                                   104
  6800.  
  6801.     Index
  6802.  
  6803.  
  6804.     $.............................23,26    copyright information............83
  6805.     /132.............................10    COUNT............................32
  6806.     /80..............................11    DB.........................16,32,52
  6807.     /BEEP............................12    debugging........................68
  6808.     /BG..............................10    decimal numbers..................19
  6809.     /DPAGE...........................12    delimiters.......................14
  6810.     /DWIDTH..........................12    description of files.............95
  6811.     /FF..............................11    diagnostic messages..............62
  6812.     /FG..............................10    direct addressing................22
  6813.     /LINES...........................11    DM...............................33
  6814.     /PAGELEN.........................11    DS.........................16,33,52
  6815.     /PATH.........................12,59    duplicate labels.................17
  6816.     /TIMER...........................13    DW.........................16,34,52
  6817.     /VIDEO.........................9,97    educational discount.............85
  6818.     8086 Book........................15    EJECT............................34
  6819.     8087.......................28,31,55    EJECTIF..........................34
  6820.     8087 registers...................22    ENDP..........................35,38
  6821.     =................................40    ENDSTRUC...................35,39,52
  6822.     aborting assembly................59    EQU.....................15,16,20,35
  6823.     advanced version order form......99    error messages...................62
  6824.     ambiguities......................28    ERRORLEVEL.......................60
  6825.     arithmetic operators.............25    EXE format.......................67
  6826.     ASCII............................20    execution of assembled program...67
  6827.     assembler variables..............40    expert mode......................60
  6828.     BASIC.........................69,69    expression result types..........25
  6829.     binary numbers...................19    expressions................20,23,25
  6830.     BSAVE.........................32,70    fields...........................14
  6831.     bug reporting procedure..........96    hex numbers......................19
  6832.     changes to CHASM.................79    IBM macro assembler..............91
  6833.     characters.......................20    IF............................36,46
  6834.     CHASM revision history...........79    immediate data...................19
  6835.     CHASM's source code..............83    INCLUDE..........................36
  6836.     CHASM.CFG.........................9    indirect addressing........23,53,75
  6837.     CHKJMP...........................40    indirect branching............29,57
  6838.     coercing expression results......26    INLINE........................35,76
  6839.     COM format.......................67    input files......................14
  6840.     COM2DATA......................69,69    instruction prefixes.............30
  6841.     comments.........................15    internal labels..................44
  6842.     compatibles....................7,97    interrupt vectors................68
  6843.     conditional assembly..........36,45    JMP..............................29
  6844.     configuring CHASM.................9    JMPS.............................29
  6845.     conversion of programs...........91    label significant characters.....17
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851.  
  6852.  
  6853.  
  6854.  
  6855.  
  6856.  
  6857.  
  6858.  
  6859.  
  6860.  
  6861.  
  6862.  
  6863.  
  6864.  
  6865.                                                                   105
  6866.  
  6867.     labels.....................15,16,24    red tape.........................83
  6868.     legal nonsense...................83    registers........................21
  6869.     LENGTH function............20,27,52    REP..............................30
  6870.     limitations.......................6    requirements......................7
  6871.     LIST.............................36    reserved characters..............14
  6872.     listing.......................58,58    reserved strings.................18
  6873.     location counter..............23,26    resolution of ambiguities........28
  6874.     LOCK.............................30    royalty information..............85
  6875.     MACRO............................37    running assembled programs.......67
  6876.     macro blank parameters...........44    running CHASM....................58
  6877.     macro internal labels............44    SEG..............................30
  6878.     macro nesting....................45    segment override........22,30,56,75
  6879.     macro parameters.................43    segment registers................21
  6880.     macros...........................41    short jumps......................29
  6881.     MAP...........................37,78    sign extended.................21,28
  6882.     memory operands..................22    source code (CHASM's)............83
  6883.     messages.........................62    standard DOS files...............14
  6884.     mnemonic list (8087).............90    strings..........................24
  6885.     mnemonic list (8088).............88    STRUC.........................39,52
  6886.     modifying CHASM'S I/O defaults....9    structures.................20,51,72
  6887.     multi-segment programs...........57    symbol table dump................59
  6888.     NOCHKJMP.........................40    symbolic debugging...............78
  6889.     NOLIST...........................37    syntax...........................14
  6890.     NUMZAP..........................102    system requirements...............7
  6891.     object code format...............67    Tandy............................98
  6892.     OFFSET function...............20,26    Tanstaafl........................87
  6893.     operand expressions..............25    The 8086 Book....................28
  6894.     operands.........................19    TURBO function...................20
  6895.     order form.......................99    Turbo Pascal...............20,70,83
  6896.     ORG........................37,52,69    Turbo Pascal function results....73
  6897.     outside the program segment......57    Turbo Pascal inline code.........76
  6898.     pausing assembly.................59    TURBO(x) function................77
  6899.     PC-Write.........................14    user-supported software..........85
  6900.     PCjr...........................7,98    VPRINT..........................101
  6901.     permission to copy...............84    WAIT.............................55
  6902.     phase error.............35,49,52,64    WAITOFF.......................39,55
  6903.     PRIMER.DOC........................4    WAITON...........................39
  6904.     PROC.............................38
  6905.     program segment prefix........67,67
  6906.     program termination..............68
  6907.     programming notes................83
  6908.     prompt mode......................58
  6909.     pseudo-ops.......................32
  6910.     PSP...........................67,67
  6911.     RADIX.........................19,38
  6912.  
  6913.  
  6914.  
  6915.  
  6916.  
  6917.  
  6918.  
  6919.  
  6920.  
  6921.  
  6922.  
  6923.  
  6924.  
  6925.  
  6926.  
  6927.  
  6928.  
  6929.  
  6930.  
  6931.