home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / DRI-archive / roche / SID86_User_Guide.txt < prev    next >
Text File  |  2009-12-11  |  106KB  |  2,974 lines

  1. SID86UG.WS4     ("SID-86 User's Guide" 2nd Ed. for CP/M-86)
  2. -----------
  3.  
  4. (Retyped by Emmanuel ROCHE. Posted to comp.os.cpm.amethyst by
  5. Roche on 18 Apr 2005.)
  6.  
  7. "SID-86 User's Guide"
  8. First Edition: March 1982       (With Q, SR, and Z commands added by me.)
  9. Second Edition: August 1982     (Code-macros are still not documented...)
  10.  
  11. (Pages i and ii missing.)
  12.  
  13.  
  14. Table of Contents
  15. -----------------
  16.  
  17. (To be done...)
  18.  
  19.  
  20. Section 1: SID-86 Operation
  21. ---------------------------
  22.  
  23. SID-86  is a powerful symbolic debugger designed for use with the CP/M-86 and
  24. MP/M-86 operating systems. It expands on the features of the standard CP/M-86
  25. debugger,  DDT-86,  allowing users to test and debug  programs interactively.
  26. SID-86  includes  symbolic  assembly and  disassembly,  expressions involving
  27. hexadecimal,  decimal, ASCII, and symbolic values, permanent breakpoints with
  28. pass  counts,  and trace without call. You should be familiar with  the Intel
  29. 8086  processor,  ASM-86  and  the CP/M-86 or  MP/M-86  operating  system, as
  30. described in the "CP/M-86 Operating System System Guide" or "MP/M-86 Operating
  31. System System Guide".
  32.  
  33.  
  34. 1.1 Invoking SID-86
  35. -------------------
  36.  
  37. Invoke SID-86 by entering one of the following commands:
  38.  
  39.         (a) SID86
  40.         (b) SID86 filename
  41.         (c) SID86 filename {,filename...}
  42.         (d) SID86 * filename {,filename...}
  43.  
  44. Form  (a)  simply  loads and executes SID-86.  After  displaying  its sign-on
  45. message and prompt character, #, SID-86 is ready to accept your commands. Form
  46. (b) is similar to form (a), except that, after SID-86 is loaded, it loads the
  47. file specified by "filename". If the filetype is omitted from "filename", CMD
  48. is assumed. Note that SID-86 cannot load a file of type H86.
  49.  
  50. Form (c) is similar to form (b) but, once the program is loaded, SID-86 loads
  51. the other files in the command line into its symbol table. Form (d) is similar
  52. to form (c), except that no program is loaded, only symbol files.
  53.  
  54. Forms (b), (c), and (d) are analogous to the command sequences:
  55.  
  56.         A>SID86
  57.         SID86 x.x
  58.         #Efilename
  59.  
  60.         A>SID86
  61.         SID86 x.x
  62.         #Efilename {,filename...}
  63.  
  64.         A>SID86
  65.         SID86 x.x
  66.         #E* filename {,filename...}
  67.  
  68. At this point, the program that was loaded using form (b) or (c) is ready for
  69. execution.  (See Section 3.4, "The E Command", for a complete  description of
  70. file loading.)
  71.  
  72.  
  73. 1.2 SID-86 Command Conventions
  74. ------------------------------
  75.  
  76. When  SID-86  is ready to accept a command, it prompts you with a  pound sign
  77. ("#").  In  response,  you can type a command line, or a  Ctrl-C  to  end the
  78. debugging  session  (see  Section  1.4). A command line  can  have  up  to 64
  79. characters, and must be terminated with a carriage return. While entering the
  80. command, use standard CP/M-86 line-editing functions (Ctrl-X, Ctrl-H, Ctrl-R,
  81. etc) to correct typing errors. SID-86 does not process the command line until
  82. a carriage return is entered.
  83.  
  84. The first character of each command line determines the command action. Table
  85. 1-1  summarizes SID-86 commands. SID-86 commands are defined  individually in
  86. Section 3.
  87.  
  88.         Table 1-1. SID-86 Command Summary
  89.         ---------------------------------
  90.  
  91.         Command Action
  92.         ------- ----------------------------------
  93.            A    Enter assembly language statements
  94.            B    Compare blocks of memory
  95.            D    Display memory in hexadecimal and ASCII
  96.            E    Load program and symbols for execution
  97.            F    Fill memory block with a constant
  98.            G    Begin execution with optional breakpoints
  99.            H    Hexadecimal arithmetic
  100.            I    Set up file control block and command tail
  101.            L    List memory using 8086 mnemonics
  102.            M    Move memory blocks
  103.            P    Set, clear, display pass points
  104.            Q    Query I/O ports
  105.            R    Read disk file into memory
  106.            S    Set memory to new values
  107.            SR   SeaRch pattern in memory
  108.            T    Trace program execution
  109.            U    Untraced program monitoring
  110.            V    Show memory layout of disk file read
  111.            W    Write contents of memory block to disk
  112.            X    Examine or modify CPU state
  113.            Z    Examine 8087 co-processor
  114.  
  115. The  command character can be followed by one or more arguments, which can be
  116. symbolic  expressions,  filenames,  or other  information,  depending  on the
  117. command.  Arguments  are  separated from each other by commas  or  spaces.No
  118. spaces are allowed between the command character and the first argument. Note
  119. that,  if the first character of a SID-86 command line is a  semicolon (";"),
  120. the  entire line is treated as a comment and ignored. Several commands (G, P,
  121. S,  T,  and U) can be preceded by a minus sign. The effect of the  minus sign
  122. varies  between  commands.  (Section 3, "SID-86  Commands",  provides  a full
  123. explanation of the effect of the minus sign on individual commands.)
  124.  
  125.  
  126. 1.3 Specifying a 20-Bit Address
  127. -------------------------------
  128.  
  129. Most SID-86 commands require one or more address as operands. Because the 8086
  130. can address up to 1 megabyte of memory, addresses must be 20-bit values. Enter
  131. a 20-bit address as follows:
  132.  
  133.         ssss:oooo
  134.  
  135. where "ssss" represents an optional 16-bit segment number and "oooo" is a 16-
  136. bit  offset.  SID-86  combines these values to produce a  20-bit  address, as
  137. follows:
  138.  
  139.           ssss
  140.         +  oooo
  141.         -------
  142.           eeeee
  143.  
  144. The  segment value, ssss, is optional. If you omit the segment  value, 
  145. uses  a default value appropriate to the command being executed, as described
  146. in Section 3.4, "The E Command".
  147.  
  148.  
  149. 1.4 Terminating SID-86
  150. ----------------------
  151.  
  152. Terminate SID-86 by typing a Ctrl-C in response to the pound sign prompt. This
  153. returns  control  to the CCP. Note that CP/M-86 or MP/M-86 does not  have the
  154. SAVE  facility  found in CP/M for 8-bit machines. Thus, if SID-86 is  used to
  155. patch  a file, write the file to disk using the W command before exiting SID-
  156. 86.
  157.  
  158.  
  159. 1.5 SID-86 Operation with Interrupts
  160. ------------------------------------
  161.  
  162. SID-86 operates in systems with interrupts enabled or disabled, and preserves
  163. the  interrupt state of the program being executed under SID-86.  When SID-86
  164. controls the CPU, either when initially invoked or when regaining control from
  165. the  program being tested, the condition of the interrupt flag is the same as
  166. it  was  when  SID-86 was invoked, except for a  few  critical  regions where
  167. interrupts  are  disabled. While the program being tested has control  of the
  168. CPU,  the  user's  CPU  state, which can be  displayed  with  the  X command,
  169. determines the state of the interrupt flag.
  170.  
  171.  
  172. Section 2: SID-86 Expressions
  173. -----------------------------
  174.  
  175. An  important facility of SID-86 is the ability to reference absolute machine
  176. addresses through expressions. Expressions can involve names obtained from the
  177. program  under  test  that are included in the SYM file  produced  by ASM-86.
  178. Expressions  can  also consist of literal values in hexadecimal,  decimal, or
  179. ASCII  character string form. You can then combine these values  with various
  180. operators,  to provide access to subscripted and indirectly-addressed data or
  181. program areas. This section describes expressions, so that you can incorporate
  182. them  as command parameters in the individual command forms that  follow this
  183. section.
  184.  
  185.  
  186. 2.1 Literal Hexadecimal Numbers
  187. -------------------------------
  188.  
  189. SID-86  normally  accepts  and  displays  values  in  hexadecimal.  The valid
  190. hexadecimal  digits  consist  of  the  decimal digits  0  through  9  and the
  191. hexadecimal  digits A, B, C, D, E, and F, corresponding to the decimal values
  192. 10 through 15, respectively.
  193.  
  194. A  literal  hexadecimal number in SID-86 consists of one  or  more contiguous
  195. hexadecimal  digits. If you type four digits, then the leftmost digit is most
  196. significant,  while  the rightmost digit is least significant. If  the number
  197. contains  more than four digits, the rightmost four are taken as significant,
  198. and  the remaining leftmost digits are discarded. The examples below show the
  199. corresponding hexadecimal and decimal values for the given input values.
  200.  
  201.         Input Value     Hexadecimal     Decimal
  202.         -----------     -----------     -------
  203.                1           0001             1
  204.              100           0100           256
  205.             fffe           FFFE         65534
  206.            10000           0000             0
  207.            38001           8001         32769
  208.  
  209.  
  210. 2.2 Literal Decimal Numbers
  211. ---------------------------
  212.  
  213. Enter decimal numbers by preceding the number with the # symbol. In this case,
  214. the number that follows must consist of one or more decimal digits (0 through
  215. 9)  with  the most significant digit on the left, and  the  least significant
  216. digit  on the right. Decimal values are padded or truncated according  to the
  217. rules  of hexadecimal numbers, as described above, by converting  the decimal
  218. number to the equivalent hexadecimal value.
  219.  
  220. The  input  values shown to the left below produce  the  internal hexadecimal
  221. values shown to the right below:
  222.  
  223.         Input Value     Hexadecimal
  224.         -----------     -----------
  225.               #9           0009
  226.              #10           000A
  227.             #256           0100
  228.           #65535           FFFF
  229.           #65545           0009
  230.  
  231.  
  232. 2.3 Literal Character Values
  233. ----------------------------
  234.  
  235. SID-86 accepts one or two graphic ASCII characters enclosed in apostrophes as
  236. literal  values in expressions. Characters remain as typed within  the paired
  237. apostrophes  (i.e.,  no case translation occurs) with the  leftmost character
  238. treated as the most significant, and the rightmost character treated as least
  239. significant. Character strings of length one are padded on the left with 
  240. Strings of length greater than zero are not allowed in expressions, except as
  241. described in the S command.
  242.  
  243. Note that the enclosing apostrophes are not included in the character string,
  244. nor  are they included in the character count, with one exception: a  pair of
  245. contiguous  apostrophes is reduced to a single apostrophe and included in the
  246. string as a normal graphic character.
  247.  
  248. The  strings shown to the left below produce the hexadecimal values  shown to
  249. the  right below. (For these examples, note that upper-case ASCII alphabetics
  250. begin at the encoded hexadecimal value 41; lower-case alphabetics begin at 61;
  251. a space is hexadecimal 20, and an apostrophe is encoded as hexadecimal 27.)
  252.  
  253.         Input String    Hexadecimal
  254.         ------------    -----------
  255.               'A'          0041
  256.              'AB'          4142
  257.              'aA'          6141
  258.              ''''          0027
  259.            ''''''          2727
  260.              ' A'          2041
  261.              'A '          4120
  262.  
  263.  
  264. 2.4 Register Values
  265. -------------------
  266.  
  267. You  can use the contents of registers in the CPU state of the  program under
  268. test  in  expressions. Simply use the register name wherever  a  number would
  269. normally  be valid. For example, if you know that, at a certain point  in the
  270. program, the BX register points to a data area you want to see, the command
  271.  
  272.         DBX
  273.  
  274. displays the desired area of memory.
  275.  
  276. Note  that,  when assembling 8086 instructions using the A  command, register
  277. names are treated differently than in other expressions. In particular, use of
  278. a  register  name in an assembly language statement entered in the  A command
  279. refers to the name of a register, and not its contents.
  280.  
  281.  
  282. 2.5 Stack References
  283. --------------------
  284.  
  285. Elements in the stack can be included in expressions. A caret ("^") refers to
  286. the  16-bit  value  at  the top of the stack (pointed to  by  the  SS  and SP
  287. registers  in the user's CPU state). A sequence of n carets refer to  the nth
  288. 16-bit  value  on the stack. You can use this feature to set a  breakpoint on
  289. return from a subroutine, when all that is known is that the return address is
  290. on the stack, even though the actual value is not known. The commands
  291.  
  292.         G,^
  293.         G,^^:^
  294.  
  295. set breakpoints on return from near and far subroutines, respectively.
  296.  
  297.  
  298. 2.6 Symbolic References
  299. -----------------------
  300.  
  301. Given  that a symbol table is present during a SID-86 debugging  session, you
  302. can reference values associated with symbols through the following three forms
  303. of a symbol reference:
  304.  
  305.         (a) .s
  306.         (b) @s
  307.         (c) =s
  308.  
  309. where  "s" represents a sequence of one to thirty-one characters that match a
  310. symbol in the table.
  311.  
  312. Form (a) produces the 16-bit value corresponding to the symbol "s" (i.e., the
  313. value  associated with the symbol in the table). Form (b) produces the 16-bit
  314. value  contained  in  the two memory locations given by  .s,  while  form (c)
  315. results  in the 8-bit value at .s in memory. Note that forms (b) and  (c) use
  316. the contents of the DS register as the segment component when fetching the 16-
  317. bit  or 8-bit contents of memory. Suppose, for example, that the input symbol
  318. table contains two symbols, and appears as follows:
  319.  
  320.         0100 GAMMA      0102 DELTA
  321.  
  322. Further,  suppose that memory starting at 0100 in the segment referred  to by
  323. the DS register contains the following byte data values:
  324.  
  325.         0100: 02 3E 4D 22
  326.  
  327. Based  upon this symbol table and these memory values, the  symbol references
  328. shown  to  the left below produce the hexadecimal values shown  to  the right
  329. below.  Recall  that  16-bit  8086 memory values are  stored  with  the least
  330. significant byte first, and thus the word values at 0100 and 0102 are 3E02 and
  331. 224D, respectively.
  332.  
  333.         Symbol Reference        Hexadecimal
  334.         ----------------        -----------
  335.             .GAMMA                 0100
  336.             .DELTA                 0102
  337.             @GAMMA                 3E02
  338.             @DELTA                 224D
  339.             =GAMMA                 0002
  340.             =DELTA                 004D
  341.  
  342.  
  343. 2.7 Qualified Symbols
  344. ---------------------
  345.  
  346. Duplicate  symbols can occur in the symbol table, due to separately assembled
  347. or  compiled  modules  that  independently use the  same  name  for different
  348. subroutines  or data areas. Further, block structured languages  allow nested
  349. name definitions that are identical, but non-conflicting. Thus, SID-86 allows
  350. reference to qualified symbols that take the form:
  351.  
  352.         S1/S2/.../Sn
  353.  
  354. where  "S1"  through  "Sn" represents symbols that are present  in  the table
  355. during a particular session.
  356.  
  357. SID-86 always searches the symbol table from the first to last symbol, in the
  358. order  the symbols appear in the symbol file. For a qualified  symbol, SID-86
  359. begins by matching the first S1 symbol, then scans for a match with symbol S2,
  360. continuing  until symbol Sn is matched. If this search and match procedure 
  361. not  successful, SID-86 prints the "?" response to the console.  Suppose, for
  362. example, that the symbol table appears in the symbol file as follows:
  363.  
  364.         0100 A  0300 B  0200 A  3E00 C  20F0 A  0102 A
  365.  
  366. with  memory  initialized as shown in the previous section. In  the following
  367. example,  the  unqualified and qualified symbol references shown to  the left
  368. produce the hexadecimal values shown to the right.
  369.  
  370.         Symbol Reference        Hexadecimal
  371.         ----------------        -----------
  372.             .A                     0100
  373.             @A                     3E02
  374.             .A/A                   0200
  375.             .C/A/A                 0102
  376.             =C/A/A                 004D
  377.             .B/A/A                 20F0
  378.  
  379.  
  380. 2.8 Operators in Expressions
  381. ----------------------------
  382.  
  383. Literal numbers, strings, and symbol references can be combined into symbolic
  384. expressions using unary and binary "+" and "-" operators. The entire sequence
  385. of  numbers, symbols, and operators must be written without  embedded blanks.
  386. Further, the sequence is evaluated from left to right, producing a four-digit
  387. hexadecimal  value at each step in the evaluation. Overflow and underflow are
  388. ignored  as  the  evaluation proceeds. The final  value  becomes  the command
  389. parameter,  whose  interpretation depends upon the particular  commend letter
  390. that precedes it.
  391.  
  392. When  placed  between  two  operands, the  "+"  indicates  "addition"  to the
  393. previously  accumulated  value. The sum becomes the new accumulated  value to
  394. this point in the evaluation.
  395.  
  396. The  "-"  symbol  causes  SID-86 to subtract  the  literal  number  or symbol
  397. reference  from  the  16-bit  value  accumulated  thus  far  in  the symbolic
  398. expression.  If  the  expression begins with a minus sign,  then  the initial
  399. accumulated value is taken as zero. That is,
  400.  
  401.         -x
  402.  
  403. is computed as
  404.  
  405.         0-x
  406.  
  407. where  "x"  is  any  valid symbolic expression.  For  example,  the following
  408. command:
  409.  
  410.         DFF00-200,-#512
  411.  
  412. is equivalent to the simple command:
  413.  
  414.         DFD00,FE00
  415.  
  416. In  commands  that specify a range of addresses (B, D, L, F, M,  and  W), the
  417. ending  address of the range can be indicated as an offset from  the starting
  418. address.  To do this, precede the desired offset by a plus sign. For example,
  419. the command
  420.  
  421.         D121,+7
  422.  
  423. displays  the memory from address 121 to 128 (121 + 7). Use of the unary plus
  424. operator at other times is not allowed.
  425.  
  426.  
  427. 2.9 Sample Symbolic Expressions
  428. -------------------------------
  429.  
  430. The  formulation of SID-86 symbolic expressions is most often closely related
  431. to the program structures in the program under test. Suppose you want to debug
  432. a sorting program that contains the data items listed below:
  433.  
  434.         LIST:   names  the  base of a table of byte values to  sort, assuming
  435.                 there  are  no  more than 255 elements,  denoted  by LIST(0),
  436.                 LIST(1), ..., LIST(254).
  437.  
  438.            N:   is  a byte variable that gives the actual number of  items in
  439.                 LIST, where the value of N is less than 256. The items to sort
  440.                 are stored in LIST(0) through LIST(N-1).
  441.  
  442.            I:   is the byte subscript that indicates the next item to compare
  443.                 in  the sorting process. LIST(I) is the next item to place in
  444.                 sequence, where I is in the range 0 through N-1.
  445.  
  446. Given these data areas, the command
  447.  
  448.         D.LIST,+#254
  449.  
  450. displays the entire area reserved for sorting:
  451.  
  452.         LIST(0), LIST(1), ..., LIST(254)
  453.  
  454. The command
  455.  
  456.         D.LIST,+=i
  457.  
  458. displays the LIST vector up to and including the next item to sort:
  459.  
  460.         LIST(0), LIST(1), ..., LIST(I)
  461.  
  462. The command
  463.  
  464.         D.LIST+=I,+0
  465.  
  466. displays only LIST(I). Finally, the command
  467.  
  468.         D.LIST,+=N-1
  469.  
  470. displays only the area of LIST that holds active items to sort:
  471.  
  472.         LIST(0), LIST(1), ..., LIST(N-1)
  473.  
  474.  
  475. Section 3: SID-86 Commands
  476. --------------------------
  477.  
  478. This section defines SID-86 commands and their arguments. SID-86 commands give
  479. you  control of program execution, and allow you to display and modify system
  480. memory and the CPU state.
  481.  
  482.  
  483. 3.1 The A (Assemble) Command
  484. ----------------------------
  485.  
  486. The  A command assembles Intel 8086 mnemonics directly into memory.  The form
  487. is:
  488.  
  489.         As
  490.  
  491. where "s" is the 20-bit address where assembly starts. SID-86 responds to the
  492. A  command  by displaying the address of the memory  location  where assembly
  493. begins. At this point, you enter assembly language statements as described in
  494. Section  4  on Assembly Language Syntax. When a statement is  entered, SID-86
  495. converts it to binary, places the value(s) in memory, and displays the address
  496. of the next available memory location. This process continues until you enter
  497. a blank line or a line containing only a period (".").
  498.  
  499. SID-86 responds to invalid statements by displaying a question mark ("?") and
  500. redisplaying the current assembly address.
  501.  
  502. Note  that,  wherever  a  numeric  value is  valid  in  an  assembly language
  503. statement,  an  expression  can be entered. There is  one  difference between
  504. expressions  in assembly language statements and those appearing elsewhere in
  505. SID-86: under the A command, references to registers refer to the names of the
  506. registers, while elsewhere they refer to the contents of the registers. Under
  507. the  A command, there is no way to reference the contents of a register in an
  508. expression.
  509.  
  510. The following are examples of the A command.
  511.  
  512.         #A213                   Assemble at offset 0213.
  513.         nnnn:0213 mov ax,#128   Set AX register to decimal 128.
  514.         nnnn:0216 push ax       Push AX register on stack.
  515.         nnnn:0217 call .proc1   Call  procedure whose address is the value of
  516.                                 the symbol PROC1.
  517.  
  518.         nnnn:021A test byte [.i/i], 80
  519.  
  520. Test  the most significant bit of the byte whose address is the value  of the
  521. second occurrence of the symbol I.
  522.  
  523.         nnnn:021E jz .done      Jump  if Zero flag set to the  location whose
  524.                                 address is the value of the symbol DONE.
  525.  
  526.         nnnn:0220 mov al,[.array+4]
  527.  
  528. Move the contents of the memory byte whose address is the value of the symbol
  529. ARRAY plus 4 to the AL register.
  530.  
  531.  
  532. 3.2 The B (Block Compare) Command
  533. ---------------------------------
  534.  
  535. The B command compares two blocks of memory, and displays any discrepancies at
  536. the screen. The form is:
  537.  
  538.         Bs1,f1,s2
  539.  
  540. where "s1" is the 20-bit address of the start of the first block; "f1" is the
  541. offset of the final byte of the first block; and "s2" is the 20-bit address of
  542. the start of the second block. If the segment is not specified in s2, the same
  543. value is used that was used for s1.
  544.  
  545. Any differences in the two blocks are displayed at the screen in the form:
  546.  
  547.         a1 b1 a2 b2
  548.  
  549. where the "a1" and the "a2" are the adresses in the blocks; "b1" and "b2" are
  550. the  values at the indicated addresses. If no differences are  displayed, the
  551. blocks are identical.
  552.  
  553. The following are examples of the B command.
  554.  
  555.         #B40:0,1FF,60:0
  556.  
  557. Compares 200h bytes starting at 40:0 with the block starting at 60:0.
  558.  
  559.         #Bes:.array1,+ff,.array2
  560.  
  561. Compares 256 bytes starting at offset ARRAY1 in the Extra Segment with ARRAY2
  562. in the Extra Segment.
  563.  
  564.  
  565. 3.3 The D (Display) Command
  566. ---------------------------
  567.  
  568. The  D command displays the contents of memory as8-bit or  16-bit hexadecimal
  569. values and in ASCII. The forms are:
  570.  
  571.         (a) D
  572.         (b) Ds
  573.         (c) Ds,f
  574.         (d) DW
  575.         (e) DWs
  576.         (f) DWs,f
  577.  
  578. where  "s" is the 20-bit address where the display starts, and "f" is the 16-
  579. bit offset within the segment specified in "s" where the display finishes.
  580. Memory is displayed on one or more display lines. Each display line shows the
  581. values  of up to 16 memory locations. For the first three forms,  the display
  582. line appears as follows:
  583.  
  584.         ssss:oooo bb bb ... bb cc...c
  585.  
  586. where  "ssss" is the segment being displayed, and "oooo" is the offset within
  587. segment  "ssss".  The bb's represent the contents of the memory  locations in
  588. hexadecimal,  and the c's represent the contents of memory in ASCII. A period
  589. (".") represents any non-graphic ASCII character.
  590.  
  591. In  response  to  form (a), SID-86 displays memory from  the  current display
  592. address for 12 display lines. The response to form (b) is similar to form (a),
  593. except  that the display address is first set to the 20-bit address "s". Form
  594. (c)  displays the memory block between locations "s" and "f". The  next three
  595. forms are analogous to the first three, except that the contents of memory are
  596. displayed as 16-bit values, rather than 8-bit values, as shown below:
  597.  
  598.         ssss:oooo wwww wwww ... wwww cccc...cc
  599.  
  600. During a long display, you can abort the D command by typing any character at
  601. the console.
  602.  
  603. The following are examples of the D command.
  604.  
  605.         #DF00,F23               Display memory bytes from offset 0F00h through
  606.                                 0F23h in the current Data Segment.
  607.  
  608.         #D.array+=i,+#10        Display  11 bytes starting at the location of
  609.                                 ARRAY(I).
  610.  
  611.         #DW#128,#255            Displays   memory  words  from  offset 0080h
  612.                                 through 00FFh.
  613.  
  614.  
  615. 3.4 The E (Load Program, Symbols for Execution) Command
  616. -------------------------------------------------------
  617.  
  618. The E command loads a file into memory so that a subsequent G, T, or U command
  619. can  begin program execution, and allows one or more symbol table files to be
  620. loaded. The E command takes the forms:
  621.  
  622.         (a) E <filename>
  623.         (b) E <filename> <symbol filename> {,<symbol filename>...}
  624.         (c) E * <symbol filename> {,<symbol filename>...}
  625.         (d) E
  626.  
  627. Form  (a) loads the file by the name <filename> using the BDOS load function.
  628. The file is assumed to be in the CMD file format, as described in the "CP/M-86
  629. System  Guide". If no filetype is specified, CMD is assumed. The  contents of
  630. the  CS, DS, ES, and IP registers are altered according to the information in
  631. the  header record of the CMD file loaded. When the load is  complete, SID-86
  632. displays  the start and end addresses of each segment in the file loaded. Use
  633. the V command to redisplay this information at a later time.
  634.  
  635. Form  (b) loads the file <filename> as described above, and then loads one or
  636. more  symbol table files. If the filetype is omitted from a  symbol filename,
  637. SYM is assumed. SID-86 displays the message:
  638.  
  639.         SYMBOLS
  640.  
  641. when  it begins loading the symbol file(s). If SID-86 detects an  invalid hex
  642. digit  or  an  invalid symbol name, it displays an  error  message  and stops
  643. loading the symbol file. The symbols loaded up to the time the error occurred
  644. can  be displayed with the H command, to determine the exact location  of the
  645. error  in the SYM file. A maximum of 64K bytes is available for  symbol table
  646. storage.
  647.  
  648. While SID-86 allows symbol files to be loaded with separate E commands, each E
  649. command  requests  another  memory  allocation  from  the  operating system.
  650. Therefore, if you are loading more than one symbol table file, you should load
  651. all the files with a single E command, using form (b) or (c).
  652.  
  653. Form (c) does not load a program, but simply loads the indicated symbol table
  654. file(s).
  655.  
  656. Form (d) releases all memory allocations made from SID-86, without loading any
  657. files.
  658.  
  659. When loading a program file with the E command, SID-86 releases any blocks of
  660. memory allocated by any previous E or R commands or by programs executed under
  661. SID-86.  Thus, only one file at a time can be loaded for execution,  and that
  662. file should be loaded before any symbol tables are read.
  663.  
  664. SID-86  issues  an  error  message if a file does  not  exists  or  cannot be
  665. successfully loaded in the available memory.
  666.  
  667. The format of the symbol table file is that produced by ASM-86, as follows:
  668.  
  669.         nnnn symbol1    nnnn symbol2    ...
  670.         ...
  671.         ...
  672.  
  673. where  "nnnn" is a four-digit hexadecimal number, and spaces,  tabs, carriage
  674. returns, and line feeds can serve as delimiters between hex values and symbol
  675. names. Symbol names can be up to thirty-one characters in length.
  676.  
  677. The following are examples of the E command.
  678.  
  679.         #Etest                  Load file TEST.CMD.
  680.  
  681.         #Etest.cmd test.sym     Load  file  TEST.CMD  and  symbol  table file
  682.                                 TEST.SYM.
  683.  
  684.         #Etest test io format   Load  file  TEST.CMD and  symbol  table files
  685.                                 TEST.SYM, IO.SYM, and FORMAT.SYM.
  686.  
  687.         #E* test1               Load only the symbol table file TEST1.SYM.
  688.  
  689.  
  690. 3.5 The F (Fill) Command
  691. ------------------------
  692.  
  693. The F command fills an area of memory with a byte or word constant. The forms
  694. are:
  695.  
  696.         (a) Fs,f,b
  697.         (b) FWs,f,w
  698.  
  699. where "s" is a 20-bit starting address of the block to be filled, and "f" is a
  700. 16-bit  offset of the final byte of the block within the segment specified in
  701. "s".
  702.  
  703. In  response to form (a), SID-86 stores the 8-bit value "b" in  locations "s"
  704. through  "f".  In  form (b), the 16-bit value "w" is stored  in  location "s"
  705. through "f" in standard form, low 8-bits first followed by high 8-bits.
  706.  
  707. If  "s"  is  greater than "f" or the value "b" is  greater  than  255, SID-86
  708. responds  with  a question mark ("?"). SID-86 issues an error message  if the
  709. value stored in memory cannot be read back successfully, indicating faulty or
  710. non-existant RAM at the location indicated.
  711.  
  712. The following are examples of the F command.
  713.  
  714.         #F100,13F,0             Fill memory from 0100h to 013Fh with 00h.
  715.  
  716.         #F.array,+255,ff        Fill the 256-byte block starting at ARRAY with
  717.                                 the constant 0FFh.
  718.  
  719.  
  720. 3.6 The G (Go) Command
  721. ----------------------
  722.  
  723. The  G command transfers control to the program being tested,  and optionally
  724. sets one or two breakpoints. The forms are:
  725.  
  726.         (a) G
  727.         (b) G,b1
  728.         (c) G,b1,b2
  729.         (d) Gs
  730.         (e) Gs,b1
  731.         (f) Gs,b1,b2
  732.         (g) -G (with forms "a" through "f")
  733.  
  734. where  "s" is a 20-bit address where program execution is to start,  and "b1"
  735. and "b2" are 20-bit addresses of breakpoints. If no segment value is supplied
  736. for  any of these three addresses, the segment value defaults to the contents
  737. of the CS register.
  738.  
  739. In forms (a), (b), and (c), no starting address is supplied, so SID-86 derives
  740. the 20-bit address from the CS and IP registers. Form (a) transfers control to
  741. your program without setting any breakpoints. Form (b) and (c) set one and two
  742. breakpoints, respectively, before passing control to your program. Forms (d),
  743. (e),  and  (f) are analogous to (a), (b), and (c), except that the CS  and IP
  744. registers are first set to "s".
  745.  
  746. The  forms  in  (g)  are  analogous to forms  (a)  through  (f),  except that
  747. intermediate pass points displays are suppressed.
  748.  
  749. Once  control has been transferred to the program under test, it  executes in
  750. real-time  until  a breakpoint is encountered. At this point,  SID-86 regains
  751. control,  clears  the  breakpoints set by the G  command,  and  indicates 
  752. address  at  which  execution of the program under  test  was  interrupted as
  753. follows:
  754.  
  755.         *ssss:oooo .symbol
  756.  
  757. "ssss"  corresponds  to the CS, "oooo" corresponds to the IP where  the break
  758. occurred, and ".symbol" is the symbol whose value is equal to "oooo", if such
  759. a symbol exists. When a breakpoint returns control to SID-86, the instruction
  760. at the breakpoint address has not yet been executed.
  761.  
  762. The following are examples of the G command.
  763.  
  764.         #G              Begin program execution at address given by CS and IP
  765.                         registers, with no breakpoints set.
  766.  
  767.         #G.start,.error Begin  program  execution at label START in  the code
  768.                         segment, setting a breakpoint at label ERROR.
  769.  
  770.         #G,.error,^     Continue program execution at address given by CS and
  771.                         IP  registers, with breakpoints at label ERROR and at
  772.                         the  address  at  the top of  the  stack  (the return
  773.                         address of the procedure being executed).
  774.  
  775.         #-G,34F         Begin   execution   with  a   breakpoint   at 034Fh,
  776.                         suppressing intermediate pass point display.
  777.  
  778.  
  779. 3.7 The H (Hexadecimal Math) Command
  780. ------------------------------------
  781.  
  782. The H command provides several useful arithmetic functions. The forms are:
  783.  
  784.         (a) Ha,b
  785.         (b) Ha
  786.         (c) H
  787.  
  788. Form  (a) computes the sum (ssss), difference (ddd), product  (pppppppp), and
  789. quotient  (qqqq) with the remainder (rrrr) of two 16-bit values.  The results
  790. are displayed in hexadecimal as follows:
  791.  
  792.         + ssss - dddd * pppppppp / qqqq (rrrr)
  793.  
  794. Underflow and overflow are ignored in addition and subtraction.
  795.  
  796. Form  (b)  displays the value of the expression "a" in  hexadecimal, decimal,
  797. ASCII (if the value has a graphic ASCII equivalent), and symbolic (if a symbol
  798. exists with a value equal to the value of the expression) form as shown:
  799.  
  800.         hhhh #ddddd 'c' .s
  801.  
  802. Form  (c)  displays the symbols currently loaded in the SID-86  symbol table.
  803. Each symbol is displayed in the form:
  804.  
  805.         nnnn <symbol name>
  806.  
  807. You can abort the display by pressing any key at the console.
  808.  
  809. The following are examples of the H command.
  810.  
  811.         #H              List all symbols and values loaded with E command(s).
  812.  
  813.         #H.open         Show the value of the symbol OPEN in hex and decimal.
  814.  
  815.         #H@index        Show the word contents of the memory location at INDEX
  816.                         in hex and decimal.
  817.  
  818.         #H5C28,80       Show  sum, difference, product, and quotient of 5C28h
  819.                         and 0080h.
  820.  
  821.  
  822. 3.8 The I (Input Command Tail) Command
  823. --------------------------------------
  824.  
  825. The  I command prepares a file control block (FCB) and command tail buffer in
  826. SID-86's base page, and copies this information into the base page of the last
  827. file loaded with the E command. The command takes the following form:
  828.  
  829.         I<command tail>
  830.  
  831. where  <command tail> is a character string that usually contains one or more
  832. filenames. The first filename is parsed into the default file control block at
  833. 005Ch.  The  optional second filename is parsed into the second  part  of the
  834. default  file  control block beginning at 006Ch. The  characters  in <command
  835. tail> are also copied into the default command buffer at 0080h. The length of
  836. <command tail> is stored at 0080h, followed by the character string 
  837. terminated
  838. with a binary zero.
  839.  
  840. If  a file has been loaded with the E command, SID-86 copies the file control
  841. block and command buffer from the base page of SID-86 to the base page of the
  842. program  loaded. The location of SID-86's base page can be obtained  from the
  843. 16-bit  value  at  location 0:6. The location of the base page  of  a program
  844. loaded with the E command is the value displayed for DS upon completion of the
  845. program load.
  846.  
  847. The following are examples of the I command.
  848.  
  849.         #Ifile1.cmd
  850.  
  851. Set  up  a  file control block at 005Ch for the file FILE1.CMD,  and  put the
  852. string  "FILE1.CMD"  in the buffer at 0080h (in the Data Segment of  the last
  853. file loaded with an E command).
  854.  
  855.         #Ia:file1 b:file2 c:file3 $px
  856.  
  857. Set  up  file  control blocks at 005Ch and 006Ch for  the  files  A:FILE1 and
  858. B:FILE2, and copy the string following the "I" into the buffer at 0080h.
  859.  
  860.  
  861. 3.9 The L (List) Command
  862. ------------------------
  863.  
  864. The  L  command lists the contents of memory in assembly language.  The forms
  865. are:
  866.  
  867.         (a) L
  868.         (b) Ls
  869.         (c) Ls,f
  870.         (d) -L
  871.         (e) -Ls
  872.         (f) -Ls,f
  873.  
  874. where  "s"  is  a 20-bit address where the list starts, and "f"  is  a 16-bit
  875. offset within the segment specified in "s" where the list finishes.
  876.  
  877. Each disassembled instruction is in the following form:
  878.  
  879.         label:
  880.         ssss:oooo <prefixes> opcode <operands> <.symbol> <=memory value>
  881.  
  882. where "label" is the symbol whose value is equal to the offset "oooo", if such
  883. a  symbol exists; <prefixes> are segment override, lock and  repeat prefixes;
  884. "opcode" is the mnemonic for the instruction, <operands> field contains 0, 1,
  885. or  2  operands, as required by the instruction, and <symbol>  is  the symbol
  886. whose value is equal to the numeric operand, if there is one and such a symbol
  887. exists.  If the instruction references a memory location, the contents of the
  888. location are displayed in the <memory value> field as a byte, word, or double
  889. word, as indicated by the instruction.
  890.  
  891. Form (a) lists twelve disassembled instructions from the current list address.
  892. Form (b) sets the list address to "s" and then lists twelve instructions. Form
  893. (c)  lists  disassembled code from "s" through "f". The last three  forms are
  894. analogous to the first three, except that no symbolic information is displayed
  895. (the labels and <symbol> fields are omitted).
  896.  
  897. In  all  cases,  the list address is set to the  next  unlisted  location, in
  898. preparation  for  a subsequent L command. When SID-86 regains control  from a
  899. program  being tested (see G, T, and U commands), the list address is  set to
  900. the current value of the CS and IP registers.
  901.  
  902. You  can  abort long displays by typing any key during the list  process. Or,
  903. enter Ctrl-S to halt the display temporarily.
  904.  
  905. The  syntax of the assembly language statements produced by the L  command is
  906. described in Section 5, "Assembly Language Syntax for A and L Commands".
  907.  
  908. If  the  memory location being disassembled is not a valid  8086 instruction,
  909. SID-86 displays it in the form:
  910.  
  911.         ??= nn
  912.  
  913. where "nn" is the hexadecimal value of the contents of the memory location.
  914.  
  915. The following are examples of the L command.
  916.  
  917.         #L243C,244E    Disassemble instructions from 243Ch through 244Eh.
  918.  
  919.         #L.find,+20    Disassemble 20h bytes from the label FIND.
  920.  
  921.         #L.err+3       Disassemble 12 lines of code from the label ERR plus 
  922. 3.
  923.  
  924.  
  925. 3.10 The M (Move) Command
  926. -------------------------
  927.  
  928. The M command moves a block of data values from one area of memory to another.
  929. The form is:
  930.  
  931.         Ms,f,d
  932.  
  933. where "s" is the 20-bit starting address of the block to be moved; "f" is the
  934. offset of the final byte to be moved within the segment described by "s", and
  935.  "d"  is the 20-bit address of the first byte of the area to receive the data.
  936. If  the segment is not specified in "d", the same value is used that was used
  937. for "s".
  938.  
  939. Note  that,  if "d" is between "s" and "f", part of the block being  moved is
  940. overwritten  before  it is moved, because data is  transferred  starting from
  941. location "s".
  942.  
  943. The following are examples of the M command.
  944.  
  945.         #M20:2400,+9,30:100     Move 10 bytes from 20:2400 to 30:100.
  946.  
  947.         #M.array,+#63,.array2   Move 64 bytes from ARRAY to ARRAY2.
  948.  
  949.  
  950. 3.11 The P (Pass Point) Command
  951. -------------------------------
  952.  
  953. The P command sets, clears, and displays pass points. The forms are:
  954.  
  955.         (a) Pa,n
  956.         (b) Pa
  957.         (c) -Pa
  958.         (d) -P
  959.         (e) P
  960.  
  961. A  pass  point is a permanent breakpoint that remains in effect  until  it is
  962. explicitly  removed,  as opposed to breakpoints set with the G  command, that
  963. must  be  re-entered  with each G command. Pass points  have  associated pass
  964. counts, ranging from 1 to 0FFFFh. The pass count indicates how many times the
  965. instruction  at  the  pass point executes before the control  returns  to the
  966. console. Up to sixteen pass points can be set at a time.
  967.  
  968. An  important  distinction between breakpoints and pass points is  that, when
  969. execution stops at a breakpoint, the instruction at the breakpoint has not yet
  970. been  executed. When execution stops due to a pass point whose pass count has
  971. reached 1, the instruction at the pass point has been executed. This makes it
  972. simple  to  proceed from a pass point with a G  command,  without immediately
  973. encountering the same pass point.
  974.  
  975. Forms  (a) and (b) are used to set pass points. Form (a) sets a pass point at
  976. address  "a" with a pass count of "n", where "a" is the 20-bit address of the
  977. pass  point,  and "n" is the pass count, in the range 1 to 0FFFFh. If  a pass
  978. point is already active at "a", the pass count is simply changed to "n". SID-
  979. 86 responds with a question mark if there are already 16 active pass points.
  980.  
  981. Form  (b) sets a pass point at "a" with a pass count of 1. If a pass point is
  982. already active at "a", the pass count is simply changed to 1. SID-86 responds
  983. with a question mark if there are already 16 active pass points.
  984.  
  985. Forms  (c)  and (d) are used to clear pass points. Form (c)  clears  the pass
  986. point  at  location "a". SID-86 responds with a question mark if there  is no
  987. pass point set at "a". Form (d) clears all the pass points.
  988.  
  989. Form (e) displays all the active pass points in the form:
  990.  
  991.         nnnn ssss:oooo .symbol
  992.  
  993. where "nnnn" is the current pass count for the pass point, "ssss:oooo" is the
  994. segment  and offset of the pass point location, and ".symbol" is the symbolic
  995. name of the offset of the pass point, if such a symbol exists.
  996.  
  997. When  a pass point is encountered, SID-86 displays the pass point information
  998. in the form:
  999.  
  1000.         nnnn PASS ssss:oooo .symbol
  1001.  
  1002. where "nnnn", "ssss:oooo", and ".symbol" are as described above. Next, SID-86
  1003. displays  the CPU state before the instruction at the pass point is executed.
  1004. SID-86  then executes the instruction at the pass point. If the pass point is
  1005. greater than 1, SID-86 decrements the pass count and transfers control back to
  1006. the program under test.
  1007.  
  1008. When the pass count reaches 1, SID-86 displays the break address (that of the
  1009. next instruction to be excuted) in the following form:
  1010.  
  1011.         *ssss:oooo .symbol
  1012.  
  1013. Once the pass count reaches 1, it remains at 1 until the pass point is cleared
  1014. or the pass count is changed with another P command.
  1015.  
  1016. Use pass points in conjunction with the G, T, and U commands. When you use the
  1017. G or U commands, you can suppress the intermediate pass point display with the
  1018. -G  or  -U forms (see Section 3.6, "The G Command", and Section 3.17,  "The U
  1019. Command"). In this case, only the final pass points (when the pass count = 1)
  1020. are  displayed.  You  can  interrupt the G or  U  command  before  its normal
  1021. termination  by  pressing  any key at the console. SID-86 aborts the  G  or U
  1022. command  when  the  next pass point is encountered and prompts  for  the next
  1023. command.
  1024.  
  1025. You  can also use pass points in conjunction with breakpoints set with  the G
  1026. command.  If  a pass point and a breakpoint are set at the same  address, the
  1027. breakpoint  is encountered first. Otherwise, pass points behave in  the usual
  1028. manner,  decrementing  the pass count until it reaches 1  and  then returning
  1029. control to SID-86.
  1030.  
  1031. Normally, the segment registers are not displayed at pass points. You can use
  1032. the  S/-S command to enable/disable the segment register display (See Section
  1033. 3.14, "The S Command").
  1034.  
  1035. The following are examples of the P command.
  1036.  
  1037.         #P              Display active pass points.
  1038.  
  1039.         #P.error        Set pass point at label ERROR.
  1040.  
  1041.         #P.print,17     Set pass point at label PRINT with count of 17h.
  1042.  
  1043.         #-P             Clear all pass points.
  1044.  
  1045.         #-P.error       Clear pass point at label ERROR
  1046.  
  1047.  
  1048. 3.12 The QI, QO (Query I/O) Command
  1049. -----------------------------------
  1050.  
  1051. The  QI and QO commands allow access to any of the 65,536 Input/Output ports.
  1052. The QI command reads data from a port; the QO command writes data to a port.
  1053.  
  1054. The forms of the QI command are:
  1055.  
  1056.         (a) QIn
  1057.         (b) QIWn
  1058.  
  1059. where "n" is the 16-bit port number. In the case of form (a), SID-86 displays
  1060. the  8-bit value read from port "n". In the case of form (b), SID-86 displays
  1061. a 16-bit value from port "n".
  1062.  
  1063. The forms of the QO command are:
  1064.  
  1065.         (a) QOn,v
  1066.         (b) QOWn,v
  1067.  
  1068. where  "n" is the 16-bit port number, and "v" is the value to output.  In the
  1069. case  of  form  (a), the 8-bit value "v" is written to port  "n".  If  "v" is
  1070. greater  than 255, SID-86 responds with a question mark. In the case  of form
  1071. (b), the 16-bit value "v" is written to port "n".
  1072.  
  1073.  
  1074. 3.13 The R (Read) Command
  1075. -------------------------
  1076.  
  1077. The R command reads a file into a contiguous block of memory. The forms are:
  1078.  
  1079.         (a) R<filename>
  1080.         (b) R<filename>,s
  1081.  
  1082. where  <filename> is the name and type of the file to be read, and "s" is the
  1083. location to which the file is read. Form (a) lets SID-86 determine the memory
  1084. location into which the file is read. Form (b) causes SID-86 to read the file
  1085. into  the memory segment beginning at "s". This address can have the standard
  1086. form (ssss:oooo) as in the following example:
  1087.  
  1088.         #Rcpm.sys,1000:0
  1089.  
  1090. The  low-order four bits of "s" are assumed to be zero, so SID-86 reads files
  1091. on a paragraph boundary. If the memory at "s" is not available, SID-86 issues
  1092. the message:
  1093.  
  1094.         MEMORY REQUEST DENIED
  1095.  
  1096. SID-86 reads the file into memory, computes, allocates, and displays the start
  1097. and end addresses of the block of memory occupied by the file. A V command can
  1098. redisplay  this information at a later time. The default display pointer (for
  1099. subsequent D commands) is set to the start of the block occupied by the file.
  1100.  
  1101. The R command does not free any memory previously allocated by another R or E
  1102. command. Thus, a number of files can be read into memory without overlapping.
  1103. The  number  of files that can be loaded is limited to  seven  under CP/M-86,
  1104. which  is the number of memory allocations allowed by the BDOS, minus one for
  1105. SID-86 itself.
  1106.  
  1107. SID-86  issues  an error message if the file does not exist or  there  is not
  1108. enough memory to load the file.
  1109.  
  1110. The following are examples of the R command.
  1111.  
  1112.         #Rsid86.cmd     Read file SID86.CMD into memory.
  1113.  
  1114.         #Rtest          Read file TEST into memory.
  1115.  
  1116.         #Rtest,1000:0   Read  file  TEST  into memory,  starting  at 
  1117. location
  1118.                         1000:0.
  1119.  
  1120.  
  1121. 3.14 The S (Set) Command
  1122. ------------------------
  1123.  
  1124. The S command changes the contents of bytes or words of memory. The forms are:
  1125.  
  1126.         (a) Ss
  1127.         (b) SWs
  1128.         (c) S
  1129.         (d) -S
  1130.  
  1131. where "s" is the 20-bit address where the change occurs.
  1132.  
  1133. SID-86  displays the memory address and its current contents on the following
  1134. line. In response to form (a), the display is:
  1135.  
  1136.         ssss:oooo bb
  1137.  
  1138. and, in response to form (b); the display is:
  1139.  
  1140.         ssss:oooo wwww
  1141.  
  1142. where  "bb"  and "wwww" are the contents of memory in byte and  word formats,
  1143. respectively.
  1144.  
  1145. In  response to one of the above displays, you can choose to alter the memory
  1146. location  or  to  leave it unchanged. If you enter  a  valid  expression, the
  1147. contents  of  the byte (or word) in memory is replaced with the value  of the
  1148. expression. If you do not enter a value, the contents of memory are unaffected
  1149. and  the  contents of the next address are displayed. In either  case, SID-86
  1150. continues to display successive memory addresses and values until you enter a
  1151. period  (".")  on  a  line  by itself  or  until  SID-86  detects  an invalid
  1152. expression.
  1153.  
  1154. In response to form (a), you can enter a string of ASCII characters, beginning
  1155. with  a quotation mark (') and ending with a carriage return.  The characters
  1156. between  the  quotation  mark and the carriage return  are  placed  in memory
  1157. starting  at the address displayed. No case conversion takes place.  The next
  1158. address displayed is the address following the character string.
  1159.  
  1160. SID-86  issues an error message if the value stored in memory cannot  be read
  1161. back  successfully,  indicating  faulty or non-existant RAM  at  the location
  1162. indicated.
  1163.  
  1164. The  forms (c) and (d) control the display of the segment registers  when the
  1165. CPU  state is displayed with the trance command and at pass points.  Form (c)
  1166. turns on the segment register display, and form (d) turns it off. It is often
  1167. convenient to turn off the segment register display while debugging, to allow
  1168. the CPU state display to fit on one line.
  1169.  
  1170. The following are examples of the S command.
  1171.  
  1172.         #S.array+3              Begin set at ARRAY(3).
  1173.         nnnn:1234  55  0        Set byte to 0.
  1174.         nnnn:1235  55  'abc'    Set 3 bytes to 'a', 'b', 'c'.
  1175.         nnnn:1238  55  #75      Set byte to decimal 75.
  1176.         nnnn:1239  55  .        Terminate set command.
  1177.         #S                      Enable  segment register display in CPU state
  1178.                                 display.
  1179.         #-S                     Disable segment register display in CPU state
  1180.                                 display.
  1181.  
  1182.  
  1183. 3.15 The SR (Search) Command
  1184. ----------------------------
  1185.  
  1186. The  SR  (SeaRch) command searches a block of memory for a  given  pattern of
  1187. numeric or ASCII values, and lists the addresses where the pattern occurs. The
  1188. form is:
  1189.  
  1190.         SRs,f,pattern
  1191.  
  1192. where  "s" is the 20-bit starting address of the block to be searched, "f" is
  1193. the  offset of the final address of the block, and "pattern" is a list of one
  1194. or more hexadecimal values and/or ASCII strings. ASCII strings are enclosed in
  1195. double quotes (") and can be any length. For example,
  1196.  
  1197.         SR200,300,"The form",0D,0A
  1198.  
  1199. For  each occurrence of "pattern", SID-86 displays the 20-bit address  of the
  1200. first byte of the pattern, in the form:
  1201.  
  1202.         ssss:oooo
  1203.  
  1204. If no addresses are listed, "pattern" was not found.
  1205.  
  1206.  
  1207. 3.16 The T (Trace) Command
  1208. --------------------------
  1209.  
  1210. The  T  command  traces  program execution for  1  to  0FFFFh  program steps,
  1211. displaying the CPU state before each step. The forms are:
  1212.  
  1213.         (a) T
  1214.         (b) Tn
  1215.         (c) TW
  1216.         (d) TWn
  1217.         (e) -T (with forms "a" through "d")
  1218.  
  1219. where  "n" is the number of program steps to execute before returning control
  1220. to the console. If "n" is omitted, a single program step is executed.
  1221.  
  1222. A  program  step  is  generally  a  single  instruction,  with  the following
  1223. exceptions:
  1224.  
  1225. *  If  a  BDOS interrupt instruction is traced, the entire  BDOS  function is
  1226. treated as one program step, and executes in real-time. This is because SID-86
  1227. itself makes BDOS calls, and the BDOS is not re-entrant.
  1228.  
  1229. *  If  the traced instruction is a MOV or POP whose destination is  a segment
  1230. register, the CPU executes the next instruction immediately. This is due to a
  1231. feature  of the 8086 that disables interrupts (including the Trace interrupt)
  1232. for one instruction after a MOV or POP loads a segment register. This allows a
  1233. sequence such as:
  1234.  
  1235.         MOV SS,StackSegment
  1236.         MOV SP,StackOffset
  1237.  
  1238. to  be  executed  with no chance of an interrupt  occurring  between  the two
  1239. instructions, at which time the stack is undefined. A sequence of such MOV or
  1240. POP instructions, plus one instruction after the sequence, is considered a one
  1241. program step.
  1242.  
  1243. * If any of the TW forms are used and the traced instruction is a CALL, CALLF,
  1244. or INT, the entire called subroutine or interrupt handler (and any subroutines
  1245. called therein) is treated as a one program step and executes in real-time.
  1246.  
  1247. Before  each  program  step is executed, SID-86 displays the  CPU  state, the
  1248. disassembled instruction to be executed, the symbolic name of the instruction
  1249. operand (if any), and the contents of the memory location(s) referenced by the
  1250. instruction  (if  appropriate).  (See Section 3.20, "The  X  Command",  for a
  1251. detailed  description  of the CPU state display.) If there is a  symbol whose
  1252. value  is  equal  to  the IP, the symbol name followed by  a  colon  (":") is
  1253. displayed  on the line preceding the CPU state display. The segment registers
  1254. are  not  normally displayed with the T command, which allows the  entire CPU
  1255. state to be displayed on one line. To enable the segment register display, use
  1256. the  S command (see Section 3.14, "The S Command"). With the segment register
  1257. display  enabled, the display of the CPU state is identical to that of  the X
  1258. command.
  1259.  
  1260. In  all  of  the forms, control transfers to the program  under  test  at the
  1261. address  indicated by the CS and IP registers. If "n" is not specified, as in
  1262. forms  (a),  one  program step is executed.  Otherwise,  SID-86  executes "n"
  1263. program steps and displays the CPU state before each step, as in form (b). You
  1264. can  abort  a  long trace before "n" steps have been executed  by  typing any
  1265. character at the console.
  1266.  
  1267. When  "n"  steps have been executed, SID-86 displays the address of  the next
  1268. instruction to be executed, along with the symbolic value of the IP, if there
  1269. is such a symbol, in the form:
  1270.  
  1271.         *ssss:oooo .symbol
  1272.  
  1273. Forms  (c)  and  (d) are analogous to forms (a) and (b),  except  in  the way
  1274. subroutine  calls are treated. In the TW forms, the entire  subroutine called
  1275. from  the program level being traced is treated as a single program step, and
  1276. executes  in  real-time. This allows tracing at a high-level of  the program,
  1277. ignoring subroutines that have already been debugged, or for other reasons are
  1278. not currently of interest.
  1279.  
  1280. If  the command is preceded by a minus sign, as in form (e),  symbolic labels
  1281. and  symbolic operands are omitted from the CPU state display. This can speed
  1282. up  the  display when large symbol tables are loaded, by skipping  the symbol
  1283. table lookup.
  1284.  
  1285. When  a  single instruction is being traced, interrupts are disabled  for the
  1286. duration  of  the  instruction.  This prevents  SID-86  from  tracing through
  1287. interrupt  handlers  when  debugging  on systems  in  which  interrupts occur
  1288. frequently.
  1289.  
  1290. After  a  T  command, the list address used in the L command  is  set  to the
  1291. address of the next instruction to be executed, and the default segment values
  1292. are set to the CS and DS register values.
  1293.  
  1294. The following are examples of the T command.
  1295.  
  1296.         #T              Trace one program step.
  1297.  
  1298.         #Tffff          Trace 65535 steps.
  1299.  
  1300.         #-T#500         Trace 500 program steps with symbolic lookup disabled.
  1301.  
  1302.  
  1303. 3.17 The U (Untrace) Command
  1304. ----------------------------
  1305.  
  1306. The  U  command  is similar to the T command, except that  the  CPU  state is
  1307. displayed  only before the first instruction is executed, rather  than before
  1308. every step. The forms are:
  1309.  
  1310.         (a) U
  1311.         (b) Un
  1312.         (c) UW
  1313.         (d) UWn
  1314.         (e) -U (with forms "a" through "d")
  1315.  
  1316. where "n" is the number of instructions to execute before returning control to
  1317. the  console. You can abort the U command before "n" steps have been executed
  1318. by striking any key at the console.
  1319.  
  1320. Form  (e)  differs from the analogous T command in that  SID-86  disables the
  1321. display of intermediate pass points (while the pass count is greater than 1).
  1322. In  this  case,  only when the pass count reaches 1 is  the  pass information
  1323. displayed (see Section 3.11, "The P Command").
  1324.  
  1325. The following are examples of the U command.
  1326.  
  1327.         #U200
  1328.  
  1329. Trace without display 200h steps.
  1330.  
  1331.         #-U200
  1332.  
  1333. Trace  without  display 200h steps, suppressing the  intermediate  pass point
  1334. display.
  1335.  
  1336.  
  1337. 3.18 The V (Value) Command
  1338. --------------------------
  1339.  
  1340. The V command displays information about the last file loaded with the E or R
  1341. commands, excluding symbol tables loaded with the E command. The form is:
  1342.  
  1343.         V
  1344.  
  1345. If  the  last file was loaded with the E command, the V command  displays the
  1346. start and end addresses of each of the segments contained in the file. If the
  1347. last  file was read with the R command, the V command displays the  start and
  1348. end addresses of the block of memory where the file was read. SID-86 responds
  1349. to the V command with a question mark if neither the R or E commands have been
  1350. used.
  1351.  
  1352.  
  1353. 3.19 The W (Write) Command
  1354. --------------------------
  1355.  
  1356. The W command writes the contents of a contiguous block of memory to disk. The
  1357. forms are:
  1358.  
  1359.         (a) W<filename>
  1360.         (b) W<filename>,s,f
  1361.  
  1362. where <filename> is the filename and filetype of the disk file to receive the
  1363. data, and "s" and "f" are the 20-bit first and last addresses of the block to
  1364. be written. If the segment is not specified in "f", SID-86 uses the same value
  1365. that was used for "s".
  1366.  
  1367. With  form (a), SID-86 assumes the "s" and "f" values from the last file read
  1368. with a R command. If no file was read with an R command, SID-86 responds with
  1369. a question mark ("?"). This form is useful for writing out files after patches
  1370. have been installed, assuming the overall length of the file is unchanged.
  1371.  
  1372. With  form (b), where "s" and "f" are specified as 20-bit addresses,  the low
  1373. four  bits  of  "s" are assumed to be 0. Thus, the block  being  written must
  1374. always start on a paragraph boundary.
  1375.  
  1376. If  a  file with the name specified in the W command  already  exists, SID-86
  1377. deletes it before writing a new file.
  1378.  
  1379. The following are examples of the W command.
  1380.  
  1381.         #Wtest.cmd              Write to the file TEST.CMD the contents of the
  1382.                                 memory  block read into by the most  recent R
  1383.                                 command.
  1384.  
  1385.         #Wb:test.cmd,40:0,3FF   Write  the contents of the memory  block 40:0
  1386.                                 through  40:3FF to the file TEST.CMD on drive
  1387.                                 B.
  1388.  
  1389.  
  1390. 3.20 The X (Examine CPU State) Command
  1391. --------------------------------------
  1392.  
  1393. The  X  command allows you to examine and alter the CPU state of  the program
  1394. under test. The forms are:
  1395.  
  1396.         (a) X
  1397.         (b) Xr
  1398.         (c) Xf
  1399.  
  1400. where  "r"  is  the  name of one of the 8086 CPU  registers  and  "f"  is the
  1401. abbreviation  of one of the CPU flags. Form (a) displays the CPU state in the
  1402. form:
  1403.  
  1404.                     AX    BX    CX   ...   SS    ES    IP
  1405.         ---------  xxxx  xxxx  xxxx  ...  xxxx  xxxx  xxxx
  1406.          <instruction>   <symbol name>    <memory value>
  1407.  
  1408. The  nine hyphens at the beginning of the line indicate the state of the nine
  1409. CPU  flags.  Each  position  can  be either  a  hyphen,  indicating  that the
  1410. corresponding  flag is not set (0), or a 1-character abbreviation of the flag
  1411. name, indicating that the flag is set (1). The abbreviation of the flag names
  1412. are shown in Table 3-1.
  1413.  
  1414.         Table 3-1. Flag Name Abbreviations
  1415.  
  1416.         Character       Name
  1417.         ---------       --------
  1418.             O           Overflow
  1419.             D           Direction
  1420.             I           Interrupt Enable
  1421.             T           Trap
  1422.             S           Sign
  1423.             Z           Zero
  1424.             A           Auxiliary Carry
  1425.             P           Parity
  1426.             C           Carry
  1427.  
  1428. <instruction>  is  the  disassembled instruction at the next  location  to be
  1429. executed,  which is indicated by the CS and IP registers. If the symbol table
  1430. contains   a  symbol  whose  value  is  equal  to  one  of  the  operands in
  1431. <instruction>,  the  symbol  name is displayed in  the  <symbol  name> field,
  1432. preceded  by a period ("."). If <instruction> references memory, the contents
  1433. of  the  referenced  location(s) are displayed in the  <memory  value> field,
  1434. preceded by an equal sign. Either a byte, word, or double word value is shown,
  1435. depending on the instruction. In addition to displaying the machine state, the
  1436. first  form changes the values of the default segments back to the CS  and DS
  1437. register  values, and the default offset for the L command to the IP register
  1438. value.
  1439.  
  1440. Form  (b)  allows you to alter the registers in the CPU state of  the program
  1441. being  tested.  The "r" following the X is the name of one of the  16-bit CPU
  1442. registers. SID-86 responds by displaying the name of the register, followed by
  1443. its current value. If you type a carriage return, the value of the register is
  1444. not changed. If you type a valid expression, the contents of the register are
  1445. changed  to the value of the expression. In either case, the next register is
  1446. then  displayed. This process continues until you enter a period (".")  or an
  1447. invalid expression, or the last register is displayed.
  1448.  
  1449. Form (c) allows you to alter one of the flags in the CPU state of the program
  1450. being tested. SID-86 responds by displaying the name of the flag, followed by
  1451. its current state. If you type a carriage return, the state of the flag is not
  1452. changed.  If you type a valid value, the state of the flag is changed to that
  1453. value.  Only one flag can be examined or altered with each Xf command. Set or
  1454. reset flags by entering a value of 1 or 0.
  1455.  
  1456. The following are examples of the X command.
  1457.  
  1458.         #Xbp            Change registers, starting with BP.
  1459.         BP=1000 2B64    Change BP to hex 2B64.
  1460.         SI=2000 #12345  Change SI to decimal 12345.
  1461.         DI=0020 .var+6  Change DI to value of symbol VAR plus 6.
  1462.         CS=0040 .       Terminate X command.
  1463.  
  1464.  
  1465. 3.21 The Z (Display 8087 Math Co-processor Registers) Command
  1466. -------------------------------------------------------------
  1467.  
  1468. (Not documented... Due to Richard Plinston.)
  1469.  
  1470.          CW   SW   TW      IP        OP
  1471.         037F 0000 FFFF 0000 0000 0000 0000
  1472.  
  1473.         0  0000 0000 0000 0000 0000
  1474.         1  0000 0000 0000 0000 0000
  1475.         2  0000 0000 0000 0000 0000
  1476.         3  0000 0000 0000 0000 0000
  1477.         4  0000 0000 0000 0000 0000
  1478.         5  0000 0000 0000 0000 0000
  1479.         6  0000 0000 0000 0000 0000
  1480.         7  0000 0000 0000 0000 0000
  1481.  
  1482.  
  1483. Section 4: Default Segment Values
  1484. ---------------------------------
  1485.  
  1486. SID-86  has  an  internal mechanism that keeps track of  the  current segment
  1487. value, making segment specification an optional part of a SID-86 command. SID-
  1488. 86  divides  the  command set into two types of  commands,  according  to the
  1489. segment  a command defaults to, if you do not specify a segment value  in the
  1490. command line.
  1491.  
  1492. The  first  type of command, pertaining to the code segment,  includes  the A
  1493. (Assemble), L (List Mnemonics), P (Pass Points), and W (Write) commands. These
  1494. commands  use  the  internal  type-1 segment value  if  no  segment  value is
  1495. specified in the command.
  1496.  
  1497. When  invoked, SID-86 sets the type-1 segment value to 0, and changes it when
  1498. one of the following actions is taken:
  1499.  
  1500. * When an E command loads a file, SID-86 sets the type-1 segment value to the
  1501. value of the CS register.
  1502.  
  1503. * When an R command reads a file, SID-86 sets the type-1 segment value to the
  1504. base segment where the file was read.
  1505.  
  1506. *  When an X command changes the value of the CS register, SID-86 changes the
  1507. type-1 segment value to the new value of the CS register.
  1508.  
  1509. * When SID-86 regains control from a user program after a G, T, or U command,
  1510. it sets the type-1 segment value to the value of the CS register.
  1511.  
  1512. * When an A or L command explicitly specifies a segment value, SID-86 sets the
  1513. type-1 segment value to the segment value specified.
  1514.  
  1515.  
  1516. The  second  type of command, pertaining to the data segment, includes  the D
  1517. (Display),  F (Fill), M (Move), and S (Set) commands. These commands  use the
  1518. internal type-2 segment value if no segment value is specified in the command.
  1519.  
  1520. When  invoked, SID-86 sets the type-2 segment value to 0, and changes it when
  1521. one of the following actions is taken:
  1522.  
  1523. * When an E command loads a file, SID-86 sets the type-2 segment value to the
  1524. value of the DS register.
  1525.  
  1526. * When an R command reads a file, SID-86 sets the type-2 segment value to the
  1527. base segment where the file was read.
  1528.  
  1529. *  When an X command changes the value of the DS register, SID-86 changes the
  1530. type-2 segment value to the new value of the DS register.
  1531.  
  1532. * When SID-86 regains control from a user program after a G, T, or U command,
  1533. it sets the type-2 segment value to the value of the DS register.
  1534.  
  1535. *  When a D, F, M, or S command explicitly specifies a segment  value, SID-86
  1536. sets the type-2 segment value to the segment value specified.
  1537.  
  1538.  
  1539. When  evaluating  programs  that  have  identical values  in  the  CS  and DS
  1540. registers,  all  SID-86 commands defaults to the same  segment  value, unless
  1541. explicitly overridden.
  1542.  
  1543. Table  4-1  summarizes SID-86's default segment values. Note that the  G (Go)
  1544. command  does  not  fall  into either group, because it  defaults  to  the CS
  1545. register.
  1546.  
  1547.         Table 4-1. SID-86 Default Segment Values
  1548.  
  1549.         Command Type-1  Type-2
  1550.         ------- ------  ------
  1551.            A      *
  1552.            B              *
  1553.            D
  1554.            E      @       @
  1555.            F              *
  1556.            G      @       @
  1557.            H
  1558.            I
  1559.            L      *
  1560.            M              *
  1561.            P      %
  1562.            Q
  1563.            R      *       @
  1564.            S              *
  1565.            SR
  1566.            T      @       @
  1567.            U      @       @
  1568.            V
  1569.            W      *
  1570.            X      @       @
  1571.            Z
  1572.  
  1573. Abbreviations Used:
  1574. * = Use this segment default if none specified;
  1575.     change default if specified explicitly.
  1576. @ = Change this segment default.
  1577. % = Use this segment default if none specified.
  1578.  
  1579.  
  1580. Section 5: Assembly Language Syntax for A and L commands
  1581. --------------------------------------------------------
  1582.  
  1583. In  general,  the syntax of the assembly language statements in the  A  and L
  1584. commands  is standard Intel 8086 assembly language. Several  minor exceptions
  1585. are listed below.
  1586.  
  1587. *  Up  to three prefixes (LOCK, repeat, segment override) can  appear  in one
  1588. statement, but they all must precede the opcode of the statement. Alternately,
  1589. a prefix can be entered on a line by itself.
  1590.  
  1591. *  The  distinction  between  byte and word string  instructions  is  made as
  1592. follows:
  1593.  
  1594.         Byte    Word
  1595.         ----    ----
  1596.         LODSB   LODSW
  1597.         STOSB   STOSW
  1598.         SCASB   SCASW
  1599.         MOVSB   MOVSW
  1600.         CMPSB   CMPSW
  1601.  
  1602. * The mnemonics for near and far control transfer instructions are as follows:
  1603.  
  1604.         Short   Normal  Far
  1605.         -----   ------  ---
  1606.         JMPS    JMP     JMPF
  1607.                 CALL    CALLF
  1608.                 RET     RETF
  1609.  
  1610. * If the operand of a CALLF or JMPF instruction is a 20-bit absolute address,
  1611. it is entered in the form:
  1612.  
  1613.         ssss:oooo
  1614.  
  1615. where "ssss" is the segment and "oooo" is the offset of the address.
  1616.  
  1617. * Operands that can refer to either a byte or word are ambiguous, and must be
  1618. preceded either by the prefix BYTE or WORD. These prefixes can be abbreviated
  1619. to BY and WO. For example:
  1620.  
  1621.         INC BYTE[BP]
  1622.         NOT WORD[1234]
  1623.  
  1624. Failure to supply a prefix when needed results in an error message.
  1625.  
  1626. *  Operands that address memory directly are enclosed in square  brackets, to
  1627. distinguish them from immediate values. For example:
  1628.  
  1629.         ADD AX,5        ; Add 5 to register AX
  1630.         ADD AX,[5]      ; Add the contents of location 5 to AX
  1631.  
  1632. * The forms of register indirect memory operands are:
  1633.  
  1634.         [pointer register]
  1635.         [index register]
  1636.         [pointer register + index register]
  1637.  
  1638. where the pointer registers are BX and BP, and the index registers are SI and
  1639. DI. Any of these forms can be preceded by a numeric offset. For example:
  1640.  
  1641.         ADD BX,[BP+SI]
  1642.         ADD BX,3[BP+SI]
  1643.         ADD BX,1D47[BP+SI]
  1644.  
  1645.  
  1646. Section 6: SID-86 Sample Session
  1647. --------------------------------
  1648.  
  1649. In  the  following  sample session, the user  interactively  debugs  a simple
  1650. program.  User  input  is shown in Italic print; remarks  in  square brackets
  1651. explain the steps involved.
  1652.  
  1653. [Type source file of program to test.]
  1654.  
  1655. A>type typ.a86
  1656. ; Display the contents of an
  1657. ; ASCII file at the console.
  1658. ;--------------------------------
  1659. ; Base Page locations used.
  1660. ;
  1661. fcb     EQU     005Ch           ; File Control Block
  1662. ;
  1663. ; ASCII characters used.
  1664. ;
  1665. eof     EQU     1Ah             ; CP/M End-Of-File character
  1666. ;
  1667. ; Interrupts used.
  1668. ;
  1669. bdosi   EQU     224             ; BDOS Interrupt Number
  1670. ;
  1671. ; BDOS functions used.
  1672. ;
  1673. ConOutC EQU      2              ; Console Output
  1674. OpenC   EQU     15              ; Open File
  1675. ReadC   EQU     20              ; Read File
  1676. SetDMAc EQU     26              ; Set DMA Address
  1677. ;
  1678.  
  1679. ;--------------------------------
  1680. ; Main.
  1681. ;
  1682. start:  MOV     DX,fcb          ; Points to FCB
  1683.         CALL    open            ; Open file
  1684. loop:   CALL    GetChr          ; Get one char
  1685.         CMP     AL,eof          ; Is it the EOF char?
  1686.         JZ      done            ; Yes: the end
  1687.         CALL    ConOut          ; No: display it
  1688.         JMPS    loop            ;     and loop.
  1689. ;
  1690. ; The end. Back to CP/M.
  1691. ;
  1692. done:   MOV     DL,0            ; = ?
  1693.         MOV     CL,0            ; = Reset function
  1694.         JMP     bdos            ; Ditto
  1695. ;
  1696. ;--------------------------------
  1697. ; Get a char from DMA buffer.
  1698. ;
  1699. GetChr: CMP     bPtr,bSize      ; See if we need a new buffer fill
  1700.         JC      Get1            ;
  1701.         CALL    FilBuf          ; Yes: Refill buffer from file
  1702. Get1:   MOV     BX,OFFSET buffer  ;
  1703.  
  1704.         MOV     AL,buffer[BX]   ; Get next character from buffer
  1705.         INC     bPtr            ; Increment buffer pointer
  1706.         RET                     ;
  1707. ;
  1708. ;--------------------------------
  1709. ; Fill DMA buffer from file.
  1710. ;
  1711. FilBuf: MOV     DX,OFFSET buffer  ;
  1712.         CALL    SetDMA          ;
  1713.         MOV     DX,5Ch          ;
  1714.         CALL    read            ;
  1715.         MOV     bPtr,00h        ;
  1716.         RET                     ;
  1717. ;
  1718. ;--------------------------------
  1719. ; Open a file.
  1720. ;
  1721. Open:   MOV     CL,openc        ;
  1722.         CALL    bdos            ; Do it the old fashioned way
  1723.         CMP     AL,0FFh         ;
  1724.         JNZ     err             ;
  1725.         RET                     ;
  1726. ;
  1727. ;--------------------------------
  1728.  
  1729. ; Set DMA Address.
  1730. ;
  1731. SetDMA: MOV     CL,SetDMAc      ;
  1732.         JMPS    bdos            ;
  1733. ;
  1734. ;--------------------------------
  1735. ; Read one record from file.
  1736. ;
  1737. Read:   MOV     CL,ReadC        ;
  1738.         CALL    bdos            ;
  1739.         CMP     AL,00h          ;
  1740.         JNZ     err             ;
  1741.         RET                     ;
  1742. ;
  1743. ;--------------------------------
  1744. ; Console Output.
  1745. ;
  1746. ConOut: MOV     CL,ConOutC      ;
  1747.         JMPS    bdos            ;
  1748. ;
  1749. ;--------------------------------
  1750. ; Print a string.
  1751. ;
  1752. PrintM: MOV     CL,9            ;
  1753.         JMPS    bdos            ;
  1754. ;
  1755. ;--------------------------------
  1756. ; Provides Old fashioned BDOS call.
  1757. ;
  1758. bdos:   INT     bdosi           ; IBM PC
  1759.         RET                     ;
  1760. ;
  1761. ;--------------------------------
  1762. ; Print error message and abort.
  1763. ;
  1764. Err:    MOV     DX,OFFSET ErrorM  ;
  1765.         CALL    printm          ;
  1766.         JMP     done            ;
  1767. ;
  1768. ;--------------------------------
  1769.         DSEG
  1770. ;--------------------------------
  1771.         ORG     100h            ; Reserve Base Page
  1772. ;
  1773. ErrorM  DB      'ERROR',0Dh,0Ah,'$'
  1774. bSize   EQU     80h             ; Buffer Size = 128 characters
  1775. buffer  RS      bSize           ; Reserve them
  1776. bPtr    DB      bSize           ; Buffer Pointer = 1st char
  1777.  
  1778. ;
  1779. ;--------------------------------
  1780. ;
  1781.         END
  1782.  
  1783. [Assemble TYP.A86 file.]
  1784.  
  1785. A>asm typ
  1786.  
  1787. CP/M 8086 ASSEMBLER VER 1.1
  1788. END OF PASS 1
  1789. END OF PASS 2
  1790. END OF ASSEMBLY.  NUMBER OF ERRORS:   0.  USE FACTOR:  0%
  1791.  
  1792. [Type list file created by ASM-86.]
  1793.  
  1794. A>type typ.lst
  1795.  
  1796. CP/M ASM86 1.1  SOURCE: TYP.A86 
  1797. PAGE   1
  1798.  
  1799.  
  1800.                         ; Display the contents of an
  1801.                         ; ASCII file at the console.
  1802.                         ;--------------------------------
  1803.                         ; Base Page locations used.
  1804.                         ;
  1805.    005C                 fcb     EQU     005Ch           ; File Control Block
  1806.                         ;
  1807.                         ; ASCII characters used.
  1808.                         ;
  1809.    001A                 eof     EQU     1Ah             ; CP/M End-Of-File character
  1810.                         ;
  1811.                         ; Interrupts used.
  1812.                         ;
  1813.    00E0                 bdosi   EQU     224             ; BDOS Interrupt Number
  1814.                         ;
  1815.                         ; BDOS functions used.
  1816.                         ;
  1817.    0002                 ConOutC EQU      2              ; Console Output
  1818.    000F                 OpenC   EQU     15              ; Open File
  1819.  
  1820.    0014                 ReadC   EQU     20              ; Read File
  1821.    001A                 SetDMAc EQU     26              ; Set DMA Address
  1822.                         ;
  1823.                         ;--------------------------------
  1824.                         ; Main.
  1825.                         ;
  1826.  0000 BA5C00            start:  MOV     DX,fcb          ; Points to FCB
  1827.  0003 E83B00       0041         CALL    open            ; Open file
  1828.  0006 E81000       0019 loop:   CALL    GetChr          ; Get one char
  1829.  0009 3C1A                      CMP     AL,eof          ; Is it the EOF char?
  1830.  000B 7405         0012         JZ      done            ; Yes: the end
  1831.  000D E84900       0059         CALL    ConOut          ; No: display it
  1832.  0010 EBF4         0006         JMPS    loop            ;     and loop.
  1833.                         ;
  1834.                         ; The end. Back to CP/M.
  1835.                         ;
  1836.  0012 B200              done:   MOV     DL,0            ; = ?
  1837.  0014 B100                      MOV     CL,0            ; = Reset function
  1838.  0016 E94800       0061         JMP     bdos            ; Ditto
  1839.                         ;
  1840.                         ;--------------------------------
  1841.                         ; Get a char from DMA buffer.
  1842.                         ;
  1843.  0019 803E880180        GetChr: CMP     bPtr,bSize      ; See if we need a new buffer fill
  1844.  
  1845.  001E 7203         0023         JC      Get1            ;
  1846.  0020 E80C00       002F         CALL    FilBuf          ; Yes: Refill buffer from file
  1847.  0023 BB0801            Get1:   MOV     BX,OFFSET buffer  ;
  1848.  0026 8A870801                  MOV     AL,buffer[BX]   ; Get next character from buffer
  1849.  002A FE068801                  INC     bPtr            ; Increment buffer pointer
  1850.  002E C3                        RET                     ;
  1851.                         ;
  1852.                         ;--------------------------------
  1853.                         ; Fill DMA buffer from file.
  1854.  
  1855. CP/M ASM86 1.1  SOURCE: TYP.A86 
  1856. PAGE   2
  1857.  
  1858.  
  1859.                         ;
  1860.  002F BA0801            FilBuf: MOV     DX,OFFSET buffer  ;
  1861.  0032 E81600       004B         CALL    SetDMA          ;
  1862.  0035 BA5C00                    MOV     DX,5Ch          ;
  1863.  0038 E81400       004F         CALL    read            ;
  1864.  003B C606880100                MOV     bPtr,00h        ;
  1865.  0040 C3                        RET                     ;
  1866.                         ;
  1867.                         ;--------------------------------
  1868.                         ; Open a file.
  1869.                         ;
  1870.  0041 B10F              Open:   MOV     CL,openc        ;
  1871.  
  1872.  0043 E81B00       0061         CALL    bdos            ; Do it the old fashioned way
  1873.  0046 3CFF                      CMP     AL,0FFh         ;
  1874.  0048 751A         0064         JNZ     err             ;
  1875.  004A C3                        RET                     ;
  1876.                         ;
  1877.                         ;--------------------------------
  1878.                         ; Set DMA Address.
  1879.                         ;
  1880.  004B B11A              SetDMA: MOV     CL,SetDMAc      ;
  1881.  004D EB12         0061         JMPS    bdos            ;
  1882.                         ;
  1883.                         ;--------------------------------
  1884.                         ; Read one record from file.
  1885.                         ;
  1886.  004F B114              Read:   MOV     CL,ReadC        ;
  1887.  0051 E80D00       0061         CALL    bdos            ;
  1888.  0054 3C00                      CMP     AL,00h          ;
  1889.  0056 750C         0064         JNZ     err             ;
  1890.  0058 C3                        RET                     ;
  1891.                         ;
  1892.                         ;--------------------------------
  1893.                         ; Console Output.
  1894.                         ;
  1895.  0059 B102              ConOut: MOV     CL,ConOutC      ;
  1896.  005B EB04         0061         JMPS    bdos            ;
  1897.                         ;
  1898.                         ;--------------------------------
  1899.                         ; Print a string.
  1900.                         ;
  1901.  005D B109              PrintM: MOV     CL,9            ;
  1902.  005F EB00         0061         JMPS    bdos            ;
  1903.                         ;
  1904.                         ;--------------------------------
  1905.                         ; Provides Old fashioned BDOS call.
  1906.                         ;
  1907.  0061 CDE0              bdos:   INT     bdosi           ; IBM PC
  1908.  0063 C3                        RET                     ;
  1909.                         ;
  1910.                         ;--------------------------------
  1911.                         ; Print error message and abort.
  1912.  
  1913. CP/M ASM86 1.1  SOURCE: TYP.A86 
  1914. PAGE   3
  1915.  
  1916.  
  1917.                         ;
  1918.  0064 BA0001            Err:    MOV     DX,OFFSET ErrorM  ;
  1919.  0067 E8F3FF       005D         CALL    printm          ;
  1920.  006A E9A5FF       0012         JMP     done            ;
  1921.                         ;
  1922.  
  1923.                         ;--------------------------------
  1924.                                 DSEG
  1925.                         ;--------------------------------
  1926.                                 ORG     100h            ; Reserve Base Page
  1927.                         ;
  1928.  0100 4552524F520D      ErrorM  DB      'ERROR',0Dh,0Ah,'$'
  1929.       0A24
  1930.    0080                 bSize   EQU     80h             ; Buffer Size = 128 characters
  1931.  0108                   buffer  RS      bSize           ; Reserve them
  1932.  0188 80                bPtr    DB      bSize           ; Buffer Pointer = 1st char
  1933.                         ;
  1934.                         ;--------------------------------
  1935.                         ;
  1936.                                 END
  1937.  
  1938.  
  1939. END OF ASSEMBLY.  NUMBER OF ERRORS:   0.  USE FACTOR:  0%
  1940.  
  1941. [Type hex file produced by ASM-86.]
  1942.  
  1943. A>type typ.h86
  1944. :0400000300000000F9
  1945. :1B000081BA5C00E83B00E810003C1A7405E84900EBF4B200B100E94800803E02
  1946. :1B001B818801807203E80C00BB08018A870801FE068801C3BA0801E81600BA2E
  1947. :1B0036815C00E81400C606880100C3B10FE81B003CFF751AC3B11AEB12B114E1
  1948. :1B005181E80D003C00750CC3B102EB04B109EB00CDE0C3BA0001E8F3FFE9A5C4
  1949. :01006C81FF13
  1950. :080100824552524F520D0A24B0
  1951. :010188828074
  1952. :00000001FF
  1953.  
  1954. [Type symbol table file produced by ASM-86.]
  1955.  
  1956. A>type typ.sym
  1957.  
  1958. 0000 VARIABLES
  1959. 0188 BPTR       0108 BUFFER     0100 ERRORM
  1960.  
  1961. 0000 NUMBERS
  1962. 00E0 BDOSI      0080 BSIZE      0002 CONOUTC    001A EOF        005C FCB
  1963. 000F OPENC      0014 READC      001A SETDMAC
  1964.  
  1965. 0000 LABELS
  1966. 0061 BDOS       0059 CONOUT     0012 DONE       0064 ERR        002F FILBUF
  1967. 0023 GET1       0019 GETCHR     0006 LOOP       0041 OPEN       005D PRINTM
  1968. 004F READ       004B SETDMA     0000 START
  1969.  
  1970. [Create command file from hex file.]
  1971.  
  1972. A>gencmd typ
  1973.  
  1974. BYTES READ    007A
  1975. RECORDS WRITTEN 05
  1976.  
  1977. [Try executing the program with the file TYP.A86 as data.]
  1978.  
  1979. A>typ typ.a86
  1980. ERROR
  1981.  
  1982. [The program did not work correctly, so load the command file and symbol table
  1983. file to find out why.]
  1984.  
  1985. A>sid typ.cmd typ.sym
  1986. SID86 1.01   1/4/83
  1987.  
  1988. [SID-86 shows the start and end addresses of each segment from the file.]
  1989.  
  1990.      START      END
  1991. CS 1CC1:0000 1CC1:006F
  1992. DS 1CC8:0000 1CC8:018F
  1993. SYMBOLS
  1994.  
  1995. [Display all the symbols that SID-86 loaded.]
  1996.  
  1997. #h
  1998. 0000 VARIABLES
  1999. 0188 BPTR
  2000. 0108 BUFFER
  2001. 0100 ERRORM
  2002. 0000 NUMBERS
  2003. 00E0 BDOSI
  2004. 0080 BSIZE
  2005. 0002 CONOUTC
  2006. 001A EOF
  2007. 005C FCB
  2008. 000F OPENC
  2009. 0014 READC
  2010. 001A SETDMAC
  2011. 0000 LABELS
  2012. 0061 BDOS
  2013. 0059 CONOUT
  2014. 0012 DONE
  2015. 0064 ERR
  2016. 002F FILBUF
  2017. 0023 GET1
  2018. 0019 GETCHR
  2019. 0006 LOOP
  2020. 0041 OPEN
  2021. 005D PRINTM
  2022. 004F READ
  2023. 004B SETDMA
  2024. 0000 START
  2025.  
  2026. [Disassemble the beginning of the code segment.]
  2027.  
  2028. #l
  2029. START:
  2030.   1CC1:0000 MOV    DX,005C .FCB
  2031.   1CC1:0003 CALL   0041 .OPEN
  2032. LOOP:
  2033.   1CC1:0006 CALL   0019 .GETCHR
  2034.   1CC1:0009 CMP    AL,1A .EOF
  2035.   1CC1:000B JZ     0012 .DONE
  2036.   1CC1:000D CALL   0059 .CONOUT
  2037.   1CC1:0010 JMPS   0006 .LOOP
  2038. DONE:
  2039.   1CC1:0012 MOV    DL,00 .VARIABLES
  2040.   1CC1:0014 MOV    CL,00 .VARIABLES
  2041.   1CC1:0016 JMP    0061 .BDOS
  2042. GETCHR:
  2043.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2044.   1CC1:001E JB     0023 .GET1
  2045.  
  2046. [Set  up the default file control block at 005Ch with the name of the file to
  2047. process.]
  2048.  
  2049. #ityp.a86
  2050.  
  2051. [Trace the first two instructions of the program.]
  2052.  
  2053. #t2
  2054.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2055. --I------ 0000 0000 0000 0000 015C 0000 0000 0000 0000 MOV    DX,005C .FCB
  2056. --I------ 0000 0000 0000 005C 015C 0000 0000 0000 0003 CALL   0041 .OPEN
  2057.  
  2058. [SID-86 stops execution after two instructions, at the label OPEN.]
  2059.  
  2060. *1CC1:0041 .OPEN
  2061.  
  2062. [Display the contents of the default FCB, to make sure it is set up right.]
  2063.  
  2064. #d.fcb,+#35
  2065. 1CC8:005C 00 54 59 50 20 20 20 20 20 41 38 36 00 00 00 00 .TYP     A86....
  2066. 1CC8:006C 00 20 20 20 20 20 20 20 20 20 20 20 00 00 00 00 .           ....
  2067. 1CC8:007C 00 00 00 00 ....
  2068.  
  2069. [The FCB looks Ok. Disassemble the next few instructions.]
  2070.  
  2071. #l
  2072. OPEN:
  2073.   1CC1:0041 MOV    CL,0F .OPENC
  2074.   1CC1:0043 CALL   0061 .BDOS
  2075.   1CC1:0046 CMP    AL,FF
  2076.   1CC1:0048 JNZ    0064 .ERR
  2077.   1CC1:004A RET
  2078. SETDMA:
  2079.   1CC1:004B MOV    CL,1A .EOF
  2080.   1CC1:004D JMPS   0061 .BDOS
  2081. READ:
  2082.   1CC1:004F MOV    CL,14 .READC
  2083.   1CC1:0051 CALL   0061 .BDOS
  2084.   1CC1:0054 CMP    AL,00 .VARIABLES
  2085.   1CC1:0056 JNZ    0064 .ERR
  2086.   1CC1:0058 RET
  2087.  
  2088. [Continue program execution with a break point after the open function.]
  2089.  
  2090. #g,46
  2091. *1CC1:0046
  2092.  
  2093. [Display the CPU registers.]
  2094.  
  2095. #x
  2096.            AX   BX   CX   DX   SP   BP   SI   DI   CS   DS   SS   ES   IP
  2097. --I------ 0000 0000 0000 0000 015A 0000 0000 0000 1CC1 1CC8 0AFB 1CC8 0046
  2098. CMP    AL,FF
  2099.  
  2100. [Registers look Ok; trace a few more instructions.]
  2101.  
  2102. #t2
  2103.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2104. --I------ 0000 0000 0000 0000 015A 0000 0000 0000 0046 CMP    AL,FF
  2105. --I---A-C 0000 0000 0000 0000 015A 0000 0000 0000 0048 JNZ    0064 .ERR
  2106. *1CC1:0064 .ERR
  2107.  
  2108. [Shouldn't be getting to the ERR label -- the jump instruction seems to be of
  2109. the  wrong  flavor. It should be a JZ. Rather than editing the  source, let's
  2110. install a patch. Since the new instruction is the same length as the old one,
  2111. it will be easy. Read the file into memory (including the header record).]
  2112.  
  2113. #rtyp.cmd
  2114.   START      END
  2115. 1CEF:0000 1CEF:027F
  2116.  
  2117. [The  file was read into memory starting at paragraph 1CEF. That is where the
  2118. header record is -- the code will start 8 paragraphs later.]
  2119.  
  2120. #h1CEF,8
  2121. + 1CF7   - 1CE7   * 0000E778   / 039D (0007)
  2122.  
  2123. [The  code  starts  in paragraph 1CF7. If we use that as the base  for  the L
  2124. command, all the symbol values will be correct.]
  2125.  
  2126. #l1CF7:0
  2127. START:
  2128.   1CF7:0000 MOV    DX,005C .FCB
  2129.   1CF7:0003 CALL   0041 .OPEN
  2130. LOOP:
  2131.   1CF7:0006 CALL   0019 .GETCHR
  2132.   1CF7:0009 CMP    AL,1A .EOF
  2133.   1CF7:000B JZ     0012 .DONE
  2134.   1CF7:000D CALL   0059 .CONOUT
  2135.   1CF7:0010 JMPS   0006 .LOOP
  2136. DONE:
  2137.   1CF7:0012 MOV    DL,00 .VARIABLES
  2138.   1CF7:0014 MOV    CL,00 .VARIABLES
  2139.   1CF7:0016 JMP    0061 .BDOS
  2140. GETCHR:
  2141.   1CF7:0019 CMP    BYTE [0188],80 .BPTR
  2142.   1CF7:001E JB     0023 .GET1
  2143.  
  2144. [Disassemble the OPEN routine.]
  2145.  
  2146. #l.open,.setdma-1
  2147. OPEN:
  2148.   1CF7:0041 MOV    CL,0F .OPENC
  2149.   1CF7:0043 CALL   0061 .BDOS
  2150.   1CF7:0046 CMP    AL,FF
  2151.   1CF7:0048 JNZ    0064 .ERR
  2152.   1CF7:004A RET
  2153.  
  2154. [Assemble patch instruction.]
  2155.  
  2156. #a48
  2157.  
  2158. [Note that symbolic values may be used in the A command.]
  2159.  
  2160. 1CF7:0048 jz .err
  2161. 1CF7:004A .
  2162.  
  2163. [Write the patched file back to disk. The start and end addresses need not be
  2164. included  in  the  W command, since the overall length of  the  file  did not
  2165. change.]
  2166.  
  2167. #wtyp.cmd
  2168.  
  2169. [Reload  the  patched file and symbols. This is needed, since  the  R command
  2170. doesn't set up registers.]
  2171.  
  2172. #etyp.cmd typ.sym
  2173.      START      END
  2174. CS 1CC1:0000 1CC1:006F
  2175. DS 1CC8:0000 1CC8:018F
  2176. SYMBOLS
  2177. #ityp.a86
  2178.  
  2179. [Execute the program with a break point at DONE.]
  2180.  
  2181. #g,.done
  2182. ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  2183. ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  2184. ffffffffffffffffffff
  2185.  
  2186. [This  doesn't  look quite right. Invoke SID-86 again, leaving  off  the file
  2187. types, since SID-86 uses the appropriate defaults.]
  2188.  
  2189. A>sid typ typ
  2190. SID86 1.01   1/4/83
  2191.      START      END
  2192. CS 1CC1:0000 1CC1:006F
  2193. DS 1CC8:0000 1CC8:018F
  2194. SYMBOLS
  2195.  
  2196. [Set up default file control block.]
  2197.  
  2198. #ityp.a86
  2199.  
  2200. [Disassemble start of code segment.]
  2201.  
  2202. #l
  2203. START:
  2204.   1CC1:0000 MOV    DX,005C .FCB
  2205.   1CC1:0003 CALL   0041 .OPEN
  2206. LOOP:
  2207.   1CC1:0006 CALL   0019 .GETCHR
  2208.   1CC1:0009 CMP    AL,1A .EOF
  2209.   1CC1:000B JZ     0012 .DONE
  2210.   1CC1:000D CALL   0059 .CONOUT
  2211.   1CC1:0010 JMPS   0006 .LOOP
  2212. DONE:
  2213.   1CC1:0012 MOV    DL,00 .VARIABLES
  2214.   1CC1:0014 MOV    CL,00 .VARIABLES
  2215.   1CC1:0016 JMP    0061 .BDOS
  2216. GETCHR:
  2217.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2218.   1CC1:001E JB     0023 .GET1
  2219.  
  2220. [Trace without call, so SID-86 doesn't trace the OPEN routine, which should be
  2221. fixed.]
  2222.  
  2223. #tw2
  2224.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2225. --I------ 0000 0000 0000 0000 015C 0000 0000 0000 0000 MOV    DX,005C .FCB
  2226. --I------ 0000 0000 0000 005C 015C 0000 0000 0000 0003 CALL   0041 .OPEN
  2227. *1CC1:0006 .LOOP
  2228.  
  2229. [Disassemble next few instructions.]
  2230.  
  2231. #l
  2232. LOOP:
  2233.   1CC1:0006 CALL   0019 .GETCHR
  2234.   1CC1:0009 CMP    AL,1A .EOF
  2235.   1CC1:000B JZ     0012 .DONE
  2236.   1CC1:000D CALL   0059 .CONOUT
  2237.   1CC1:0010 JMPS   0006 .LOOP
  2238. DONE:
  2239.   1CC1:0012 MOV    DL,00 .VARIABLES
  2240.   1CC1:0014 MOV    CL,00 .VARIABLES
  2241.   1CC1:0016 JMP    0061 .BDOS
  2242. GETCHR:
  2243.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2244.   1CC1:001E JB     0023 .GET1
  2245.   1CC1:0020 CALL   002F .FILBUF
  2246. GET1:
  2247.   1CC1:0023 MOV    BX,0108 .BUFFER
  2248.  
  2249. [Trace  without  call  next three instructions, to see  if  this  sequence is
  2250. working.]
  2251.  
  2252. #tw3
  2253.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2254. --I---A-C 0000 0000 0000 0000 015C 0000 0000 0000 0006 CALL   0019 .GETCHR
  2255. --I------ 0059 0108 0000 0000 015C 0000 0000 0000 0009 CMP    AL,1A .EOF
  2256. --I---AP- 0059 0108 0000 0000 015C 0000 0000 0000 000B JZ     0012 .DONE
  2257. *1CC1:000D
  2258.  
  2259. [GETCHR is returning a 59h -- something must be wrong there. Use the E command
  2260. to bring in a fresh copy of the program.]
  2261.  
  2262. #etyp typ
  2263.      START      END
  2264. CS 1CC1:0000 1CC1:006F
  2265. DS 1CC8:0000 1CC8:018F
  2266. SYMBOLS
  2267.  
  2268. [Disassemble code segment.]
  2269.  
  2270. #l
  2271. START:
  2272.   1CC1:0000 MOV    DX,005C .FCB
  2273.   1CC1:0003 CALL   0041 .OPEN
  2274. LOOP:
  2275.   1CC1:0006 CALL   0019 .GETCHR
  2276.   1CC1:0009 CMP    AL,1A .EOF
  2277.   1CC1:000B JZ     0012 .DONE
  2278.   1CC1:000D CALL   0059 .CONOUT
  2279.   1CC1:0010 JMPS   0006 .LOOP
  2280. DONE:
  2281.   1CC1:0012 MOV    DL,00 .VARIABLES
  2282.   1CC1:0014 MOV    CL,00 .VARIABLES
  2283.   1CC1:0016 JMP    0061 .BDOS
  2284. GETCHR:
  2285.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2286.   1CC1:001E JB     0023 .GET1
  2287.  
  2288. [Trace without call, since we know the open works.]
  2289.  
  2290. #tw2
  2291.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2292. --I---AP- 0059 0108 0000 0000 015C 0000 0000 0000 0000 MOV    DX,005C .FCB
  2293. --I---AP- 0059 0108 0000 005C 015C 0000 0000 0000 0003 CALL   0041 
  2294. .OPENERROR
  2295.  
  2296. [Oops! Forgot to set up the file control block... Try again.]
  2297.  
  2298. A>sid typ typ
  2299. SID86 1.01   1/4/83
  2300.      START      END
  2301. CS 1CC1:0000 1CC1:006F
  2302. DS 1CC8:0000 1CC8:018F
  2303. SYMBOLS
  2304.  
  2305. [This should work better.]
  2306.  
  2307. #ityp.a86
  2308. #g,.getchr
  2309. *1CC1:0019 .GETCHR
  2310.  
  2311. [Disassemble GETCHR routine.]
  2312.  
  2313. #l
  2314. GETCHR:
  2315.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2316.   1CC1:001E JB     0023 .GET1
  2317.   1CC1:0020 CALL   002F .FILBUF
  2318. GET1:
  2319.   1CC1:0023 MOV    BX,0108 .BUFFER
  2320.   1CC1:0026 MOV    AL,0108[BX] .BUFFER
  2321.   1CC1:002A INC    BYTE [0188] .BPTR
  2322.   1CC1:002E RET
  2323. FILBUF:
  2324.   1CC1:002F MOV    DX,0108 .BUFFER
  2325.   1CC1:0032 CALL   004B .SETDMA
  2326.   1CC1:0035 MOV    DX,005C .FCB
  2327.   1CC1:0038 CALL   004F .READ
  2328.   1CC1:003B MOV    BYTE [0188],00 .BPTR
  2329.  
  2330. [Trace first few instructions. Note that SID-86 shows the contents of BPTR as
  2331. it is being compared.]
  2332.  
  2333. #t2
  2334.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2335. --I---A-C 0000 0000 0000 0000 015A 0000 0000 0000 0019 CMP    BYTE [0188],80 
  2336. .BPTR =80
  2337. --I--Z-P- 0000 0000 0000 0000 015A 0000 0000 0000 001E JB     0023 .GET1
  2338. *1CC1:0020
  2339.  
  2340. [The compare worked Ok; keep going.]
  2341.  
  2342. #t
  2343.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2344. --I--Z-P- 0000 0000 0000 0000 015A 0000 0000 0000 0020 CALL   002F .FILBUF
  2345. *1CC1:002F .FILBUF
  2346.  
  2347. [See what FILBUF looks like.]
  2348.  
  2349. #l
  2350. FILBUF:
  2351.   1CC1:002F MOV    DX,0108 .BUFFER
  2352.   1CC1:0032 CALL   004B .SETDMA
  2353.   1CC1:0035 MOV    DX,005C .FCB
  2354.   1CC1:0038 CALL   004F .READ
  2355.   1CC1:003B MOV    BYTE [0188],00 .BPTR
  2356.   1CC1:0040 RET
  2357. OPEN:
  2358.   1CC1:0041 MOV    CL,0F .OPENC
  2359.   1CC1:0043 CALL   0061 .BDOS
  2360.   1CC1:0046 CMP    AL,FF
  2361.   1CC1:0048 JZ     0064 .ERR
  2362.   1CC1:004A RET
  2363. SETDMA:
  2364.   1CC1:004B MOV    CL,1A .EOF
  2365.  
  2366. [See what is in the buffer before the disk read takes place.]
  2367.  
  2368. #d.buffer,+2F
  2369. 1CC8:0108 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  2370. 1CC8:0118 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  2371. 1CC8:0128 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  2372.  
  2373. [Trace the FILBUF routine.]
  2374.  
  2375. #tw6
  2376.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2377. --I--Z-P- 0000 0000 0000 0000 0158 0000 0000 0000 002F MOV    DX,0108 
  2378. .BUFFER
  2379. --I--Z-P- 0000 0000 0000 0108 0158 0000 0000 0000 0032 CALL   004B .SETDMA
  2380. --I--Z-P- 00C3 00C3 0000 0108 0158 0000 0000 0000 0035 MOV    DX,005C .FCB
  2381. --I--Z-P- 00C3 00C3 0000 005C 0158 0000 0000 0000 0038 CALL   004F .READ
  2382. --I--Z-P- 0000 0000 0000 0000 0158 0000 0000 0000 003B MOV    BYTE [0188],00 
  2383. .BPTR =80
  2384. --I--Z-P- 0000 0000 0000 0000 0158 0000 0000 0000 0040 RET
  2385. *1CC1:0023 .GET1
  2386.  
  2387. [See what is in the buffer after the read.]
  2388.  
  2389. #d.buffer,+4F
  2390. 1CC8:0108 3B 20 44 69 73 70 6C 61 79 20 74 68 65 20 63 6F ; Display the co
  2391. 1CC8:0118 6E 74 65 6E 74 73 20 6F 66 20 61 6E 0D 0A 3B 20 ntents of an..;
  2392. 1CC8:0128 41 53 43 49 49 20 66 69 6C 65 20 61 74 20 74 68 ASCII file at th
  2393. 1CC8:0138 65 20 63 6F 6E 73 6F 6C 65 2E 0D 0A 3B 2D 2D 2D e console...;---
  2394. 1CC8:0148 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D ----------------
  2395.  
  2396. [Looks like good data in the buffer. See what's next.]
  2397.  
  2398. #l
  2399. GET1:
  2400.   1CC1:0023 MOV    BX,0108 .BUFFER
  2401.   1CC1:0026 MOV    AL,0108[BX] .BUFFER
  2402.   1CC1:002A INC    BYTE [0188] .BPTR
  2403.   1CC1:002E RET
  2404. FILBUF:
  2405.   1CC1:002F MOV    DX,0108 .BUFFER
  2406.   1CC1:0032 CALL   004B .SETDMA
  2407.   1CC1:0035 MOV    DX,005C .FCB
  2408.   1CC1:0038 CALL   004F .READ
  2409.   1CC1:003B MOV    BYTE [0188],00 .BPTR
  2410.   1CC1:0040 RET
  2411. OPEN:
  2412.   1CC1:0041 MOV    CL,0F .OPENC
  2413.   1CC1:0043 CALL   0061 .BDOS
  2414.  
  2415. [Trace the code getting the next character from the buffer.]
  2416.  
  2417. #t4
  2418.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2419. --I--Z-P- 0000 0000 0000 0000 015A 0000 0000 0000 0023 MOV    BX,0108 
  2420. .BUFFER
  2421. --I--Z-P- 0000 0108 0000 0000 015A 0000 0000 0000 0026 MOV    AL,0108[BX] 
  2422. .BUFFER =59
  2423. --I--Z-P- 0059 0108 0000 0000 015A 0000 0000 0000 002A INC    BYTE [0188] 
  2424. .BPTR =00
  2425. --I------ 0059 0108 0000 0000 015A 0000 0000 0000 002E RET
  2426. *1CC1:0009
  2427.  
  2428. [It is getting the wrong data, because BX should have the contents of BPTR in
  2429. it, rather than the address of the buffer. Need to edit, and also install fix
  2430. that we patched earlier.]
  2431.  
  2432. #^C
  2433. A>ed typ.a86
  2434.      : *#afOpen:
  2435.    65: *
  2436.    66:          CALL    bdos            ; Do it the old fashioned way
  2437.    66: *
  2438.    67:          CMP     AL,0FFh         ;
  2439.    67: *
  2440.    68:          JNZ     err             ;
  2441.    68: *sJNZ^ZJZ^Z0lt
  2442.    68:          JZ     err              ;
  2443.    68: *bfGet1:
  2444.    46: *0lt
  2445.    46:  Get1:   MOV     BX,OFFSET buffer ;
  2446.    46: *sOFFSET buffer^ZbPtr^Z0lt
  2447.    46:  Get1:   MOV     BX,bPtr         ;
  2448.    46: *sBX^ZBL^Z0lt
  2449.    46:  Get1:   MOV     BL,bPtr         ;
  2450.    46: *
  2451.    47:          MOV     AL,buffer[BX]   ; Get next character from buffer
  2452.    47: *i
  2453.    47:         MOV     BH,00h          ;
  2454.    48: ^Z
  2455.    48: *e
  2456.  
  2457. A>asm typ
  2458.  
  2459. CP/M 8086 ASSEMBLER VER 1.1
  2460. END OF PASS 1
  2461. END OF PASS 2
  2462. END OF ASSEMBLY.  NUMBER OF ERRORS:   0.  USE FACTOR:  0%
  2463.  
  2464. A>gencmd typ
  2465.  
  2466. BYTES READ    007D
  2467. RECORDS WRITTEN 05
  2468.  
  2469. [Try it again.]
  2470.  
  2471. A>typ typ.a86
  2472. ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  2473. ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  2474. ffffffffffffffffffff
  2475.  
  2476. [Still no good. I thought this was supposed to be a simple project!]
  2477.  
  2478. A>sid typ typ
  2479. SID86 1.01   1/4/83
  2480.      START      END
  2481. CS 1CC1:0000 1CC1:006F
  2482. DS 1CC8:0000 1CC8:018F
  2483. SYMBOLS
  2484. #ityp.a86
  2485. #l
  2486. START:
  2487.   1CC1:0000 MOV    DX,005C .FCB
  2488.   1CC1:0003 CALL   0044 .OPEN
  2489. LOOP:
  2490.   1CC1:0006 CALL   0019 .GETCHR
  2491.   1CC1:0009 CMP    AL,1A .EOF
  2492.   1CC1:000B JZ     0012 .DONE
  2493.   1CC1:000D CALL   005C .CONOUT
  2494.   1CC1:0010 JMPS   0006 .LOOP
  2495. DONE:
  2496.   1CC1:0012 MOV    DL,00 .VARIABLES
  2497.   1CC1:0014 MOV    CL,00 .VARIABLES
  2498.   1CC1:0016 JMP    0064 .BDOS
  2499. GETCHR:
  2500.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2501.   1CC1:001E JB     0023 .GET1
  2502.  
  2503. [Trace at the top level.]
  2504.  
  2505. #tw5
  2506.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2507. --I------ 0000 0000 0000 0000 015C 0000 0000 0000 0000 MOV    DX,005C .FCB
  2508. --I------ 0000 0000 0000 005C 015C 0000 0000 0000 0003 CALL   0044 .OPEN
  2509. LOOP:
  2510. --I---A-C 0000 0000 0000 0000 015C 0000 0000 0000 0006 CALL   0019 .GETCHR
  2511. --I------ 003B 0000 0000 0000 015C 0000 0000 0000 0009 CMP    AL,1A .EOF
  2512. --I----P- 003B 0000 0000 0000 015C 0000 0000 0000 000B JZ     0012 .DONE
  2513. *1CC1:000D
  2514.  
  2515. [Got the right data from GETCHR.]
  2516.  
  2517. #l
  2518.   1CC1:000D CALL   005C .CONOUT
  2519.   1CC1:0010 JMPS   0006 .LOOP
  2520. DONE:
  2521.   1CC1:0012 MOV    DL,00 .VARIABLES
  2522.   1CC1:0014 MOV    CL,00 .VARIABLES
  2523.   1CC1:0016 JMP    0064 .BDOS
  2524. GETCHR:
  2525.   1CC1:0019 CMP    BYTE [0188],80 .BPTR
  2526.   1CC1:001E JB     0023 .GET1
  2527.   1CC1:0020 CALL   0032 .FILBUF
  2528. GET1:
  2529.   1CC1:0023 MOV    BL,[0188] .BPTR
  2530.   1CC1:0027 MOV    BH,00 .VARIABLES
  2531.   1CC1:0029 MOV    AL,0108[BX] .BUFFER
  2532.   1CC1:002D INC    BYTE [0188] .BPTR
  2533. #t
  2534.            AX   BX   CX   DX   SP   BP   SI   DI   IP
  2535. --I----P- 003B 0000 0000 0000 015C 0000 0000 0000 000D CALL   005C .CONOUT
  2536. *1CC1:005C .CONOUT
  2537. #l
  2538. CONOUT:
  2539.   1CC1:005C MOV    CL,02 .CONOUTC
  2540.   1CC1:005E JMPS   0064 .BDOS
  2541. PRINTM:
  2542.   1CC1:0060 MOV    CL,09
  2543.   1CC1:0062 JMPS   0064 .BDOS
  2544. BDOS:
  2545.   1CC1:0064 INT    E0 .BDOSI
  2546.   1CC1:0066 RET
  2547. ERR:
  2548.   1CC1:0067 MOV    DX,0100 .ERRORM
  2549.   1CC1:006A CALL   0060 .PRINTM
  2550.   1CC1:006D JMP    0012 .DONE
  2551.   1CC1:0070 ??=    6F
  2552.   1CC1:0071 ADD    [BX+SI],AL
  2553.   1CC1:0073 ??=    C1
  2554.  
  2555. [At  this point, the data to output to the console should be in DL, but it 
  2556. is
  2557. not... Another edit.]
  2558.  
  2559. #^C
  2560. A>ed typ.a86
  2561.      : *#afConOut
  2562.    18: *0lt
  2563.    18:  ConOutC EQU      2              ; Console Output
  2564.    18: *1fConOut
  2565.    31: *0lt
  2566.    31:          CALL    ConOut          ; No: display it
  2567.    31: *i
  2568.    31:         MOV     DL,AL           ; Prepare for ConOut
  2569.    32: ^Z
  2570.    32: *e
  2571.  
  2572. A>asm typ
  2573.  
  2574. CP/M 8086 ASSEMBLER VER 1.1
  2575. END OF PASS 1
  2576. END OF PASS 2
  2577. END OF ASSEMBLY.  NUMBER OF ERRORS:   0.  USE FACTOR:  0%
  2578.  
  2579. A>gencmd typ
  2580.  
  2581. BYTES READ    007F
  2582. RECORDS WRITTEN 06
  2583.  
  2584. [One more time!]
  2585.  
  2586. A>typ typ.a86
  2587. ; Display the contents of an
  2588. ; ASCII file at the console.
  2589. ;--------------------------------
  2590. ; Base Page locations used.
  2591. ;
  2592. fcb     EQU     005Ch           ; File Control Block
  2593. ;
  2594. ; ASCII characters used.
  2595. ;
  2596. eof     EQU     1Ah             ; CP/M End-Of-File character
  2597. ;
  2598. ; Interrupts used.
  2599. ;
  2600. bdosi   EQU     224             ; BDOS Interrupt Number
  2601. ;
  2602. ; BDOS functions used.
  2603. ;
  2604. ConOutC EQU      2              ; Console Output
  2605. OpenC   EQU     15              ; Open File
  2606. ReadC   EQU     20              ; Read File
  2607. SetDMAc EQU     26              ; Set DMA Address
  2608. ;
  2609. ;--------------------------------
  2610. ; Main.
  2611. ;
  2612. start:  MOV     DX,fcb          ; Points to FCB
  2613.         CALL    open            ; Open file
  2614. loop:   CALL    GetChr          ; Get one char
  2615.         CMP     AL,eof          ; Is it the EOF char?
  2616.         JZ      done            ; Yes: the end
  2617.         MOV     DL,AL           ; Prepare for ConOut
  2618.         CALL    ConOut          ; No: display it
  2619.         JMPS    loop            ;     and loop.
  2620. ;
  2621. ; The end. Back to CP/M.
  2622. ;
  2623. done:   MOV     DL,0            ; = ?
  2624.         MOV     CL,0            ; = Reset function
  2625.         JMP     bdos            ; Ditto
  2626. ;
  2627. ;--------------------------------
  2628. ; Get a char from DMA buffer.
  2629. ;
  2630. GetChr: CMP     bPtr,bSize      ; See if we need a new buffer fill
  2631.         JC      Get1            ;
  2632.         CALL    FilBuf          ; Yes: Refill buffer from file
  2633. Get1:   MOV     BL,bPtr  ;
  2634.         MOV     BH,00h          ;
  2635.         MOV     AL,buffer[BX]   ; Get next character from buffer
  2636.         INC     bPtr            ; Increment buffer pointer
  2637.         RET                     ;
  2638. ;
  2639. ;--------------------------------
  2640. ; Fill DMA buffer from file.
  2641. ;
  2642. FilBuf: MOV     DX,OFFSET buffer  ;
  2643.         CALL    SetDMA          ;
  2644.         MOV     DX,5Ch          ;
  2645.         CALL    read            ;
  2646.         MOV     bPtr,0          ;
  2647.         RET                     ;
  2648. ;
  2649. ;--------------------------------
  2650. ; Open a file.
  2651. ;
  2652. Open:   MOV     CL,openc        ;
  2653.         CALL    bdos            ; Do it the old fashioned way
  2654.         CMP     AL,0FFh         ;
  2655.         JZ      err             ;
  2656.         RET                     ;
  2657. ;
  2658. ;--------------------------------
  2659. ; Set DMA Address.
  2660. ;
  2661. SetDMA: MOV     CL,SetDMAc      ;
  2662.         JMPS    bdos            ;
  2663. ;
  2664. ;--------------------------------
  2665. ; Read one record from file.
  2666. ;
  2667. Read:   MOV     CL,ReadC        ;
  2668.         CALL    bdos            ;
  2669.         CMP     AL,00h          ;
  2670.         JNZ     err             ;
  2671.         RET                     ;
  2672. ;
  2673. ;--------------------------------
  2674. ; Console Output.
  2675. ;
  2676. ConOut: MOV     CL,ConOutC      ;
  2677.         JMPS    bdos            ;
  2678. ;
  2679. ;--------------------------------
  2680. ; Print a string.
  2681. ;
  2682. PrintM: MOV     CL,9            ;
  2683.         JMPS    bdos            ;
  2684. ;
  2685. ;--------------------------------
  2686. ; Provides Old fashioned BDOS call.
  2687. ;
  2688. bdos:   INT     bdosi           ; IBM PC
  2689.         RET                     ;
  2690. ;
  2691. ;--------------------------------
  2692. ; Print error message and abort.
  2693. ;
  2694. Err:    MOV     DX,OFFSET ErrorM  ;
  2695.         CALL    printm          ;
  2696.         JMP     done            ;
  2697. ;
  2698. ;--------------------------------
  2699.         DSEG
  2700. ;--------------------------------
  2701.         ORG     100h            ; Reserve Base Page
  2702. ;
  2703. ErrorM  DB      'ERROR',0Dh,0Ah,'$'
  2704. bSize   EQU     80h             ; Buffer Size = 128 characters
  2705. buffer  RS      bSize           ; Reserve them
  2706. bPtr    DB      bSize           ; Buffer Pointer = 1st char
  2707. ;
  2708. ;--------------------------------
  2709. ;
  2710.         END
  2711.  
  2712. [Done  at last. Just out of curiosity, let's find out how many characters are
  2713. in the file by setting a pass point with a high count at CONOUT.]
  2714.  
  2715. A>sid typ typ
  2716. SID86 1.01   1/4/83
  2717.      START      END
  2718. CS 1CC1:0000 1CC1:007F
  2719. DS 1CC9:0000 1CC9:018F
  2720. SYMBOLS
  2721. #ityp.a86
  2722.  
  2723. [Hopefully, there are fewer than 65535 characters!]
  2724.  
  2725. #p.conout,ffff
  2726.  
  2727. [Begin execution, with a break point at DONE.]
  2728.  
  2729. #g,.done
  2730. FFFF PASS 1CC1:005E .CONOUT
  2731. --I----P- 003B 0000 0000 003B 015A 0000 0000 0000 005E MOV    CL,02 
  2732. .CONOUTC;
  2733. FFFE PASS 1CC1:005E .CONOUT
  2734. --I---AP- 0220 0001 0000 1820 015A 0000 0000 0000 005E MOV    CL,02 .CONOUTC
  2735. FFFD PASS 1CC1:005E .CONOUT
  2736. --I---A-- 0244 0002 0000 1844 015A 0000 0000 0000 005E MOV    CL,02 
  2737. .CONOUTCD
  2738. FFFC PASS 1CC1:005E .CONOUT
  2739. --I---A-- 0269 0003 0000 1869 015A 0000 0000 0000 005E MOV    CL,02 
  2740. .CONOUTCi
  2741. FFFB PASS 1CC1:005E .CONOUT
  2742. --I---AP- 0273 0004 0000 1873 015A 0000 0000 0000 005E MOV    CL,02 
  2743. .CONOUTCs
  2744. FFFA PASS 1CC1:005E .CONOUT
  2745. --I---AP- 0270 0005 0000 1870 015A 0000 0000 0000 005E MOV    CL,02 
  2746. .CONOUTCp
  2747. FFF9 PASS 1CC1:005E .CONOUT
  2748. --I------ 026C 0006 0000 186C 015A 0000 0000 0000 005E MOV    CL,02 
  2749. .CONOUTCl
  2750. FFF8 PASS 1CC1:005E .CONOUT
  2751. --I---AP- 0261 0007 0000 1861 015A 0000 0000 0000 005E MOV    CL,02 
  2752. .CONOUTCa
  2753. FFF7 PASS 1CC1:005E .CONOUT
  2754. --I---AP- 0279 0008 0000 1879 015A 0000 0000 0000 005E MOV    CL,02 
  2755. .CONOUTCy
  2756. FFF6 PASS 1CC1:005E .CONOUT
  2757. --I---AP- 0220 0009 0000 1820 015A 0000 0000 0000 005E MOV    CL,02 .CONOUTC
  2758. FFF5 PASS 1CC1:005E .CONOUT
  2759.  
  2760. [This is too messy. Using the -G command will suppress the display of the CPU
  2761. registers until the pass count is 1.]
  2762.  
  2763. #-g,.done
  2764. the contents of an
  2765. ; ASCII file at the console.
  2766. ;--------------------------------
  2767. ; Base Page locations used.
  2768. ;
  2769. fcb     EQU     005Ch           ; File Control Block
  2770. ;
  2771. ; ASCII characters used.
  2772. ;
  2773. eof     EQU     1Ah             ; CP/M End-Of-File character
  2774. ;
  2775. ; Interrupts used.
  2776. ;
  2777. bdosi   EQU     224             ; BDOS Interrupt Number
  2778. ;
  2779. ; BDOS functions used.
  2780. ;
  2781. ConOutC EQU      2              ; Console Output
  2782. OpenC   EQU     15              ; Open File
  2783. ReadC   EQU     20              ; Read File
  2784. SetDMAc EQU     26              ; Set DMA Address
  2785. ;
  2786. ;--------------------------------
  2787. ; Main.
  2788. ;
  2789. start:  MOV     DX,fcb          ; Points to FCB
  2790.         CALL    open            ; Open file
  2791. loop:   CALL    GetChr          ; Get one char
  2792.         CMP     AL,eof          ; Is it the EOF char?
  2793.         JZ      done            ; Yes: the end
  2794.         MOV     DL,AL           ; Prepare for ConOut
  2795.         CALL    ConOut          ; No: display it
  2796.         JMPS    loop            ;     and loop.
  2797. ;
  2798. ; The end. Back to CP/M.
  2799. ;
  2800. done:   MOV     DL,0            ; = ?
  2801.         MOV     CL,0            ; = Reset function
  2802.         JMP     bdos            ; Ditto
  2803. ;
  2804. ;--------------------------------
  2805. ; Get a char from DMA buffer.
  2806. ;
  2807. GetChr: CMP     bPtr,bSize      ; See if we need a new buffer fill
  2808.         JC      Get1            ;
  2809.         CALL    FilBuf          ; Yes: Refill buffer from file
  2810. Get1:   MOV     BL,bPtr         ;
  2811.         MOV     BH,00h          ;
  2812.         MOV     AL,buffer[BX]   ; Get next character from buffer
  2813.         INC     bPtr            ; Increment buffer pointer
  2814.         RET                     ;
  2815. ;
  2816. ;--------------------------------
  2817. ; Fill DMA buffer from file.
  2818. ;
  2819. FilBuf: MOV     DX,OFFSET buffer  ;
  2820.         CALL    SetDMA          ;
  2821.         MOV     DX,5Ch          ;
  2822.         CALL    read            ;
  2823.         MOV     bPtr,00h        ;
  2824.         RET                     ;
  2825. ;
  2826. ;--------------------------------
  2827. ; Open a file.
  2828. ;
  2829. Open:   MOV     CL,openc        ;
  2830.         CALL    bdos            ; Do it the old fashioned way
  2831.         CMP     AL,0FFh         ;
  2832.         JZ     err              ;
  2833.         RET                     ;
  2834. ;
  2835. ;--------------------------------
  2836. ; Set DMA Address.
  2837. ;
  2838. SetDMA: MOV     CL,SetDMAc      ;
  2839.         JMPS    bdos            ;
  2840. ;
  2841. ;--------------------------------
  2842. ; Read one record from file.
  2843. ;
  2844. Read:   MOV     CL,ReadC        ;
  2845.         CALL    bdos            ;
  2846.         CMP     AL,0            ;
  2847.         JNZ     err             ;
  2848.         RET                     ;
  2849. ;
  2850. ;--------------------------------
  2851. ; Console Output.
  2852. ;
  2853. ConOut: MOV     CL,ConOutC      ;
  2854.         JMPS    bdos            ;
  2855. ;
  2856. ;--------------------------------
  2857. ; Print a string.
  2858. ;
  2859. PrintM: MOV     CL,9            ;
  2860.         JMPS    bdos            ;
  2861. ;
  2862. ;--------------------------------
  2863. ; Provides Old fashioned BDOS call.
  2864. ;
  2865. bdos:   INT     bdosi           ; IBM PC
  2866.         RET                     ;
  2867. ;
  2868. ;--------------------------------
  2869. ; Print error message and abort.
  2870. ;
  2871. Err:    MOV     DX,OFFSET ErrorM  ;
  2872.         CALL    printm          ;
  2873.         JMP     done            ;
  2874. ;
  2875. ;--------------------------------
  2876.         DSEG
  2877. ;--------------------------------
  2878.         ORG     100h            ; Reserve Base Page
  2879. ;
  2880. ErrorM  DB      'ERROR',0Dh,0Ah,'$'
  2881. bSize   EQU     80h             ; Buffer Size = 128 characters
  2882. buffer  RS      bSize           ; Reserve them
  2883. bPtr    DB      bSize           ; Buffer Pointer = 1st char
  2884. ;
  2885. ;--------------------------------
  2886. ;
  2887.         END
  2888.  
  2889. [Reached the break point at DONE.]
  2890.  
  2891. *1CC1:0014 .DONE
  2892.  
  2893. [Display the currently active pass points.]
  2894.  
  2895. #p
  2896. F229 1CC1:005E .CONOUT
  2897.  
  2898. [The  pass  count went from FFFF to F229, so the difference is the  number of
  2899. times  CONOUT  was  called, or the number of characters in  the  file.  The H
  2900. command will perform the subtraction, and display the result in decimal.]
  2901.  
  2902. #hffff-F229
  2903. 0DD6 #3542
  2904.  
  2905. [3542 characters in the file.]
  2906.  
  2907. #^C
  2908. A>
  2909.  
  2910.  
  2911. Appendix A: SID-86 Error Messages
  2912. ---------------------------------
  2913.  
  2914. Table A-1. SID-86 Error Messages
  2915.  
  2916. Error Message           Meaning
  2917. -------------           -------
  2918. AMBIGUOUS  OPERAND      An  attempt  was made to assemble a  command  with an
  2919.                         ambiguous operand. Precede the operand with the prefix
  2920.                         "BYTE" or "WORD".
  2921.  
  2922. BAD  FILE  NAME         A  filename  in an E, R, or W command  is incorrectly
  2923.                         specified.
  2924.  
  2925. BAD  HEX  DIGIT         A  SYM  file  being loaded with an E  command  has an
  2926.                         invalid hexadecimal digit.
  2927.  
  2928. CANNOT CLOSE            The disk file written by a W command cannot be closed.
  2929.  
  2930. DISK READ ERROR         The  disk file specified in an R command could not be
  2931.                         read properly.
  2932.  
  2933. DISK WRITE ERROR        A  disk  write  operation could  not  be successfully
  2934.                         performed  during a W command, probably due to a full
  2935.                         disk.
  2936.  
  2937. INSUFFICIENT MEMORY     There is not enough memory to load the file specified
  2938.                         in an R or E command.
  2939.  
  2940. MEMORY REQUEST DENIED   A request for memory during an R command could not be
  2941.                         fulfilled either because the maximum number of memory
  2942.                         allocations  has already been made, or the  memory at
  2943.                         the  specified address is not available. Up  to eight
  2944.                         blocks  of  memory can be allocated at  a  given time
  2945.                         under CP/M-86.
  2946.  
  2947. NO FILE                 The  file specified in an R or E command could not be
  2948.                         found on the disk.
  2949.  
  2950. NO SPACE                There is no space in the directory for the file being
  2951.                         written by a W command.
  2952.  
  2953. SYMBOL LENGTH ERROR     A symbol in a SYM file being loaded with an E command
  2954.                         has more than thirty-one characters.
  2955.  
  2956. SYMBOL TABLE FULL       There is no more space in SID-86's symbol table.
  2957.  
  2958. VERIFY ERROR AT s:o     The  value placed in memory by a Fill, Set,  Move, or
  2959.                         Assemble  command  could not be read  back correctly,
  2960.                         indicating  bad RAM or attempting to write to  ROM or
  2961.                         non-existent memory at the indicated location.
  2962.  
  2963.  
  2964. Index
  2965. -----
  2966.  
  2967. (To be done...)
  2968.  
  2969.  
  2970. EOF
  2971.  
  2972.  
  2973.  
  2974.