home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / z8e.z80 < prev    next >
Encoding:
Text File  |  1994-07-13  |  196.6 KB  |  7,754 lines

  1.     title    *   *** Z8E - Z80 Debug Monitor ***    *
  2.     subttl    (C) Copyright 1984, 1985   by Richard A. Surwilo  
  3.  
  4. ;------------------------------------------------------------------------------
  5. ;
  6. ;  Copyright (C) 1984, 1985   by Richard A. Surwilo.  All rights reserved. 
  7. ;
  8. ;  No part of this publication may be reproduced, transmitted, transcribed,
  9. ;  stored in a retrieval system, or translated into any language or computer 
  10. ;  language in any form or by any means, electronic, mechanical, magnetic,
  11. ;  optical, chemical, manual or otherwise, without express prior written 
  12. ;  permission of:
  13. ;
  14. ;      Richard  A. Surwilo  330 Calvin Court, Wyckoff, NJ 074816
  15. ;
  16. ;  Note:
  17. ;        This program is distributed in violation of the restrictions
  18. ;        on reproduction and transmission outlined above.  It would
  19. ;        appear that Rick Surwilo released this program to the public
  20. ;        domain without removing the notice.
  21. ;
  22. ;------------------------------------------------------------------------------
  23. ;
  24. ;                       Revision history
  25. ;
  26. ;  27 Dec 88 jrs v3.5    Released 24 Jan 89.  Includes a few patches by
  27. ;            George Havach.
  28. ;
  29. ;        1.    Changed operation of <cr> in some commands to make
  30. ;            a more consistent user interface.  (I won't be
  31. ;            offended if users want it changed back - jrs.)
  32. ;
  33. ;        2.    Enhancement to patch 1.5:- altered the search for
  34. ;            "MACRO-80" sentinel in .PRN files to allow for a
  35. ;            TITLE pseudo-op.
  36. ;
  37. ;        3.    Shortened and improved the code for the 'I' command.
  38. ;
  39. ;        4.    Tested and corrected the ANSIXYCP module which I have
  40. ;            been supplying since May 1987.  The code has now been
  41. ;            incorporated into the main source file and can be
  42. ;            activated during assembly by setting "aterm equ true".
  43. ;
  44. ;        5.    Discarded the '#' command introduced in 3.3.11 as with
  45. ;            a minor adjustment the 'L' command with no file name
  46. ;            does the same thing.
  47. ;
  48. ;        6.    If S or J was last command issued then <cr> alone
  49. ;            repeats S or J in single-step mode.  Very useful for
  50. ;            stepping through a small section of a program.
  51. ;
  52. ;    (gah)    7.    Adapted a patch by George Havach to correct the display
  53. ;            of IX and IY in disassembled instructions when upper
  54. ;            case is set.
  55. ;
  56. ;    (gah)    8.    Made room for patching in 'clear screen' code at
  57. ;            MBANNR: for more dignified start-up.
  58. ;
  59. ;    (gah)    9.    Replaced tilde ("~") with period (".") as a general
  60. ;            substitute for non-displayable ASCII characters, for
  61. ;            consistency with practically every other screen-dump
  62. ;            utility.  [Retained "hazeltine" conditional - jrs]
  63. ;
  64. ;  12 Dec 88 jrs v3.4    Made patch 3.3.1 object-configurable because some
  65. ;            terminals, particularly those which have binary
  66. ;            cursor addressing, must use an offset of 80h to stop
  67. ;            the BDOS from expanding tabs and for those terminals
  68. ;            clearing bit 7 is nasty.
  69. ;
  70. ;   5 Dec 88 eg  v3.3    Included a number of fixes and features submitted by
  71. ;  (installed by jrs)    Eric Gans in January and March 88.
  72. ;
  73. ;         1.    Clear bit 7 of characters sent to screen to avoid
  74. ;            strange effects on some computers (such as Kaypro
  75. ;            which prints graphic characters if bit 7 is on).
  76. ;
  77. ;         2.    Allow 'z' command without an address to mean dis-
  78. ;            assemble from last instruction for last-specified
  79. ;            number of lines.
  80. ;
  81. ;         3.    Allow 'g' command without an address to mean the
  82. ;            equivalent of 'g  pc'  or  'g  $' (i.e. continue
  83. ;            execution from current instruction).
  84. ;
  85. ;         4.    Show absolute destination addresses when dis-
  86. ;            assembling relative jump instructions (jr and djnz).
  87. ;
  88. ;         5.    Display flags along with registers when using the
  89. ;            's' and 'x' commands.
  90. ;
  91. ;         6.    Allow easy refresh of the 'animated debug' screen
  92. ;            after program output has disturbed it.  Use 'j  #'
  93. ;            to force refresh.
  94. ;
  95. ;         7.    After Z8E's internal disk I/O operations, reset
  96. ;            DMA to 80h for the benefit of target programs.
  97. ;
  98. ;         8.    Allow cancellation of commands with CAN (ctrl-X)
  99. ;            when argument buffer is empty.  For example if you
  100. ;            have entered 'd  100' then first ^X erases the '100'
  101. ;            and the second cancels the 'd'.
  102. ;
  103. ;         9.    Implement '>' command to change user number and so
  104. ;            allow loading of files from user areas other than
  105. ;            that from which Z8E was initiated.
  106. ;
  107. ;        10.    Implement '?' command to evaluate and display argument
  108. ;            expressions.  Accepts a register name as the first
  109. ;            operand.  (reg) allows indirect addressing so that,
  110. ;            for example, '?  (hl)' displays value at the memory
  111. ;            location whose address is contained in HL.
  112. ;
  113. ;        11.    Implement '#' command to recall and display the
  114. ;            highest address occupied by a program.
  115. ;            
  116. ;   4 Dec 88 jrs v3.2    Expand asterisks in file names when using 'i' command.
  117. ;
  118. ;  27 Nov 88 jrs v3.1    Bug fix - deleted three spurious instructions from
  119. ;            the initialisation code which was added to support
  120. ;            breakpoint vectors at addresses other than 38h.
  121. ;
  122. ;  16 Nov 88 jrs v3.0    Bumped version number to regain sequence with USA.
  123. ;            Until now there were two independent streams of
  124. ;            development.  (A date prefixed by '-' denotes a
  125. ;            version from the "USA" stream).
  126. ;
  127. ;            Extended Jim Moore's idea of substituting RST 30h
  128. ;            (RST 6) for RST 38h (RST 7).  Now the breakpoint
  129. ;            vector address can be patched without re-assembling.
  130. ;
  131. ;  11 Nov 88 jrs v1.5    Added code to distinguish between .PRN files created
  132. ;            by Macro-80 and Z80ASM 1.3 so Z8E can load symbols
  133. ;            from either type of .PRN file.
  134. ;
  135. ;- 30 Nov 87 eg  v2.1    FCB and command tail initialisation routine supplied
  136. ;            by Eric Gans.  [Does not appear in the current source
  137. ;            as it duplicated v1.4 but consumed more code space.]
  138. ;
  139. ;  15 May 87 jrs v1.4    Implemented "I" command to initialise the command
  140. ;            tail at 80h and the default FCB name blocks at 5Ch
  141. ;            and 6Ch.
  142. ;
  143. ;            Renamed I(nput) command to L(oad) to make way for new
  144. ;            I(nitialise) command.  Documentation changed 13/6/87.
  145. ;
  146. ;            Filtered source code to all lower case.  Sometime
  147. ;            Between 1.0 And 1.2 The Comments Had Been Modified So
  148. ;            That Every Word Started With A Capital Letter And It
  149. ;            Really Did Look Quite Silly.
  150. ;
  151. ;  20 Apr 87 jrs v1.3    Fixed register display in animated debug mode.  Z8E
  152. ;            now handles EX AF,AF' and EXX instructions correctly.
  153. ;            Duplicates patch of 21 Oct 86 but was developed quite
  154. ;            independently and coded very differently.
  155. ;
  156. ;            Added equates to tailor the source to assemblers
  157. ;            other than M80.
  158. ;
  159. ;- 21 Oct 86 fh  v2.0    Fixed register display in animated debug mode.  Z8E
  160. ;  (installed by gmi)    now handles EX AF,AF' and EXX instructions correctly.
  161. ;
  162. ;  08 Mar 86 jrs v1.2    (No version number change - all mods purely cosmetic)
  163. ;            Modified org directives to bypass bug in m80
  164. ;            Added jterm conditional for testing
  165. ;            Added hazeltine conditional for tilde suppression
  166. ;            Changed dates to more universal format
  167. ;
  168. ;  16 Jan 86 ijb v1.2    Cursor addressing for post '=>' in jdbg75
  169. ;            to cover systems that have a destructive bs
  170. ;
  171. ;-  3 Dec 85 jgm v?.?    Added EQUates for breakpoint address so it could be
  172. ;            something other than 38h.
  173. ;
  174. ;  25 Sep 85 ras v1.1    Fix case bug
  175. ;            Fix usym bug
  176. ;            Clean up comments                
  177. ;
  178. ;    ras = Richard Surwilo        Stamford, Connecticut
  179. ;    ijb = ?
  180. ;    jrs = Jon Saxton        Sydney, New South Wales
  181. ;    jgm = Jim Moore            Anaheim, California
  182. ;    eg  = Eric Gans            Los Angeles, California
  183. ;    fh  = Frankie Hogan
  184. ;    gbi = Gary Inman        Los Angeles, California
  185. ;    gah = George Havach        California
  186. ;
  187. ;------------------------------------------------------------------------------
  188.  
  189. true    equ    -1
  190. false    equ    0
  191.  
  192. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  193. ; The following EQUates should both be set to FALSE to generate a "standard"
  194. ; Z8E.COM for distribution.  The JTERM is mine which I only put in for use
  195. ; while testing to save having to configure the object code for my terminal.
  196. ; (jrs 8 mar 86)  The ATERM is for an ANSI-compatible terminal such as a
  197. ; VT100 in which case setting ATERM to TRUE will cause the ANSIXYCP module
  198. ; to be included during assembly.  (jrs 28 dec 88)
  199.  
  200. jterm    equ    false        ;Should always be false for distribution
  201. aterm    equ    false        ;- - - ditto - - -
  202.  
  203. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  204. ; The following equ should normally be set to 0.  It is only required if
  205. ; you have a Hazeltine terminal which uses tilde as a command character
  206.  
  207. hazeltine equ    false
  208.  
  209. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  210. ; Configure this source to your favourite assembler by setting one of
  211. ; the following equates to true.  If you use an assembler not mentioned
  212. ; below then make up a new equate for it.
  213.  
  214. M80    equ    false        ;Microsoft's Macro-80
  215. ASMB    equ    false        ;Cromemco's Z80 assembler
  216. SLR    equ    true        ;SLR's lightning-fast Z80ASM assembler
  217.  
  218. ; (Note that there is no real distinction between M80 and SLR.  Either
  219. ;  assembler may be used with either EQUate set TRUE.)
  220. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  221.  
  222. compact    equ    jterm or aterm
  223.  
  224.      if    compact
  225.     if    ASMB
  226.       conmsg    Non-standard version (not for distribution)
  227.     else
  228.       .printx    * Non-standard version (not for distribution) *
  229.     endif
  230.      endif
  231.  
  232.      if    not ASMB
  233.     .Z80            ;so M80 users don't need /z switch
  234.      endif
  235.  
  236.      if    ASMB
  237.     list    nogen
  238. page    macro            ;Equivalence M80's "page" and ASMB's "form"
  239.     form
  240.     endm
  241.      endif
  242.  
  243. maxbp    equ    16        ;Number    of breakpoints configured
  244.  
  245. bs    equ    08h        ;ASCII     backspace
  246. tab    equ    09h        ;    tab
  247. lf    equ    0Ah        ;    line feed
  248. formf    equ    0Ch        ;    form feed
  249. cr    equ    0Dh        ;    carriage return
  250. esc    equ    1Bh        ;       escape    
  251. ctlx    equ    'X' and    1fh    ;    control    x - delete line
  252. ctlc    equ    'C' and    1fh    ;    control    c - warm boot
  253. eof    equ    'Z' and    1fh    ;    control    z - logical eof
  254. quote    equ    27h        ;    quote
  255. tilde    equ    7Eh        ;    tilde
  256. del    equ    7Fh        ;    del
  257.  
  258. bdos    equ    5
  259. fcb5c    equ    5Ch        ;CP/M default FCB
  260.  
  261. nop    equ    000        ;Z80 instructions
  262. jp    equ    0C3h
  263. rst38    equ    0FFh
  264.  
  265. iobuf    equ    80h        ;Disk read buffer for symbol loading
  266.  
  267.     page
  268.  
  269. ;******************************************************************************
  270. ;*
  271. ;*    nint:      Initialization - relocating loader - symbol loader
  272. ;*
  273. ;*    Initialization:
  274. ;*    - Save system I    register
  275. ;*    - Determine max symbol length before loading symbol table
  276. ;*        permissable values are 6 and 14 which are converted to bit
  277. ;*      masks by bumping by one 
  278. ;*    - Set CP/M DMA address to 80h
  279. ;*    - Check first command line argument for (xx) where xx is the
  280. ;*      number of slots in the symbol table to reserve.
  281. ;*    - Move first file name found in command line to local memory
  282. ;*      since it will be loaded last.  At the end of initialization
  283. ;*      (or symbol loading if required) this file name will be loaded
  284. ;*      into the keyboard input buffer and the file will be loaded
  285. ;*      just as if the user had entered the info as a Z8E command.
  286. ;*    - Move all subsequent file names in the    command    line buffer to
  287. ;*      local input buffer (inbf) in low memory, where they can
  288. ;*      be found by the parse    routine (prsr).
  289. ;*
  290. ;*    Relocating loader:
  291. ;*    - Move absolute    memory image of    Z8E to top of TPA
  292. ;*    - Adjust all addresses in relocated monitor to reflect new
  293. ;*      execution area.  This is accomplished by repeated calls to
  294. ;*      zlen to calculate instruction    lengths.
  295. ;*    - All addresses    < the absolute value of    z8eorg are considered
  296. ;*      to be    absolute values    and are    not modified.
  297. ;*    - Relocate all address pointers    in command and operand jump
  298. ;*      tables.
  299. ;*
  300. ;******************************************************************************
  301.  
  302.       if    M80 or SLR
  303.     aseg
  304.       endif
  305.  
  306.       if ASMB
  307.     abs
  308.       endif
  309.  
  310.       if    ASMB
  311.     entry    case,column,init,row,rowb4?,mxycp
  312.     entry    ttyi,ttyi00,ttyo,ttyq,maxlen,bdos,xycp
  313.     entry    rstVec,coMask,mBannr
  314.       endif
  315.  
  316. ;     if    SLR or M80
  317. ;    Use :: at end of label name to generate a global symbol
  318. ;    when assembling to a .REL file (i.e. when using M80 or
  319. ;    when using Z80ASM with the /M switch).  Doing it this
  320. ;    way lets us assemble to a .REL file with either assembler
  321. ;    or directly to a .COM file with Z80ASM without changing
  322. ;    the source at all.
  323. ;     endif
  324.  
  325.     org    100h
  326.  
  327.     jp    nint
  328.  
  329.       if    ASMB
  330. rstVec:
  331.       else
  332. rstVec::
  333.       endif
  334.     defb    38h        ;Default (but patchable) breakpoint vector
  335.  
  336.       if    ASMB
  337. coMask:
  338.       else
  339. coMask::
  340.       endif
  341.     defb    7Fh        ;Mask applied to characters before output
  342.                 ;to screen.  Patch to 0FFh if your terminal
  343.                 ;needs high-order bit set on occasions.
  344.  
  345.       if    ASMB
  346. mbannr:
  347.       else
  348. mbannr::
  349.       endif
  350.       if    jTerm
  351.     defb    15h,17h
  352.       else
  353.     defb    cr,cr,cr,cr,cr    ;Patch with "clear screen" code
  354.       endif
  355.     defb    cr,lf
  356.     defb    'Z8E  V3.5 - 24 Jan 89'
  357.     defb    cr,lf
  358.     defb    'Copyright (c) 1984, 1985  Richard A. Surwilo'
  359.     defb    cr,lf,lf
  360.     defb    0
  361.  
  362. nint:
  363.     ld    sp,stack
  364.     ld    a,i        ;Save i reg for user
  365.     ld    (ireg),a
  366.     call    init
  367.     ld    de,mbannr    ;Dispense with formalities
  368.     call    print
  369.  
  370. ; Patch code for a specific breakpoint routine address.
  371. ;
  372. ; Adapted from an idea by Jim Moore (3 Dec 85) but made object-patchable
  373. ; (jrs 15 Nov 88)
  374.  
  375.     ld    a,(rstVec)    ;Get breakpoint vector address
  376.     ld    l,a
  377.     ld    h,0 
  378.     ld    (nint03+1),hl    ;Patch the code
  379.     inc    hl        ;HL now holds rstVec+1
  380.     ld    (nint71+1),hl    ;Patch some more code
  381.     or    0C7h        ;Convert vector address into RST xx
  382.     ld    (g400+1),a    ;Patch the code
  383.     ld    (g518+1),a
  384.  
  385. ; Patch code for terminal output - jrs 3.4
  386.  
  387.     ld    a,(coMask)    ;Get console output character mask
  388.     ld    (ttyo00+1),a
  389.  
  390. ; Do config based on max length of symbol names
  391.  
  392.     ld    a,(maxlen)    ;Check max symbol length
  393.     inc    a        ;Create mask        
  394.     cp    15
  395.     ld    b,a        ;B - maxlen mask - 15
  396.     ld    a,62        ;A - maxlin disassembly line length (62)
  397.     ld    c,68        ;C - column to display first byte of memory
  398.                 ;    window for J command
  399.     ld    d,3        ;D - bytes per line of memory window display
  400.     jp    z,nint00    ;Z - max symbol length is 14
  401.  
  402.                 ;If not 14 - use default values
  403.     ld    b,7        ;B - maxlen mask -  7
  404.     ld    a,30        ;A - maxlin disassembly line length (30)
  405.     ld    c,56        ;C - column to display first byte of memory
  406.     ld    d,7        ;    window for J command
  407. nint00:    ld    (maxlin),a
  408.     ld    a,b
  409.     ld    (maxlen),a
  410.     ld    a,c
  411.     ld    (fwndow),a
  412.     ld    a,d
  413.     ld    (nlmask),a
  414.  
  415. ;Reset CP/M DMA address for those instances in which Z8E is used to debug
  416. ;itself.  Otherwise DMA address is left where Z8E stopped loading itself.
  417. ;(Last statement no longer true - see patch 3.3.1)
  418.  
  419.     ld    de,80h
  420.     ld    c,26
  421.     call    bdos
  422.     
  423.     ld    a,jp        ;Initialize where L80 fears to tread
  424.  
  425. ; The next instruction is PATCHED before it is executed
  426. nint03:    ld    (38h),a        ;Init trap to breakpoint handler
  427.  
  428.     ld    hl,5dh        ;Save current contents of default fcb
  429.     ld    a,(hl)
  430.     cp    '('        ;Is first char in fcb a paren?
  431.     dec    hl        
  432.     jr    nz,nint25    ;Not paren - no user symbol table requested
  433.     inc    hl        ;Point back to paren
  434.     ld    de,inbf        ;Start of input buffer here in low memory
  435.     ld    b,15        ;Max chars in fcb following first paren
  436. nint05:    inc    hl        ;Bump fcb pointer
  437.     ld    (de),a        ;Move char to low memory keyboard input buffer
  438.                 ;so that prsr thinks this is keyboard input
  439.     inc    de        ;Bump input buffer pointer 
  440.     ld    a,(hl)
  441.     cp    ')'        ;Look for trailing paren
  442.     jr    z,nint10
  443.     djnz    nint05        ;Examine entire fcb at 5ch looking for paren
  444.     ld    hl,fcb5c    ;Trailing paren not found - this must be
  445.                 ; kookie file name
  446.     jr    nint25        ;Ignore
  447.                 
  448. ;Call iarg to determine amount of space to allocate in user symbol table.
  449. ;This arg must be enclosed in parentheses and must appear after the first
  450. ;arg in the command line.  Since opening and closing parens were found
  451. ;add a pound sign to make this into default decimal number then call xval
  452. ;to evaluate.
  453.  
  454. nint10:    ex    de,hl        ;HL - input buffer pointer
  455.     ld    (hl),'#'    ;Add trailing paren before calling iarg
  456.                 ;who will evaluate argument as if it was
  457.                 ;entered from keyboard
  458.     inc    hl
  459.     ld    (hl),a        ;Restore trailing paren following pound sign
  460.     inc    hl
  461.     ld    (hl),0        ;Add end of line null
  462.     call    iarg
  463.     ex    de,hl        ;DE - evaluated argument
  464.     ld    hl,fcb5c
  465.     jr    nz,nint25    ;Arg error - ignore input
  466.     ld    hl,81h        ;Start of command line tail
  467. nint15:    ld    a,(hl)
  468.     ld    (hl),' '    ;Replace the text which appeared between
  469.                 ;the parens and the parens themselves with
  470.                 ;spaces
  471.  
  472.     cp    ')'        ;Closing paren ends search
  473.     jr    z,nint20
  474.     inc    hl        ;Point to char following closing paren
  475.     jr    nint15
  476. nint20:    ex    de,hl        ;Arg to hl for mult times maxlen bytes per 
  477.                 ;symbol table entry
  478.     add    hl,hl
  479.     add    hl,hl
  480.     add    hl,hl
  481.     ld    a,(maxlen)    ;8 or 16 bytes per symbol table entry?
  482.     cp    7
  483.     jp    z,nint22    ;z - must be 8
  484.     add    hl,hl
  485. nint22:    ex    de,hl    
  486.     ld    (usymbl),de    ;Save number of bytes to reserve
  487.     ld    hl,6ch        ;since user symbol table arg was present then
  488.                 ;target file must be in default fcb number 2
  489.  
  490. nint25:    ld    de,zbuf        ;Local buffer
  491.     ld    bc,16
  492.     ldir            ;Move FCB contents to local memory
  493.     ld    hl,80h        ;Command line buffer address
  494.     ld    a,(hl)
  495.     and    a        ;Test for no input
  496.     jr    z,nint55    ;No input - clear symbol table
  497.     ld    c,a        ;BC - number of    chars in command line buffer
  498.     ld    (hl),b        ;Clear byte count
  499.     add    hl,bc        ;Point to last char in buffer
  500.     inc    hl
  501.     ld    (hl),b        ;Set end of line null after last char
  502.     ld    hl,81h
  503. nint30:    ld    a,(hl)        ;Look for start    of first file name
  504.     and    a        ;Found the end of line null?
  505.     jr    z,nint55    ;Z - no    files to load
  506.     cp    ' '        ;Leading space?
  507.     jr    nz,nint35    ;Not space - found start of file name
  508.     inc    hl
  509.     dec    c        ;Decrement command line    byte count
  510.     jr    nint30        ;Keep looking for start    of file    name
  511. nint35:    ld    de,znmbuf    ;Save name here    for later display
  512.     ld    (de),a
  513.     inc    de
  514. nint40:    inc    hl        ;Find first trailing space
  515.     ld    a,(hl)
  516.     cp    ' '
  517.     jr    z,nint45    ;Found space - move remainder of buffer
  518.     ld    (de),a        ;Save file name    character for display
  519.     inc    de
  520.     and    a        ;End of    line?
  521.     jr    z,nint55    ;z - only one file specified
  522.     dec    c
  523.     jr    nint40
  524. nint45:    ld    a,c        ;Check byte count
  525.     cp    inbfsz        ;versus    size of    our local input    buffer
  526.     jr    c,nint50    ;carry - size is ok
  527.     ld    c,inbfsz    ;Only move as much as will fit
  528. nint50:    ld    de,inbf
  529.     ldir            ;Move command line to local memory
  530.     xor    a
  531.  
  532. nint55:    ld    hl,z8eorg    ;clear local symbol table to nulls
  533.     ld    b,z8e-z8eorg    ;symbol    table size
  534. nint60:    ld    (hl),a        ;nulls to entire local symbol table
  535.     inc    hl
  536.     djnz    nint60
  537.     ld    hl,(06)        ;start of bdos
  538.     ld    l,a        ;init stack address to 256 boundary
  539.     ld    bc,nmem        ;monitor size
  540.     and    a
  541.     sbc    hl,bc        ;hl - starting address of z8e in upper
  542.                 ;memory
  543.     ld    (z8eb),hl    ;monitor bias -    for relocation work
  544.     ld    de,(usymbl)
  545.     sbc    hl,de
  546.     ld    (ntpa),hl    ;end of    tpa - for symbol loading
  547.     ld    a,d        ;check for no user symbol table
  548.     or    e
  549.     jr    z,nint75    ;no table - no clearing required
  550. nint70:    ld    (hl),0        ;fill user symbol table with nulls
  551.     inc    hl
  552.     dec    de
  553.     ld    a,d
  554.     or    e
  555.     jr    nz,nint70
  556. nint75:    ex    de,hl        ;hl - start of z8e in hi memory
  557.     
  558.     ld    hl,bphn-z8eorg    ;entry point to    breakpoint handler
  559.     add    hl,de
  560.  
  561. ; The next instruction will be PATCHED by the time it is executed.
  562. nint71:    ld    (39h),hl    ;Init RST 38h trap location
  563.  
  564.     ld    hl,z8eorg
  565.     ldir            ;z8e now in hi memory - relocate addresses
  566.     ld    hl,(z8eb)    ;recover hi memory starting address
  567.     ld    de,z8ecmd-z8eorg
  568.     add    hl,de        ;first instruction to relocate
  569.     ex    de,hl
  570. nint80:    call    zlen00        ;calculate instruction length
  571.     ld    h,d
  572.     ld    l,e        ;de - current instruction   hl - ditto
  573.     ld    b,0
  574.     add    hl,bc
  575.     ex    de,hl        ;de - next address to relocate
  576.     ld    a,c        ;test length
  577.     sub    3
  578.     jr    c,nint90    ;one or    two byters are non-relocatable
  579.     ld    c,a
  580.     add    hl,bc        ;bump if four byter
  581.     ld    a,(hl)
  582.     ld    hl,z80r        ;table of relocatable instructions
  583.     ld    c,z80rl        ;size
  584.     cpir
  585.     jr    nz,nint90    ;nz - not relocatable
  586.     ex    de,hl
  587.     dec    hl        ;point to address byte requiring bias
  588.     ld    a,(hl)
  589.     sub    z8eorg shr 8    ;test for absolute address < z8eorg
  590.     jr    c,nint85    ;absolute - no relocation needed
  591.     ld    b,a
  592.     ld    a,(z8ebh)    ;hi order byte of address bias
  593.     add    a,b        ;plus upper byte of operand address
  594.     ld    (hl),a        ;set relocated address
  595. nint85:    inc    hl
  596.     ex    de,hl        ;de - next address to test
  597. nint90:    ld    bc,nrel-z8eorg    ;end of    relocatable portion of monitor
  598.     ld    hl,(z8eb)
  599.     add    hl,bc        ;hl - absolute end of relocated    monitor
  600.     and    a
  601.     sbc    hl,de        ;reached end?
  602.     jr    nc,nint80    ;nc - more
  603.     ld    de,ncmd+zopjtl    ;size -    command    and operand jump tables
  604.     ld    hl,(z8eb)    ;base of relocated monitor
  605.     ld    a,-(high z8eorg); [was:  ld a,-(z8eorg/256)]
  606.     add    a,h        ;relocation bias byte to add to    ptrs
  607.     ld    d,a        ;d - bias to add  e - count of pointers
  608.                 ;              requiring relocation
  609.     add    hl,bc        ;first point to    operand    names
  610.     ld    bc,zopjtb    ;add length of operand name table
  611.     add    hl,bc        ;point to first    entry in jump table
  612. nint95:    inc    hl
  613.     ld    a,(hl)        ;hi byte jump table entry
  614.     add    a,d        ;plus bias
  615.     ld    (hl),a        ;replace in table
  616.     inc    hl
  617.     dec    e
  618.     jr    nz,nint95    ;nz - more table entries to relocate
  619.  
  620.  
  621. ;******************************************************************************
  622. ;*
  623. ;*    ZSYM:    Symbol table build from    .sym and .prn files
  624. ;*
  625. ;*    LFCB called to parse the input buffer (inbf) in low memory.
  626. ;*    INBF contains the command line tail which bdos passed to us at
  627. ;*    80h and which we have since moved to inbf (so that prsr thinks
  628. ;*    it's just keyboard input).
  629. ;*
  630. ;*    All valid file names are opened for input.
  631. ;*
  632. ;*    If the file name terminates with a comma then we assume    the
  633. ;*    user is    specifying a bias which    is to be added to every    symbol
  634. ;*    loaded from the    file.
  635. ;*
  636. ;*    zsym    general    file handiling
  637. ;*    .sym    load L80 .sym file or load SLR .lst file
  638. ;*    .prn    load M80 .prn file or load SLR .prn file
  639. ;*
  640. ;*    Symbol table always begins on an 8 or 16 byte boundary  
  641. ;*    depending on the value in maxlen. 
  642. ;*
  643. ;******************************************************************************
  644.  
  645. zsym:    call    lfcb        ;Initialize fcb
  646.     jp    nz,zstx        ;nz - error
  647.     ld    de,mldg        ;Display loading message
  648.     call    nprint        ;Output    crlf - then print
  649.     ld    de,prsbf
  650.     call    print        ;Display file name
  651.     ld    a,c         ;lfcb returns delimeter in c reg
  652.     ld    (delim),a    ;Temp save delimiter so we know if a bias has
  653.                 ;been specified
  654.     call    crlf
  655.     call    lopn        ;Try to    open symbol table file
  656.     dec    a        ;
  657.     jp    m,zfnf        ;m - file not found
  658.     ld    a,(delim)    ;Check delimeter
  659.     cp    ','
  660.     ld    hl,00
  661.     jr    nz,zsym10    ;nz - no comma means no    symbol bias
  662.     call    prsr        ;Let prsr extract symbol bias
  663.     jp    nz,zoff        ;Parse error - use bias    of 0000
  664.     ld    (delim),a    ;Save delimeter    which followed bias
  665.     ld    de,prsbf
  666.     ld    hl,00
  667.     call    xval        ;Evaluate bias
  668.     jr    z,zsym10    ;z - numeric bias specified
  669.  
  670.                 ;User has specified a bias in the form
  671.                 ; of a symbol name         
  672.     ld    hl,(ntpa)    ;Check bias specified by symbol    name
  673.     ld    a,(maxlen)
  674.     cpl
  675.     ld    e,a
  676.     ld    d,0ffh        ;Lower end of TPA by amount equal to 
  677.                 ; the value of maxlen negated to insert
  678.                 ; jump to bdos
  679.     add    hl,de
  680.     ld    a,(case)    ;Check case of symbol table
  681.     and    a
  682.     jp    z,zsym05    ;z - symbol names are already in upper case
  683.     ld    de,prsbf    ;prsr stored symbol name here 
  684. zsym00:    ld    a,(de)
  685.     and    a
  686.     jp    z,zsym05    ;z - end of label symbol name
  687.     call    ilcs        ;Change each char in symbol name to lower case
  688.     ld    (de),a
  689.     inc    de        ;Store converted character
  690.     jp    zsym00
  691. zsym05:    ld    de,prsbf    
  692.     call    fsym00        ;Search    symbol table
  693.     jp    nz,zoff        ;nz - not found
  694.     ld    a,(maxlen)
  695.     or    l
  696.     ld    l,a
  697.     ld    a,(hl)        ;Fetch hi order    address    associated
  698.                 ; with symbol
  699.     dec    hl
  700.     ld    l,(hl)
  701.     ld    h,a        ;HL - symbol value
  702. zsym10:    ld    (bias),hl    ;Bias to add to    each symbol address
  703.     ld    hl,00
  704.     ld    a,(fcbtyp)
  705.     ld    bc,(ntpa)    ;Current end of TPA
  706.     cp    'S'        ;Is this a .sym    file?
  707.     jp    z,.sym        ;.SYM file loaded differently from .PRN
  708.     cp    'L'
  709.     jp    nz,.prn        ;If not .LST then must be .PRN
  710.     ld    de,.lst??    ;Look for .LST string id string      
  711.     ld    (pstrng),de    ;Store pointer to string to find
  712.     call    fstrng
  713.  
  714.                 ;BC - symbol table pointer
  715.  
  716. .sym:    ld    a,(maxlen)    ;Lower TPA address by 16 or 8
  717.     cpl
  718.     and    c        ;for storing next symbol and address
  719.     ld    c,a
  720.     ld    a,(maxlen)
  721.     cpl            ;This is negate plus one
  722.     add    a,c
  723.     ld    c,a
  724.     jp    c,.sym00    ;Treat carry as complement of subtraction
  725.     dec    b
  726. .sym00:
  727.     ex    de,hl
  728.     ld    hl,stack+8    ;Check for monster symbol table    ready to eat us
  729.     and    a
  730.     sbc    hl,bc
  731.     jp    nc,zmem        ;End symbol load before    stack is clobbered
  732.     ex    de,hl
  733.     ld    a,(maxlen)    ;Load symbol length mask (7 or 15)
  734.     dec    a        ;
  735.     ld    d,a        ;D - actual max length of symbols (6 or 14)
  736.     xor    a
  737. .sym10:    ld    (bc),a        ;Init symbol table entry to nulls
  738.     inc    bc
  739.     dec    d
  740.     jr    nz,.sym10
  741.     ld    e,d        ;Clear DE for hex00
  742.     xor    a
  743.     ld    (star),a    ;Clear ** found flag
  744.     ld    a,4        ;Convert four bytes of address
  745.     ld    (bytes),a
  746. .sym20:    call    nchr        ;Fetch next character in file
  747.     cp    eof
  748.     jp    z,.eof        ;End of this symbol file
  749.     cp    '0'
  750.     jr    nc,.sym25    ;c -  must be control character or space
  751.                 ;nc - possible first char of address
  752.     cp    lf
  753.     jp    z,.sym21
  754.     cp    '*'        ;** in slr .sym file?
  755.     jp    nz,.sym20
  756.     ld    (star),a
  757.     jp    .sym25
  758.  
  759. .sym21:
  760.     call    nchr        ;Fetch char following lf    
  761.     cp    cr
  762.     jp    z,.sym22    ;z - consecutive crlf's means end of page
  763.     cp    '0'
  764.     jp    nc,.sym25    ;nc - symbol address on new line
  765.     cp    eof
  766.     jp      z,.eof
  767.     cp    '*'        ;** ?
  768.     jp    nz,.sym20
  769.     ld    (star),a
  770.     jp    .sym25
  771.  
  772. .sym22:
  773.     ld    a,(fcbtyp)
  774.     cp    'L'        ;z80asm .LST file?
  775.     jp    z,.sym23
  776.     cp    'P'        ;macro 80 v3.4?
  777.     jp    nz,.sym20
  778. .sym23:
  779.     ld    de,.lst??    ;Bypass inter-page verbiage
  780.     ld    (pstrng),de
  781.     call    fstrng
  782.     cp    eof
  783.     jp    z,.eof
  784.  
  785.     call    nchr
  786.     cp    eof
  787.     jp    z,.eof
  788.  
  789.  
  790. .sym25:    call    hex00        ;Have first char of address - convert
  791.     call    totsym        ;Bump total of symbols loaded
  792.     ld    a,(fcbtyp)    ;Is this a .SYM file?
  793.     cp    'S'
  794.     call    nz,nchr        ;Eat addrress/symbol separator for .LST file
  795.     ld    a,(maxlen)
  796.     dec    a
  797.     ld    (bytes),a    ;Init max symbol length counter
  798. .sym30:    call    nchr        ;Read symbol name char
  799.     cp    tab
  800.     jp    z,.sym45
  801.     cp    cr
  802.     jp    z,.sym45
  803.     cp    ' '
  804.     jp    z,.sym45
  805.     ld    (bc),a
  806.         ld    a,(case)        ;Check user requested case
  807.     and    a
  808.     jr    z,.sym35    ;z - upper case    requested by user
  809.     ld    a,(bc)        ;Recover char
  810.     cp    'A'
  811.     jr    c,.sym35    ;c - must be number
  812.     cp    'Z'+1
  813.     jp    nc,.sym35
  814.     or    20h
  815.     ld    (bc),a          ;Restore symbol name char as lower case
  816. .sym35:    inc    bc
  817.     ld    a,(bytes)
  818.     dec    a
  819.     ld    (bytes),a
  820.     jr    nz,.sym30
  821. .sym40:    call    nchr
  822.     cp    21h
  823.     jp    nc,.sym40
  824. .sym45:    ld    a,(star)    ;Check if this was ** in address field
  825.     and    a
  826.     jp    nz,.sym50
  827.     ld    a,(relchr)    ;Check for external symbol
  828.     cp    ' '
  829.     jp    z,.sym        ;Space means absolute
  830.     cp    quote
  831.     jp    z,.sym        ;Quote means relocatable
  832. .sym50:    ld    a,(maxlen)
  833.     or    c
  834.     ld    c,a
  835.     inc    bc        ;Point BC to next higher symbol block so
  836.                 ;that rewinding by maxlen bytes will actually
  837.                 ;overlay this symbol.  This ensures that 
  838.                 ;external symbols are not kept in table. 
  839.  
  840.     jp    .sym
  841.  
  842.  
  843. .prn:                ;Don't yet know if this .prn file was
  844.                 ;generated by M80 or Z80ASM.  To find out
  845.                 ;I pull a dirty trick.  I force a read
  846.                 ;and look for a formfeed, up to 80 characters
  847.                 ;of program title, a HT and "MACRO-80" in the
  848.                 ;I/O buffer, then I reset the pointer so that
  849.                 ;the next character read comes from the
  850.                 ;beginning of the file.  Will probably get
  851.                 ;confused by a HT in the program title.
  852.                 ;  jrs 14/11/88, 22/12/88.
  853.  
  854.     call    nchr        ;Force a read.  First byte of file is
  855.                 ; returned in A, pointer to next byte in HL
  856.     cp    formf        ;Test character
  857.     jr    nz,.prnBB    ;Exit M80 testing now if not a formfeed
  858.     ld    b,82        ;Maximum number of characters to search
  859.     ld    a,tab        ;What to look for
  860.     cpir
  861.     jr    nz,.prnBB    ;If no tab then not an M80 .prn file
  862.     ex    de,hl        ;Point at strings to be compared
  863.     ld    hl,.m80??
  864.     ld    b,(hl)        ;Number of bytes to compare
  865.     inc    hl
  866. .prnAA:
  867.     ld    a,(de)        ;Compare bytes
  868.     cp    (hl)
  869.     jp    nz,.prnBB    ;Exit loop if different
  870.     inc    hl        ; otherwise step the pointers
  871.     inc    de
  872.     djnz    .prnAA        ;Loop until difference encountered or
  873. .prnBB:                ; all bytes compared.
  874.     ld    hl,iobuf    ;Reset buffer pointer
  875.     ld    bc,(ntpa)
  876.     jp    nz,.slr        ;If not M80 then do Z80ASM .prn file load
  877.  
  878.     ; End of dirty trick code
  879.  
  880.     ld    de,.prn??
  881.     ld    (pstrng),de
  882.     call    fstrng
  883.     cp    eof
  884.     jp    nz,.prn00
  885. .prnCC:
  886.     ld    de,msymnf       ;display symbol table not found message   
  887.     call    print
  888.     jp    .eof50          ;check for more symbol files to load
  889.  
  890. .prn00:
  891.     ld    bc,(ntpa)       ;bc - current end of the tpa
  892.     dec    bc              ;this points us into the next lower 
  893.                                 ;symbol table block
  894.                 ;this is first char of symbol table
  895.     xor    a
  896.     or    l        ;get next byte from file but without bumping
  897.                 ;pointer allowing us to reread same char (in
  898.                 ;case it is last character in buffer    
  899.  
  900.     call    z,read        ;only do true read if last character was last
  901.                 ;in buffer    
  902.     ld    a,(hl)
  903.     cp    '0'
  904.     jp    c,.pr325    ;non-numeric: macro-80 v3.44    
  905.                 
  906.     cp    '9'+1
  907.     jp    c,.pr4        ;numeric:     macro-80 v3.4
  908.  
  909.  
  910. ;Macro-80 v3.4 dec 1980 symbol table load    
  911.                 
  912. .pr325:    ld    a,(maxlen)
  913.     cpl
  914.     and    c               ;now rewind within 8 or 16 byte block 
  915.                 ;(depending on maxlen) in order to point
  916.                 ;to first byte                               
  917.     ld    c,a
  918.  
  919.         ex    de,hl           ;de - save file buffer pointer 
  920.     ld    hl,stack + 16   ;check for encroaching symbol table
  921.     sbc    hl,bc           ;versus current symbol table address
  922.     jp    nc,zmem         ;nc - out of memory
  923.     ex    de,hl           ;return file buffer pointer
  924.     ld    a,(maxlen)
  925.     ld    d,a
  926.     dec    d        ;d - symbol name length
  927.     xor    a              
  928.     ld    e,a
  929. .pr330:    ld    (bc),a          ;pre-clear name portion of symbol table to 
  930.                                 ;nulls
  931.     inc    bc
  932.     dec    d               ;now any name less than maxlen chars in length
  933.     jp    nz,.pr330       ;is terminated with a null
  934.     ld    a,(maxlen)
  935.     cpl
  936.     and    c
  937.     ld    c,a
  938. .pr335:    call    nchr            ;next char from file buffer
  939.     cp    21h
  940.     jp    nc,.pr351    ;nc - this is first character of symbol name
  941.     cp    eof        ;end of    file?
  942.     jp    z,.eof
  943.     cp    lf        ;line feed?
  944.     jp    nz,.pr335
  945. .pr340:    call    nchr        ;get character following line feed
  946.     cp    cr
  947.     jp    z,.pr342
  948.     cp    formf        ;form feed?
  949.     jp    nz,.pr351
  950. .pr342:    ld    e,3        ;symbols resume    three lines hence following
  951.                 ;a form feed character - so count linefeeds
  952.     cp    cr        ;did we find cr or a formf?
  953.     jp    nz,.pr345    ;nz - formf
  954.     dec    e        ;just look for two lf's
  955. .pr345:    call    nchr
  956.     cp    lf
  957.     jp    nz,.pr345    ;loop til three found
  958.     dec    e
  959.     jp    nz,.pr345
  960.  
  961.     xor    a
  962.     or    l        ;get next byte from file but without bumping
  963.                 ;pointer allowing us to reread same char in
  964.                 ;case it is last character in buffer    
  965.  
  966.     call    z,read        ;only do true read if last character was last
  967.                 ;in buffer    
  968.     ld    a,(hl)
  969.     cp    cr        ;four crlf's is eof
  970.     jp    z,.eof
  971.  
  972. .pr350:    call    nchr            ;next char from file
  973.     cp    eof
  974.     jp    z,.eof
  975.     cp    tab
  976.     jp    z,.pr355
  977. .pr351:    ld    (bc),a        ;move character    of symbol name
  978.     ld    a,(case)        ;check user requested case
  979.     and    a
  980.     jr    z,.pr352        ;z - user wants upper case
  981.     ld    a,(bc)          ;get char back from symbol table
  982.     cp    'A'
  983.     jr    c,.pr352        ;must be numeric - no case here
  984.     cp    'Z'+1
  985.     jr    nc,.pr352
  986.     add    a,20h
  987.     ld    (bc),a          ;replace char with lower case equivalent
  988. .pr352:    inc    bc
  989.     jp    .pr350
  990.  
  991. .pr355:    ld    a,4
  992.     ld    (bytes),a
  993. .pr357:    call    nchr
  994.     cp    ' '
  995.     jp    z,.pr357
  996.  
  997.     call    hex00           ;now read the next four characters from the
  998.                 ;file and convert them to a hex address -
  999.                 ;store in symbol table entry
  1000.  
  1001.  
  1002.     ld    a,(relchr)      ;recover char which followed address
  1003.  
  1004.     cp    ' '             ;this char followed address
  1005.     jr    z,.pr370        ;microsoft absolute address 
  1006.     cp    quote           ;relocatable address?
  1007.     jp    nz,.pr325
  1008.                                 ;by not rewinding the symbol table pointer
  1009.                                 ;the next symbol will overlay this one.  
  1010.  
  1011. .pr370:    dec    bc
  1012.     call    totsym
  1013.  
  1014.     jp    .pr325
  1015.  
  1016.  
  1017. ;macro-80 v3.44 symbol loading routine
  1018.                 
  1019. .pr4:    ld    a,(maxlen)    ;lower tpa address by maxlen
  1020.     cpl
  1021.     and    c        ;for storing next symbol and address
  1022.     ld    c,a        ;bc - next address of symbol table entry
  1023.                 ;     on an 8 or 16 byte boundary    
  1024.     ex    de,hl
  1025.     ld    hl,stack+8    ;check for monster symbol table    
  1026.     and    a
  1027.     sbc    hl,bc
  1028.     jp    nc,zmem        ;end symbol load before    stack is clobbered
  1029.     ex    de,hl
  1030.     ld    a,(maxlen)
  1031.     dec    a        ;pre-clear symbol table entry with nulls
  1032.     ld    d,a
  1033.     xor    a
  1034. .pr410:    ld    (bc),a        ;for length equal to maxlen
  1035.     inc    bc
  1036.     dec    d
  1037.     jr    nz,.pr410
  1038.     ld    e,d        ;clear de for hex00
  1039.     ld    a,4        ;convert four bytes of address
  1040.     ld    (bytes),a
  1041. .pr420:    call    nchr        ;fetch next character in file
  1042.     cp    eof
  1043.     jp    z,.eof
  1044.     cp    '0'
  1045.     jr    nc,.pr425    ;nc - address digit
  1046.     cp    lf
  1047.     jp    nz,.pr420    ;nz - leading space or cr
  1048.  
  1049.  
  1050.     call    nchr        ;check character following lf
  1051.     cp    cr
  1052.     jp    z,.eof        ;blank line is eof
  1053.  
  1054.     cp    formf        ;form feed?
  1055.     jp    nz,.pr425    ;no - first character of next address
  1056.  
  1057.     ld    e,3        ;must be form feed
  1058. .pr421:    call    nchr
  1059.     cp    lf        ;three lf's follow form feed before symbols
  1060.                 ;resume on next page
  1061.     jp    nz,.pr421
  1062.     dec    e
  1063.     jp    nz,.pr421
  1064.  
  1065.     call    nchr
  1066.     cp    eof
  1067.     jp    z,.eof
  1068.  
  1069. .pr425:    
  1070.     call    hex00        ;have first char of address - convert
  1071.  
  1072.     call    nchr        ;eat address/symbol separator
  1073.  
  1074.     ld    a,(maxlen)
  1075.     dec    a
  1076.     ld    (bytes),a    ;max chars to store in symbol table
  1077.  
  1078.  
  1079. .pr430:    call    nchr        ;read symbol name char
  1080.     cp    21h        
  1081.     jp    c,.pr440    ;found separator
  1082.     ld    (bc),a
  1083.         ld    a,(case)        ;check user requested case
  1084.     and    a
  1085.     jr    z,.pr435    ;c - upper case    requested by user
  1086.     ld    a,(bc)        ;recover char
  1087.     cp    'A'
  1088.     jr    c,.pr435    ;c - must be number
  1089.     cp    'Z'+1
  1090.     jr    nc,.pr435
  1091.     or    20h
  1092.     ld    (bc),a          ;restore symbol name char as lower case
  1093. .pr435:    inc    bc              ;bump symbol table pointer
  1094.     ld    a,(bytes)    ;character counter
  1095.     dec    a
  1096.     ld    (bytes),a
  1097.     jp    nz,.pr430    ;not max length
  1098.  
  1099.                 
  1100. .pr438:    call    nchr        ;eat chars until next address found
  1101.     cp    eof        
  1102.     jp    z,.eof
  1103.     cp    ' '        ;found symbol/address
  1104.     jp    nz,.pr438
  1105.  
  1106.  
  1107. .pr440:    ld    a,(maxlen)
  1108.     cpl
  1109.     and    c
  1110.     ld    c,a
  1111.  
  1112.     ld    a,(relchr)      ;recover char which followed address
  1113.     cp    ' '             ;this char followed address
  1114.     jr    z,.pr450        ;microsoft absolute address 
  1115.     cp    quote           ;relocatable address?
  1116.     jp    nz,.pr4            ;nz - must be  external symbol. we don't
  1117.                                 ;actually load them or count them in total.
  1118.                                 ;by not rewinding the symbol table pointer
  1119.                                 ;the next symbol will overlay this one.  
  1120.  
  1121. .pr450:    dec    bc
  1122.     call    totsym
  1123.     jp    .pr4
  1124.  
  1125. ; SLR Z80ASM symbol table loading routines
  1126.  
  1127. .slr:
  1128.     ld    de,.slr??    ;If this .prn file really is a Z80ASM
  1129.     ld    (pstrng),de    ;product then we can use existing code
  1130.     call    fstrng        ;to load the symbols.
  1131.     cp    eof
  1132.     jp    nz,.sym
  1133.     ld    de,msymnf       ;display symbol table not found message   
  1134.     call    print
  1135.     jp    .eof50          ;check for more symbol files to load
  1136.  
  1137.  
  1138. .eof:                           ;We always pre-decrement the symbol table
  1139.                                 ;pointer in anticipation of storing the next
  1140.                                 ;symbol.  Now that we hit the end of a symbol
  1141.                                 ;table we must adjust the pointer in 
  1142.                                 ;preparation for loading the symbols from the
  1143.                                 ;next file (if there is one).
  1144.         ld    a,(maxlen)
  1145.     ld    l,a
  1146.     ld    h,0
  1147.     inc    l
  1148.     add    hl,bc           ;point to last loaded symbol
  1149.     ld    b,h
  1150.     ld    c,l             ;bc - spare copy
  1151.     cpl
  1152.     and    c
  1153.     ld    c,a
  1154.     ld    (ntpa),bc       ;save current end of tpa address
  1155.         ld    a,(nsymhi)      ;hi order number of symbols loaded (bcd)
  1156.     call    hexc            ;convert to ascii  
  1157.     ld    h,a             ;returned in a - move to h (other digit in l)
  1158.     ld    (mhex),hl       ;store in message
  1159.     ld    a,(nsymlo)
  1160.     call    hexc            ;convert lo order
  1161.     ld    h,a
  1162.     ld    (mhex+2),hl
  1163.     ld    de,msym..       ;display number of symbols loaded message
  1164.     ld    c,9
  1165.     call    bdos
  1166.     ld    de,mhex         ;now look thru ascii number of symbols to 
  1167.                                 ;strip leading zeros
  1168.     ld    b,3
  1169. .eof10:    ld    a,(de)          
  1170.     cp    '0'
  1171.     jr    nz,.eof20       ;nz - found first non-zero
  1172.     inc    de
  1173.     djnz    .eof10          ;if first three chars zero - fall thru and
  1174.                                 ;print the fourth regardless
  1175. .eof20: ld      c,09
  1176.     call    bdos            ;print the number as string ending with $
  1177.     call    crlf
  1178.     ld    hl,(tsym)       ;now add in bcd total for this file to bcd
  1179.                                 ;total for all files
  1180.     ld    de,(nsym)       ;tsym - total for all files
  1181.                                 ;nsym - total for this file
  1182.     ld    a,h
  1183.     add    a,d
  1184.     daa
  1185.     ld    h,a
  1186.     ld    a,l
  1187.     adc    a,e
  1188.     daa
  1189.     ld    l,a
  1190.     ld    (tsym),hl
  1191.     ld      hl,00           ;clear out total for next file
  1192.     ld    (nsym),hl
  1193.     ld    hl,(z8eb)
  1194.     ld    de,symflg-z8eorg
  1195.     add    hl,de           ;hl - pointer to symbol flag in hi memory
  1196.     xor    a               
  1197.     ld    (hl),a        ;zero -    symbol table present
  1198.     ld    (symflg),a      ;also set flag in lo memory where we are
  1199.                                 ;currently so that fsym knows theres a symbol
  1200.                                 ;table to search thru if the user specified a
  1201.                                 ;symbol name bias as part of the command line
  1202.  
  1203. .eof50:    ld    a,(delim)       ;check command line delimter
  1204.     and    a               ;test for end of line null
  1205.     jp    nz,zsym         ;nz - not null means more files
  1206.  
  1207.  
  1208.  
  1209.                     
  1210. load:    ld    hl,(ntpa)    ;current end of    memory
  1211.     ld    a,(symflg)    ;check for symbol table
  1212.     and    a
  1213.     jr    nz,load00    ;nz - no symbol    table
  1214.     ld    d,a
  1215.     ld    a,(maxlen)
  1216.     ld    e,a        ;de - length of a symbol table block
  1217.     inc    e
  1218.     sbc    hl,de        ;compensate for    pre-increment of pointer
  1219. load00:    ld    de,(06)        ;de - real entry point to bdos
  1220.     ld    (06),hl        ;point to our origin in    hi memory
  1221.     ld    (hl),jp        ;init jump to bdos at start of z8e
  1222.     inc    hl
  1223.     ld    (hl),e
  1224.     inc    hl
  1225.     ld    (hl),d
  1226.     ld    e,0        ;de - old start of bdos address in also our 
  1227.                                 ;ending address
  1228.     ld    hl,(z8eb)       ;load out starting address in hi memory
  1229.     ld    bc,z8e-z8eorg   ;fetch the number of bytes between z8e's base
  1230.                                 ;address and the entry point of the command    
  1231.                                 ;processor  - internal symbol table size
  1232.  
  1233.     add    hl,bc
  1234.     ld    b,h
  1235.     ld    c,l        ;BC - relocated    z8e address
  1236.     ex    de,hl           ;DE - entry point z8e   HL - old start of bdos
  1237.     dec    hl              ;HL - last byte in our memory
  1238.     ld    (hl),b
  1239.     dec    hl
  1240.     ld    (hl),c        ;z8e (monitor entry point) on stack
  1241.     ld    sp,hl           ;now set current stack to just below our  
  1242.                                 ;return address
  1243.     ex    de,hl           ;hl - relocated address z8e
  1244.     inc    hl
  1245.     inc    hl              ;hl - points to ld  sp,0000 instruction at the
  1246.                                 ;start of the command processor. replace 0000
  1247.                                 ;with the address bdos-1 
  1248.     ld    (hl),e          ;set real stack address
  1249.     inc    hl
  1250.     ld    (hl),d
  1251.     ld    hl,(z8eb)    ;base of relocated code
  1252.     ld    de,fcb-z8eorg    ;relative offset from start of monitor
  1253.     add    hl,de
  1254.     ex    de,hl        ;de - fcb address in relocated monitor in hi
  1255.                                 ;memory
  1256.     ld    hl,zbuf        ;
  1257.     ld    bc,16
  1258.     ldir            ;init fcb with saved file name
  1259.     ld    de,mz8eld    ;print memory space occupied by    z8e
  1260.     call    print
  1261.     ld    hl,(z8eb)       ;display our base address in upper memory
  1262.     call    outadr
  1263.     ld    a,'-'           
  1264.     call    ttyo
  1265.     call    space
  1266.     call    space
  1267.     ld    hl,(06)         ;this points to the new jump to bdos
  1268.     inc    hl              
  1269.     ld    e,(hl)          ;de - old start of bdos address
  1270.     inc    hl
  1271.     ld    d,(hl)
  1272.     ex    de,hl
  1273.     ld    l,0             ;256 byte boundary to bypass cp/m serial no.
  1274.     call    outadr
  1275.  
  1276.     ld    a,(symflg)      ;test for presence of symbol table
  1277.     and    a
  1278.     jr    nz,load40       ;nz - no table
  1279.     ld    de,msymld       ;display start address of symbol table message
  1280.     call    print
  1281.     ld    hl,(06)         ;vector to bdos is start of symbol table
  1282.     call    outadr
  1283.     ld    a,'-'
  1284.     call    ttyo
  1285.     call    space
  1286.     call    space
  1287.     ld    hl,(z8eb)       ;start of internal symbol table is end of 
  1288.                                 ;symbol table built from files
  1289.     dec    hl
  1290.     call    outadr
  1291.  
  1292.     ld    a,(tsymhi)      ;total number of symbols from all files (bcd)
  1293.     call    hexc            ;convert to ascii
  1294.     ld    h,a             ;move hi order ascii digit to h
  1295.     ld    (mhex),hl       ;store double ascii digit
  1296.     ld    a,(tsymlo)
  1297.     call    hexc            ;convert lo order
  1298.     ld    h,a
  1299.     ld    (mhex+2),hl     ;save in string
  1300.     ld    de,tsym..       ;total symbols message
  1301.     ld    c,9
  1302.     call    bdos
  1303.     ld    de,mhex         ;address of ascii digits
  1304.     ld    b,3             ;check for leading zeros
  1305. load20:    ld    a,(de)          
  1306.     cp    '0'
  1307.     jr    nz,load30       ;nz - found first nz in string
  1308.     inc    de
  1309.     djnz    load20          ;check first three digits then fall thru and
  1310.                                 ;print fourth regardless
  1311. load30:    ld    c,09
  1312.     call    bdos
  1313.  
  1314. load40:    ld    hl,(06)
  1315.     dec    hl              ;hl - address of new tpa
  1316.     ld    de,mnvmem       ;display address as memory available
  1317.     call    print
  1318.     call    outadr
  1319.     call    crlf
  1320.     ld    (hl),0          ;now store two zeros at the top of the tpa and
  1321.                                 ;set stack pointer to this very same address.
  1322.                                 ;this allows users to do a warm boot via ret 
  1323.                                 ;in the same way as if they had been loaded by
  1324.                                 ;cp/m.
  1325.     dec    hl
  1326.     ld    (hl),0
  1327.     ld    bc,(z8eb)       ;our relocated address in hi memory 
  1328.     ex    de,hl           ;de - last available location in tpa
  1329.     ld    hl,spreg-z8eorg ;address (relative to the start of z8e) where
  1330.                                 ;we store the user stack pointer address
  1331.     add    hl,bc           ;hl - pointer to 
  1332.     ld    (hl),e          ;save user stack in spreg in hi memory 
  1333.     inc    hl
  1334.     ld    (hl),d
  1335.     ld    hl,z8e-z8eorg   
  1336.     ld    a,(zbufnm)    ;first char of file name
  1337.     cp    ' '             ;do we have a file to load?
  1338.     jr    z,load50        ;z - no 
  1339.     ld    de,mldg         ;display loading message and target file name
  1340.     call    nprint
  1341.     ld    de,znmbuf
  1342.     call    print           
  1343.                                 ;enter the monitor in hi memory at entry
  1344.                                 ;point lldr10 
  1345.         
  1346.     ld    hl,lldr10-z8eorg
  1347.     ld    bc,(z8eb)
  1348. load50:    add    hl,bc           ;hl - actual address of lldr10 in hi memory
  1349.     ex    de,hl           ;now clear out the buffer at 80h so the user
  1350.                                 ;program doesn't mistakenly think that our
  1351.                                 ;command line tail is really his.
  1352.     ld    hl,iobuf
  1353.     ld    (hl),0          ;set number of chars zero (80h)
  1354.     inc    hl
  1355.     ld    b,127           ;clear until start of tpa
  1356. load60:    ld    (hl),' '
  1357.     inc    hl
  1358.     djnz    load60
  1359.     ex    de,hl           ;lldr10 address back to HL
  1360.     jp    (hl)            ;Hi-ho, hi-ho to the loader we must go 
  1361.  
  1362.  
  1363.  
  1364.     page
  1365. ;This routine reads one char from the disk I/O 
  1366. ;buffer returning it in A. Upon entry we check
  1367. ;the low order buffer pointer - 0 means we hit 
  1368. ;the  256 boundary (end of buffer) and a  read
  1369. ;is needed. 
  1370.  
  1371. nchr:    xor    a
  1372.     or    l
  1373.     call    z,read
  1374.     ld    a,(hl)
  1375.     inc    hl
  1376.     ret
  1377.  
  1378. read:    push    bc
  1379.     push    de
  1380.     ld    de,fcb
  1381.     ld    c,20            ;sequential file read
  1382.     call    bdos
  1383.     and    a               ;test for error
  1384.     ld    hl,iobuf        ;assume ok - init i/o buffer address
  1385.     pop    de
  1386.     pop    bc
  1387.     ret    z               ;z - no errors
  1388.     ld    de,msymnf       ;display symbol table not found message   
  1389.     call    print
  1390.     ld    sp,stack        ;reinit stack
  1391.     jp    .eof50          ;check for more symbol files to load
  1392.  
  1393.  
  1394. ;hexc
  1395. ;Convert byte in a to two ASCII hex digits.
  1396. ;return: a - converted hi order digit
  1397. ;        l -           lo order digit
  1398.  
  1399. hexc:    ld    h,a
  1400.     rrca
  1401.     rrca
  1402.     rrca
  1403.     rrca
  1404.     call    hexc00
  1405.     ld    l,a
  1406.     ld    a,h
  1407. hexc00:    and    0fh
  1408.     add    a,90h
  1409.     daa
  1410.     adc    a,40h
  1411.     daa
  1412.     ret
  1413.  
  1414.  
  1415. ;hex:
  1416. ;This routine is called by the symbol table
  1417. ;building routines, .sym and .prn and its
  1418. ;function is to convert ascii addresses
  1419. ;into binary.  Since we are reading files in
  1420. ;a known format we don't init any loop counts;
  1421. ;instead, we look for delimeters. 
  1422.  
  1423.  
  1424. hex:    call    nchr            ;get char from disk i/o buffer
  1425. hex00:    cp    3ah             ;convert ascii to hex
  1426.     jp    c,hex10         ;c - must be delimeter
  1427.     sub    7
  1428. hex10:    sub    '0'
  1429.     ex    de,hl           ;shift hl left four
  1430.     add    hl,hl
  1431.     add    hl,hl
  1432.     add    hl,hl
  1433.     add    hl,hl
  1434.     or    l               ;or in this new digit
  1435.     ld    l,a
  1436.     ex    de,hl
  1437.     ld    a,(bytes)
  1438.     dec    a
  1439.     ld    (bytes),a
  1440.     jp    nz,hex
  1441.     call    nchr
  1442.     cp    'I'             ;global?
  1443.     call    z,nchr          ;z - need to read next to determine absolute
  1444.                                 ;    or relocatable
  1445.  
  1446.     ld    (relchr),a      ;we need to save this character for .prn files
  1447.                                 ;so we can tell whether to add this symbol
  1448.                                 ;to the count of symbols loaded.  if this
  1449.                                 ;is an external name we skip the add.
  1450.  
  1451.     cp    ' '             ;space means absolute
  1452.     jr    z,hex30         ;no bias added to absolute symbols
  1453.     ld    a,(biaslo)
  1454.     add    a,e             ;add in bias as specified by user or default
  1455.                                 ;as initialized by us (zero)
  1456.     ld    e,a
  1457.     ld    a,(biashi)
  1458.     adc    a,d
  1459.     ld    d,a
  1460. hex30:    ld    a,(maxlen)      ;now point to last byte of symbol table
  1461.                                 ;entry, which is where we will store
  1462.                                 ;address just computed 
  1463.     cpl
  1464.     and    c
  1465.     ld    c,a
  1466.     ld    a,(maxlen)
  1467.     or    c
  1468.     ld    c,a             ;never worry about carry - we always start 
  1469.                                 ;with 256 boundary
  1470.         ld    a,d             ;store lo order symbol address
  1471.     ld    (bc),a
  1472.     dec    bc        ;point to penultimate byte in block
  1473.     ld    a,e             ;hi order byte of address into symbol table
  1474.     ld    (bc),a
  1475.     ld    a,(maxlen)    ;mask to rewind symbol table pointer to the
  1476.                 ;start of this block
  1477.     cpl
  1478.     and    c
  1479.     ld    c,a
  1480.     ret
  1481.  
  1482.  
  1483. totsym:    ld    de,nsymlo       ;nsym - bcd running count of the number of 
  1484.     ld    a,(de)        ;       symbols loaded so far
  1485.     add    a,1        ;bump by one symbol
  1486.     daa                     ;keep bcd format
  1487.     ld    (de),a
  1488.     ret    nc
  1489.     dec    de              ;account for carry by bumping hi order byte
  1490.     ld    a,(de)
  1491.     add    a,1
  1492.     daa
  1493.     ld    (de),a
  1494.     ret
  1495.                                 
  1496.  
  1497. ;zstx:            
  1498. ;Possible syntax error was detected as lfcb tried to init the FCB.
  1499. ;However, we never keep track of how many files appeared in the 
  1500. ;command line we just keep calling lfcb.  Hence, we will always get
  1501. ;an error return at some point when the input buffer runs out of 
  1502. ;valid input.  We check for real syntax error or end of command
  1503. ;line by examining the first byte of the parse buffer:  if zero then
  1504. ;prsr found no valid characters in the input buffer and this is the
  1505. ;end of input - else, lfcb found real syntax error.
  1506.  
  1507.  
  1508. zstx:    ld    a,(prsbf)
  1509.     and    a        ;real syntax error - or    end of input?
  1510.     jp    z,load          ;z - more files 
  1511.     ld    de,mldg        ;display loading message and symbol name
  1512.                 ;to preserve the syntax used on good loads
  1513.     call    nprint
  1514.     ld    de,prsbf    ;display file name currently in parse buffer so
  1515.                 ;user knows where goof was
  1516.     call    print
  1517.     call    crlf
  1518.     ld    de,msntx    ;now display syntax error
  1519.     call    print
  1520.     jp    .eof50        ;check for more files to load
  1521.  
  1522.  
  1523. zfnf:    ld    de,mfilnf    ;display file not found 
  1524.     call    print
  1525.     jp    .eof50
  1526.  
  1527.  
  1528. zmem:    ld    de,mmem??    ;display out of memory message
  1529.     call    print
  1530.     call    crlf
  1531.     ld    hl,maxlen
  1532.     ld    l,(hl)
  1533.     ld    h,00        
  1534.     add    hl,bc
  1535.     ld    (ntpa),hl
  1536.     jp    load
  1537.  
  1538.  
  1539. zoff:    ld    de,minvof    ;display invalid offset using 0000 message
  1540.     call    print
  1541.     ld    hl,00
  1542.     jp    zsym10
  1543.  
  1544.  
  1545. fstrng:    
  1546.     push    bc
  1547.     push    de
  1548. fstr00:    
  1549.     ld    de,(pstrng)     ;address of canned string pointer
  1550.     ld    a,(de)        ;length
  1551.     ld    b,a
  1552.     inc    de
  1553. fstr10:    call    nchr        ;get char
  1554.     cp    eof
  1555.     jp    z,fstr20
  1556.     ex    de,hl        ;DE - buffer ptr  HL - "symbols:" string ptr
  1557.     cp    (hl)
  1558.     ex    de,hl
  1559.     jp    nz,fstr00    ;mismatch read more from file
  1560.     inc    de
  1561.     djnz    fstr10          ;check entire string length
  1562. fstr20:    pop    de
  1563.     pop    bc    
  1564.     ret
  1565.  
  1566. .lst??:    defb    .lstsz        ;string length
  1567.     defb    'Symbol Table:'
  1568.     defb    cr,lf,cr,lf
  1569. .lstsz    equ    $ - .lst?? - 1
  1570.  
  1571.  
  1572. .prn??:    defb    .prnsz        ;string length    
  1573.     defb    'Symbols:'    ;string to search for in M80's .prn files 
  1574.                 ;indicating start of symbol table
  1575.     defb    cr,lf
  1576. .prnsz    equ    $ - .prn?? - 1
  1577.  
  1578. .slr??:    defb    .slrsz
  1579.     defb    'Symbols Detected.'
  1580.     defb    cr,lf
  1581. .slrsz    equ    $ - .slr?? - 1
  1582.  
  1583. .m80??:    defb    .m80sz
  1584.     defb    'MACRO-80'
  1585. .m80sz    equ    $ - .m80?? - 1
  1586.  
  1587. tsym:
  1588. tsymhi:    defb    0
  1589. tsymlo:    defb    0
  1590.  
  1591. usymbl:    defw    0
  1592.  
  1593. pstrng:    defw    0
  1594.  
  1595. relchr:    defb    0
  1596.  
  1597. .idprn:    defb    0
  1598.  
  1599. star:    defb    0
  1600.  
  1601. nsym:
  1602. nsymhi:    defb    0
  1603. nsymlo:    defb    0
  1604. mhex:    defb    '    '
  1605.     defb    '$'
  1606.  
  1607. msym..:    defb    'Number Of Symbols Loaded: $'
  1608.  
  1609. tsym..:    defb    cr,lf
  1610.     defb    'Total Symbols:   $'
  1611.  
  1612. msymnf:    defb    'Symbol Table Not Found'
  1613.     defb    cr,lf,0
  1614.  
  1615. minvof:    defb    'Invalid Offset - Using 0000'
  1616.     defb    cr,lf,0
  1617.  
  1618. msymld:    defb    cr,lf
  1619.     defb    'Symbol Table:    '
  1620.     defb    0
  1621.  
  1622. mz8eld:    defb    cr,lf
  1623.     defb    'Z8E Relocated:   '
  1624.     defb    0
  1625.  
  1626. mnvmem:    defb    cr,lf
  1627.     defb    'Top Of Memory:   '
  1628.     defb    00
  1629.  
  1630. z8eb:    defb    00
  1631. z8ebh:    defb    00
  1632. ntpa:    defw    00
  1633.  
  1634. bytes:    defb    00
  1635.  
  1636. zbuf:    defb    00
  1637. zbufnm:    defb    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1638. znmbuf:
  1639.     rept    18
  1640.     defw    0,0
  1641.     endm
  1642.     if    ASMB
  1643. init:
  1644.     else
  1645. init::
  1646.     endif
  1647.     ret
  1648.     defs    255
  1649.     page
  1650. ;******************************************************************************
  1651. ;*
  1652. ;*    z8e:    Entry point to monitor
  1653. ;*
  1654. ;*        Each command begins with the output of the '*' prompt.
  1655. ;*        Command    character is validated by checking the cmd table,
  1656. ;*
  1657. ;*        Relative position of command letter in cmd table also used
  1658. ;*        as index into command jump table jtcmd.
  1659. ;*
  1660. ;*        All commands entered with b = 0.
  1661. ;*
  1662. ;******************************************************************************
  1663.  
  1664.  
  1665.     org    ($+255) and 0ff00h
  1666. ;was    org    256*(($+255)/256)
  1667.  
  1668. z8eorg:
  1669.                 ;Note: first three bytes here become a jump to
  1670.     defs    16        ;      BDOS after we are loaded
  1671.                 ;
  1672.                 ;This is the internal symbol table
  1673.  
  1674. z8e:    and    a        ;Any do-nothing    instruction with the sign
  1675.                 ;bit set to indicate end of internal symbol
  1676.                 ;table
  1677.  
  1678.     defb    31h        ;LD SP,nnnn - Load monitor stack pointer
  1679. z8esp:    defw    8000h        ;Actual    address    filled in by nint at load
  1680.                 ;time when we figure out where bdos is
  1681.  
  1682. z8ecmd:    ld    hl,z8e
  1683.     push    hl
  1684.     ld    de,prompt    ;display prompt (asterisk)
  1685.     call    nprint
  1686.     ld    hl,jstepf    ;full screen debugging in effect?
  1687.     ld    a,(hl)
  1688.     and    a
  1689.     jr    nz,z8e10    ;nz - no
  1690.  
  1691.     ld    c,10
  1692.     call    spaces        ;If this was jdbg clear command line residue
  1693.     ld    b,10        
  1694. z8e00:    call    bksp
  1695.     djnz    z8e00
  1696.  
  1697. z8e10:    call    inchar        ;Read in command character
  1698.  
  1699. ; +++ jrs 3.5.6 ++++++++++++++++++
  1700.     cp    cr        ;+Check for empty command line
  1701.     jr    nz,z8e16    ;+Something there - process it
  1702.     ld    a,(lcmd)    ;+Nothing - see if S or J was last command
  1703.     cp    'J'        ;+Repeat 'J' command?
  1704.     jp    z,jdbg00    ;+
  1705.     ld    hl,1        ;+
  1706.     cp    'S'        ;+Repeat 'S' command?
  1707.     jp    z,step40    ;+
  1708.     ld    a,cr        ;+
  1709. z8e16:                ;+
  1710. ; ++++++++++++++++++++++++++++++++
  1711.     call    ixlt        ;Translate to upper case for compare
  1712.     ld    (lcmd),a
  1713.     cp    'J'        ;If command is anything but j then indicate
  1714.                 ;that screen is corrupted.  at next invokation
  1715.                 ;jdbg will know to repaint the screen. 
  1716.     jr    z,z8e20
  1717.     ld    (jstepf),a    ;Full screen flag nz - full screen debugging
  1718.                 ;in progress
  1719.  
  1720.  
  1721. z8e20:    ld    bc,ncmd        ;total number of commands
  1722.     ld    hl,cmd        ;table of ascii    command    characters
  1723.     cpir
  1724.     jp    nz,e???        ;command letter not found in table
  1725.     ld    hl,jtcmd    ;command jump table
  1726.     add    hl,bc
  1727.     add    hl,bc        ;index into table
  1728.     ld    e,(hl)        ;lo order command processing routine
  1729.     inc    hl
  1730.     ld    d,(hl)        ;upper address
  1731.     ld    c,3
  1732.     call    spaces        ;print spaces regardless
  1733.     ex    de,hl        ;hl - address of command processing routine
  1734.     jp    (hl)
  1735.     page
  1736. ;******************************************************************************
  1737. ;*
  1738. ;*    bphn:    breakpoint handler - rst38s land here
  1739. ;*
  1740. ;*        bphn   - bphn00      save all user    registers
  1741. ;*        bphn10 - bphn20      check    that user pc matches entry in brktbl.
  1742. ;*        bphn80          special single step processing.
  1743. ;*
  1744. ;*    note:    sbps is    both a flag and    the count of the number    of step    bps.
  1745. ;*        sbps is    set to 1 merely    to indicate that the single-stepping
  1746. ;*        is in effect.  then the    number of step bps is added to one.
  1747. ;*        hence, if 1 step bp was    set then  sbps = 2 and if 2 step bps
  1748. ;*        were set (conditional jump, call, ret) sbps = 3.
  1749. ;*
  1750. ;******************************************************************************
  1751.  
  1752. bphn:    ld    (hlreg),hl    ;save user hl
  1753.     pop    hl        ;pop breakpoint    pc from    stack
  1754.     ld    (spreg),sp    ;save user sp
  1755.     ld    sp,(z8esp)    ;switch    to our stack
  1756.     dec    hl        ;point to location of rst instruction
  1757.     ld    (pcreg),hl    ;save user pc
  1758.     ld    (dereg),de    ;save user de
  1759.     ld    (bcreg),bc    ;save user bc
  1760.     push    af
  1761.     pop    hl        ;user accumulator and flag to hl
  1762.     ld    (afreg),hl    ;save user af
  1763.     ld    a,i
  1764.     ld    h,a        ;save user i reg
  1765.     ld    a,r
  1766.     ld    l,a        ;save user r reg
  1767.     ld    (rreg),hl
  1768.     ex    af,af'          ;Bank In Prime Regs
  1769.     exx
  1770.     ld    (hlpreg),hl    ;save
  1771.     ld    (depreg),de
  1772.     ld    (bcpreg),bc
  1773.     push    af
  1774.     pop    hl
  1775.     ld    (afpreg),hl
  1776.     ld    (ixreg),ix    ;save user ix
  1777.     ld    (iyreg),iy    ;save user iy
  1778.     ld    a,(bps)
  1779.     and    a        ;check for zero    bp count
  1780.     jp    z,bp???        ;error - no bps    set
  1781.     ld    b,a        ;b - number of breakpoints
  1782.     ld    hl,brktbl    ;breakpoint storage table
  1783.     xor    a
  1784.     ld    c,a        ;init breakpoint found flag
  1785. bphn10:    ld    e,(hl)
  1786.     inc    hl
  1787.     ld    d,(hl)        ;de - breakpoint address
  1788.     inc    hl
  1789.     ld    a,(hl)        ;saved contents    of breakpoint address
  1790.     inc    hl
  1791.     ld    (de),a        ;replace rst 38    with actual data
  1792.     ld    a,(pcregl)    ;user pc - lo order
  1793.     xor    e
  1794.     ld    e,a        ;versus    breakpoint address in table
  1795.     ld    a,(pcregh)
  1796.     xor    d        ;check hi order
  1797.     or    e
  1798.     jr    nz,bphn20    ;no match - check next entry in    table
  1799.     ld    c,b        ;pc found in table set c reg nz
  1800. bphn20:    djnz    bphn10        ;restore all user data
  1801.     ld    hl,sbps        ;fetch number of step bps (0-2)
  1802.     ld    b,(hl)
  1803.     xor    a
  1804.     ld    (hl),a        ;clear regardless
  1805.     or    c        ;test bp found flag
  1806.     jp    z,bp???        ;z - bp    not in table
  1807.     inc    hl        ;point to bp count
  1808.     ld    d,(hl)        ;d - bp count
  1809.     dec    b
  1810.     jp    m,bphn30    ;m - this was user bp not step or jdbg
  1811.     ld    a,(hl)
  1812.     sub    b        ;subtract number of step bps from bp count
  1813.     ld    (hl),a        ;restore bp count
  1814.     ld    a,(lcmd)    ;what command got us here?
  1815.     cp    'S'        ;step?
  1816.     jr    z,bphn90    ;step command - check count
  1817.  
  1818.                 ;now we know we have jdbg in progress.  need
  1819.                 ;to check for user specified bp at the same 
  1820.                 ;address. if we find one stop trace. 
  1821.     ld    a,b        ;number of step bps to accumulator (1 or 2).
  1822.                 
  1823.     sub    c        ;compare number of step bps with the offset 
  1824.                 ;into the bp table where the current bp was
  1825.                 ;found.  since step bps are always at the end
  1826.                 ;of the table we can determine how bp was set.
  1827.  
  1828.      jp    nc,jdbg30    ;nc - we are at end of table so more tracing
  1829.  
  1830. bphn30:    ld    a,c
  1831.     neg
  1832.     add    a,d        ;create index into pass count table
  1833.     add    a,a
  1834.     ld    hl,psctbl    ;pass count table
  1835.     add    a,l
  1836.     ld    l,a
  1837.     jr    nc,bphn35
  1838.     inc    h
  1839. bphn35:    ld    e,(hl)
  1840.     inc    hl
  1841.     ld    d,(hl)        ;de - pass count
  1842.     ld    a,d
  1843.     or    e
  1844.     jr    z,bphn50    ;no count in effect 
  1845.     dec    de
  1846.     ld    (hl),d
  1847.     dec    hl
  1848.     ld    (hl),e        ;restored updated count
  1849.     ld    a,d
  1850.     or    e        ;did it    just go    zero?
  1851.     jr    z,bphn50    ;count just expired
  1852.     ld    a,b        ;pass count not zero - go or jdbg?
  1853.     and    a
  1854.     jp    p,jdbg30    ;if step flag p we had step bps
  1855.     ld    hl,(pcreg)
  1856.     jp    g100        ;continue go command
  1857. bphn50:    or    b        ;test if we had step bps
  1858.     jp    m,bphn60    ;this was go - print bp message
  1859.     ld    a,'X'
  1860.     ld    (lcmd),a    ;clear command letter so xreg disassembles
  1861.     call    home        ;home cursor
  1862.     call    xreg
  1863.     ld    b,22        ;cursor on penultimate line 
  1864.     ld    c,00
  1865.     call    xycp
  1866.         
  1867. bphn60:    ld    de,bpmsg    ;print *bp*
  1868.     call    print        ;print message pointed to by de
  1869.     ld    hl,(pcreg)
  1870.     call    outadr        ;display breakpoint address
  1871.     ex    de,hl
  1872.     call    fadr        ;attempt to find label at this address
  1873.     ex    de,hl        ;de - bp address
  1874.     jp    nz,z8e        ;nz - no label found
  1875.     ld    a,(maxlen)
  1876.     dec    a        
  1877.     ld    c,a        ;c - max size of label
  1878.     call    printb
  1879.     jp    z8e
  1880. bphn90:    call    xreg        ;display all registers
  1881.     ld    hl,(nstep)    ;fetch trace count
  1882.     dec    hl
  1883.     ld    a,l
  1884.     or    h                  
  1885.     jp    z,z8e        ;count expired - prompt    for command
  1886.     call    ttyq        ;test for abort    trace
  1887.     cp    cr
  1888.     jp    z,z8e
  1889.     call    crlf        ;
  1890.     jp    step40        ;continue trace
  1891.  
  1892.  
  1893. bp???:    ld    de,bpemsg
  1894.     call    print
  1895.     ld    hl,(pcreg)
  1896.     call    outadr
  1897.     jp    z8e
  1898.  
  1899.  
  1900. e???:    ex    de,hl
  1901.     ld    de,em???
  1902.     call    print
  1903.     ex    de,hl
  1904.     ret
  1905.     page
  1906. ;******************************************************************************
  1907. ;*
  1908. ;*    jdbg:    animated debugger
  1909. ;*        
  1910. ;*    Jdbg allows the user to watch the Z80 CPU actually execute the
  1911. ;*    code.  Jdbg displays 18 disassembled instructions on the screen
  1912. ;*    as well as a user defined memory block referred to in the 
  1913. ;*    comments as a window.
  1914. ;*
  1915. ;*    Entry point jdbg:
  1916. ;*    
  1917. ;*    Jdbg processes user input as a prelude to the actual animation
  1918. ;*    of the code.  The user enters the starting address to animate
  1919. ;*    optionally preceded by a subroutine qualifier.  The subroutine
  1920. ;*    qualifier may be either a "*" which instructs Z8E not to trace
  1921. ;*    any subroutines which are located below 100h (ie. bdos calls),
  1922. ;*    or it may be a "/" which means no tracing of any subroutines.
  1923. ;*    Jdbg will also paint the original screen with the register
  1924. ;*    contents as well as the memory window.  The contents of the 
  1925. ;*    memory window are also moved into argbuf so that we can compare
  1926. ;*    the 'old' contents with the 'new' contents once a the first bp
  1927. ;*    is reached.
  1928. ;*
  1929. ;*    Entry point jdbg30:
  1930. ;*
  1931. ;*     Entered here via bphn who determines that animation is in
  1932. ;*    effect.  In order to cut down on superfluous cursor move-
  1933. ;*    ment on the screen we compare the old register and memory
  1934. ;*    window contents with the new contents following the latest
  1935. ;*    bp.  We only output the changes.  Next we determine if the 
  1936. ;*    current pc exists in disassembled form somewhere on the 
  1937. ;*    screen; if not, we display 18 new disassembled instructions 
  1938. ;*    with the current pc as line one.
  1939. ;*
  1940. ;*    Exit jdbg95:
  1941. ;*
  1942. ;*    Save current register contents and jump to step40 for next
  1943. ;*    single step.
  1944. ;*
  1945. ;******************************************************************************
  1946.  
  1947. jdbg:
  1948.     call    iedtbc        ;get command line
  1949.     jp    p,jdbg02    ;p - have input
  1950.  
  1951. jdbg00:    ld    hl,lastro
  1952.     ld    b,(hl)        ;row position of arrow on screen
  1953.     ld    c,18        ;column
  1954.     call    xycp
  1955.     ld    c,2
  1956.     call    spaces
  1957.     ld    b,17h
  1958.     ld    c,00
  1959.     call    xycp
  1960.     ld    hl,jstepf
  1961.     ld    a,(hl)
  1962.     ld    (hl),1
  1963.     and    a
  1964.     jp    z,jdbg90    ;J was last means screen intact - just move
  1965.                 ;arrow, else fall thru and repaint screen.
  1966.                 ;Indicate single step
  1967. jdbg01:                ;+ eg 3.3.6
  1968.     ld    a,10
  1969.     jr    jdbg10        ;init timer    
  1970.  
  1971. jdbg02:    ld    a,(hl)        ;check first char of input
  1972.     cp    '#'        ;+ eg 3.3.6
  1973.     jr    nz,jdbg2a    ;+ Skip if not repaint request
  1974.     ld    hl,jstepf    ;+
  1975.     ld    (hl),1        ;+ Signal repaint request
  1976.     jr    jdbg01        ;+
  1977. jdbg2a:                ;+
  1978.     ex    de,hl        ;de - save input buffer    address
  1979.     ld    hl,wflag    ;wflag tells us    whether    to trace subroutines
  1980.                 ;or walk around    them
  1981.     ld    (hl),0ffh    ;conditionally assume trace all
  1982.     sub    '/'        ;slash means don't trace any
  1983.     jr    z,jdbg03    ;
  1984.     add    a,'/'-'*'    ;check for star    - no trace of bdos subs
  1985.     jr    nz,jdbg05
  1986.     inc    a        ;set flag one to indicate no trace of subs
  1987.                 ;at address < 100h (bdos calls)
  1988. jdbg03:    ld    (hl),a        ;set wflag
  1989.     xor    a        ;if slash or space replace with    null in    inbf
  1990.                 ;so parser will    ignore
  1991.     ld    (de),a
  1992. jdbg05:    call    iarg        ;now evaluate address
  1993.     jr    z,jdbg08    ;z - no error
  1994.     ld    a,(inbfnc)    ;check number of characters
  1995.     dec    a        ;check for just / or just *
  1996.     jr    z,jdbg00    ;treat as single step
  1997.     ld    (jstepf),a    ;indicate screen corrupted
  1998.     jp    e???        ;error -
  1999. jdbg08:    ld    (pcreg),hl    ;save address at which to start    tracing
  2000.     and    a        ;check delimter
  2001.     ld    a,10        ;no delimeter use default timer value
  2002.     jr    z,jdbg10
  2003.     call    iarg        ;check if user wants non-default timer
  2004.     ld    a,10
  2005.     jr    nz,jdbg10    ;error - use default
  2006.     ld    a,l        ;a - timer value as entered by user
  2007. jdbg10:    ld    (timer),a
  2008.     ld    b,24        ;xmit crlf's to clear screen
  2009. jdbg15:    call    crlf        ;clear screen
  2010.     djnz    jdbg15
  2011.     call    rgdisp        ;display current user regs
  2012.     call    zwnw        ;display disassembled window
  2013.     ld    a,(wnwsiz)
  2014.     and    a        ;test if window being displayed
  2015.     jr    z,jdbg28
  2016.     ld    de,window    ;save user specified memory block til next bp
  2017.     ld    hl,(wnwtab)    ;start of memory window address
  2018.     ld    bc,3
  2019. jdbg20: ld    a,(fwndow)    ;position cursor starting at column 
  2020.     sub    6
  2021.     call    curs
  2022.            call    outadr        ;display address of memory window
  2023. jdbg25:    ld    a,(fwndow)
  2024.     call    curs        ;column position on screen of memory window
  2025.                 ;is (rel pos * 3) + (fwndow)
  2026.     ld    a,(hl)        ;display this byte
  2027.  
  2028.     ld    (de),a        ;save this byte in window between bps
  2029.     call    outhex
  2030.     inc    b        ;move and display user specifed number 
  2031.                                 ;of bytes (wnwsiz)
  2032.     ld    a,(wnwsiz)
  2033.     sub    b
  2034.     jr    z,jdbg28
  2035.     inc    hl
  2036.     inc    de
  2037.     ld    a,(nlmask)    ;check for new line time
  2038.     and    b
  2039.     jr    nz,jdbg25    ;not end of line - display next byte else...
  2040.     jr    jdbg20        ;...display address first
  2041. jdbg28:    ld    a,3        ;point to very first instruction
  2042.     jp    jdbg75
  2043.  
  2044.  
  2045.                 ;breakpoint handler jumps here for full
  2046.                 ;screen single step
  2047. jdbg30:    ld      c,3 
  2048.     call    spaces        ;remove => from screen
  2049.     ld    b,c        ;(c=0 after spaces executes)
  2050.     ld    hl,regcon    ;new contents of registers following bp
  2051.     ld    de,regsav    ;old prior to bp       
  2052. jdbg35:    ld    a,(de)        ;compare old vs new
  2053.     cp    (hl)
  2054.     inc    hl
  2055.     inc    de
  2056.     jr    nz,jdbg40    ;different - display new
  2057.     ld    a,(de)        ;check hi order byte of this reg pair 
  2058.     cp    (hl)
  2059.     jr    z,jdbg45    ;z - hi and lo bytes the same so try next reg
  2060. jdbg40:
  2061. ;    ld    a,4        ;col position of reg pair is (rel pos * 9) + 3
  2062. ;    and    b
  2063. ;    jr    z,jdbg42
  2064. ;    ld    a,3
  2065. ;    and    b        ;- 9 bytes deleted here
  2066. ;    inc    a
  2067.     push    bc        ;+save register number
  2068.     ld    c,b        ;+move it to c while we build line number
  2069.     ld    b,0        ;+assume first line for now
  2070.     ld    a,7        ;+regs-per-line mask
  2071.     cp    c        ;+generate carry if second line
  2072.     rl    b        ;+shift carry into line number
  2073.     and    c        ;+generate line-relative register number
  2074.     ld    c,a        ;+col = reg * 9 + 3 if non-prime
  2075.     add    a,a        ;+ *2
  2076.     add    a,a        ;+ *4
  2077.     add    a,a        ;+ *8
  2078.     add    a,c        ;+ *9
  2079.     bit    2,c        ;+is it a prime (alternate) register?
  2080.     jr    z,jdbg42    ;+skip if not
  2081.     add    a,c        ;+*10
  2082.     sub    3        ;+col = reg * 10 if prime
  2083. jdbg42:
  2084.     add    a,3        ;+
  2085.     ld    c,a        ;+
  2086.     call    xycp        ;+
  2087.     pop    bc        ;+ added 29 bytes
  2088.  
  2089. ;    add    a,3        ;- deleted another 5 bytes here
  2090. ;    call    curs        ;- nett cost = 14 bytes for new code
  2091. ;                ;- but we save 19 bytes in 'curs:' routine
  2092.  
  2093.     ld    a,(hl)        ;display upper byte of reg contents
  2094.     call    outhex
  2095.     dec    hl        ;rewind to pick up lo order byte
  2096.     ld    a,(hl)
  2097.     inc    hl
  2098.     call    outhex        ;display lo order
  2099. jdbg45:    inc    hl
  2100.     inc    de
  2101.     inc    b
  2102.     ld    a,regsiz/2    ;number of reg pairs to display
  2103.     sub    b
  2104.     jr    nz,jdbg35            
  2105.     call    space
  2106.     ld    b,1
  2107.     ld    c,36
  2108.     call    xycp
  2109.     
  2110.     ld    b,0
  2111.     call    pswDsp        ;now display flag reg mnemonics
  2112.     
  2113.     ld    a,(wnwsiz)    ;check window size
  2114.     and    a
  2115.     jr    z,jdbg60    ;z - no memory window in effect
  2116.     ld    hl,(wnwtab)    ;hl - address of start of window
  2117.     ld    bc,03
  2118.     ld    de,window    ;old contents of window stored here 
  2119. jdbg50:    ld    a,(de)        ;compare old vs new
  2120.     cp    (hl)
  2121.     jr    z,jdbg55    ;same - no reason to display
  2122.     ld    a,(fwndow)    ;col position of byte is (rel pos * 3) + 50
  2123.     call    curs
  2124.     ld    a,(hl)        ;display byte
  2125.  
  2126.     ld    (de),a        ;we only need to move byte if it changed
  2127.  
  2128.     call    outhex
  2129. jdbg55:    inc    b        ;bump memory window byte count
  2130.     ld    a,(wnwsiz)      ;max size
  2131.     inc    hl
  2132.     inc    de
  2133.     sub    b
  2134.     jr    nz,jdbg50    ;loop until entire window examined
  2135.             
  2136. jdbg60:    ld    a,18        ;init count of disassembled instructions
  2137.     ld    (jlines),a
  2138.     ld    de,(zasmfl)    ;address of first disassembled instruction
  2139.                 ;on screen
  2140. jdbg65:    ld    hl,(pcreg)
  2141.     and    a
  2142.     sbc    hl,de
  2143.     jr    z,jdbg70    ;found - pc exists somewhere on screen
  2144.     call    zlen00        ;compute length    of this    instruction
  2145.     ld    b,0
  2146.     ex    de,hl        ;hl - address on disassembled instruction
  2147.     add    hl,bc        ;add length to compute address of next inline
  2148.                 ;instruction for display
  2149.     ex    de,hl        ;de - restore new istruction pointer
  2150.     ld    hl,jlines
  2151.     dec    (hl)        ;dec screen line count
  2152.     jr    nz,jdbg65
  2153.     ld    hl,(pcreg)    ;pc not    on screen - so current pc will be new
  2154.                 ;first pc on screen
  2155.     ld    (zasmfl),hl
  2156.     ld    bc,0300h    ;cursor    row 4 -    col 1
  2157.     call    xycp
  2158.     call    zwnw        ;instruction not on screen so paint a new
  2159.                 ;screen    starting at current pc
  2160.     ld    a,3        ;disassembled instructions start on line 4
  2161.     jr    jdbg75
  2162. jdbg70:    ld    a,(jlines)
  2163.     neg
  2164.     add    a,21        ;a - screen row    on which to position cursor
  2165. jdbg75:    ld    (lastro),a    ;save position of arrow
  2166.     ld    b,a        ;pass to xycp
  2167.     ld    c,18        ;pass column
  2168.     call    xycp        ;position cursor routine
  2169.     ld    de,mrrow
  2170.     call    print
  2171.     ld    a,(lastro)    ;xy positioning added after '=>' as
  2172.                 ;some systems have a destructive bs
  2173.     ld    c,17        ;new cursor loc
  2174.     call    xycp        ;put it there
  2175.     ld    a,(jstepf)
  2176.     dec    a        ;test if single stepping
  2177.     jp    z,jdbg95
  2178.     call    ttyq
  2179.     ld    hl,timer
  2180.     ld    b,(hl)
  2181.     jr    z,jdbg80
  2182.     cp    '0'
  2183.     jr    c,jdbg78
  2184.     cp    3ah
  2185.     jr    nc,jdbg95
  2186.     and    0fh
  2187.     ld    (hl),a
  2188.     ld    b,a
  2189.     jr    jdbg80
  2190. jdbg78:    cp    cr        ;carriage return ends command
  2191.     jr    z,jdbg95
  2192.         
  2193. jdbg80:    call    clok
  2194.  
  2195. jdbg90:    ld    de,regsav    ;move current reg contents to save area 
  2196.     ld    hl,regcon
  2197.     ld    bc,regsiz
  2198.     ldir
  2199.     jp    step40
  2200.  
  2201.  
  2202.                 ;user requested abort from console
  2203. jdbg95: ld    b,22        ;position cursor on line 23 for prompt
  2204.     ld    c,0
  2205.     call    xycp
  2206.     xor    a
  2207.     ld    (jstepf),a    ;indicate we have full screen of data
  2208.     jp    z8e        ;to z8e command processor 
  2209.  
  2210.  
  2211.  
  2212. zwnw:                ;display disassembly window
  2213.     ld    a,18        ;number of instructions to disassemble 
  2214. zwnw05:    ld    hl,(pcreg)
  2215.     ld    (zasmfl),hl    ;save pc of first line
  2216. zwnw10:    ld    (jlines),a
  2217.     ld    (zasmpc),hl    ;save here as well
  2218.     ld    de,zasmbf+96    ;disassemble in upper portion of buffer to
  2219.                 ;prevent overlap with big memory windows.
  2220.                 ;otherwise, every time we disassemble a new
  2221.                 ;screen we have to repaint the window.
  2222.  
  2223.     call    zasm10        ;disassemble first instruction
  2224.     ld    a,30        ;test line length
  2225.     cp    c
  2226.     jr    z,zwnw20
  2227.     ld    c,42
  2228. zwnw20:    call    printb
  2229.     call    crlf
  2230.     ld    hl,(zasmnx)    ;hl - next address to disassemble
  2231.     ld    a,(jlines)
  2232.     dec    a
  2233.     jr    nz,zwnw10
  2234.     ld    b,3        ;position cursor next to next instruction    
  2235.                 ;to execute which is the first one on the 
  2236.                 ;screen - line 4  col 20 
  2237.     ld    c,20
  2238.     call    xycp
  2239.     ret
  2240.  
  2241.  
  2242.                 ;display regs at top of screen:
  2243. rgdisp:    call    home        ;home cursor
  2244.     call    xreg        ;display regs
  2245.     call    pswDsp        ;display flag reg
  2246.     jp    crlf
  2247.  
  2248.  
  2249.  
  2250. curs:    push    bc        ;This routine has been simplified and shortened
  2251.     push    de        ;by 19 bytes because it is no longer used for
  2252.     push    hl        ;register display positioning.  jrs 20/4/87
  2253.     ld    d,a
  2254.     ld    e,c        ;save base row address
  2255. ;    cp    3        ;test if reg or memory window (3 is reg)
  2256. ;    ld    a,7
  2257. ;    jr    z,curs00    ;z - regs are eight per line (first line)
  2258.  
  2259.     ld    a,(nlmask)
  2260. curs00:    and    b        ;item number mod lnmask is the relative pos of
  2261.     ld    c,a        ;reg contents or memory data byte
  2262.     add    a,a        ;
  2263.     add    a,c
  2264.     ld    c,a        ;c - rel pos times three
  2265.  
  2266. ;    ld    a,d        ;if base column address is < 50 then this is
  2267.                 ;reg display
  2268. ;    sub    3
  2269. ;    ld    h,a
  2270. ;    ld    a,c
  2271. ;    jr    nz,curs20    ;nz - not reg display - must be memory
  2272. ;    add    a,a        ;so multiply times three again 
  2273. ;    add    a,c        ;times 9 in all for register display
  2274.  
  2275. curs20:    add    a,d        ;add in base
  2276.     ld    c,a        ;c - absolute col number
  2277. ;    xor    a        ;test if this is reg or memory window display
  2278. ;    or    h
  2279. ;    jr    z,curs30    ;z - this is register display
  2280.     ld    a,(fwndow)
  2281.     cp    68        ;14-char symbols in effect?
  2282.     jp    z,curs40
  2283. curs30:    srl    b
  2284. curs40:    ld    a,0fch
  2285.     and    b        ;now compute row number 
  2286.     rrca
  2287.     rrca
  2288.     add    a,e        ;base row address
  2289.     ld    b,a        ;b - absolute row number
  2290.     call    xycp        ;convert row and column to xy cursor address
  2291.     pop    hl
  2292.     pop    de
  2293.     pop    bc
  2294.     ret
  2295.  
  2296.  
  2297.  
  2298. clok:
  2299.     ld    d,50          ;idle loop - decrement to 0 and reload
  2300.     ld    e,00
  2301.     dec    b        ;user specified the loop counter
  2302.     ret    m
  2303. clok10:    dec    de
  2304.     ld    a,e
  2305.     or    d
  2306.     jr    nz,clok10
  2307.     jr    clok
  2308.  
  2309.     page
  2310. ;******************************************************************************
  2311. ;*
  2312. ;*    exam:    examine    memory and display in hex and ascii.  user is allowed
  2313. ;*        to modify memory after every byte is displayed.    ilin called
  2314. ;*        to parse input buffer into a single string of bytes which is
  2315. ;*        returned in argbuf.  the byte count of the string is returned
  2316. ;*        in argbc, and this number of bytes is transferred to the
  2317. ;*        current    memory address.
  2318. ;*
  2319. ;*        user may optionally scan memory    by entering cr.     command
  2320. ;*        terminates when    a single space is entered.
  2321. ;*
  2322. ;*        enter:    b - 0
  2323. ;*               de - address at which to    display    first byte
  2324. ;*
  2325. ;******************************************************************************
  2326.  
  2327. exam:    call    ilin
  2328.     jp    nz,e???
  2329.     ex    de,hl    
  2330. exam00:    call    newlin
  2331.     ld    a,(de)        ;fetch byte to display regardless
  2332.     call    outbyt
  2333.     call    byte
  2334.     jr    nz,exam00     ;nz - don't replace memory contents
  2335.     cp    '.'
  2336.     jr    nz,exam10
  2337.     ld    a,(inbfnc)
  2338.     dec    a
  2339.     ret    z
  2340. exam10:    ld    hl,argbc    ;byte count to c
  2341.     ld    c,(hl)
  2342.     ld    b,0
  2343.     ld    (exampt),de
  2344.     ld    hl,argbf    ;start of evaluated input
  2345.     ldir
  2346.     ld    a,(trmntr)
  2347.     cp    cr
  2348.     jr    z,exam00
  2349.     ld    de,(exampt)
  2350.     jr    exam00
  2351.     page
  2352. ;------------------------------------------------------------------------------
  2353. ;
  2354. ;    hsym:    display symbol table
  2355. ;
  2356. ;    User may display the symbol table on the console.  If no arg
  2357. ;    entered on command line then the entire table is dumped start-
  2358. ;    ing with the first symbol.  If a valid symbol is entered then
  2359. ;    we will try to find the symbol in the table; if found, the 
  2360. ;    table is dumped starting at that point.  If the symbol is not
  2361. ;    found the user gets a ? and the command terminates.
  2362. ;
  2363. ;    Symbols are displayed in blocks of 32.  After each block the 
  2364. ;    user is given the opportunity of continuing or ending the 
  2365. ;    command:
  2366. ;
  2367. ;        cr - Terminate            \  jrs 27 Dec 88
  2368. ;        not cr - Display next block        /  v 3.5.1
  2369. ;
  2370. ;------------------------------------------------------------------------------
  2371.  
  2372. hsym:    call    ilin        ;Read in line of data
  2373.     ld    hl,z8e        ;Assume no symbol entered
  2374.     jr    nz,hsym10    ;NZ - no input means display entire table
  2375.     ld    de,prsbf    
  2376.     call    fsym        ;Attempt to find this symbol name in table
  2377.     jp    nz,e???        ;Error - symbol    not found in symbol table
  2378.     ld    a,(maxlen)
  2379.     or    l        ;Point to next symbol table entry (next block)
  2380.     ld    l,a        ;HL - ptr to last byte in this entry 
  2381.     inc    hl        ;Now next entry toward hi memory
  2382. hsym10:    ld    a,(maxlen)    ;Max size of symbol name
  2383.     ld    c,a
  2384.     dec    c
  2385.     inc    a        ;Make 8 or 16
  2386.     ld    e,a
  2387.     xor    a
  2388.     ld    d,a        ;DE - size of symbol table entry
  2389.     sbc    hl,de        ;Previous entry toward low memory
  2390.     ld    a,(hl)        ;Null means this is unused slot is user 
  2391.                 ;defined symbol table
  2392.     and    a
  2393.     jr    z,hsym10
  2394.     dec    a        ;Neg means this is jp opcode (0c3h) of jump to
  2395.                 ;BDOS
  2396.     ret    m
  2397.     ld    a,(maxlen)
  2398.     srl    a
  2399.     srl    a
  2400.     xor    2
  2401.     and    b        ;Check symbols per line count
  2402.     call    z,crlf        ;crlf every fourth
  2403.     dec    b        ;Now decrement symbols per line count
  2404.     call    printb        ;Treat symbol table entry as a buffer and 
  2405.                 ;Six chars or until null, whichever is first
  2406.     inc    c        ;Tack on two spaces
  2407.     inc    c
  2408.     call    spaces
  2409.     ld    a,(maxlen)
  2410.     or    l        ;Point to last byte in symbol table block
  2411.     ld    l,a
  2412.     ld    d,(hl)        ;Upper byte of symbol address
  2413.     dec    hl
  2414.     ld    e,(hl)        ;Low order
  2415.     ex    de,hl
  2416.     call    outadr        ;HL - symbol address to display
  2417.     ld    c,4
  2418.     call    spaces        ;Next symbol name starts 4 spaces to the right
  2419.     ex    de,hl        ;HL - symbol table pointer
  2420.     ld    a,(maxlen)
  2421.     cpl
  2422.     and    l        ;Rewind to point to byte zero of entry
  2423.     ld    l,a
  2424.     ld    a,b
  2425.     and    31        ;Displayed block of 32 symbols?
  2426.     jr    nz,hsym10
  2427.     call    crlf
  2428.     call    ttyi        ;Test if user wants abort
  2429.     cp    cr
  2430.     jr    nz,hsym10    ;Not CR - continue (jrs v3.5.1)
  2431.     ret            ;CR - end command
  2432.     page
  2433. ;*****************************************************************************
  2434. ;*
  2435. ;*    usym:   write symbol table to disk
  2436. ;*
  2437. ;*****************************************************************************
  2438.  
  2439. usym:    call    iedtbc        ;get a command line 
  2440.     ret    m        ;no input ends command
  2441.     call    bldf        ;build fcb
  2442.     jp    nz,esntx    ;syntax error
  2443.     ld    hl,z8e        ;start at beginning
  2444.     ld    a,(symflg)    ;do we even have a symbol table?
  2445.     and    a
  2446.     ret    nz        ;no table - end command
  2447.     ld    b,128        ;disk write buffer size
  2448.     ld    (lines),a    ;clear symbols per line counter
  2449.     ld    de,symbuf
  2450. usym10:    ld    a,(maxlen)
  2451.     ld    c,a        ;max size of symbol name
  2452.     cpl
  2453.     and    l        ;rewind to byte zero of symbol table entry
  2454.     ld    l,a
  2455.     ld    a,b        ;temp save buffer count
  2456.     ld    b,0
  2457.     sbc    hl,bc
  2458.     dec    hl        ;point to 8 or 16 byte boundary
  2459.     ld    b,a        ;restore buffer count    
  2460.  
  2461.     ld    a,(hl)        ;null means this is unused slot in user 
  2462.                 ;defined symbol table
  2463.     and    a
  2464.     jr    z,usym10
  2465.     dec    a        ;neg means this is jp opcode (0c3h) of jump to
  2466.                 ;bdos
  2467.     jp    p,usym20
  2468.     call    pcrlf        ;hit end of table - put crlf in buffer
  2469.     ld    a,eof
  2470.     ld    b,1        ;force buffer write
  2471.     call    putc        ;put eof in file
  2472.     jp    closef        ;this is a wrap
  2473.  
  2474. usym20:    ld    a,(maxlen)    
  2475.     or    l
  2476.     ld    l,a        ;point to hi order byte of symbol address
  2477.     call    pbin        ;put address in buffer
  2478.     ld    a,' '
  2479.     call    putc        ;followed by space just like l80
  2480.     ld    a,(maxlen)
  2481.     cpl
  2482.     and    l        ;rewind to byte zero of symbol entry
  2483.     ld    l,a
  2484.  
  2485.     dec    c        ;14 Sep 85   restore maxlen size as count
  2486.     
  2487. usym25:    ld    a,(hl)        ;fetch char of symbol name
  2488.     and    a        ;null?
  2489.     jr    z,usym40    ;name is less than 6 chars long
  2490.     call    putc        ;put valid symbol name chars in buffer
  2491.     dec    c
  2492.     jr    z,usym40    ;z - just moved last char    
  2493.     inc    hl
  2494.     jr    usym25
  2495. usym40:    ld    a,tab        ;tab separates name and next address
  2496.     call    putc        ;insert tab before address field
  2497.     ld    a,(lines)
  2498.     dec    a
  2499.     ld    (lines),a
  2500.     and    3        ;insert crlf every fourth symbol
  2501.     jr    nz,usym10
  2502.     call    pcrlf
  2503.     jr    usym10
  2504.  
  2505.  
  2506.  
  2507. pcrlf:    ld    a,cr
  2508.     call    putc
  2509.     ld    a,lf
  2510.     jr    putc
  2511.  
  2512.  
  2513.                 ;convert two byte binary address to ascii
  2514.                 ;and put into buffer
  2515. pbin:    call    pbin00
  2516.     dec    hl
  2517. pbin00:    ld    a,(hl)
  2518.     call    binx            
  2519.     call    putc
  2520.     ld    a,(hl)
  2521.     call    binx00
  2522.  
  2523.  
  2524. putc:    ld    (de),a        ;just like pascal - put char into buffer
  2525.     inc    de
  2526.     dec    b        ;buffer count passed in b 
  2527.     ret    nz
  2528. putc00:    ld    de,symbuf    ;hit end of buffer - reinit pointer to start
  2529.     call    bwrite        ;write current buffer [ras 14 sep 85]
  2530.     ld    b,128        ;reinit tally
  2531.     ret
  2532.     page
  2533.  
  2534. ;------------------------------------------------------------------------------
  2535. ;
  2536. ;    dump:  Dump memory in hex and ASCII
  2537. ;
  2538. ;    Memory is dumped in hex    and ASCII in user-specified block size.
  2539. ;    If the D command is given without arguments then memory    is dumped
  2540. ;    beginning at the address where we left off as store in blkptr.
  2541. ;    User is    queried    after each block is dumped:
  2542. ;
  2543. ;        cr - End command            \  v 3.5.1
  2544. ;        Not    cr - Dump next consecutive block    /  jrs 27 Dec 88
  2545. ;
  2546. ;------------------------------------------------------------------------------
  2547.  
  2548. dump:    call    iedtbc        ;Solicit input
  2549.     jp    p,dump00    ;p - input present
  2550.     ld    de,(bsiz)    ;No input means    use previous block size
  2551.     ld    hl,(blkptr)    ;   ...    and address
  2552.     jr    dump30
  2553. dump00:    call    iarg        ;Read in next arg (starting address)
  2554.     jp    nz,e???        ;Invalid starting address
  2555.     ex    de,hl        ;DE - starting address to dump
  2556.     call    iarg        ;Next arg (block size)
  2557.     jr    z,dump15    ;Z - no    errors
  2558.     ld    hl,000        ;Default to block size of 256
  2559.     jr    dump20
  2560. dump15:    xor    a
  2561.     or    h        ;Test for block    size or    ending address
  2562.     jr    z,dump20    ;Less than 256 must be block size
  2563.     sbc    hl,de        ;Compute size
  2564.     jp    c,e???
  2565. dump20:    ld    a,l
  2566.     or    h
  2567.     jr    nz,dump25
  2568.     inc    h
  2569. dump25:    ld    (bsiz),hl
  2570.     ex    de,hl        ;DE - block size   HL -    memory pointer
  2571. dump30:    ld    b,16        ;Init bytes-per-line count
  2572.     call    ttyq
  2573.     cp    cr
  2574.     ret    z
  2575.     call    crlf        ;Display current address on new line
  2576.     call    outadr
  2577.     ld    c,2
  2578.     call    spaces        ;Hex display starts two    spaces right
  2579. dump40:    dec    b        ;Decrement column count
  2580.     ld    a,(hl)
  2581.     inc    hl
  2582.     call    othxsp        ;Display memory    in hex
  2583.     inc    c        ;Tally of hex bytes displayed
  2584.     dec    de        ;Decrement block count
  2585.     ld    a,d
  2586.     or    e        ;Test for end of block
  2587.     jr    z,dump50    ;Z - end of block
  2588.     xor    a
  2589.     or    b        ;End of    line?
  2590.     jr    nz,dump40    ;Not end of line - dump    more in    hex
  2591.     jr    dump60
  2592. dump50:    ld    a,(bsizhi)
  2593.     and    a        ;Block size greater than 256?
  2594.     jr    nz,dump55    ;NZ - greater
  2595.     ld    a,(bsizlo)
  2596.     and    0f0h        ;Block size less than 16?
  2597.     jr    z,dump60    ;Z - less
  2598. dump55:    ld    a,(bsizlo)
  2599.     and    0fh        ;Block size multiple of    16?
  2600.     jr    z,dump60    ;Multiple of 16
  2601.     neg
  2602.     add    a,16
  2603.     ld    b,a
  2604.     add    a,a
  2605.     add    a,b
  2606. dump60:    add    a,3        ;Plus three - begin ASCII display
  2607.     ld    b,a        ;Pad line until    ASCII display area
  2608. dump70:    call    space
  2609.     djnz    dump70
  2610.     sbc    hl,bc        ;Rewind    memory point by    like amount
  2611. dump80:    ld    a,(hl)        ;Start ASCII display
  2612.     inc    hl
  2613.     call    asci
  2614.     dec    c
  2615.     jr    nz,dump80
  2616.     call    ttyq        ;CR aborts command
  2617.     cp    cr
  2618.     jp    z,z8e
  2619.     ld    a,d        ;Test for block    size tally expired
  2620.     or    e
  2621.     jr    nz,dump30
  2622.     ld    de,(bsiz)    ;Reinit    block size
  2623.     call    ttyi        ;Query user for    more
  2624.     cp    cr
  2625. ; Next two lines replaced by inverted test - 27 Dec 88 - jrs - V 3.5.1
  2626. ;    call    z,crlf
  2627. ;    jr    z,dump30    ;not cr    - next block
  2628. ;----                (Comment on last line is wrong anyway!)
  2629.     call    nz,crlf        ;Not cr - next block
  2630.     jr    nz,dump30
  2631. ;----
  2632.     ld    (blkptr),hl
  2633.     ret            ;end command
  2634.     page
  2635. ;******************************************************************************
  2636. ;*
  2637. ;*    rgst:  display and optionally modify individual    registers
  2638. ;*
  2639. ;*    call iedt:   read edited input into inbf
  2640. ;*    call prsr:   parse input
  2641. ;*    call mreg:   validate register name and    map into reg storage
  2642. ;*    call iarg:   query user    for replacement
  2643. ;*
  2644. ;******************************************************************************
  2645.  
  2646. rgst:    ld    c,' '        ;get edited input
  2647.     ld    b,inbfsz
  2648.     call    iedt
  2649.     ret    m
  2650.     ld    a,(trmntr)
  2651.     cp    ' '
  2652.     call    z,bksp
  2653.     call    prsr
  2654.     or    b        ;unbalanced quotes (prime reg?)
  2655.     jp    p,rgst00
  2656.     and    7fh
  2657.     cp    3
  2658.     jr    nz,rgst25
  2659.     dec    hl
  2660.     ld    a,(hl)
  2661.     sub    quote
  2662.     jr    nz,rgst25
  2663.     ld    (hl),a
  2664. rgst00:    ld    a,(inbfnc)    ;number    of characters in buffer
  2665.     cp    4
  2666.     jr    nc,rgst25    ;error - too many chars
  2667.     neg
  2668.     add    a,4        ;calculate space padding
  2669.     ld    c,a
  2670.     cp    3        ;was it    one?
  2671.     jr    nz,rgst10
  2672.     ld    a,(de)
  2673.     call    ixlt
  2674.     cp    'P'
  2675.     jr    nz,rgst10
  2676.     ld    (inbfnc),a    ;any number > 2    indicates 16 bit register
  2677. rgst10:    call    spaces
  2678.     ld    a,(hl)        ;check last char in parse buffer
  2679.     sub    quote
  2680.     jr    nz,rgst15    ;not quote
  2681.     ld    (hl),a        ;replace with null
  2682. rgst15:    call    mreg        ;validate register name
  2683.     jr    nz,rgst25    ;error
  2684.     ld    a,(regtrm)    ;mreg stored char following reg    name
  2685.     and    a
  2686.     jr    nz,rgst25    ;error - no operators allowed
  2687.     ld    a,(inbfnc)    ;now check number of chars in buffer
  2688.     ld    b,a        ;save in b reg for 8 or    16 bit reg test
  2689.     dec    a        ;test for one -    8 bit reg
  2690.     ld    c,3
  2691.     jr    z,rgst20
  2692.     ld    a,(hl)
  2693.     call    outhex        ;display byte of reg contents
  2694.     dec    hl
  2695.     ld    c,1
  2696. rgst20:    ld    a,(hl)
  2697.     call    othxsp
  2698.     call    spaces        ;reg c - number    of spaces to print
  2699.     ex    de,hl        ;de - save reg contents    pointer
  2700. rgst22:    call    istr        ;query user for    reg value replacement
  2701.     ld    a,(inbfnc)    ;test number of    chars in input buffer
  2702.     dec    a        ;
  2703.     jp    m,rgst40    ;none -    prompt for next    reg name
  2704.     call    irsm
  2705.     jr    z,rgst30
  2706.     ld    a,(inbfnc)
  2707.     and    a
  2708.     jr    z,rgst22
  2709. rgst25:    call    e???
  2710.     jr    rgst40        ;accept    new reg    name
  2711. rgst30:    ex    de,hl
  2712.     ld    (hl),e
  2713.     dec    b        ;test for 16 bit reg
  2714.     jr    z,rgst40    ;z - 8 bit reg
  2715.     inc    hl
  2716.     ld    (hl),d        ;save upper byte of user input
  2717. rgst40:    call    crlf
  2718.     call    space5
  2719.     jp    rgst
  2720.  
  2721.  
  2722.  
  2723. mreg:    ld    c,23        ;number    of reserved operands
  2724.     call    oprn00        ;check validity    of register name
  2725.     ld    a,(de)        ;last char examined by operand routine
  2726.     call    oprtor
  2727.     ret    nz        ;error - not null or valid operator
  2728.     ld    (regtrm),a    ;save terminator character for rgst
  2729.     ld    a,c
  2730.     cp    17        ;valid reg names are less than 17
  2731.     jr    c,mreg00    ;so far    so good
  2732.     sub    23        ;last chance - may be pc
  2733.     ret    nz        ;error - invalid reg name
  2734.     ld    a,10        ;make pc look like p for mapping
  2735. mreg00:    ld    hl,regmap    ;ptrs to register contents storage
  2736.     add    a,l        ;index into table by operand value
  2737.     ld    l,a
  2738.     jr    nc,mreg05
  2739.     inc    h
  2740. mreg05:    ld    a,b        ;b reg set m by    prsr if    trailing quote
  2741.     and    a
  2742.     ld    a,0        ;assume    no quote - not prime reg
  2743.     jp    p,mreg10    ;p - correct assumption
  2744.     ld    a,8        ;bias pointer for prime    reg contents
  2745. mreg10:    add    a,(hl)
  2746.     ld    c,a        ;save mapping byte
  2747.     and    7fh        ;strip sign
  2748.                 ;so iarg knows 16 bit reg pair
  2749.     ld    hl,regcon    ;use mapping byte to build pointer
  2750.     add    a,l
  2751.     ld    l,a
  2752.     jr    nc,mreg50
  2753.     inc    h
  2754. mreg50:    xor    a        ;hl - pointer to register contents
  2755.     ret
  2756.  
  2757.     page
  2758. ;******************************************************************************
  2759. ;*
  2760. ;*    qprt:    read and display / write to i/o    ports
  2761. ;*
  2762. ;*        contents of ports are displayed    and the    user is    queried
  2763. ;*        input character    effects    the current port address:
  2764. ;*
  2765. ;*        space -    display    next sequential    port on    same line
  2766. ;*        lf    -    display    next sequential    port on    new line
  2767. ;*        cr    -    end command
  2768. ;*        slash -    display    same port on same line
  2769. ;*        ^     -    display    previous port on new line
  2770. ;*
  2771. ;*        any other input    is treated as a    replacement byte and
  2772. ;*        is output to the current port address.    any of the
  2773. ;*        above characters may be    used to    continue the display.
  2774. ;*
  2775. ;*        enter: e  - port at which to begin display
  2776. ;*
  2777. ;******************************************************************************
  2778.  
  2779. qprt:
  2780. nprt:
  2781.     xor    a
  2782.     ld    (parenf),a
  2783.       call    iedtbc        ;get port specified by user
  2784.     ld    hl,port
  2785.     ld    e,(hl)
  2786.     jp    m,qprt30    ;m - no input means use last port number
  2787.     ex    de,hl
  2788.         call    iarg        ;extract address
  2789.     jp    nz,e???
  2790.     ex    de,hl         ;e - new port number
  2791.     ld    (hl),e
  2792.     ld    a,(parenf)
  2793.     cp    '('
  2794.     jr    nz,qprt30
  2795.     ld    c,2
  2796.     call    spaces
  2797. qprt00:    ld    c,e
  2798.     in    a,(c)
  2799.     ld    b,a
  2800.     call    outhex
  2801.     ld    c,2
  2802.     call    spaces
  2803.     ld    c,8        ;number of bits to display
  2804. qprt10:    sla    b        ;most significant bit to carry
  2805.     ld    a,'0'        
  2806.     adc    a,0        ;carry makes it a 1
  2807.     call    ttyo
  2808.     dec    c
  2809.     jr    nz,qprt10
  2810.     ld    c,e
  2811.     ld    b,3
  2812.     call    ttyq
  2813.     cp    cr
  2814.     ret    z
  2815.     call    clok        ;so we don't go faster than the terminal
  2816.     ld    e,c
  2817.     ld    a,b
  2818.     and    a
  2819.     ret    p
  2820.     ld    b,12
  2821. qprt20:    call    bksp
  2822.     djnz    qprt20
  2823.     jr    qprt00
  2824. qprt30:    call    crlf
  2825.     ld    a,e
  2826.     ld    (port),a
  2827.     call    othxsp
  2828.     call    space
  2829.     ld    c,e
  2830.     ld    a,(lcmd)
  2831.     cp    'N' 
  2832.     jr    z,qprt50
  2833.            in    a,(c)    
  2834.     call    outbyt        
  2835. qprt50:    call    byte
  2836.     ld    a,(trmntr)
  2837.     jr    nz,qprt60
  2838.     cp    '.'
  2839.     ret    z
  2840.     ld    hl,argbc
  2841.     ld    b,(hl)
  2842.     ld    hl,argbf
  2843.     ld    c,e        ;port number
  2844.     otir
  2845.     jr    qprt30    
  2846. qprt60:    cp    ' '
  2847.     jr    nz,qprt30
  2848.     dec    de
  2849.     jr    qprt30
  2850.  
  2851.  
  2852.     page
  2853. ;******************************************************************************
  2854. ;*
  2855. ;*    break:    set breakpoint routine
  2856. ;*
  2857. ;*    breakpoint address storage table (brktbl) is examined and user
  2858. ;*    specified breakpoint is    considered valid unless:
  2859. ;*
  2860. ;*             - table full
  2861. ;*             - address already exists in table
  2862. ;*
  2863. ;*    optional pass counts can be specified by the user immediatley following
  2864. ;*    the breakpoint if they are enclosed in parens.
  2865. ;*
  2866. ;*    entry point brk30:
  2867. ;*          entered from single step command to set breakpoint.  two table
  2868. ;*          slots are    permanently available for step breakpoints. step
  2869. ;*          routine calls with c pos to tell us not to look for more args
  2870. ;*          in the input buffer.
  2871. ;*
  2872. ;******************************************************************************
  2873.  
  2874. break:    call    iedtbc
  2875.     ret    m        ;end command - no input
  2876.     ld    c,0ffh        ;set neg - distinguish ourselves from step
  2877. brk10:    ld    a,(bps)        ;fetch current bp count
  2878.     cp    maxbp        ;table full
  2879.     jp    nc,e???        ;full -    abort command
  2880.     ld    b,a        ;save current count
  2881.     call    iarg
  2882.     jp    nz,e???
  2883.     ex    de,hl        ;de - breakpoint address to set
  2884. brk30:    ld    hl,brktbl
  2885.     xor    a
  2886.     or    b        ;check for no breakpoints in effect
  2887.     jr    z,brk60        ;none -    bypass check for duplicate
  2888. brk40:    ld    a,e
  2889.     cp    (hl)        ;check lo order    address    match
  2890.     inc    hl
  2891.     jr    nz,brk50    ;no match - check next
  2892.     ld    a,d
  2893.     sub    (hl)        ;check hi order
  2894.     jr    nz,brk50    ;no match - check next
  2895.     or    c
  2896.     ret    p
  2897.     ld    hl,bps        ;pointer to bp count
  2898.     ld    a,(hl)
  2899.     sub    b        ;create    index into psctbl
  2900.     jr    brk70
  2901. brk50:    inc    hl
  2902.     inc    hl        ;bump past contents storage byte
  2903.     djnz    brk40
  2904. brk60:    ld    (hl),e        ;set in    table
  2905.     inc    hl
  2906.     ld    (hl),d
  2907.     ld    hl,bps        ;breakpoint count
  2908.     ld    a,(hl)        ;fetch current count for user as index
  2909.     inc    (hl)        ;bump bp count
  2910. brk70:    ld    de,psctbl    ;base of pass count table
  2911.     add    a,a        ;two byte table
  2912.     add    a,e
  2913.     ld    e,a
  2914.     jr    nc,brk80
  2915.     inc    d
  2916. brk80:    xor    a
  2917.     ld    (de),a        ;pre-clear pass    count table entry
  2918.     inc    de
  2919.     ld    (de),a
  2920.     or    c        ;test if this was step calling
  2921.     ret    p        ;i'm positive it was
  2922.     ld    a,(delim)    ;check delimeter which followed    bp address
  2923.     and    a
  2924.     ret    z        ;end of    line null - terminate command
  2925.     cp    ','        ;check for pass    count delimeter
  2926.     jp    nz,brk10    ;not comma means treatt    this as    new bp
  2927.     call    iarg        ;get next arg
  2928.     jp    nz,e???        ;nz - evaluation error
  2929.     ex    de,hl        ;de - pass count as entered by user
  2930.     ld    (hl),d        ;store pass count in table
  2931.     dec    hl
  2932.     ld    (hl),e
  2933.     and    a        ;check delimeter
  2934.     jp    nz,brk10    ;nz - more arguments follow
  2935.     ret            ;end of    line null - terminate command
  2936.     page
  2937.  
  2938. ;******************************************************************************
  2939. ;*
  2940. ;*    cbreak:    clear breakpoint 
  2941. ;*
  2942. ;*    breakpoint address storage table (brktbl) is examined and breakpoint
  2943. ;*    is removed if found. breakpoint    is removed by bubbling up all bp
  2944. ;*    addresses which    follow,    ditto for pass counts.
  2945. ;*
  2946. ;******************************************************************************
  2947.  
  2948. cbreak:    call    iedtbc
  2949.     ret    m        ;no input ends command
  2950.     ld    a,(bps)        ;fetch breakpoint count
  2951.     or    a        ;any if    effect
  2952.     ret    z        ;no
  2953.     ld    b,a        ;temp save count
  2954.     call    iarg        ;extract address to clear from input buffer
  2955.     ld    de,brktbl    ;bp address storage table
  2956.     jr    z,cbrk10
  2957.     ld    a,(prsbf)
  2958.     cp    '*'
  2959.     jp    nz,e???
  2960.     ld    a,(inbfnc)
  2961.     dec    a
  2962.     jp    nz,e???
  2963.     ld    (bps),a
  2964.     ret
  2965.  
  2966. cbrk10:    ld    a,(de)        ;test lo order address for match
  2967.     cp    l
  2968.     inc    de
  2969.     jr    nz,cbrk20    ;no match - examine next entry
  2970.     ld    a,(de)
  2971.     cp    h        ;versus    hi order bp address
  2972. cbrk20:    inc    de
  2973.     inc    de        ;bump past contents save location
  2974.     jr    z,cbrk30    ;zero -    found bp in table
  2975.     djnz    cbrk10
  2976.     jp    e???        ;error - breakpoint not    found
  2977. cbrk30:    ld    h,0ffh        ;rewind    to point to bp address
  2978.     ld    l,-3
  2979.     add    hl,de
  2980.     ex    de,hl        ;de - ptr to bp      hl - ptr to next bp
  2981.     ld    a,b        ;multiply number of bps    remaining in table
  2982.                 ;times three bytes per entry
  2983.     add    a,a
  2984.     add    a,b
  2985.     ld    c,a        ;init c    for ldir
  2986.     ld    a,b        ;save number of    bps remaining
  2987.     ld    b,0
  2988.     ldir            ;bubble    up all remaining entries in table
  2989.     ld    c,a        ;
  2990.     ld    hl,bps        ;address of bp count
  2991.     ld    a,(hl)        ;
  2992.     dec    (hl)        ;decrement system breakpoint count
  2993.     sub    c        ;compute relative number of pass count table
  2994.                 ;entry we wish to clear
  2995.     add    a,a        ;times two bytes per entry
  2996.     ld    l,a
  2997.     ld    h,b        ;cheap clear
  2998.     ld    de,psctbl
  2999.     add    hl,de        ;index into pass count table
  3000.     ex    de,hl
  3001.     ld    hl,02
  3002.     add    hl,de        ;de - ptr to pass count     hl - next in table
  3003.     sla    c        ;number    of pass    counts to move
  3004.     ldir
  3005.     ld    a,(delim)    ;recheck delimeter
  3006.     and    a
  3007.     jr    nz,cbreak    ;not end of line terminator - clear more
  3008.     ret
  3009.     page
  3010. ;***********************************************************************
  3011. ;*
  3012. ;*     obreak:    output all breakpoints and associated pass counts to
  3013. ;*        console.  search symbol    table for match, if symbol name
  3014. ;*        found display it along with address.
  3015. ;*
  3016. ;*     wbreak:    wipe out (clear) all breakpoints currently in effect
  3017. ;*
  3018. ;*        entered:  b - zero
  3019. ;*
  3020. ;***********************************************************************
  3021.  
  3022. obreak:    ld    a,(bps)        ;fetch bp count
  3023.     dec    a        ;test for no breakpoints
  3024.     ret    m        ;m - none
  3025.     ld    b,a        ;save count
  3026. obrk00:    ld    hl,brktbl    ;base of breakpoint storage table
  3027.     ld    e,b        ;use current breakpoint    count as index
  3028.     ld    d,0        ;clear
  3029.     add    hl,de        ;this is a three byte table
  3030.     add    hl,de
  3031.     add    hl,de
  3032.     ld    e,(hl)        ;fetch lo order    bp address
  3033.     inc    hl
  3034.     ld    d,(hl)        ;upper address
  3035.     ex    de,hl
  3036.     call    outadr        ;display address
  3037.     ex    de,hl        ;hl - breakpoint table
  3038.     call    fadr        ;check symbol table for    name match
  3039.                 ;   symbol table pointer returned in de
  3040.                 ;   zero flag set if found
  3041.     ld    a,(maxlen)
  3042.     ld    c,a
  3043.     dec    bc        ;max number of chars in    a symbol name
  3044.     ex    de,hl        ;hl - symbol table address if
  3045.     call    z,printb    ;display name if found in symbol table
  3046.     ld    a,b
  3047.     add    a,a        ;bp number times two
  3048.     ld    hl,psctbl    ;base of pass count table
  3049.     add    a,l
  3050.     ld    l,a
  3051.     jr    nc,obrk10
  3052.     inc    h
  3053. obrk10:    ld    e,(hl)        ;lo order pass count
  3054.     inc    hl
  3055.     ld    d,(hl)        ;upper byte
  3056.     ld    a,d        ;test if pass count in effect
  3057.     or    e
  3058.     jr    z,obrk20    ;z - no    pass count for this bp
  3059.     inc    c
  3060.     call    spaces
  3061.     ex    de,hl
  3062.     call    outadr        ;display pass count in hex
  3063. obrk20:    call    crlf
  3064.     ld    c,5
  3065.     call    spaces
  3066.     dec    b        ;dec bp    count
  3067.     jp    p,obrk00
  3068.     ret
  3069.  
  3070.  
  3071.  
  3072. kdmp:    call    iedtbc        ;let user input address of memory to display
  3073.     ret    m        ;no input ends command
  3074.     call    iarg        ;evaluate user arg        
  3075.     jp    nz,e???
  3076.     ex    de,hl        ;de - save memory address
  3077.     call    iarg        ;now get count
  3078.     ld    a,0
  3079.     jr    nz,kdmp20    ;error during input - display 00 bytes
  3080.     or    h
  3081.     jp    nz,e???        ;greater than 256 is error
  3082.     ld    a,(maxlen)    ;max symbol length
  3083.     ld    b,2        ;assume big names
  3084.     cp    15        
  3085.     ld    a,18        ;number of disassembled lines displayed
  3086.     jr    z,kdmp00
  3087.     ld    b,3        ;double number of lines one extra time
  3088. kdmp00:    add    a,a        ;times two
  3089.     djnz    kdmp00
  3090.     cp    l
  3091.     jr    c,kdmp20    ;if number of bytes specified by user is too
  3092.                 ;large then use default
  3093.     ld    a,l        ;use value specified by user
  3094. kdmp20:    ld    (wnwtab),de
  3095.     ld    (wnwsiz),a
  3096.     ret
  3097.     page
  3098. ;**************************************************************************
  3099. ;*
  3100. ;*             begin/resume execution of user program
  3101. ;*
  3102. ;*    address    entered:     execution begins at entered address
  3103. ;*    no address entered:  execution resumed at specified by saved pc
  3104. ;*
  3105. ;*    breakpoint table examined:
  3106. ;*          -    memory contents    from each address is removed from user
  3107. ;*        program    and saved in breakpoint    table
  3108. ;*          -    rst 38 instruction is placed at    each breakpoint    address
  3109. ;*        in user    program
  3110. ;*
  3111. ;*    user registers restored
  3112. ;*
  3113. ;***************************************************************************
  3114.  
  3115. go:    call    iedtbc        ;query user for    execution address
  3116.  
  3117. ;    ret    m        ;- eg 3.3.3 no input - reprompt
  3118.     jp    p,g001        ;+ Skip if argument supplied, else:
  3119.     ld    hl,(pcreg)    ;+ Use current PC
  3120.     jr    g002        ;+
  3121. g001:                ;+
  3122.     call    iarg
  3123.     jp    nz,e???        ;error - invalid argument
  3124. g002:                ;+
  3125.     call    crlf
  3126.     call    crlf
  3127. g100:    ld    (jmplo),hl    ;store execution address
  3128.     ld    a,jp
  3129.     ld    (jmp),a        ;set jp    instruction
  3130.     ld    (jmp2jp),a    ;just in case 
  3131.     ld    a,(bps)        ;check breakpoint count
  3132.     and    a
  3133.     jp    z,g600        ;z - no    bps in effect -    no restoration needed
  3134.     ld    b,a
  3135.     ld    hl,brktbl
  3136.     ld    c,0ffh
  3137. g300:    ld    e,(hl)
  3138.     inc    hl
  3139.     ld    d,(hl)        ;de - breakpoint address removed from table
  3140.     inc    hl        ;point to contents save    byte in    table
  3141.     ld    a,(de)
  3142.     ld    (hl),a
  3143.     ld    a,(jmplo)
  3144.     cp    e        ;check if bp from table    matches    next pc
  3145.     jr    nz,g400        ;no match - set    breakpoint
  3146.     ld    a,(jmphi)
  3147.     cp    d        ;check hi order    next pc    address
  3148.     jr    nz,g400        ;no match - set    bp
  3149.     ld    c,b        ;set flag - current pc matches breakpoint
  3150.     jr    g500
  3151. g400:    ld    a,rst38        ;set rst38 instruction
  3152.     ld    (de),a        ;save user byte    in brktbl
  3153. g500:    inc    hl
  3154.     djnz    g300        ;examine all entries
  3155.     inc    c        ;current pc match breakpoint?
  3156.     jp    z,g600        ;z - no (c reg not 0ffh)
  3157.     ld    a,(sbps)    ;check number of step breakpoints
  3158.     and    a        ;tracing?
  3159.     jp    nz,g600        ;nz - this is trace
  3160.  
  3161.                 ;pc points to address in breakpoint table
  3162.                 ;next instruction will not be executed where
  3163.                 ;it resides.  it will be moved to our internal
  3164.                 ;buffer (execbf) and executed there. then we
  3165.                 ;set an rst38 at actual location in user 
  3166.                 ;program.  this allows us to debug loops in 
  3167.                 ;which only one bp is set.  otherwise we would
  3168.                 ;not be able to set a bp at the address where
  3169.                 ;the pc points and debugging loops would be
  3170.                 ;impossible.      
  3171.     ld    hl,execbf
  3172.     ld    de,(jmplo)    ;de - pointer to next instruction to execute
  3173.     ld    (jmplo),hl    ;execute buffer
  3174.     ld    b,4        ;clear execute buffer
  3175. g505:    ld    (hl),nop
  3176.     inc    hl
  3177.     djnz    g505
  3178.     call    zlen00        ;calculate length
  3179.                 ;if instruction modifies pc then zlen lets us
  3180.                 ;know by setting b reg nz and c contains 
  3181.                 ;instruction length
  3182.  
  3183.     ld    (jropnd),hl    ;if this is a jr instruction we need to save
  3184.                 ;address where we will be jumping 
  3185.  
  3186.  
  3187.                 ;default execbf has been initialized:
  3188.                 ;
  3189.                 ;four nops     
  3190.                 ;     jp   user program 
  3191.                 ;     
  3192.     ex    de,hl        ;hl - ptr to user instruction
  3193.     ld    de,execbf
  3194.     ld    a,(hl)        ;first object byte from    user program
  3195. g518:    ld    (hl),rst38    ;replace
  3196.     push    bc        ;b - if nz this is a pc modifying instruction
  3197.                 ;c - number of bytes of object code for this
  3198.                 ;    instruction
  3199. g520:    ld    (de),a        ;into execute buffer
  3200.     inc    de
  3201.     inc    hl        ;bump user program pointer
  3202.     ld    a,(hl)        ;next byte of instruction from user program
  3203.     dec    c
  3204.     jr    nz,g520
  3205.     pop    bc
  3206.                 ;the four nops in execbf have now been replaced
  3207.                 ;by from one to four bytes of actual user
  3208.                 ;instruction.  if user instruction was shorter
  3209.                 ;than four bytes the nops remain and are 
  3210.                 ;executed until the jump back to the user 
  3211.                 ;program at jmp2jp is reached.
  3212.  
  3213.  
  3214.     ld    (jmp2),hl    ;address of next inline instruction within
  3215.                 ;user code    
  3216.  
  3217.     ex    de,hl        ;de - next inline instruction in user program
  3218.     xor    a
  3219.     or    b
  3220.     jr    z,g600        ;z - the instruction in execbf is not a pc 
  3221.                 ;modifying instruction
  3222.  
  3223.     ld    a,(execbf)    ;first byte of instruction
  3224.     dec    c        ;one byte instruction?
  3225.     jr    z,g600
  3226.     dec    c
  3227.     jr    z,g550        ;two byter
  3228.     dec    c
  3229.     jr    nz,g600        ;nz - must be four byter
  3230.     ld    b,c        ;clear for cpir
  3231.     ld    c,z803sl    ;test for call instruction
  3232.     ld    hl,z803s    ;load list of first byte of call instructions
  3233.     cpir
  3234.     jr    nz,g600        ;nz - not call
  3235.  
  3236.                 ;moving call instructions and executing them
  3237.                 ;locally requires special processing because
  3238.                 ;the z80 will store the address pc+3 on the
  3239.                 ;stack.  in this case we do not want the 
  3240.                 ;address  execbf+3 on the stack.  we want the
  3241.                 ;address of the actual location of the user
  3242.                 ;instruction+3 on the stack.  we must do this
  3243.                 ;by simulating a call instruction. we use the
  3244.                 ;jp instruction which is equivalent to the
  3245.                 ;call and we also push a computed return 
  3246.                 ;address on to the user stack pointed to by 
  3247.                 ;spreg.
  3248.  
  3249.     ld    bc,08        ;point to jump instruction which is equivalent
  3250.                 ;to call (call nz = jp nz)
  3251.     add    hl,bc
  3252.     ld    a,(hl)        ;fetch jump object byte 
  3253.     ld    hl,(spreg)    ;push next pc onto user stack
  3254.     dec    hl        ;decrement user sp
  3255.     ld    (hl),d        ;de - "return address"
  3256.     dec    hl
  3257.     ld    (hl),e
  3258.     ld    (spreg),hl
  3259.     ld    (execbf),a    ;store jp op code    
  3260.     ld    hl,jmp2        ;if conditional call and we fall thru
  3261.                 ;we need to go back to address of call
  3262.                 ;in user program + 3
  3263.     ld    (hl),e
  3264.     inc    hl
  3265.     ld    (hl),d
  3266.     jr    g600
  3267.                 ;if next instruction to execute is a 
  3268.                 ;relative jump we need to replace it with
  3269.                 ;an absolute equivalent.  this is because
  3270.                 ;having relocated the user jr instruction
  3271.                 ;into execbf we will undoubtedly be out of
  3272.                 ;range of the destination.
  3273.  
  3274. g550:    ld    c,z802cl    ;check if this is relative jump
  3275.     ld    hl,z802c
  3276.     and    a        ;clear carry
  3277.     cpir
  3278.     jr    nz,g600        ;not a jr
  3279.     ld    a,c
  3280.     ld    bc,z802c
  3281.     sbc    hl,bc
  3282.     dec    hl
  3283.     ld    bc,z803c
  3284.     add    hl,bc        ;point to equivalent absolute jump
  3285.     and    a
  3286.     ld    a,(hl)
  3287.     ld    hl,execbf
  3288.     jr    nz,g555        ;nz - not last in list (not djnz)
  3289.  
  3290.                 ;replace djnz with  dec   b
  3291.                 ;            jp    nz,
  3292.              
  3293.     ld    (hl),05        ;dec b instruction
  3294.     inc    hl
  3295.     ld    a,0c2h        ;jp nz absolute
  3296. g555:    ld    (hl),a
  3297.     inc    hl
  3298.     ld    bc,(jropnd)    ;if this is a conditional jr we need the
  3299.                 ;absolute destination of the jump
  3300.     ld    (hl),c
  3301.     inc    hl
  3302.     ld    (hl),b
  3303.  
  3304. g600:    ld    iy,(iyreg)    ;restore user iy
  3305.     ld    ix,(ixreg)    ;restore user ix
  3306.     ld    a,(rreg)
  3307.     ld    r,a        ;restore user r    reg
  3308.     ld    a,(ireg)
  3309.     ld    i,a        ;restore user i    reg
  3310.     ld    bc,(bcpreg)    ;restore user grade a prime regs
  3311.     ld    de,(depreg)
  3312.     ld    hl,(afpreg)
  3313.     push    hl
  3314.     pop    af
  3315.     ld    hl,(hlpreg)
  3316.     ex    af,af'
  3317.     exx
  3318.     ld    hl,(afreg)    ;restore user accumulator and flag
  3319.     push    hl
  3320.     pop    af
  3321.     ld    bc,(bcreg)    ;restore user bc
  3322.     ld    de,(dereg)    ;restore user de
  3323.     ld    hl,(hlreg)    ;restore user hl
  3324.     ld    sp,(spreg)    ;restore user sp
  3325.     jp    jmp
  3326.     page
  3327. ;******************************************************************************
  3328. ;*
  3329. ;*    step:  Single step (trace) routine
  3330. ;*
  3331. ;*    Call zlen to determine where to    set breakpoint.
  3332. ;*
  3333. ;*        pass:       de -    current    pc address
  3334. ;*
  3335. ;*        returned:  b:  z - next    instruction will not modify pc.
  3336. ;*                   set bp at address specified by pc+length.
  3337. ;*
  3338. ;*               b: nz - next    instruction will modify    pc (jumps,
  3339. ;*                   calls, and returns) thus set    bp at address
  3340. ;*                   returned in hl.
  3341. ;*
  3342. ;*               c:     - number of bytes in current instruction.
  3343. ;*
  3344. ;*        zlen handles secondary breakpoint to set for all conditional
  3345. ;*        call, return, and jump instructions.
  3346. ;*
  3347. ;*    Call brk00 to set breakpoint.
  3348. ;*
  3349. ;*        pass:       b - current number of breakpoints.
  3350. ;*              hl - address at which    to set breakpoint.
  3351. ;*
  3352. ;*    entry point step:    entered by    user via (s)ingle step command.
  3353. ;*    entry point step40:  entered by    breakpoint handler - step count    nz
  3354. ;*
  3355. ;*    exit:    to go routine to resume    execution.
  3356. ;*
  3357. ;******************************************************************************
  3358.  
  3359. step:    ld    a,0ffh
  3360.     ld    (wflag),a    ;set trace subroutine flag on
  3361.     call    iedtbc        ;query user for    trace count
  3362.     ld    hl,0001
  3363.     jp    m,step40    ;null input - step count of one
  3364.     call    prsr
  3365.     jp    nz,e???
  3366.     ld    a,(de)        ;first character from parse buffer
  3367.     sub    '/'
  3368.     ld    (wflag),a    ;may be    slash -    no subroutine tracing
  3369.     ld    hl,00
  3370.     jr    nz,step20
  3371.     ld    (de),a
  3372.     ld    a,(inbfnc)
  3373.     dec    a
  3374.     inc    hl
  3375.     jr    z,step40
  3376.     dec    hl
  3377. step20:    call    xval        ;evaluate contents of parse buffer
  3378.     jp    nz,e???
  3379.     ld    de,(pcreg)
  3380.     ld    a,(de)        ;first byte of op code at current pc
  3381.     cp    0c7h        ;test for rst
  3382.     jp    z,e???        ;no tracing of rsts 
  3383. step40:    ld    (nstep),hl    ;save step count
  3384.     ld    hl,sbps        ;set step flag nz - trace in effect
  3385.     inc    (hl)
  3386.     ld    de,(pcreg)    ;fetch current pc
  3387.     call    zlen00        ;determine number of bytes in instruction
  3388.     inc    b        ;test where to set breakpoint
  3389.     djnz    step50        ;nz - set at address in    hl
  3390.     ex    de,hl
  3391.     add    hl,bc        ;z - set at address pc + instruction length
  3392. step50:    ld    a,(bps)        ;get current number of bps
  3393.     ld    b,a        ;pass to set bp    routine    in b reg
  3394.     ex    de,hl        ;de - bp address to set
  3395.     call    brk30
  3396.     ld    hl,(pcreg)    ;resume    execution at next pc
  3397.     xor    a
  3398.     or    b
  3399.     jp    nz,g100        ;nz - collision    with user bp
  3400.     ex    de,hl
  3401.     ld    hl,sbps        ;step bp set by    brk30 -    bump count
  3402.     inc    (hl)
  3403.     ex    de,hl
  3404.     jp    g100
  3405.     page
  3406. ;******************************************************************************
  3407. ;*
  3408. ;*    asmblr:    z80 assembler
  3409. ;*
  3410. ;******************************************************************************
  3411.  
  3412. asmblr:
  3413.     call    ilin
  3414.     jp    nz,e???
  3415. asm000:    call    crlf
  3416.     ld    (zasmpc),hl    ;save here as well
  3417.     call    zasm08        ;disassemble first instruction
  3418.  
  3419. asm005:
  3420.     ld    hl,(asmbpc)
  3421. asm010:    call    crlf
  3422.     call    outadr        ;display current assembly pc
  3423.     ld    c,22        ;
  3424.     call    spaces        ;leave room for    object code
  3425.     ld    a,3
  3426.     ld    hl,objbuf    ;zero scratch object code buffer
  3427. asm015:    ld    (hl),c
  3428.     inc    hl
  3429.     dec    a
  3430.     jp    p,asm015
  3431.     ld    (oprn01),a    ;init operand key values to 0ffh
  3432.     ld    (oprn02),a
  3433.     call    iedtbc        ;get user input
  3434.     ret    m        ;m - no    input ends command
  3435.     call    cret
  3436.     call    prsr        ;parse to obtain label
  3437.     ld    a,(hl)        ;check last character
  3438.     cp    ':'
  3439.     jr    nz,asm040    ;no colon found    - must be op code
  3440.     ld    (hl),0        ;erase colon
  3441.     ld    a,(de)        ;fetch first char of label from    parse buffer
  3442.     cp    'A'
  3443.     jp    c,asm??l    ;error - first character must be alpha
  3444.     cp    'z'+1
  3445.     jp    nc,asm??l    ;label error
  3446.     cp    'a'
  3447.     jr    nc,asm030
  3448.     cp    'Z'+1
  3449.     jp    nc,asm??l
  3450. asm030:    ld    hl,00
  3451.     ld    (isympt),hl    ;clear pointer
  3452.     call    isym        ;attempt to insert symbol into symbol table
  3453.     jp    nz,asm??t    ;error - symbol    table full
  3454.     ld    (isympt),hl    ;save pointer to symbol    value in symbol    table
  3455.     call    prsr        ;extract opcode
  3456.     jp    m,asm005    ;m - statement contains    label only
  3457. asm040:    ld    a,(delim)    ;check delimeter
  3458.     cp    ','        ;check for invalid terminator
  3459.     jp    z,asm??o
  3460.     ld    c,73        ;number    of opcodes in table as index
  3461. asm050:    dec    c
  3462.     jp    m,asm??o    ;opcode    not found
  3463.     ld    b,0
  3464.     ld    hl,zopcnm    ;table of opcode names
  3465.     add    hl,bc
  3466.     add    hl,bc        ;index times four
  3467.     add    hl,bc
  3468.     add    hl,bc
  3469.     ld    de,prsbf    ;start of parse    buffer
  3470.     ld    b,4
  3471. asm060:    ld    a,(de)        ;character from    parse buffer
  3472.     and    a        ;null?
  3473.     jr    nz,asm070
  3474.     ld    a,' '        ;for comparison    purposes
  3475. asm070:    call    ixlt        ;force upper case for compare
  3476.     cp    (hl)
  3477.     jr    nz,asm050    ;mismatch - next opcode    name
  3478.     inc    de
  3479.     inc    hl
  3480.     djnz    asm060        ;must match all    four
  3481.     ld    a,(de)        ;null following    opcode?
  3482.     and    a
  3483.     jp    nz,asm??o    ;error - opcode    more than 4 characaters
  3484.     ld    hl,ikey        ;relative position in table is key value
  3485.     ld    (hl),c        ;save opcode key value
  3486.     call    prsr        ;extract first operand
  3487.     jp    m,asm085    ;m - none
  3488.     call    oprn        ;evaluate operand
  3489.     jr    nz,asm??u    ;error - bad first operand
  3490.     ld    de,oprn01
  3491.     call    opnv        ;save operand value and    key
  3492.     ld    a,(delim)
  3493.     cp    ','
  3494.     jr    nz,asm085    ;need comma for    two operands
  3495.     call    prsr        ;extract second    operand
  3496.     jp    m,asm??s    ;error - comma with no second operand
  3497.     cp    ','
  3498.     jp    z,asm??s    ;illegal line termination
  3499.     call    oprn        ;evaluate operand
  3500.     jr    nz,asm??u    ;error - bad second operand
  3501.     ld    de,oprn02
  3502.     call    opnv        ;save second operand value and key
  3503. asm085:    xor    a
  3504.     ld    c,a
  3505. asm090:    ld    hl,zopcpt    ;opcode    name pointer table
  3506.     ld    b,0
  3507.     add    hl,bc        ;index into table
  3508.     ld    a,(ikey)    ;fetch opcode key value
  3509.     cp    (hl)        ;check for match
  3510.     jr    nz,asm095    ;
  3511.     inc    h        ;point to first    operand    table
  3512.     ld    de,oprn01    ;address of first operand key value
  3513.     call    opnm        ;check validity
  3514.     jr    nz,asm095    ;no match - next
  3515.     ld    b,a        ;save modified key value
  3516.     inc    h        ;point to second operand table
  3517.     ld    de,oprn02    ;address of second operand key value
  3518.     call    opnm
  3519.     jr    z,ibld        ;match - attempt final resolution
  3520. asm095:    inc    c        ;bump index
  3521.     jr    nz,asm090    ;nz - check more
  3522. asm??u:    ld    a,'U'        ;error
  3523.     jp    asm???
  3524.  
  3525.  
  3526.  
  3527.  
  3528. ibld:    ld    hl,objbuf    ;object    code temp buffer
  3529.     ld    e,a        ;save second operand key
  3530.     ld    a,(hl)        ;check first byte of object buffer
  3531.     and    a        ;null?
  3532.     ld    a,c        ;instruction key to accumulator    regardless
  3533.     ld    c,e        ;save second operand modified key
  3534.     jr    z,ibld00    ;z - not ix or iy instruction
  3535.     inc    hl        ;point to byte two of object code
  3536. ibld00:    cp    40h
  3537.     jr    c,ibld55    ;c - 8080 instruction
  3538.     cp    0a0h
  3539.     jr    nc,ibld10    ;nc - not ed instruction
  3540.     ld    (hl),0edh    ;init byte one of object code
  3541.     inc    hl
  3542.     cp    80h        ;check which ed    instruction we have
  3543.     jr    c,ibld55    ;c - this is exact object byte
  3544.     add    a,20h        ;add bias to obtain object byte
  3545.     jr    ibld55
  3546. ibld10:    cp    0e0h
  3547.     jr    nc,ibld20
  3548.     add    a,20h        ;8080 type - range 0c0h    to 0ffh
  3549.     jr    ibld55        ;object    byte built
  3550. ibld20:    cp    0e8h
  3551.     jr    c,ibld50    ;8 bit reg-reg arithmetic or logic
  3552.     cp    0f7h        ;check for halt    disguised as ld (hl),(hl)
  3553.     jr    nz,ibld30
  3554.     ld    a,76h        ;halt object code
  3555.     jr    ibld55
  3556. ibld30:    cp    0f8h
  3557.     jr    nc,ibld50    ;8 bit reg-reg load
  3558.     ld    d,a        ;temp save instruction key value
  3559.     ld    a,(objbuf)
  3560.     and    a        ;check for previously stored first object byte
  3561.     ld    a,d
  3562.     ld    (hl),0cbh    ;init byte regardless
  3563.     inc    hl
  3564.     jr    z,ibld40    ;z - not ix or iy instruction
  3565.     inc    hl        ;bump object code pointer - this is four byter
  3566. ibld40:    add    a,0a8h        ;add bias for comparison purposes
  3567.     cp    98h
  3568.     jr    c,ibld50    ;c - shift or rotate instruction
  3569.     rrca
  3570.     rrca
  3571.     and    0c0h        ;this is skeleton for bit instuctions
  3572.     jr    ibld55
  3573. ibld50:    add    a,a        ;form skeleton
  3574.     add    a,a
  3575.     add    a,a
  3576.     add    a,80h
  3577. ibld55:    ld    (hl),a        ;store object byte
  3578.     xor    a
  3579.     or    c        ;second    operand    need more processing?
  3580.     ld    de,oprn02
  3581.     call    nz,rslv        ;resolve second    operand
  3582.     jp    nz,asm??v    ;error - invalid operand size
  3583.     ld    de,oprn01
  3584.     ld    a,b
  3585.     and    a        ;first operand resolved?
  3586.     call    nz,rslv        ;more work to do
  3587.     jp    nz,asm??v    ;error - invalid operand size
  3588.     ld    a,(ikey)
  3589.     sub    67        ;org directive?
  3590.     jr    nz,ibld60
  3591.     ld    d,(hl)
  3592.     dec    hl
  3593.     ld    e,(hl)
  3594.     ex    de,hl
  3595.     jp    asm000        ;z - org directive
  3596. ibld60:    ld    de,objbuf
  3597.     jr    c,ibld70    ;c - instruction  nc - directive
  3598.     ld    b,a        ;number    of bytes for defb or defw or ddb
  3599.     inc    de        ;point past erroneous assembled    opcode
  3600.     inc    de
  3601.     sub    3        ;test for ddb
  3602.     jr    c,ibld75    ;c - must be defb or defw
  3603.     dec    a
  3604.     jr    nz,ibld65    ;nz - must be ddb
  3605.     ld    d,(hl)        ;must be equ
  3606.     dec    hl
  3607.     ld    e,(hl)
  3608.     ld    hl,(isympt)    ;fetch pointer to entry    in symbol table
  3609.     ld    a,h
  3610.     or    l
  3611.     jp    z,asm??u    ;error - no label on equ statement
  3612.     ld    (hl),d
  3613.     dec    hl
  3614.     ld    (hl),e        ;store value of    symbol in symbol table
  3615.     ld    c,6
  3616.     call    spaces
  3617.     ld    a,d
  3618.     call    othxsp
  3619.     ld    a,e
  3620.     call    othxsp
  3621.     jp    asm005        ;ready for next    input
  3622. ibld65:    dec    b        ;set count of object bytes to 2
  3623.     ld    c,(hl)        ;exchange hi and lo order bytes    for ddb
  3624.     dec    hl
  3625.     ld    a,(hl)
  3626.     ld    (hl),c        ;new hi order
  3627.     inc    hl
  3628.     ld    (hl),a        ;new hi order replaces old lo order
  3629.     jr    ibld75
  3630. ibld70:    call    zlen00        ;compute length    of instruction in bytes
  3631.     ld    b,c        ;b - number of bytes of    object code
  3632. ibld75:    ld    hl,(asmbpc)
  3633.     call    outadr        ;re-display current location counter
  3634. ibld80:    ld    a,(de)        ;move from scratch object buffer
  3635.     ld    (hl),a        ;into address pointed to by location counter
  3636.     inc    hl
  3637.     inc    de
  3638.     call    othxsp        ;display each object code byte
  3639.     djnz    ibld80
  3640. ibld90:    ld    (asmbpc),hl
  3641.     jp    asm005        ;next input from user
  3642.  
  3643.  
  3644.  
  3645.  
  3646. opnm:    ld    a,(de)        ;key value computed by operand routine
  3647.     xor    (hl)        ;compare with table operand table entry
  3648.     ret    z        ;true match of operand key values
  3649.     xor    (hl)        ;restore
  3650.     add    a,a        ;86 all    no operand key values (0ffh)
  3651.     ret    m
  3652.     ld    a,(hl)        ;fetch table entry
  3653.     and    7fh        ;sans paren flag for comparison    purposes
  3654.     cp    1bh        ;check table entry 8 bit - 16 bit - $ rel ?
  3655.     jr    c,opnm00    ;c - none of the above
  3656.     ld    a,(de)        ;fetch computed    key
  3657.     xor    (hl)        ;compare with paren flags
  3658.     ret    m        ;error - paren mismatch
  3659.     ld    a,(de)        ;fetch key once    more
  3660.     and    7fh        ;remove    paren flag
  3661.     cp    17h        ;computed as 8 bit - 16    bit - $    rel?
  3662.     jr    z,opnm40    ;so far    so good
  3663.     ret            ;
  3664. opnm00:    cp    19h        ;check for 8 bit reg
  3665.     jr    nc,opnm20    ;8 bit register    match
  3666.     cp    18h        ;table says must be hl - ix - iy
  3667.     ret    nz        ;computed key disagrees
  3668.     ld    a,(de)        ;fetch computed    key
  3669.     and    7        ;computed as hl    - ix - iy ?
  3670.     ret    nz        ;no
  3671. opnm10:    ld    a,(de)        ;fetch computed    key
  3672.     xor    (hl)
  3673.     ret    m        ;error - paren mismatch    on hl -    ix - iy
  3674.     jr    opnm40
  3675. opnm20:    ld    a,(de)        ;fetch computed    key of 8 bit reg
  3676.     and    a        ;
  3677.     jr    nz,opnm30    ;nz - not (hl)
  3678.     dec    a        ;error - 8 bit (hl) missing parens
  3679.     ret
  3680. opnm30:    cp    8        ;test user entered valid 8 bit reg
  3681.     jr    c,opnm40    ;c - ok
  3682.     and    a        ;test if no carry caused by paren flag
  3683.     ret    p        ;error - this is not 8 bit reg with parens
  3684.     and    7        ;psuedo    8 bit reg: (hl)    (ix) (iy)?
  3685.     ret    nz        ;no
  3686. opnm40:    ld    a,(hl)        ;fetch table entry
  3687.     and    7fh
  3688.     sub    18h        ;make values 18    thru 1f    relative zero
  3689.     cp    a        ;zero means match
  3690.     ret
  3691.  
  3692. rslv:    dec    a
  3693.     jr    z,rslv00    ;z - 8 bit reg (bits 0-2 of object byte)
  3694.     dec    a
  3695.     jr    nz,rslv20    ;nz - not 8 bit    reg (bits 3-5 of object    byte)
  3696.     dec    a        ;make neg to indicate shift left required
  3697. rslv00:    ld    c,a
  3698.     ld    a,(de)        ;fetch computed    operand    key
  3699.     and    07        ;lo three bits specify reg
  3700.     xor    6        ;create    true object code bits
  3701.     inc    c        ;test if bits 0-2 or bits 3-5
  3702.     jr    nz,rslv10    ;nz - 0    thru 2
  3703.     add    a,a
  3704.     add    a,a
  3705.     add    a,a
  3706. rslv10:    or    (hl)        ;or with skeleton
  3707.     ld    (hl),a        ;into scratch object buffer
  3708.     cp    a        ;set zero - no error
  3709.     ret
  3710. rslv20:    inc    de        ;point to low order of operand value
  3711.     ld    c,(hl)        ;c - current skeleton  (if needed)
  3712.     inc    hl        ;bump object code buffer pointer
  3713.     dec    a
  3714.     jr    nz,rslv30    ;nz - not relative jump
  3715.     ex    de,hl        ;save object code pointer in de
  3716.     ld    a,(hl)
  3717.     inc    hl
  3718.     ld    h,(hl)
  3719.     ld    l,a        ;hl - operand value computed by    xval
  3720.     ld    a,b
  3721.     ld    bc,(asmbpc)    ;current location counter
  3722.     inc    bc
  3723.     inc    bc
  3724.     sbc    hl,bc        ;calculate displacement    from current counter
  3725.     ex    de,hl        ;de - displacement  hl - object    code pointer
  3726.     ld    b,a        ;restore b reg
  3727.     ld    a,e        ;lo order displacement
  3728.     inc    d        ;test hi order
  3729.     jr    z,rslv25    ;must have been    ff (backward displacement)
  3730.     dec    d
  3731.     ret    nz        ;error - hi order not zero or ff
  3732.     cpl            ;set sign bit for valid    forward    displacement
  3733. rslv25:    xor    80h        ;toggle    sign bit
  3734.     ret    m        ;error - sign bit disagrees with upper byte
  3735.     ld    (hl),e        ;store displacement object byte
  3736.     cp    a        ;set zero flag - no errors
  3737.     ret
  3738. rslv30:    dec    a
  3739.     jr    nz,rslv40    ;nz - not 8 bit    immediate
  3740.     ld    a,36h        ;test for reg indirect - (hl),nn
  3741.     cp    c
  3742.     jr    nz,rslv35
  3743.     ld    a,(objbuf)    ;test first object byte
  3744.     cp    c
  3745.     jr    z,rslv35    ;z - (hl),nn
  3746.     inc    hl        ;must be (ix+index),nn    or  (iy+index),nn
  3747. rslv35:    ld    a,(de)        ;move lo order operand value to    object buffer
  3748.     ld    (hl),a
  3749.     inc    de
  3750.     ld    a,(de)        ;test hi order
  3751.     and    a        ;
  3752.     ret    z        ;z - must be 0 thru +255
  3753.     inc    a        ;error if not -1 thru -256
  3754.     ret
  3755. rslv40:    dec    a
  3756.     jr    nz,rslv50    ;nz - not 16 bit operand
  3757.     ld    a,(de)        ;move both bytes of operand to object buffer
  3758.     ld    (hl),a
  3759.     inc    hl
  3760.     inc    de
  3761.     ld    a,(de)        ;byte two
  3762.     ld    (hl),a
  3763.     cp    a        ;set zero flag - no errors of course
  3764.     ret
  3765. rslv50:    dec    a        ;test restart instruction or bit number
  3766.     jr    nz,rslv60    ;nz - bit or interrupt mode number
  3767.     ld    a,(de)        ;check restart value specified
  3768.     and    0c7h        ;betweed 0 and 38h?
  3769.     ret    nz        ;error
  3770.     ld    a,(de)        ;fetch lo order    operand    value
  3771.     or    0c7h        ;or with instruction skeleton
  3772.     dec    hl
  3773.     ld    (hl),a        ;rewind    object code pointer
  3774.     inc    de
  3775.     ld    a,(de)        ;check hi order    operand    value
  3776.     and    a        ;error if not zero
  3777.     ret
  3778. rslv60:    dec    hl        ;rewind    object code buffer pointer    
  3779.     ld    a,(de)
  3780.     and    0f8h        ;ensure    bit number in range 0 -    7
  3781.     ret    nz        ;error
  3782.     ld    a,(ikey)    ;fetch opcode key value
  3783.     sub    13h        ;is this bit number of interrupt mode number?
  3784.     ld    a,(de)        ;fetch operand value regardless
  3785.     jr    nz,rslv70    ;nz - bit number
  3786.     ld    (hl),46h
  3787.     and    03        ;im 0?
  3788.     ret    z
  3789.     ld    (hl),56h
  3790.     dec    a        ;im 1?
  3791.     ret    z
  3792.     ld    (hl),5eh
  3793.     dec    a        ;error if not im 2
  3794.     ret
  3795. rslv70:    add    a,a        ;shift bit number left three
  3796.     add    a,a
  3797.     add    a,a
  3798.     or    (hl)        ;or with skeleton
  3799.     ld    (hl),a
  3800.     cp    a        ;indicate no error
  3801.     ret
  3802.  
  3803.  
  3804.  
  3805. oprn:    ld    bc,22        ;count of reserved operand
  3806. oprn00:    ld    de,prsbf    ;buffer    contains operand
  3807.     ld    a,(hl)        ;last character    of operand in parse buffer
  3808.     sub    ')'
  3809.     jr    nz,oprn20    ;not paren
  3810.     ld    (hl),a        ;remove    trailing paren - replace with null
  3811.     ld    a,(de)        ;check first character of parse    buffer
  3812.     sub    '('
  3813.     ret    nz        ;error - unbalanced parens
  3814.     ld    (de),a        ;remove    leading    paren -    replace    with null
  3815.     inc    de        ;point to next character in parse buffer
  3816. oprn20:    ld    hl,zopnm    ;index into reserved operand name table
  3817.     ld    a,c
  3818.     add    a,a        ;index times two
  3819.     add    a,l
  3820.     ld    l,a
  3821.     jr    nc,oprn25
  3822.     inc    h
  3823. oprn25:    ld    a,(de)        ;from parse buffer
  3824.     call    ixlt        ;translate to upper case for compare
  3825.     cp    (hl)        ;versus    table entry
  3826.     inc    de
  3827.     jr    nz,oprn70    ;no match - check next
  3828.     ld    a,(de)        ;check second character
  3829.     call    ixlt        ;translate to upper case
  3830.     and    a        ;if null - this    is one character reg name
  3831.     jr    nz,oprn30
  3832.     ld    a,' '        ;for comparison    purposes
  3833. oprn30:    inc    hl        ;bump table pointer
  3834.     sub    (hl)
  3835.     jr    nz,oprn70    ;no match - check next
  3836.     inc    de        ;have match - bump buffer pointer
  3837.     or    b        ;
  3838.     ret    nz        ;nz - mreg calling
  3839.     ld    a,c        ;check index value
  3840.     and    07
  3841.     jr    nz,oprn80    ;not hl    ix iy -    check for residue
  3842.     ld    a,(de)
  3843.     call    oprtor        ;check for expression operator
  3844.     jr    nz,oprn85    ;no operator but not end of operand
  3845.     ld    a,ix.. or iy..    ;special ix iy hl processing
  3846.     and    c        ;test for index    reg
  3847.     jr    z,oprn35    ;z - must be hl
  3848.     and    10h        ;transform index into 0ddh or ofdh
  3849.     add    a,a
  3850.     add    a,0ddh        ;a - first byte    of index reg opcode
  3851. oprn35:    ld    c,a        ;temp save first object    byte
  3852.     ld    hl,objbuf
  3853.     xor    (hl)
  3854.     jr    z,oprn40    ;z - first operand matches second
  3855.     cp    c
  3856.     ret    nz        ;illegal ix iy hl combination
  3857.     ld    a,(oprn01)
  3858.     and    a        ;test if index reg was first operand
  3859.     jr    nz,oprn40
  3860.     dec    a        ;error - hl illegal as second
  3861.     ret
  3862.  
  3863.  
  3864. oprn40:    ld    (hl),c        ;init first byte of object code
  3865.     ld    a,(prsbf)
  3866.     and    a        ;check for previously removed parens
  3867.     ld    a,c
  3868.     ld    c,0
  3869.     jr    nz,oprn80    ;no parens - no    indexed    displacement
  3870.     and    a        ;check for ix or iy indexed instruction
  3871.     jr    z,oprn80    ;z - not index reg instruction
  3872.  
  3873.     sbc    hl,hl        ;clear hl
  3874.     ld    a,(de)        ;index reg displacement    processing
  3875.     and    a        ;test for default displacement
  3876.     call    nz,xval        ;not zero - evaluate
  3877.     jr    nz,oprn85    ;nz - displacement in error
  3878.     ld    c,00
  3879.     ld    a,l
  3880.     ld    (objbuf+2),a    ;displacement always third byte
  3881.     inc    h        ;check upper byte of index value
  3882.     jr    z,oprn50    ;must have been    0ffh
  3883.     dec    h
  3884.     ret    nz        ;error - index not -128    to +127
  3885.     cpl
  3886. oprn50:    xor    80h        ;check sign bit
  3887.     ret    m        ;bit on    - index    out of range
  3888.     cp    a        ;no error - set    zero flag
  3889.     ret
  3890. oprn70:    dec    c        ;decrement reserved operand table index
  3891.     jp    m,oprn85    ;m - not a reserved operand
  3892.     dec    de        ;rewind    parse buffer pointer
  3893.     jp    oprn20        ;next table entry
  3894. oprn80:    ld    a,(de)        ;check for end of parse    buffer
  3895.     and    a
  3896.     ret    z        ;found end of line null
  3897. oprn85:    ld    de,prsbf    ;rewind    to start of input
  3898.     xor    a
  3899.     or    b
  3900.     ret    nz        ;nz - this was mreg calling
  3901.     sbc    hl,hl        ;clear hl
  3902.     call    xval        ;evaluate operand
  3903.     ld    c,17h        ;assume    numeric    operand    found
  3904.     ret
  3905.  
  3906.  
  3907. xval:    ld    a,(de)        ;check first char of parse buffer
  3908.     and    a
  3909.     jr    nz,xval00
  3910.     inc    de        ;bump past previously removed paren
  3911. xval00:    ld    (mexp),hl    ;init expression accumulator
  3912.     xor    a
  3913.     ld    (base10),a    ;clear upper digit decimal accumulator
  3914.     sbc    hl,hl        ;clear hl
  3915.     ld    (fndsym),hl    ;clear symbol found flag
  3916.     ld    (pass2),hl
  3917. xval05:    ld    a,(de)        ;char from parse buffer
  3918.     call    ixlt        ;translate to upper case
  3919.     ld    c,a        ;save character
  3920.     inc    de        ;bump parse buffer pointer
  3921.     cp    '0'        ;check for valid ascii hex digit
  3922.     jr    c,xval25
  3923.     cp    ':'
  3924.     jr    c,xval15
  3925.     cp    'A'
  3926.     jr    c,xval25
  3927.     cp    'G'
  3928.     jr    nc,xval25
  3929.     xor    a        ;check number entered flag (b reg sign bit)
  3930.     or    b
  3931.     jp    m,xval10    ;m - this was not first    char
  3932.     ld    a,(symflg)    ;check if symbol table present in memory
  3933.     and    a
  3934. xval10:    ld    a,c        ;input character back to accumulator
  3935.     jp    p,xval25    ;p - have symbol table or invalid hex digit
  3936.     sub    7
  3937. xval15:    sub    '0'        ;ascii hex to hex nibble
  3938.     add    a,a        ;shift left five - hi bit of nibble to carry
  3939.     add    a,a
  3940.     add    a,a
  3941.     add    a,a
  3942.     add    a,a
  3943.     ld    c,4        ;loop count
  3944. xval20:    adc    hl,hl        ;hl left into carry - rotate carry into    hl
  3945.     adc    a,a        ;next bit of nibble into carry
  3946.     dec    c
  3947.     jr    nz,xval20
  3948.     ld    (base10),a    ;store what was    shifted    left out of hl
  3949.     ld    a,80h        ;set sign of b - number    entered    flag
  3950.     or    b
  3951.     ld    b,a
  3952.     jr    xval05        ;next character
  3953.  
  3954. xval25:    call    oprtor        ;have expression operator?
  3955.     jr    z,xval30
  3956.     ld    a,(pass2)
  3957.     and    a
  3958.     ret    nz
  3959.     ld    a,(pass2+1)
  3960.     and    a
  3961.     jp    z,xval35
  3962.     ret
  3963.  
  3964. xval30:    xor    a
  3965.     or    b        ;check number entered flag
  3966.     ld    a,c        ;restore unmodified input character to a
  3967.     jp    nz,xval90    ;nz - take care    of previous operator
  3968.     and    a        ;end of    line null?
  3969.     ret    z        ;
  3970.     ld    b,c        ;this operator was first char of parse buffer
  3971.     jr    xval05        ;extract what follows this leading operator
  3972.  
  3973. xval35:    ld    a,c        ;recover character
  3974.     cp    '#'        ;decimal processing?
  3975.     jr    nz,xval50    ;nz - not decimal
  3976.     ld    a,b        ;check number entered flag
  3977.     xor    80h        ;toggle
  3978.     ret    m        ;error - pound sign with no number
  3979.     ld    b,a
  3980.     push    bc
  3981.     push    de
  3982.     ex    de,hl        ;save hex number in de
  3983.     ld    hl,base10
  3984.     ld    a,6
  3985.     cp    (hl)        ;check ten thousands digit
  3986.     jr    c,xval40    ;error - obviously greater than    65535
  3987.     rrd            ;nibble    to accumulator
  3988.      inc    hl
  3989.     ld    (hl),d        ;store hex number in temp buffer
  3990.     inc    hl
  3991.     ld    (hl),e        ;lo order hex number
  3992.     dec    hl        ;point back to upper byte
  3993.     ld    e,a
  3994.     xor    a
  3995.     ld    d,a        ;de - hex nibble
  3996.     call    bcdx        ;convert hi order byte
  3997.     jr    nz,xval40    ;nz - error detected during conversion
  3998.     inc    hl        ;bump to lo byte to convert
  3999.     call    bcdx
  4000.     ex    de,hl        ;hl - converted    value
  4001. xval40:    pop    de
  4002.     pop    bc
  4003.     jr    z,xval65    ;z - no    errors detected
  4004.     ret
  4005.  
  4006.  
  4007.  
  4008. xval50:    cp    quote        ;ascii literal processing
  4009.     jr    nz,xval60    ;nz - not quote
  4010.     ex    de,hl        ;
  4011.     ld    e,(hl)        ;fetch literal from buffer
  4012.     inc    hl
  4013.     cp    (hl)        ;trailing quote    found?
  4014.     jr    z,xval55    ;found
  4015.     ld    d,e        ;make literal just fetch hi order of operand
  4016.     ld    e,(hl)        ;fetch new literal as lo order
  4017.     inc    hl
  4018.     cp    (hl)        ;trailing quote?
  4019.     ret    nz        ;error - more than two chars between quotes
  4020. xval55:    ex    de,hl        ;de - parse buffer ptr     hl - operand
  4021.     inc    de        ;bump past trailing quote
  4022.     jr    xval65
  4023.  
  4024.  
  4025. xval60:    dec    de        ;point to start    of operand in parse buffer
  4026.     ld    (pass2),de
  4027.     call    fsym        ;search    symbol table
  4028.     jp    z,xval62    ;symbol    found
  4029.     ld    a,(de)
  4030.     inc    de
  4031.     cp    '$'        ;check for pc relative expression
  4032.     jp    nz,xval61
  4033.     ld    hl,(asmbpc)    ;current location value    is expression value
  4034.     jr    xval65
  4035.                 ;symbol not found - retry evaluation process
  4036.                 ;with pass2 flag set.  now token must be a
  4037.                 ;valid hex digit or error 
  4038. xval61:    ld    de,(pass2)    
  4039.     ld    a,b
  4040.     or    80h        ;set sign in b - valid digit detected which
  4041.                 ;tells xval this must be hex number
  4042.     ld    b,a
  4043.     sbc    hl,hl        ;clear hex number accumulator
  4044.     jp    xval05
  4045. xval62:    ld    a,(maxlen)    ;point to last byte of sym table entry
  4046.     or    l
  4047.     ld    l,a
  4048.     ld    a,(hl)        ;hi order symbol address
  4049.     dec    hl
  4050.     ld    l,(hl)        ;lo order
  4051.     ld    h,a
  4052. xval65:    ld    a,b        ;check number entered flag
  4053.     and    a
  4054.     ret    m        ;error - numbers entered previous to symbol
  4055.     xor    80h        ;toggle    flag
  4056.     ld    b,a
  4057.     ld    a,(de)        ;check char following symbol name in buffer
  4058.     ld    c,a        ;make it new current character
  4059.     inc    de
  4060.     jp    xval30
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066. xval90:    ld    c,a        ;temp save operator
  4067.     ld    a,80h        ;toggle    number entered flag
  4068.     xor    b
  4069.     ret    m        ;return    nz - consecutive operators
  4070.     ld    b,c        ;new on    deck operator
  4071.     cp    '-'        ;test last operator
  4072.     push    de        ;save buffer pointer
  4073.     jr    nz,xval95    ;nz - addition
  4074.     ex    de,hl
  4075.     sbc    hl,hl        ;clear
  4076.     sbc    hl,de        ;force current value neg by subtraction from 0
  4077. xval95:    ex    de,hl
  4078.     ld    hl,(mexp)    ;fetch accumulated operand total
  4079.     add    hl,de        ;add in    current
  4080.     pop    de        ;restore buffer    pointer
  4081.     ld    a,b        ;check operator    that got us here
  4082.     and    a        ;end of    line null?
  4083.     jp    nz,xval00    ;no -
  4084.     ret            ;operand processing complete
  4085.  
  4086.  
  4087.  
  4088. fsym:
  4089.     ld    hl,(06)        ;de - buffer   hl - symbol table
  4090. fsym00:    ld    a,(maxlen)
  4091.     and    l
  4092.     ld    c,a
  4093.     ld    a,b        ;temp save
  4094.     ld    b,0
  4095.     ex    de,hl        ;de - symbol table ptr    hl - parse buffer
  4096.     sbc    hl,bc        ;rewind    parse buffer to    start of symbol
  4097.     ex    de,hl        ;de - parse buffer  hl - symbol    table pointer
  4098.     ld    b,a        ;restore b reg
  4099.     ld    a,(maxlen)
  4100.     or    l
  4101.     ld    l,a
  4102.     inc    hl        ;next block of symbol table
  4103.     ld    a,(hl)        ;first character of symbol name
  4104.     dec    a
  4105.     ret    m        ;end of    table
  4106.     ld    a,(maxlen)
  4107.     dec    a
  4108.     ld    c,a        ;chars per symbol 
  4109. fsym10:    ld    a,(de)        ;fetch char from buffer
  4110.     call    oprtor
  4111.     jr    nz,fsym20    ;nz - not operator or end of line null
  4112.     ld    a,(hl)
  4113.     and    a        ;null means end    of symbol name in symbol table
  4114.     jr    nz,fsym00
  4115.     ld    (fndsym),hl    ;set symbol found flag nz -
  4116.     ret
  4117. fsym20:    cp    (hl)
  4118.     jr    nz,fsym00
  4119.     inc    hl
  4120.     inc    de
  4121.     dec    c
  4122.     jr    nz,fsym10
  4123.     ld    (fndsym),hl    ;set symbol found flag nz -
  4124. fsym30:    ld    a,(de)
  4125.     call    oprtor
  4126.     ret    z
  4127.     inc    de
  4128.     jr    fsym30
  4129.  
  4130.  
  4131.  
  4132. isym:    call    fsym        ;search    for symbol in table
  4133.     jr    z,isym00    ;z - symbol found
  4134.     ld    a,(hl)        ;test for empty    slot in    table
  4135.     and    a
  4136.     ret    nz        ;symbol    table full
  4137.     ld    (symflg),a    ;indicate non-empty symbol table
  4138. isym00:    ld    a,(maxlen)    ;rewind    point to start of table    entry
  4139.     ld    c,a
  4140.     cpl    
  4141.     and    l
  4142.     ld    l,a
  4143.     ex    de,hl        ;de - pointer to start of symbol
  4144.     ld    hl,prsbf
  4145.     ld    b,0        ;move symbol from parse    buffer to table
  4146.     dec    c
  4147.     ldir
  4148.     ld    hl,(asmbpc)    ;fetch value of    symbol
  4149.     ex    de,hl        ;hl - pointer to address storage
  4150.     ld    (hl),e        ;lo order current location into    table
  4151.     inc    hl
  4152.     ld    (hl),d        ;upper byte
  4153.     xor    a
  4154.     ret
  4155.     page
  4156. ;******************************************************************************
  4157. ;*
  4158. ;*    prsr:    command    line parse routine
  4159. ;*
  4160. ;*    prsr will extract one argument from the    input buffer (inbf) and
  4161. ;*    write it into the parse    buffer (prsbf).    an argument is treated
  4162. ;*    as starting with the first non-delimeter character encountered
  4163. ;*    in the input buffer and ends with the next delimeter found.
  4164. ;*    all intervening    characters between the two delimeters are
  4165. ;*    treated    as the argument    and are    moved to prsbf.
  4166. ;*
  4167. ;*    as each character is extracted from inbf a zero is written back
  4168. ;*    to replace it.  thus a program which needs to extract multiple args
  4169. ;*    need not save pointers in between calls    since prsr is trained
  4170. ;*    to strip leading delimeters while looking for the start    of an
  4171. ;*    argument:
  4172. ;*
  4173. ;*         delimeters: null, space, comma
  4174. ;*
  4175. ;*    exit:        de - starting address of parse buffer
  4176. ;*             b - sign bit: set if unbalanced parens, else sign reset
  4177. ;*             bits 6-0: number of chars in the parse    buffer
  4178. ;*             a - actual    delimter char which caused to terminate
  4179. ;*             f - zero flag set if no error
  4180. ;*        quoflg - set equal to ascii quote if at    leeat one quote    found
  4181. ;*
  4182. ;*    error exit:  f - zero flag reset
  4183. ;*
  4184. ;******************************************************************************
  4185.  
  4186. prsr:    xor    a
  4187.     ld    (quoflg),a    ;clear quote flag
  4188.     ld    hl,prsbf    ;start of parser scratch buffer
  4189.     ld    b,prsbfz    ;buffer    size
  4190.     ld    c,b
  4191. prsr10:    ld    (hl),0        ;clear parse buffer to nulls
  4192.     inc    hl
  4193.     djnz    prsr10
  4194.     ld    hl,prsbf    ;start of parse    buffer
  4195.     ld    de,inbf        ;start of input    buffer
  4196.     ld    c,inbfl        ;max size of input buffer
  4197. prsr20:    ld    a,(de)        ;from input buffer
  4198.     ex    de,hl
  4199.     ld    (hl),0        ;erase as we pick from input buffer
  4200.     ex    de,hl
  4201.     dec    c        ;decrement buffer size tally
  4202.     ret    m        ;error -  end of input buffer reached
  4203.     inc    de        ;bump input buffer pointer
  4204.     call    zdlm00        ;check for delimeter
  4205.     jr    z,prsr20    ;delimeter found - continue search
  4206.     ld    (parenf),a
  4207.     ld    c,nprsbf-prsbf    ;parse buffer size
  4208. prsr30:    ld    (hl),a
  4209.     and    a
  4210.     jr    z,prsr60    ;end of    line null always ends parse
  4211.     cp    quote        ;quote?
  4212.     jr    nz,prsr50
  4213.     ld    (quoflg),a
  4214.     ld    a,b        ;quote found - toggle flag
  4215.     xor    80h
  4216.     ld    b,a
  4217. prsr50:    dec    c        ;decrement buffer size tally
  4218.     ret    m        ;error - end of    parse buffer reached
  4219.     ld    a,(de)        ;next char from    input buffer
  4220.     ex    de,hl
  4221.     ld    (hl),0        ;clear as we remove
  4222.     ex    de,hl
  4223.     inc    de
  4224.     inc    b        ;bumping character count tests quote flag
  4225.     call    p,zdlm        ;only look for delimeters if quote flag off
  4226.     inc    hl        ;bump parse buffer pointer
  4227.     jr    nz,prsr30
  4228.     dec    hl
  4229. prsr60:    ld    de,prsbf    ;return    pointing to start of parse buffer
  4230.     ld    (delim),a
  4231.     ret            ;zero flag set - no errors
  4232.  
  4233.  
  4234.  
  4235. asm??l:    ld    a,'L'
  4236.     jr    asm???
  4237. asm??o:    ld    a,'O'
  4238.     jr    asm???
  4239. asm??p:    ld    a,'P'
  4240.     jr    asm???
  4241. asm??s:    ld    a,'S'
  4242.     jr    asm???
  4243. asm??t:    ld    a,'T'
  4244.     jr    asm???
  4245. asm??v:    ld    a,'V'
  4246.  
  4247. asm???:    ld    (asmflg),a
  4248.     call    cret
  4249.     ld    hl,(asmbpc)
  4250.     call    outadr
  4251.     ld    de,m????
  4252.     call    print
  4253.     jp    asm010
  4254.  
  4255.  
  4256. zdlm:    cp    ','
  4257.     ret    z
  4258. zdlm00:    and    a
  4259.     ret    z
  4260.     cp    tab
  4261.     ret    z
  4262.     cp    ' '
  4263.     ret
  4264.  
  4265. oprtor: cp    '+'
  4266.     ret    z
  4267.     cp    '-'
  4268.     ret    z
  4269.     and    a
  4270.     ret
  4271.  
  4272.  
  4273.  
  4274. opnv:    ex    de,hl        ;de - operand value  hl    - operand key storage
  4275.     ld    a,(prsbf)    ;check first byte of parse buffer
  4276.     and    a        ;if null - paren was removed
  4277.     ld    a,c        ;key value to accumulator
  4278.     jr    nz,opnv00    ;nz - no paren
  4279.     or    80h        ;found null - set paren    flag
  4280. opnv00:    ld    (hl),a        ;store key value
  4281.     inc    hl
  4282.     ld    (hl),e        ;lo order operand value
  4283.     inc    hl
  4284.     ld    (hl),d        ;hi order
  4285.     ret                                                
  4286.  
  4287.  
  4288.     page
  4289. ;******************************************************************************
  4290. ;*
  4291. ;*    zlen:  determine the number of bytes in    a z80 instruction
  4292. ;*
  4293. ;*
  4294. ;*    entry point zlen00: used to return instruction length.
  4295. ;*
  4296. ;*                de:     address of instruction
  4297. ;*
  4298. ;*    return:     b:  z - inline    instruction (next pc will be pc    plus length)
  4299. ;*            nz - pc modifying instruction such as call,     jump, or ret
  4300. ;*             (see hl below)
  4301. ;*         c:     number    of bytes in this instruction.
  4302. ;*        de:     preserved
  4303. ;*        hl:     next pc following the execution of the    instruction
  4304. ;*             pointed to by de.
  4305. ;*
  4306. ;******************************************************************************
  4307.  
  4308. zlen00:    ld    a,(de)        ;fetch first byte of op    code
  4309.     cp    0cbh        ;test for shift/bit manipulation instruction
  4310.     ld    bc,02
  4311.     ret    z        ;10-4 this is a    cb and length is always    2
  4312.     cp    0edh        ;test for fast eddie
  4313.     jr    nz,zlen15    ;
  4314.     inc    de        ;fetch byte two    of ed instruction
  4315.     ld    a,(de)
  4316.     dec    de        ;restore pointer
  4317.     ld    hl,z80ed    ;ed four byter table
  4318.     ld    c,z80edl    ;length
  4319.     cpir
  4320.     ld    c,4        ;assume    ed four    byter
  4321.     ret    z        ;correct assumption
  4322.     ld    c,2        ;set length for    return - if not    2 must be 4
  4323.     cp    45h        ;test for retn
  4324.     jr    z,zlen10
  4325.     cp    4dh        ;test for reti
  4326.     ret    nz        ;non-pc    modifying two byte ed
  4327. zlen10:    ld    a,0c9h        ;treat as ordinary return instruction
  4328.     jp    zlen80
  4329. zlen15:    cp    0ddh        ;check for dd and fd index reg instructions
  4330.     jr    z,zlen20
  4331.     cp    0fdh
  4332.     jr    nz,zlen40
  4333. zlen20:    inc    de        ;fetch byte two    of index reg instruction
  4334.     ld    a,(de)
  4335.     dec    de        ;restore pointer
  4336.     cp    0e9h        ;check for reg indirect    jump
  4337.     jr    nz,zlen30    ;
  4338.     inc    b        ;reg indirect jump - set pc modified flag nz
  4339.     ld    a,(de)        ;recheck for ix    or iy
  4340.     ld    hl,(ixreg)    ;assume    ix
  4341.     cp    0ddh
  4342.     ret    z        ;correct assumption
  4343.     ld    hl,(iyreg)
  4344.     ret
  4345. zlen30:    ld    hl,z80fd    ;check for dd or fd two    byter
  4346.     ld    c,z80fdl
  4347.     cpir
  4348.     ld    c,2        ;assume    two
  4349.     ret    z
  4350.     ld    hl,z80f4    ;not two - try four
  4351.     ld    c,z80f4l
  4352.     cpir
  4353.     ld    c,4        ;assume    four
  4354.     ret    z        ;correct assumption
  4355.     dec    c        ;must be three
  4356.     ret
  4357. zlen40:    and    0c7h        ;check for 8 bit immediate load
  4358.     cp    06
  4359.     ld    c,2        ;assume    so
  4360.     ret    z
  4361.     dec    c        ;assume    one byte op code
  4362.     ld    a,(de)
  4363.     cp    3fh
  4364.     jr    c,zlen50    ;opcodes 0 - 3f    require    further    investigation
  4365.     cp    0c0h        ;8 bit reg-reg loads and arithmetics do    not
  4366.     ret    c
  4367. zlen50:    ld    hl,z803        ;check for three byter
  4368.     ld    c,z803l
  4369.     cpir
  4370.     jr    nz,zlen60    ;nz - not three
  4371.     ld    hl,z803s    ;established three byter - test conditional
  4372.     ld    c,z803cl
  4373.     cpir
  4374.     ld    c,3        ;set length
  4375.     ret    nz        ;nz - three byte inline    instruction
  4376.     ld    hl,z803s
  4377.     ld    c,z803sl    ;now weed out jumps from calls
  4378.     cpir
  4379.     ld    c,3
  4380.     ld    b,c        ;set pc    modified flag -    we have    call or    jump
  4381.     ex    de,hl
  4382.     inc    hl
  4383.     ld    e,(hl)
  4384.     inc    hl
  4385.     ld    d,(hl)        ;de - address from instruction
  4386.     ex    de,hl
  4387.     dec    de
  4388.     dec    de        ;restore instruction pointer
  4389.     jr    z,zlen55    ;z - this is a call
  4390.     cp    jp        ;test for unconditional jump
  4391.     jr    nz,zlen85
  4392.     ret
  4393. zlen55:    ld    a,(wflag)    ;test for no subroutine    trace flag
  4394.     and    a        ;zero means no sub tracing
  4395.     ld    b,a        ;clear for return - if sub trace off
  4396.     ret    z        ;subroutine trace off -    return with b reg 00
  4397.                 ;so bp is set at next inline instruction
  4398.     dec    b
  4399.     jr    nz,zlen58
  4400.     ld    a,b
  4401.     or    h
  4402.     ret    z
  4403. zlen58:    ld    a,(de)        ;recover call object byte
  4404.     ld    b,c        ;set nz    - pc modifying instruction
  4405.     cp    0cdh        ;unconditional call??
  4406.     jr    nz,zlen85    ;zlen85    - set secondary    breakpoint if tracing
  4407.     ret
  4408.  
  4409. zlen60:    ld    hl,z802
  4410.     ld    c,z802l        ;test for two byter
  4411.     cpir
  4412.     jr    nz,zlen70    ;not two
  4413.     ld    hl,z802c    ;test for relative jump
  4414.     ld    c,z802cl
  4415.     cpir
  4416.     ld    c,2        ;in any    case length is two
  4417.     ret    nz        ;nz - not relative jump
  4418.     ld    h,b        ;clear
  4419.     inc    b        ;set pc    modified flag nz
  4420.     inc    de        ;fetch relative    displacement
  4421.     ld    a,(de)
  4422.     ld    l,a
  4423.     add    a,a        ;test forward or backward
  4424.     jr    nc,zlen65    ;p - forward
  4425.     dec    h        ;set hl    negative
  4426. zlen65:    add    hl,de        ;compute distance from instruction
  4427.     inc    hl        ;adjust    for built in bias
  4428.     dec    de        ;restore pointer
  4429.     ld    a,(de)        ;fetch first byte of instruction
  4430.     cp    18h        ;uncondtional jump?
  4431.     jr    nz,zlen85    ;conditional - set secondary bp    if tracing
  4432.     ret
  4433. zlen70:    ld    hl,z801        ;check for return instruction
  4434.     ld    c,z801l
  4435.     cpir
  4436.     ld    c,1        ;length    must be    1 in any case
  4437.     ret    nz
  4438.     cp    0e9h        
  4439.     jr    nz,zlen80    ;nz - not  jp (hl)
  4440.     inc    b        ;set pc    modified flag
  4441.     ld    hl,(hlreg)    ;next pc contained in hlreg
  4442.     ret
  4443. zlen80:    ld    hl,(spreg)    ;return    instructions hide next pc in stack
  4444.     ld    b,(hl)
  4445.     inc    hl
  4446.     ld    h,(hl)
  4447.     ld    l,b        ;hl - return address removed from stack
  4448.     ld    b,c        ;set b nz - pc modification flag
  4449.     cp    0c9h
  4450.     ret    z        ;unconditional return
  4451. zlen85:    ld    a,(sbps)    ;count of special step breakpoints
  4452.     and    a        ;test for zero
  4453.     ret    z        ;zero -    monitor    is not tracing
  4454.     ld    a,(bps)        ;fetch number of bps currently in effect
  4455.     ld    b,a        ;pass to set breakpoint    routine    in b reg
  4456.     ex    de,hl        ;de - bp to set
  4457.     call    brk30        ;set conditional breakpoint
  4458.     xor    a
  4459.     or    b
  4460.     ld    b,0
  4461.     ld    de,(pcreg)    ;for setting inline bp - condition not m
  4462.     ret    nz        ;nz - collision    with user bp
  4463.     ld    hl,sbps
  4464.     inc    (hl)        ;bump count of step bps
  4465.     ret
  4466.     page
  4467. ;******************************************************************************
  4468. ;*
  4469. ;*    pswDsp:    display    current    state of flag register
  4470. ;*
  4471. ;*    pswbit:    table of bit masks with    which to test f    reg.
  4472. ;*        two byte entry per bit (sign, zero, carry, parity).
  4473. ;*
  4474. ;*    pswmap - table of offsets into operand name table featuring a
  4475. ;*         two byte entry    for each flag bit.
  4476. ;*         bit 4 (unused by z80) from pswbit entry is on/off flag
  4477. ;*         lo bytes are the off states (p    nz nc po).
  4478. ;*         hi bytes are the on states  (m     z  c pe).
  4479. ;*
  4480. ;*    - current state    of flag    register is displayed
  4481. ;*    - user queried for changes
  4482. ;*    - input    is parsed and tested for valid flag reg    mnemonics
  4483. ;*    - if valid mnemonic found flag bit is set or reset accordingly
  4484. ;*
  4485. ;*    exit:    to z8e for next    command
  4486. ;*
  4487. ;******************************************************************************
  4488.  
  4489. pswDsp:    ld    de,3
  4490.     ld    b,0            ;+ eg 3.3.5a
  4491. psw00:    ld    hl,pswbit        ;table of bit mask for flags
  4492.     add    hl,de            ;
  4493.     add    hl,de            ;index times two
  4494.     ld    a,e
  4495.     neg                ;now calculate index into pswmap
  4496.     add    a,3
  4497.     add    a,a
  4498.     ld    c,a
  4499.     ld    a,(freg)        ;fetch current flag of user
  4500.     and    0f7h
  4501.     and    (hl)            ;unused    bit in flag - ensure it's off
  4502.     ld    hl,pswmap
  4503.     add    hl,bc            ;pointer to mnemonic is    8 bytes    away
  4504.     jr    z,psw10            ;this is an off    bit (nz    nc p po)
  4505.     inc    hl            ;on
  4506. psw10:    ld    c,(hl)            ;fetch index into operand name table
  4507.     ld    hl,zopnm
  4508.     add    hl,bc            ;two bytes per table entry
  4509.     add    hl,bc
  4510.     ld    c,2            ;print both chars of mnemonic name
  4511.     call    printb
  4512.     call    space
  4513.     dec    e            ;do all    four flag bits
  4514.     jp    p,psw00
  4515.     call    crlf
  4516.     ld    a,(lcmd)
  4517.  
  4518. ;    cp    'J'            ;- eg 3.3.5a
  4519. ;    ret    z            ;-
  4520.     cp    'P'            ;+ Routine can now be called from
  4521.     ret    nz            ;+  elsewhere
  4522.  
  4523.     call    space5
  4524. psw50:    call    iedtbc
  4525.     ret    m            ;no input
  4526. psw55:    call    prsr
  4527.     ret    nz            ;parse error - end command
  4528.     ld    bc,116h            ;
  4529.     call    oprn20            ;check validity    of this    token
  4530.     ld    a,c
  4531.     ld    bc,pswcnt        ;number    of flag    reg mnemonics
  4532.     ld    hl,pswmap
  4533.     cpir                ;check table
  4534.     jp    nz,e???            ;error - nmemonic not found
  4535.     ld    hl,pswbit        ;bit mask table
  4536.     add    hl,bc
  4537.     ld    a,(hl)            ;fetch mask
  4538.     ex    de,hl            ;
  4539.     ld    hl,freg            ;de - mask ptr     hl - user flag    ptr
  4540.     and    08            ;bit says turn on or off
  4541.     ld    a,(de)            ;new copy of mask
  4542.     jr    nz,psw60        ;nz - turn on
  4543.     cpl
  4544.     and    (hl)            ;and with current user flag
  4545.     ld    (hl),a            ;return    flag reg with bit now off
  4546.     jr    psw55            ;check for more    input
  4547. psw60:    and    0f7h            ;turn off on/off flag (bit 4)
  4548.     or    (hl)
  4549.     ld    (hl),a            ;now turn on specified bit
  4550.     jr    psw55
  4551.     page
  4552. ;******************************************************************************
  4553. ;*
  4554. ;*    movb:    move memory
  4555. ;*
  4556. ;*    call bcde to fetch destination block address and byte count
  4557. ;*    call prsr
  4558. ;*    check for head to head or tail to tail move
  4559. ;*
  4560. ;*    exit: to z8e for next command
  4561. ;*
  4562. ;******************************************************************************
  4563.  
  4564. movb:    call    bcde        ;bc - byte count  de - destination  hl - source
  4565.     jp    nz,e???        ;input error ends command
  4566.     xor    a
  4567.     sbc    hl,de
  4568.     adc    a,a
  4569.     add    hl,de
  4570.     add    hl,bc
  4571.     dec    hl
  4572.     ex       de,hl        ;de - address of last byte of source block
  4573.     sbc    hl,de
  4574.     adc    a,a
  4575.     add    hl,de        ;hl - original destination address
  4576.     ex    de,hl
  4577.     cp    3
  4578.     jr    nz,movb00    ;head to head
  4579.     ex    de,hl
  4580.     add    hl,bc
  4581.     dec    hl
  4582.     ex    de,hl
  4583.     lddr
  4584.     ret
  4585. movb00:    inc    hl
  4586.     and    a
  4587.     sbc    hl,bc
  4588.     ldir    
  4589.     ret
  4590.     page
  4591. ;******************************************************************************
  4592. ;*
  4593. ;*    yfil:    fill memory
  4594. ;*
  4595. ;*    call bcde to get byte count, starting address, and fill byte
  4596. ;*
  4597. ;*    exit:    to z8e for next    command
  4598. ;*
  4599. ;******************************************************************************
  4600.  
  4601. yfil:    call    bcde        ;bc - byte count  de - fill byte  hl - block
  4602.     jp    nz,e???        ;input error ends command
  4603.     ex    de,hl
  4604. yfil00:    ld    hl,argbf
  4605.     ld    a,(argbc)
  4606. yfil10:    ldi
  4607.     inc    b
  4608.     djnz    yfil20
  4609.     inc    c
  4610.     dec    c
  4611.     ret    z
  4612. yfil20:    dec    a
  4613.     jr    nz,yfil10
  4614.     jr    yfil00
  4615.     page
  4616. ;*********************************************************************
  4617. ;
  4618. ;    CUSER    Change user routine    EG    5 Jan 88
  4619. ;
  4620. ;    10 Jan 88    Added check for bad args
  4621. ;
  4622. ;    Uses '>' as command
  4623. ;
  4624. ;*********************************************************************
  4625.  
  4626. cuser:    call     iedtbc
  4627.     ret     m
  4628.     call     iarg        ; gets user in HL as a hex no
  4629.     jp     nz,e???        ; don't allow bad (would go to user 0)
  4630.     ld     a,h
  4631.     or     a
  4632.     jp     nz,e???        ; 2 - byte user number?
  4633.     ld     a,l
  4634.     cp     10h
  4635.     jr     c,cusok        ; you can enter user in hex or decimal with '#'
  4636.     sub     6        ; else convert to decimal
  4637.     cp     10h        ; see if still too big
  4638.     jp    nc,e???
  4639. cusok:    ld     c,32
  4640.     ld     e,a
  4641.     jp     bdos        ; change user
  4642.  
  4643. ;*******************************************************************
  4644. ;
  4645. ;    QEVAL - expression evaluator    EG 10 Jan 88
  4646. ;
  4647. ;    Uses '?' as command
  4648. ;
  4649. ;*******************************************************************
  4650. qeval:     call     iedtbc        ; get input
  4651.     ret     m        ; none
  4652.     call     iarg        ; Z8E does all the real work
  4653.     jp     nz,e???        ; check for valid arg
  4654.     call     crlf
  4655.     ld     a,h        ; see if 1 byte
  4656.     or     a
  4657.     jr     nz,qev01    ; 2-byte number
  4658.     ld     a,l
  4659.     call     outhex        ; hex byte 
  4660.     ld     a,l
  4661.     cp     7fh        ; see if printable
  4662.     ret     nc
  4663.     cp     ' '        
  4664.     ret     c
  4665.     ld     c,3
  4666.     call     spaces        ; even up with spaces
  4667.     ld     a,27h        ; quote
  4668.     call     ttyo
  4669.     ld     a,l        ; show char
  4670.     call     ttyo
  4671.     ld     a,27h
  4672.     jp     ttyo
  4673. qev01:    jp     outadr        ; output 2-byte result
  4674.  
  4675. ;***********************************************************
  4676. ;
  4677. ;    GADR - Get program addr data    EG 20 Feb 88
  4678. ;
  4679. ;    Uses '#' as command
  4680. ;
  4681. ;    Deleted 5/Jan/89 by jrs - unnecessary as L command
  4682. ;    with no file name (now) does the same thing.
  4683. ;
  4684. ;************************************************************
  4685. ;gadr:    ld     hl,(loadn)
  4686. ;    ld     c,10        ; out-of-memory flag
  4687. ;    jp     lbin22    
  4688.     page
  4689. ;------------------------------------------------------------------------------
  4690. ;
  4691. ;    Initialise default FCB fields and command line    (16 may 87  jrs)
  4692. ;
  4693. ;    Calls iedtbc to get command tail
  4694. ;          lfcb   twice to extract file names
  4695. ;
  4696. ;    exit:    FCB name fields at 5Ch and 6Ch initialised
  4697. ;        Command tail set up at 80h
  4698. ;
  4699. ;------------------------------------------------------------------------------
  4700.  
  4701. ifcb:                ;(Condensed, improved version - jrs 27 Dec 88)
  4702.  
  4703.     call    iedtbc        ;Get command tail
  4704.     dec    hl        ;Point at input buffer length
  4705.     push    hl        ;Save input buffer pointer
  4706.     ld    hl,fcb5c    ;Zero out the default FCB
  4707.     ld    b,32
  4708. ifcb00:    ld    (hl),0
  4709.     inc    hl
  4710.     djnz    ifcb00
  4711.     ld    l,fcb5c+1    ;Blank out the two file names
  4712.     call    iblank
  4713.     ld    l,fcb5c+17
  4714.     call    iblank
  4715.     pop    hl        ;Get input buffer pointer
  4716.     ld    de,80h        ;Destination is command line buffer
  4717.     ld    b,(hl)        ;Get input buffer length
  4718.     ld    a,b        ;Load length ready to put in command buffer
  4719.     inc    b        ;Account for the length byte itself
  4720. ifcb02:
  4721.     ld    (de),a        ;Store character in command buffer
  4722.     inc    de        ;Increment pointers
  4723.     inc    hl
  4724.     ld    a,(hl)        ;Load character from input buffer
  4725.     call    ixlt        ;Translate to upper case
  4726.     djnz    ifcb02        ;Loop until all copied
  4727.     xor    a        ;Terminate the command buffer properly
  4728.     ld    (de),a
  4729.     call    lfcb        ;Get a file name (if any)
  4730.     jr    nz,ifcb12    ;Skip if error
  4731.     ld    de,fcb5c    ;Copy FCB to default FCB at 5ch
  4732.     ld    hl,fcb
  4733.     ld    bc,12        ;(only move 12 bytes)
  4734.     ldir
  4735. ifcb12:
  4736.     call    lfcb        ;Do second file name (if any)
  4737.     ret    nz        ;Exit now if error
  4738.     ld    hl,fcb        ;Copy file name part of FCB to
  4739.     ld    de,fcb5c+16    ; second segment of default FCB
  4740.     ld    bc,12
  4741.     ldir
  4742.     ret
  4743.  
  4744. iblank:                ;Blank out 11 bytes at HL
  4745.     ld    b,11
  4746. ibl00:    ld    (hl),' '
  4747.     inc    hl
  4748.     djnz    ibl00
  4749.     ret
  4750.  
  4751.  
  4752. ; I originally intended that the following code should be used to expand
  4753. ; asterisks in file names but I never invoked it anywhere!  Eventually
  4754. ; someone complained and I corrected the omission by adding some code to
  4755. ; the LFCB routine.  When I (re)discovered this code I noticed that it was
  4756. ; longer than the code added to LFCB so I commented it out.  I am leaving
  4757. ; it here because LFCB was never intended to handle ambiguous file names.
  4758. ; I don't think there is a problem but should there turn out to be some
  4759. ; sort of wierd conflict then it should be easy to activate this little
  4760. ; routine.    jrs 27 Dec 88
  4761. ;
  4762. ;iwild:                ;Expand asterisks in file names
  4763. ;    ld    bc,8        ;Enter with HL pointing at FCB+1
  4764. ;    call    iexp        ; i.e. first byte of file name.
  4765. ;    ld    bc,3
  4766. ;;    call    iexp
  4767. ;;    ret
  4768. ;iexp:
  4769. ;    ld    a,'*'
  4770. ;    cpir
  4771. ;    ret    nz
  4772. ;    inc    bc
  4773. ;    dec    hl
  4774. ;iexp10:
  4775. ;    ld    (hl),'?'
  4776. ;    inc    hl
  4777. ;    dec    c
  4778. ;    ret    z
  4779. ;    jr    iexp10
  4780.     page
  4781. ;******************************************************************************
  4782. ;*
  4783. ;*    lldr:    Load file
  4784. ;*    User may supply    optional load bias if file name ends with comma.
  4785. ;*
  4786. ;*    lfcb:    Parse input buffer (inbf) and init FCB
  4787. ;*
  4788. ;*        Return:    z  - FCB initialized
  4789. ;*            nz - syntax error
  4790. ;*
  4791. ;*    lopn:    Attempt to open file
  4792. ;*
  4793. ;*        Return:    nz - file opened
  4794. ;*             z - file not found
  4795. ;*
  4796. ;*    lmem:    Test if sufficient memory available for loading
  4797. ;*
  4798. ;*        Return: nc - out of memory
  4799. ;*
  4800. ;*    lbin: Loader
  4801. ;*
  4802. ;*        Eof found:     end command
  4803. ;*        Out of memory: query user whether to continue
  4804. ;*
  4805. ;******************************************************************************
  4806.  
  4807. lldr:    call    iedtbc        ;Get file name
  4808.     jp     p,lldr00         ;P - have input in inbf
  4809.     ld    hl,(loadn)
  4810.     ld    a,l
  4811.     or    h
  4812.     jp    z,e???
  4813. ;    ld    c,a        ;-
  4814.     ld    c,10        ;+ 3.5.5 jrs 5/jan/89
  4815.     jp    lbin22
  4816. lldr00:    call    crlf
  4817.     call    lfcb        ;Init FCB with name and    drive
  4818.     jp    nz,esntx    ;nz - syntax error
  4819.     ld    de,mldg        ;Display loading string
  4820.     call    nprint
  4821.     ld    de,prsbf
  4822.     ld    a,(de)        ;A - first char    of file    name
  4823.     ld    b,a
  4824.     call    print
  4825.     ld    a,','
  4826.     cp    c        ;C - terminator    following file name (from lfcb)
  4827.     ld    hl,100h        ;Assume    no bias
  4828.     jr    nz,lldr05    ;NZ - no comma means no    load bias
  4829.     call    iarg        ;Check for load    bias
  4830.     jp    nz,esntx    ;Error - bad argument
  4831.     call    imem        ;Check available memory
  4832.     jp    nc,emem??    ;Out of    memory
  4833. lldr05:    ld    (loadb),hl    ;Save load bias
  4834.     ld    a,'.'        ;Test if file name is period
  4835.     sub    b
  4836.     jr    z,lbin        ;File name is period - no open needed
  4837. lldr10:    call    lopn        ;Attempt to open file -    entry from nint
  4838.     jp    z,efilnf    ;Z - file not found
  4839.  
  4840.  
  4841. lbin:
  4842.     ld    hl,(loadb)    ;Fetch starting    load address
  4843. lbin00:    push    hl
  4844.     ex    de,hl
  4845.     ld    c,26        ;Set CP/M DMA address
  4846.     call    bdos
  4847.     ld    de,fcb
  4848.     ld    c,20        ;CP/M sequential file read
  4849.     call    bdos
  4850.     pop    de        ;Recover DMA address
  4851.     ld    hl,80h
  4852.     add    hl,de        ;Compute next DMA address
  4853.     ld    (cflag),a    ;Save EOF indicator as continuation flag
  4854.     ld    c,a
  4855.     and    a
  4856.     jr    nz,lbin20    ;NZ - end of file
  4857.     call    imem        ;Test if memory    available to load next sector
  4858.     jr    c,lbin00    ;C - not out of    memory
  4859. lbin20:    ex    de,hl
  4860.     dec    hl
  4861.     ld      (loadn),hl    ;End of load address
  4862. lbin22: ld    de,mlodm    ;Print loaded message
  4863.     call    nprint
  4864.     ex    de,hl        ;DE - ending address of    load
  4865.     ld    hl,(loadb)
  4866.     call    outadr        ;Display starting address of load
  4867.     ex    de,hl
  4868.     call    outadr        ;Display ending    address
  4869.     and    a
  4870.     sbc    hl,de
  4871.     inc    h
  4872.     ld    de,mlodpg
  4873.     call    nprint        ;Display pages string
  4874.     ld    l,a        ;zero L    reg
  4875.     ld    a,h        ;Hi byte of ending address is number of pages
  4876.     cp    100
  4877.     jr    c,lbin30    ;Less than 100
  4878.     ld    l,'2'
  4879.     sub    200
  4880.     jr    nc,lbin25    ;Greater than 200
  4881.     dec    l        ;change    to ASCII 1
  4882.     add    a,100        ;Restore actual page count less 100
  4883. lbin25:    ld    h,a        ;Save page count
  4884.     ld    a,l
  4885.     call    ttyo
  4886. lbin30:    ld    d,2fh
  4887.     ld    a,h
  4888. lbin35:    inc    d        ;Tens and units    decimal    conversion loop
  4889.     sub    10
  4890.     jr    nc,lbin35
  4891.     add    a,10        ;Restore remainder
  4892.     ld    e,a        ;Temp save while we print tens
  4893.     ld    a,d
  4894.     inc    l
  4895.     dec    l        ;Test L    reg
  4896.     jr    nz,lbin40    ;NZ - ASCII 1 or 2 in L
  4897.     cp    '0'        ;Suppress leading zero - less than 10 pages
  4898. lbin40:    call    nz,ttyo        ;Print tens digit
  4899.     ld    a,e
  4900.     or    '0'
  4901.     call    ttyo        ;Print units
  4902.     call    crlf
  4903. ;    xor    a        ;- eg 3.3.7a Test eof flag
  4904. ;    or    c        ;-
  4905.     ld    a,c        ;+ Test EOF flag
  4906.     cp    10        ;+ Was it set by GADR (see 3.3.11)
  4907.     jp    z,z8e        ;+ Exit if so
  4908.     or    a        ;+
  4909. ;    jp    nz,z8e        ;- nz - true eof means file loading complete
  4910.     jr    nz,z8ej        ;+
  4911.     ld    de,mmem??    ;Print "out of memory" message
  4912.     call    print
  4913.     ld    de,mcntu
  4914.     call    print        ;Print continue? prompt
  4915.     call    inchar
  4916.     call    ixlt        ;Make sure its upper case
  4917.     cp    'Y'
  4918.     call    crlf
  4919.     jp    z,lbin        ;User wants more loading
  4920. z8ej:                ;+
  4921.     ld    c,26        ;+ "Set DMA" function
  4922.     ld    de,80h        ;+ Restore default DMA for user program
  4923.     call    bdos        ;+
  4924.     jp    z8e        ;Next command
  4925.  
  4926.  
  4927. lfcb:    call    prsr        ;parse input buffer to extract file name
  4928.     ld    d,a        ;save char which terminated file name
  4929.     ld    a,14
  4930.     cp    b        ;over 14 chars is ng file name
  4931.     ret    c
  4932.     ld    c,b        ;b and c - byte    count of file name
  4933.     djnz    lfcb00        ;test for only one char    in name
  4934.     ld    a,(prsbf)    ;only one - is it period?
  4935.     sub    '.'
  4936.     jr    nz,lfcb00
  4937.     ld    c,d        ;return    terminator
  4938.     ld    a,(cflag)    ;continuation allowed?
  4939.     and    a        ;let lldr decide
  4940.     ret
  4941. lfcb00:    ld    b,0
  4942.     ld    a,':'        ;check for drive specifier in input
  4943.     cpdr
  4944.     ld    b,c        ;b - number of chars preceding colon
  4945.     ld    c,d        ;return    terminator in c
  4946.     ld    de,fcb
  4947.     ld    a,0
  4948.     jr    nz,lfcb10    ;nz - no colon
  4949.     dec    b
  4950.     ret    nz        ;syntax    error -    more than one char
  4951.     ld    a,(hl)        ;fetch drive specifier
  4952.     call    ixlt
  4953.     ld    (hl),a        ;back to parse buffer as upper case    
  4954.     sub    40h        ;make name into    number
  4955.     inc    hl
  4956. lfcb10:                
  4957.            ld    (de),a        ;store drive number in fcb
  4958.     ld    a,' '
  4959.     ld    b,11        ;clear file name in fcb    to spaces
  4960. lfcb20:    inc    de
  4961.     ld    (de),a
  4962.     djnz    lfcb20
  4963.     ld    b,8        ;max chars allowed in file name
  4964.     ld    de,fcbnam
  4965. lfcb30:    call    lfcb90
  4966.     ret    m        ;error - too many chars    in file    name
  4967.     ld    b,3        ;max chars allowed in file type
  4968.     ld    de,fcbtyp
  4969.     and    a
  4970.     ret    z        ;z - no    file type after    all
  4971.  
  4972.  
  4973.  
  4974. lfcb90:    inc    hl        ;Bump buffer pointer
  4975.     ld    a,(hl)
  4976.     and    a        ;Test for null at end of file name
  4977.     ret    z        ;Null found - nothing more to parse
  4978.     call    ixlt
  4979.     ld    (hl),a        ;Translate parse buffer    to upper case
  4980.     cp    '.'
  4981.     ret    z        ;Period    found -    move file type into FCB
  4982.  
  4983. ; --- Added 4 Dec 88 --- jrs
  4984.     cp    '*'        ;Expandable wildcard?
  4985.     jr    z,lfcb95
  4986. ; --- end of added code ---
  4987.     dec    b        ;Dec max chars allowed
  4988.     ret    m        ;Error if name or extension is too long
  4989.                 ; or a character follows an asterisk
  4990.     ld    (de),a        ;Upper case only into FCB
  4991.     inc    de
  4992.     jr    lfcb90
  4993. ; --- Added 4 Dec 88 --- jrs
  4994. lfcb95:
  4995.     ld    a,'?'
  4996. lfcb96:
  4997.     ld    (de),a
  4998.     inc    de
  4999.     djnz    lfcb96
  5000.     jr    lfcb90
  5001. ; --- end of added code ---
  5002. lopn:
  5003.     ld    hl,fcbnam    ;test for file name present
  5004.     ld    a,(hl)
  5005.     cp    ' '
  5006.     ret    z        ;space found means not file
  5007. ;;    dec    hl
  5008. ;;    ld    a,(hl)        ;drive specifier
  5009. ;;    and    a        ;test for default drive
  5010. ;    jr    z,lopn00    ;z - default means no selection    required
  5011. ;    dec    a        ;select    drive
  5012. ;    ld    e,a
  5013. ;    ld    c,14
  5014. ;    call    bdos
  5015. lopn00:    ld    de,fcb
  5016.     ld    b,nfcb-fcbext
  5017.     ld    hl,fcbext    ;clear remainder of fcb
  5018. lopn10:    ld    (hl),0
  5019.     inc    hl
  5020.     djnz    lopn10
  5021.     ld    c,15
  5022.     call    bdos        ;tell bdos to open file
  5023.     inc    a        ;test open return code
  5024.     ret            ;nz - open ok
  5025.  
  5026. imem:    ex    de,hl        ;de - next load    address
  5027.     ld    a,d
  5028.     ld    hl,07        ;ptr to    prt to start of    z8e
  5029.     cp    (hl)
  5030.     ex    de,hl
  5031.     ret    c        ;c - not out of memory
  5032.     ex    de,hl
  5033.     ret            ;de - last address loaded plus one
  5034.  
  5035. esntx:    ld    de,msntx    ;print syntax error
  5036.     jr    eprint
  5037.  
  5038. emem??:    ld    de,mmem??    ;print out of memory
  5039.     call    nprint
  5040.     jr    eprint
  5041.  
  5042. efilnf:    ld    de,mfilnf    ;print file not    found
  5043.  
  5044. eprint:    call    nprint
  5045.     jp    z8e
  5046.     page
  5047. ;*****************************************************************************
  5048. ;*
  5049. ;*            write memory segment to disk command
  5050. ;*
  5051. ;*****************************************************************************
  5052.  
  5053. writ:    call    iedtbc        ;fetch line of input
  5054.     ret    m        ;no input - 
  5055.     call    bldf        ;build fcb with first arg in buffer
  5056.     jr    nz,esntx    ;oops - syntax error
  5057.     ld    a,(delim)    ;check char that terminated file name
  5058.     and    a
  5059.     jr    nz,writ10    ;nz - not null means user entered addresses
  5060.  
  5061.     ld    de,(loadb)    ;use default begin and end address of the last
  5062.     ld    hl,(loadn)    ;file loaded
  5063.     jr    writ30
  5064. writ10:    call    iarg        ;get address
  5065.     jp    nz,e???        ;invalid address
  5066.     ex    de,hl
  5067.     cp    ' '        ;space terminator
  5068.     jp    nz,e???        ;anything but is error
  5069. writ20:    call    iarg        ;get end address 
  5070.     jp    nz,e???
  5071. writ30:    ld    (endw),hl    ;save address of where to end writing
  5072.     ex    de,hl
  5073.     ld    c,3
  5074.     call    spaces
  5075.     call    outadr        
  5076.     ex    de,hl
  5077.     ld    c,6
  5078.     call    spaces
  5079. writ40:    call    bwrite
  5080.     ld    hl,127
  5081.     add    hl,de
  5082.     ld    b,6
  5083. writ50:    call    bksp
  5084.     djnz    writ50
  5085.     call    outadr
  5086.     inc    hl
  5087.     ex    de,hl
  5088.     ld    hl,(endw)
  5089.     sbc    hl,de
  5090.     jr    nc,writ40
  5091.     jp    closef
  5092.     
  5093.     
  5094.  
  5095. ;******************************************************************************
  5096. ;*
  5097. ;*    find:    locate string in memory
  5098. ;*
  5099. ;*        call iarg - get    starting address of seach
  5100. ;*
  5101. ;*        call in00 - get    match data concatenating multiple arguments
  5102. ;*                into a single string
  5103. ;*
  5104. ;*        addresses at which matches found displayed 8 per line.
  5105. ;*        search continues until end of memory reached
  5106. ;*        user may cancel    search at any time by hitting any key.
  5107. ;*
  5108. ;*        exit: to z8e for next command
  5109. ;*
  5110. ;******************************************************************************
  5111.  
  5112. find:    call    iedtbc
  5113.     ret    m        ;m - no    input
  5114.     call    iarg        ;extract starting address of search
  5115.     jp    nz,e???        ;error
  5116.     ex    de,hl        ;save starting address of search in de
  5117. find00:    call    in00        ;extract search    string concatenating multiple
  5118.                 ;arguments
  5119.     jp    nz,e???        ;error - output    command    prompt
  5120.     xor    a
  5121.     ld    (lines),a    ;clear crlf flag
  5122.     ex    de,hl        ;starting address of search - hl
  5123.     ld    de,argbf    ;argument stored here
  5124.     
  5125.     ld    bc,(fndsym)
  5126.     ld    a,c
  5127.     or    b        ;symbol found?
  5128.     jp    z,find40    ;no
  5129.     
  5130.     ex    de,hl        ;hl - argument buffer
  5131.     ld    b,(hl)        ;reverse order of the two bytes for symbols
  5132.     inc    hl
  5133.     ld    a,(hl)
  5134.     ld    (hl),b
  5135.     dec    hl
  5136.     ld    (hl),a
  5137.     ex    de,hl
  5138.     
  5139. find40:    ld    bc,(argbc)    ;number    of bytes to look for
  5140.     call    crlf
  5141. find50:    call    srch        ;do the    search
  5142.     jr    nz,find60    ;not found
  5143.     call    outadr        ;display address where match found
  5144.     ld    a,(lines)
  5145.     dec    a        ;carriage return after 8 addresses displayed
  5146.     ld    (lines),a
  5147.     and    7
  5148.     call    z,crlf
  5149.     call    ttyq        ;user requesting abort?
  5150.     cp    cr
  5151.     ret    z        ;abort - return    to z8e
  5152. find60:    inc    hl        ;point to next address at which    to start search
  5153.     add    hl,bc        ;ensure    we won't hit end of memory by adding
  5154.                 ;in string size
  5155.     ret    c        ;impending end of memory
  5156.     sbc    hl,bc        ;restore pointer
  5157.     jr    find50
  5158.  
  5159. srch:    push    bc
  5160.     push    de
  5161.     push    hl
  5162. srch00:    ld    a,(de)
  5163.     cpi
  5164.     jp    nz,srch10    ;no match
  5165.     inc    de
  5166.     jp    pe,srch00    ;tally not expired - check next
  5167. srch10:    pop    hl
  5168.     pop    de
  5169.     pop    bc
  5170.     ret
  5171.     page
  5172. ;******************************************************************************
  5173. ;*
  5174. ;*    verify:    verify two blocks of data are identical
  5175. ;*
  5176. ;*        enter: de - starting address of    block 1
  5177. ;*
  5178. ;*        call bcde to get address of block 2 and    byte count
  5179. ;*
  5180. ;*        mismatch:   block 1 address and    byte are displayed
  5181. ;*                block 2 address and    byte are displayed
  5182. ;*                console intrrogated    - any input terminates verify
  5183. ;*
  5184. ;*        exit:    to z8e for next    command
  5185. ;*
  5186. ;******************************************************************************
  5187.  
  5188. verify:    call    bcde        ;get block 2 address and byte count
  5189.     jp    nz,e???
  5190.     ex    de,hl
  5191. verf00:    ld    a,(de)        ;byte from block 1
  5192.     xor    (hl)        ;versus    byte from block    two
  5193.     jr    z,verf10    ;match - no display
  5194.     call    newlin
  5195.     ld    a,(de)
  5196.     call    othxsp        ;display block 1 data
  5197.     call    space
  5198.     call    outadr        ;display block two address
  5199.     ld    a,(hl)
  5200.     call    outhex        ;display results of xor
  5201.     call    ttyq        ;check input status
  5202.     cp    cr
  5203.     ret    z
  5204. verf10:    inc    hl        ;bump block 1 pointer
  5205.     inc    de        ;bump block 2 pointer
  5206.     dec    bc        ;dec byte count
  5207.     ld    a,b
  5208.     or    c
  5209.     jr    nz,verf00
  5210.     ret
  5211.     page
  5212. ;******************************************************************************
  5213. ;*
  5214. ;*    xreg:    display    machine    state
  5215. ;*
  5216. ;*        regptr:    table contains offsets to names    in operand name    table.
  5217. ;*            sign bit set indicates prime register.
  5218. ;*
  5219. ;*        regmap:    table contains offsets to reg contents table (regcon)
  5220. ;*            sign bit ignored (used by rgst command).
  5221. ;*
  5222. ;*        regcon:    table of register contents.
  5223. ;*
  5224. ;*        exit:    make current pc    current    disassembly location counter.
  5225. ;*            set bit    6 of disassembly flag byte (zasmfb)
  5226. ;*            jump to    zasm30 to disassemble current instruction.
  5227. ;*
  5228. ;******************************************************************************
  5229.  
  5230. xreg:    call    cret
  5231.     ld    bc,0        ;init reg index
  5232. xreg00:    call    xreg05        ;display reg name and contents
  5233.     inc    c
  5234.     ld    a,c
  5235.     cp    8
  5236.     call    z,crlf
  5237.     ld    a,c
  5238.     cp    0ch
  5239.     ld    b,0
  5240.     jr    nz,xreg00
  5241.     ld    a,(lcmd)
  5242.     cp    'J'        ;animated command in effect?
  5243.     ret    z        ;z - no disassembly required
  5244.     ld    hl,(pcreg)
  5245.     ld    (zasmpc),hl
  5246. ;    jp    zasm30        ;- eg 3.3.5b
  5247.     call    zasm30        ;+
  5248.     jp    pswDsp        ;+
  5249.  
  5250. xreg05:    ld    hl,regptr    ;map of    reg name pointers
  5251.     ld    d,b
  5252.     add    hl,bc
  5253.     ld    a,(hl)        ;extract pointer
  5254.     and    7fh        ;strip sign for    name indexing
  5255.     ld    e,a
  5256.     ld    b,(hl)        ;save copy of offset - need sign later
  5257.     ld    hl,zopnm    ;register name table
  5258.     add    hl,de
  5259.     add    hl,de        ;two bytes per entry
  5260.     ld    a,(hl)
  5261.     call    ttyo        ;display character one
  5262.     inc    hl
  5263.     ld    a,(hl)
  5264.     cp    ' '        ;is second character a space?
  5265.     jr    nz,xreg10
  5266.     ld    a,'C'        ;replace space - this is pc
  5267. xreg10:    call    ttyo        ;display second    character
  5268.     xor    a
  5269.     or    b        ;now test sign
  5270.     jp    p,xreg20    ;sign not set -    not prime reg
  5271.     ld    a,27h        ;display quote
  5272.     call    ttyo
  5273. xreg20:    ld    a,':'
  5274.     call    ttyo
  5275.     ld    hl,regmap    ;map of    pointers to reg    contents
  5276.     add    hl,de
  5277.     ld    a,(hl)
  5278.     jp    p,xreg30    ;p - not prime reg
  5279.     add    a,8        ;prime contents    8 bytes    past non-prime
  5280. xreg30:    and    7fh        ;ignore    sign
  5281.     ld    e,a
  5282.     ld    hl,regcon    ;start of register contents storage
  5283.     add    hl,de
  5284.     ld    d,(hl)        ;hi order contents
  5285.     dec    hl
  5286.     ld    e,(hl)
  5287.     ex    de,hl
  5288.     call    outadr        ;display contents
  5289.     ret
  5290.  
  5291.     page
  5292. ;******************************************************************************
  5293. ;*
  5294. ;*    zasm
  5295. ;*
  5296. ;*    the disassembler is divided into two routines:
  5297. ;*
  5298. ;*    zasm - computes    the instruction    key value and finds the    opcode nmemonic
  5299. ;*    opn  - uses the    key value to determine the number of operands and
  5300. ;*           displays    the operands.
  5301. ;*
  5302. ;*    entered: de - starting address to disassemble
  5303. ;*
  5304. ;*        zasm maps the 695 z80 instrucions into 256 key values. 
  5305. ;*              the instruction key value becomes the index into the
  5306. ;*              opcode name pointer table (zopcnm), the first operand table
  5307. ;*        (zopnd1), and the second operand table (zopnd2).
  5308. ;*
  5309. ;*        disassembly is done in user specified block sizes if the
  5310. ;*        disassembly count evaluates to a number    between    1 and 255. if
  5311. ;*        the count is greater than 255 the block    is disassembled    and the
  5312. ;*        the command terminates.
  5313. ;*
  5314. ;*
  5315. ;*        zasm15 - start of the disassembly loop
  5316. ;*        zasmpc - address of the    instruction being disassembled
  5317. ;*        zasmfb - disassembly flag byte
  5318. ;*        zmflag - flag indicating directive processing (defb and    defw)
  5319. ;*
  5320. ;*                bit    6 - xreg calling
  5321. ;*                bit    5 - asmblr calling
  5322. ;*                bit    0 - write to disk flag
  5323. ;*
  5324. ;*
  5325. ;*
  5326. ;******************************************************************************
  5327.  
  5328.  
  5329. zasm:
  5330.     call    iedtbc
  5331.  
  5332. ;    ret    m        ;- eg 3.3.2
  5333.     jp    p,zasm0        ;+ Skip if arguments supplied, otherwise ...
  5334.     ld    b,0        ;+ Signal no file write
  5335.     ld    hl,16        ;+ Assume 16 lines of code
  5336.     ld    (zasmwt),hl    ;+
  5337.     ld    (zasmct),hl    ;+
  5338.     jr    zasm06        ;+
  5339. zasm0:                ;+
  5340.     call    iarg
  5341.     jp    nz,e???
  5342.     ex    de,hl
  5343.     call    iarg        ;read in block size
  5344.     ld    b,a        ;save delimeter
  5345.     jr    z,zasm00
  5346.     ld    hl,1        ;change    zero count to one
  5347. zasm00:    xor    a
  5348.     or    h
  5349.     jr    z,zasm05
  5350.     sbc    hl,de
  5351.     jp    c,e???        ;error - start address greater than end
  5352.     add    hl,de
  5353. zasm05:    ld    (zasmct),hl    ;save as permanent block count
  5354.     ld    (zasmwt),hl    ;save as working tally
  5355.     ex    de,hl        ;hl - current instruction pointer
  5356.     ld    (zasmpc),hl
  5357. zasm06:                ;+ eg 3.3.2
  5358.     call    crlf
  5359.     ld    a,b        ;check command line delimeter
  5360.     ld    (dwrite),a    ;save as write to disk flag:
  5361.                 ;z - no write   nz - write
  5362.     and    a
  5363.     call    nz,bldf        ;not end of line - build fcb
  5364.     jp    nz,esntx
  5365.  
  5366. zasm08:    ld    de,zasmbf    ;start of disassembly buffer
  5367.  
  5368. zasm10:    ld    (zasmio),de    ;init pointer
  5369.  
  5370. zasm15:    ld    de,(zasmpc)    ;fetch address to disassemble
  5371.     call    zlen00        ;calculate length
  5372.     ex    de,hl
  5373.  
  5374.                 ;loop back here for interactive disassembly -
  5375.                 ;user requests format change. c reg:
  5376.                 ;     6 and 7 off: disassemble as code
  5377.                 ;     6       on:  hex defb
  5378.                 ;     7       on:  hex defw or ascii defb
  5379.  
  5380. zasm18:    call    outadr        ;display instruction address
  5381.     ld    de,zmflag
  5382.     ld    a,c        ;save instruction length and format bits 
  5383.     ld    (de),a
  5384.     and    3fh
  5385.     ld    b,a        ;b  - length
  5386.     ld    c,a        ;c  - ditto
  5387. zasm20:    ld    a,(hl)
  5388.     call    othxsp        ;display object    code
  5389.     inc    hl
  5390.     djnz    zasm20
  5391.     ld    a,c        ;number    of object bytes
  5392.     dec    a
  5393.     xor    3
  5394.     ld    b,a        ;calculate space padding
  5395.     add    a,a
  5396.     add    a,b
  5397.     add    a,2
  5398.     ld    b,a
  5399. zasm25:    call    space
  5400.     djnz    zasm25
  5401.     ld    (zasmnx),hl    ;store address of next instruction
  5402.     and    a        ;clear carry
  5403.     sbc    hl,bc        ;point to first    byte in    instruction
  5404. zasm30:    ex    de,hl        ;de - current instruction pointer
  5405.     ld    hl,(zasmio)    ;buffer    address    storage
  5406.     ld    a,(maxlin)
  5407.     ld    b,a        ;line length based on max symbol size
  5408. zasm35:    ld    (hl),' '    ;space out buffer
  5409.     inc    hl
  5410.     djnz    zasm35
  5411.     ld    a,b
  5412.     ld    (opnflg),a
  5413.     ld    (hl),cr        ;append    crlf
  5414.     inc    hl
  5415.     ld    (hl),lf
  5416.     call    fadr        ;find address match
  5417.     ld    hl,(zasmio)
  5418.     jr    nz,zasm40    ;nz - no table or not found
  5419.     call    xsym
  5420.     ld    (hl),':'
  5421.     ld    de,(zasmpc)
  5422. zasm40:    ld    hl,zmflag    ;check interactive disassembly flag
  5423.     ld    a,(hl)        ;sign bit tells all
  5424.     and    a
  5425.     jp    p,zasm42    ;bit off - not interactive
  5426.     ld    b,6dh        ;test for defb
  5427.     sub    82h
  5428.     jr    z,zasm90
  5429.     xor    a        ;must be defw
  5430.     dec    b
  5431.     jr    zasm90
  5432. zasm42:    ld    a,(de)        ;first byte of op code
  5433.     ld    hl,op1000    ;table of z80 specific opcodes
  5434.     ld    c,4
  5435. zasm45:    cpir            ;check for fd dd ed or cb
  5436.     jr    z,zasm55    ;z - found
  5437. zasm50:    cp    40h
  5438.     jr    c,zasm90    ;opcode    range 0    - 3f
  5439.     ld    b,0e0h        ;
  5440.     cp    0c0h        ;
  5441.     jr    nc,zasm90    ;opcode    range c0 - ff
  5442.     cp    80h
  5443.     jr    nc,zasm85    ;opcode    range 80 - bf
  5444.     ld    b,0f8h        ;
  5445.     cp    76h        ;test for halt instruction
  5446.     jr    nz,zasm85    ;opcode    range 40 - 7f
  5447.     ld    a,0ffh        ;set halt instruction key value    to 0f7h
  5448.     jr    zasm90
  5449. zasm55:    inc    de
  5450.     ld    a,(de)        ;byte two of multi-byte    instruction
  5451.     dec    c        ;test for ed instruction
  5452.     jr    nz,zasm65    ;nz - not an ed
  5453.     cp    80h
  5454.     jr    nc,zasm60    ;opcode    range ed 40 - ed 7f
  5455.     cp    40h
  5456.     jr    nc,zasm90    ;legal
  5457.     ld    a,09fh
  5458.     jr    zasm90        ;map to    question marks
  5459. zasm60:    ld    b,0e0h        ;set bias
  5460.     cp    0c0h        ;test for illegal ed
  5461.     jr    c,zasm90    ;legal
  5462.     ld    a,0bfh        ;map to    question marks
  5463.     jr    zasm90        ;opcode    range ed a0 - ed bb
  5464.  
  5465.  
  5466. zasm65:    inc    c
  5467.     jr    z,zasm80    ;z - cb    instruction
  5468.     cp    0cbh        ;fd or dd - check for cb in byte two
  5469.     jr    nz,zasm70
  5470.     inc    de        ;fetch last byte of fdcb or ddcb
  5471.     inc    de
  5472.     ld    a,(de)
  5473.     rrca
  5474.     jr    c,zasm75
  5475.     and    3
  5476.     cp    3
  5477.     jr    nz,zasm75    ;error
  5478.     ld    a,(de)
  5479.     jr    zasm80
  5480. zasm70:    ld    a,(zmflag)
  5481.     sub    3
  5482.     ld    a,(de)
  5483.     jr    nz,zasm50
  5484.     ld    hl,z80f3
  5485.     ld    c,z80f3l
  5486.     cpir
  5487.     jr    z,zasm50
  5488. zasm75:    ld    a,09fh
  5489.     jr    zasm90
  5490. zasm80:    cp    40h        ;test type of cb instruction
  5491.     ld    b,0e8h
  5492.     jr    c,zasm85    ;opcode    range cb 00 - cb 3f (shift)
  5493.     rlca
  5494.     rlca
  5495.     and    03        ;hi order bits become index
  5496.     ld    b,0f0h
  5497.     jr    zasm90        ;opcode    range cb 40 - cb ff
  5498. zasm85:    rrca
  5499.     rrca
  5500.     rrca            ;bits 3-5 of cb    shift yield key
  5501.     and    07h
  5502. zasm90:    add    a,b        ;add in    bias from b reg
  5503.     ld    c,a        ;c - instruction key value
  5504.     xor    a
  5505.     ld    b,a
  5506.     ld    hl,zopcpt    ;opcode    name pointer table
  5507.     add    hl,bc        ;index into table
  5508.     ld    l,(hl)        ;fetch opname index
  5509.     ld    h,a
  5510.     add    hl,hl
  5511.     add    hl,hl        ;index times four
  5512.     ld    de,zopcnm    ;op code name table
  5513.     add    hl,de
  5514.     ex    de,hl        ;de - pointer to opcode    name
  5515.     ld    hl,(zasmio)    ;buffer    pointer    storage
  5516.     ld    a,c
  5517.     ld    (zasmkv),a    ;opcode key value 
  5518.     ld    a,(maxlen)
  5519.     ld    c,a
  5520.     inc    c        ;set label length based on max size
  5521.     
  5522.     ld    a,(lcmd)    ;if xreg use compressed output format
  5523.     cp    'X'
  5524.     jr    z,zasm92
  5525.     cp    'S'        ;step needs compressed format
  5526. zasm92:    add    hl,bc
  5527.     ld    c,4
  5528.     ex    de,hl        ;de - buffer   hl - opcode name    pointer
  5529.     ldir
  5530.     inc    bc        ;one space after opcode    for compressed format
  5531.     jr    z,zasm95
  5532.     ld    c,4        ;four spaces for true disassembly
  5533. zasm95:    ex    de,hl        ;hl - buffer pointer
  5534.     add    hl,bc        ;start of operand field    in buffer
  5535.     ld    a,(zasmkv)    ;save the instruction key value
  5536.     cp    09fh
  5537.     jr    nz,zasm99
  5538.     ld    de,(zasmpc)
  5539.     ld    a,(zmflag)
  5540.     ld    b,a
  5541. zasm97:    ld    a,(de)
  5542.     ld    c,d
  5543.     call    zhex
  5544.     dec    b
  5545.     jp    z,opn020
  5546.     ld    (hl),','
  5547.     inc    hl
  5548.     ld    d,c
  5549.     inc    de
  5550.     jr    zasm97
  5551. zasm99:    ld    de,zopnd1    ;table of first    operands
  5552.     add    a,e
  5553.     ld    e,a        ;instant offset
  5554.     ld    a,d
  5555.     adc    a,b
  5556.     ld    d,a
  5557.     ld    a,(de)
  5558.     inc    a
  5559.     jr    z,opn040    ;no operands
  5560.  
  5561.     page
  5562. ;******************************************************************************
  5563. ;*
  5564. ;*                          - operand processing -
  5565. ;*
  5566. ;*    enter:    b - zero (process first    operand)
  5567. ;*        c - instruction    key value
  5568. ;*
  5569. ;*   instruction key value is used to fetch operand key value:
  5570. ;*
  5571. ;*    operand    key value is in    the range 0 - 1fh
  5572. ;*    operand key value interpretted as follows:
  5573. ;*
  5574. ;*      0 - 17h  use as index to fetch literal from operand
  5575. ;*         name table (sign bit set - parens required)
  5576. ;*
  5577. ;*     18 - 1fh  operand requires processing - use as index
  5578. ;*             into oprerand jump table which is located
  5579. ;*             immediately after name table
  5580. ;*
  5581. ;*       0ffh  no operand
  5582. ;*
  5583. ;*   operand key value jump table routines: (buffer address in de)
  5584. ;*
  5585. ;*
  5586. ;*   entry point   key         action
  5587. ;*
  5588. ;*     opn100       18h     relative jump
  5589. ;*     opn200       19h     convert 8 bit operand to hex
  5590. ;*     opn300       1ah     convert 16 bit    operand    to hex
  5591. ;*     opn400       1ch     register specified in instruction
  5592. ;*     opn600       1dh     hl/ix/iy instruction
  5593. ;*     opn700       1eh     mask rst operand from bit 3-5 of rst instruction
  5594. ;*     opn800       1fh     bit number is specified in bits 3-5 of    op code
  5595. ;*
  5596. ;*    exit: to zasm15 to continue block disassembly
  5597. ;*
  5598. ;******************************************************************************
  5599.  
  5600. opn:    dec    a        ;save operand key value
  5601.     jp    p,opn010
  5602.     ld    (hl),'('
  5603.     inc    hl
  5604. opn010:    ex    de,hl        ;de - buffer address
  5605.     ld    b,a
  5606.     add    a,a        ;operand key value times two
  5607. opn012:    ld    hl,zopnm    ;base of operand name/jump table
  5608.     add    a,l        ;index into table
  5609.     ld    l,a
  5610.     jr    nc,opn014
  5611.     inc    h        ;account for carry
  5612. opn014:    ld    a,1fh
  5613.     and    b
  5614.     cp    zopnml        ;test if processing required
  5615.     jr    c,opn015    ;c - operand is    a fixed    literal
  5616.     ld    a,(hl)        ;fetch processing routine address
  5617.     inc    hl
  5618.     ld    h,(hl)        ;
  5619.     ld    l,a        ;hl - operand processing routine
  5620.     jp    (hl)        ;geronimoooooooo
  5621. opn015:    ldi            ;first byte of operand literal
  5622.     inc    bc        ;compensate for    ldi
  5623.     ex    de,hl        ;hl - buffer
  5624.     ld    a,(de)
  5625.     cp    ' '        ;test for space    as byte    two of literal
  5626.     jr    z,opn020    ;ignore    spaces appearing in byte two
  5627.     ld    (hl),a
  5628.     inc    hl        ;bump buffer pointer
  5629. opn020:    ld    a,b        ;operand key value
  5630.     cp    80h        ;test for closed paren required
  5631.     jr    c,opn030    ;c - none required
  5632.     ld    (hl),')'
  5633.     inc    hl
  5634. opn030:    ld    a,(opnflg)    ;get flag byte
  5635.     xor    0ffh        ;toggle operand number
  5636.     ld    (opnflg),a    ;
  5637.     jr    z,opn040    ;z - just finished number two
  5638.     ld    a,(zasmkv)    ;get op code key value
  5639.     ld    de,zopnd2    ;index into operand2 table
  5640.     add    a,e
  5641.     ld    e,a
  5642.     jr    nc,opn035
  5643.     inc    d
  5644. opn035:    ld    a,(de)        ;get operand2 key value 
  5645.     inc    a
  5646.     jr    z,opn040    ;z - no    second operand
  5647.     ld    (hl),','    ;separate operands with comma in buffer
  5648.     inc    hl
  5649.     jr    opn
  5650. opn040:    ld    hl,(zasmio)    ;rewind    buffer pointer
  5651.     ld    a,(maxlin)
  5652.     ld    c,a
  5653. opn041:
  5654.     ld    a,(case)
  5655.     and    a
  5656.     jr    z,opn043    ;Upper case requested - no need to convert
  5657.                 ;reg names [ras 19 Sep 85]
  5658. opn042:    ld    a,(hl)
  5659.     and    a        ;if sign bit on then no case conversion
  5660.     call    p,ilcs
  5661.     and    7Fh        ;in case we fell thru
  5662.     ld    (hl),a
  5663.     inc    hl
  5664.     dec    c
  5665.     jr    nz,opn042
  5666. opn043:                ;correct jmp from opn041 4-9-85
  5667.     ld    a,(maxlin)
  5668.     cp    30
  5669.     jr    z,opn044
  5670.     ld    a,44        ;allow 16 comment chars
  5671. opn044:
  5672.     ld    c,a        ;number of chars to print (omit crlf)
  5673.     ld    hl,(zasmio)
  5674.     ld    a,(lcmd)
  5675.     cp    'J'        ;j command
  5676.     ret    z        ;end of the line for full screen animation
  5677.     call    printb        ;print buffer
  5678.     inc    hl        ;point past crlf to next 32 byte group
  5679.     inc    hl
  5680.     ex    de,hl
  5681.     ld    a,(lcmd)    ;jettison all commands except z
  5682.     cp    'X'
  5683.     jp    z,crlf
  5684.     cp    'A'
  5685.     jp    z,crlf        
  5686.     cp    'S'
  5687.     jp    z,crlf
  5688.     xor    a
  5689.     ld    (zasmf),a
  5690.     ld    hl,(zasmct)    ;check disassembly count
  5691.     dec    hl        
  5692.     ld    a,h
  5693.     or    l        ;test for count expired
  5694.     jp    nz,opn060    ;nz - this is not a count of one so this is not
  5695.                 ;interactive disassebly
  5696.  
  5697.     call    ttyi        ;check input command letter for interactive
  5698.     call    ixlt        ;force upper case
  5699.     ld    (zasmf),a
  5700.     cp    'C'        ;code?
  5701.     call    z,cret        ;if user wants code return cursor to start of
  5702.                 ;line and disassemble again
  5703.     jp    z,zasm15
  5704.     ld    c,82h        ;assume defw
  5705.     cp    'D'        
  5706.     jr    z,opn045    ;defw -    082h
  5707.     dec    c        ;assume ascii defb
  5708.     cp    'A'
  5709.     jr    z,opn045    ;ascii defb - 081h
  5710.     cp    'B'
  5711.     jr    nz,opn046    ;none of the above
  5712.     ld    c,0c1h        ;hex defb - 0c1h
  5713. opn045:    call    cret
  5714.     ld    hl,(zasmpc)
  5715.     jp    zasm18
  5716.  
  5717.                 ;zasmf - 0 means this is block disassembly
  5718.                 ;      - nz means char entered during 
  5719.                       ;        interactive mode was not c d a or b. 
  5720.         
  5721. opn046:    cp    ';'        ;check if user wants to insert comments
  5722.     jr    nz,opn060    ;nz - user does not want to add comment    
  5723.  
  5724.     call    ttyo        ;echo semicolon
  5725.     dec    de
  5726.     dec    de        ;point to carriage return
  5727.     ld    a,' '
  5728.     ld    (de),a        ;clear crlf from buffer
  5729.     inc    de
  5730.     ld    (de),a
  5731.     inc    de
  5732.     call    write        ;end of buffer - write if required
  5733.     ld    b,29
  5734.     ld    a,(maxlin)
  5735.     sub    30
  5736.     jp    z,opn048
  5737.     dec    de
  5738.     ld    b,16
  5739.     xor    a
  5740. opn048:    ld    c,a
  5741.     push    bc
  5742.     push    de        ;save disassembly buffer pointer
  5743.     ld    d,a
  5744.     call    iedt03
  5745.     pop    de
  5746.     pop    bc
  5747.     ld    a,b        ;recover max size of comment
  5748.     dec    hl
  5749.     ld    b,(hl)        ;number actually entered
  5750.     sub    b
  5751.     ld    c,a        ;trailing spaces 
  5752.     inc    hl
  5753.     ex    de,hl        ;de - input buffer   hl - disassembly buffer
  5754.     ld    (hl),';'
  5755.     inc    hl
  5756. opn049:    dec    b        ;pre-test count
  5757.     jp    m,opn050
  5758.     ld    a,(de)        ;first char of input
  5759.     inc    de
  5760.     ld    (hl),a        ;into disassembly buffer
  5761.     inc    hl
  5762.     jr    opn049
  5763. opn050:    dec    c
  5764.     jp    m,opn055
  5765.     ld    (hl),' '
  5766.     inc    hl
  5767.     jr    opn050
  5768. opn055:    ld    (hl),cr
  5769.     inc    hl
  5770.     ld    (hl),lf
  5771.     inc    hl
  5772.     ex    de,hl
  5773.     jp    opn065
  5774.  
  5775. opn060:
  5776.     ld    a,(maxlin)    
  5777.     cp    30        ;test for 6 chars in label
  5778.     jp    z,opn065    ;z - buffer point ok
  5779.     ld    a,64-46        ;bump buffer pointer to next 64 byte chunk
  5780.     add    a,e
  5781.     ld    e,a
  5782.     jp    nc,opn065     
  5783.     inc    d
  5784.  
  5785. opn065:    call    write        ;check if write to disk flag in effect    
  5786.     
  5787.     call    crlf
  5788.     ld    (zasmio),de    ;save new buffer pointer
  5789.     ld    hl,(zasmwt)    ;check disassembly count
  5790.     xor    a
  5791.     or    h        ;less than 256?
  5792.     jr    z,opn080    ;less -    this is    tally
  5793.     ld    bc,(zasmnx)    ;fetch next disassembly    address
  5794.     sbc    hl,bc        ;versus    requested end address
  5795.     jr    c,opn095    ;c - end
  5796.     add    hl,bc        ;restore next disassembly address
  5797.     jr    opn085        ;more
  5798. opn080:    dec    hl
  5799.     ld    a,h
  5800.     or    l
  5801.     jr    nz,opn085    ;nz - more
  5802.     ld    hl,(zasmct)    ;fetch permanent block size
  5803.     ld    a,(zasmf)
  5804.     and    a
  5805.     call    z,ttyi        ;query user - more?
  5806.     cp    cr        ;return    means end
  5807.     jr    z,opn095
  5808.     jr    opn090
  5809. opn085:
  5810.     call    ttyq
  5811.     cp    cr
  5812.     jr    z,opn095    ;nz - terminate    disassembly
  5813. opn090:
  5814.     ld    (zasmwt),hl    ;restore count
  5815.     ld    hl,(zasmnx)    ;next instruction pointer
  5816.     ld    (zasmpc),hl    ;make current
  5817.     jp    zasm15        ;disassemble next instruction
  5818.  
  5819. opn095:    ld    a,(dwrite)    ;writing to disk?
  5820.     and    a
  5821.     ret    z
  5822.     ld    a,eof        ;
  5823.     ld    (de),a        ;set eof
  5824.     ld    de,zasmbf
  5825.     call    write
  5826.  
  5827.  
  5828.  
  5829. closef:    ld    de,fcb        ;close file
  5830.     ld    c,16
  5831.     jp    bdos
  5832.  
  5833.  
  5834.  
  5835. write:    push    bc    
  5836.     push    hl
  5837.     ld    hl,nzasm    ;address of end of disassembly buffer    
  5838.     and    a
  5839.     sbc    hl,de
  5840.     jr    nz,wrt10    ;not end of buffer
  5841.     ld    de,zasmbf    ;need to rewind buffer pointer 
  5842.     ld    a,(dwrite)    ;test write to disk flag
  5843.     and    a
  5844.     call    nz,bwrite    ;nz - writing to disk
  5845. wrt10:    pop    hl
  5846.     pop    bc
  5847.     ret
  5848.  
  5849.  
  5850.  
  5851. bwrite:    push    bc        ;bdos write routine
  5852.     push    de
  5853.     push    hl
  5854.     ld    c,26        ;set dma address
  5855.     call    bdos
  5856.     ld    de,fcb
  5857.     ld    c,21
  5858.     call    bdos        ;write buffer
  5859.                 ;+ eg 3.3.7b
  5860.     ld    c,26        ;+ "Set DMA" function
  5861.     ld    de,80h        ;+ Restore default DMA for user program
  5862.     call    bdos        ;+
  5863.     pop    hl
  5864.     pop    de
  5865.     pop    bc
  5866.     ret
  5867.  
  5868.  
  5869.  
  5870. bldf:    call    lfcb        ;initialize fcb
  5871.     ret    nz        ;error - invalid file name
  5872.     call    lopn
  5873.     jr    z,bldf00    ;no file - create one
  5874.     ld    de,fcb
  5875.     ld    c,19        ;file exists - delete it
  5876.     call    bdos 
  5877. bldf00:    ld    de,fcb        ;create    new file
  5878.     ld    c,22
  5879.     call    bdos        ;if no file create one
  5880.     xor    a
  5881.     ret
  5882.  
  5883.     page
  5884.  
  5885. opn100:    ld    hl,(zasmpc)
  5886.     inc    hl
  5887.     ld    a,(hl)        ;fetch relative    displacement
  5888.     ld    c,a
  5889.     inc    c
  5890.     add    a,a        ;test sign for displacement direction
  5891.     ld    b,0
  5892.     jr    nc,opn105
  5893.     dec    b        ;produce zero for forward - ff for back
  5894. opn105:    add    hl,bc        ;adjust    pc
  5895.     ex    de,hl        ;de - instruction ptr    hl - buffer
  5896.     call    fadr
  5897.     call    z,xsym
  5898.     jp    z,opn040    ;symbol    found
  5899. ;    ld    (hl),'$'    ;- eg 3.3.4a
  5900. ;    inc    hl        ;-
  5901. ;    ld    a,c        ;-
  5902. ;    inc    a        ;-
  5903.     ld    b,0
  5904. ;    cp    82h        ;-
  5905. ;    jp    opn610        ;- convert displacement to ascii
  5906.     jp    opn316        ;+
  5907.  
  5908. opn200:    call    zmqf        ;check for interactive disassembly
  5909.     jr    nc,opn205    ;sign off - not interactive
  5910.     add    a,a        ;shift out bit 6
  5911.     ld    a,(hl)
  5912.     jr    c,opn215    ;on - must be hex defb
  5913.     call    zascii        ;user wants ascii - check validity
  5914.     jr    nz,opn215    ;nz - untable to convert to ascii
  5915.     jp    opn020
  5916. opn205:    call    zndx        ;check for ix or iy instruction
  5917.     ex    de,hl        ;buffer back to de
  5918.     jr    nz,opn210    ;nz - not ix or    iy
  5919.     inc    hl
  5920.     inc    hl        ;must be  ld (ix+ind),nn
  5921. opn210:    inc    hl        ;
  5922.     ld    a,(hl)        ;fetch object byte
  5923.     jr    z,opn215    ;no conversion of ix and iy displacements 
  5924.                 ;to ascii        
  5925.     ld    a,(zasmkv)    ;check for in or out instruction
  5926.     cp    0b3h    
  5927.     jr    z,opn215    ;no conversion of port addresses to ascii
  5928.     cp    0bbh
  5929.     jr    z,opn215
  5930.     ld    a,(hl)    
  5931.     call    zascii
  5932.     jp    z,opn020
  5933. opn215:    ex    de,hl
  5934.     ld    a,(de)
  5935.     cp    10        ;decimal number?
  5936.     jr    nc,opn220    ;no - convert to hex
  5937.     call    zhex20        ;86 the    leading    zero and trailing h
  5938.     jp    opn020
  5939. opn220:    call    zhex        ;do hex    to asii    conversion
  5940.     ld    (hl),'H'    ;following 8 bit hex byte
  5941.     inc    hl
  5942.     jp    opn020
  5943.  
  5944. opn300:    call    zmqf
  5945.     jr    c,opn315    ;c - this is defw
  5946.     call    zndx
  5947.     ex    de,hl        ;de - buffer   hl - instruction    pointer
  5948.     jr    nz,opn310    ;nz - not ix or    iy
  5949.     inc    hl
  5950. opn310:    inc    hl
  5951. opn315:    ld    a,(hl)        ;fetch lo order    16 bit operand
  5952.     inc    hl
  5953.     ld    h,(hl)        ;hi order
  5954.     ld    l,a
  5955.     ex    de,hl        ;de - 16 bit operand   hl - buffer
  5956.     call    fadr
  5957.     call    z,xsym
  5958.     jp    z,opn020    ;symbol    found
  5959. opn316:                ;+ eg 3.3.4b
  5960.     ld    a,d        ;convert hi order to hex
  5961.     ld    c,a        ;save spare copy
  5962.     call    zhex
  5963.     ld    a,e
  5964.     ld    d,a
  5965.     call    zhex10
  5966.     xor    a
  5967.     or    c
  5968.     jr    nz,opn320
  5969.     ld    a,d
  5970.     cp    10
  5971.     jp    c,opn020
  5972. opn320:    ld    (hl),'h'
  5973.     inc    hl
  5974.     jp    opn020
  5975.  
  5976. opn400:
  5977.     call    zndx
  5978.     jr    nz,opn410    ;nz - not ix or    iy instruction
  5979.     inc    de
  5980.     ld    a,(de)
  5981.     cp    0cbh        ;check for indexed bit instruction
  5982.     jr    nz,opn410
  5983.     inc    de        ;byte of interest is number four
  5984.     inc    de
  5985. opn410:    ld    a,01        ;check low bit of operand key value
  5986.     and    b
  5987.     ld    a,(de)        ;fetch op code
  5988.     jr    nz,opn500    ;nz - index 01bh
  5989.     rra            ;register specified in bits 0-5
  5990.     rra
  5991.     rra
  5992. opn500:    and    007        ;register specified in bits 0-2
  5993.     xor    006        ;from the movie    of the same name
  5994.     jp    nz,opn010    ;nz - not hl or    ix or iy
  5995.     ld    a,(zasmpc)
  5996.     xor    e        ;test if pc was    incremented
  5997.     ld    (hl),'('    ;set leading paren
  5998.     inc    hl
  5999.     ld    b,080h        ;set sign bit -    closed paren required
  6000.     ex    de,hl        ;de - buffer
  6001.     jp    z,opn012
  6002.  
  6003.  
  6004.  
  6005. opn600:
  6006.     call    zndx        ;determine if ix or iy
  6007.     jr    z,opn605    ;z - must be ix    of iy
  6008.     ld    a,80h
  6009.     and    b
  6010.     jp    opn010
  6011. opn605:    
  6012.                 ;+Fix display of IX/IY when upper case is set
  6013.     push    af        ;+Adapted from patch by George Havach (3.5.7)
  6014.     ld    c,0DFh        ;+Upper case mask
  6015.     ld    a,(case)    ;+See if upper or lower case
  6016.     or    a        ;+
  6017.     jr    z,opn606    ;+Skip if upper case, otherwise
  6018.     ld    c,0FFh        ;+ adjust mask
  6019. opn606:                ;+
  6020.     ld    a,'i'        ;+First character
  6021.     and    c        ;+Select case
  6022. ;    ld    (hl),'i'    ;-Set first character
  6023.     ld    (hl),a        ;+Set first character
  6024.     inc    hl
  6025.     pop    af        ;+Second character
  6026.     adc    a,'x'        ;Carry determines x or y (from zndx)
  6027.     and    c        ;+Select case
  6028.     ld    (hl),a
  6029.     inc    hl
  6030.     ld    a,80h        ;Test for parens
  6031.     and    b
  6032.     jp    z,opn030    ;z - not indexed instruction
  6033.     inc    de
  6034.     ld    a,(de)        ;fetch second byte of instruction
  6035.     cp    0e9h        ;test for jp (ix) or jp    (iy)
  6036.     jp    z,opn020    ;output    closed paren
  6037.     inc    de
  6038.     ld    a,(de)        ;fetch displacement byte
  6039.     cp    80h        ;test sign
  6040. opn610:    ld    (hl),'+'    ;assume    forward
  6041.     jr    c,opn620    ;c - forward
  6042.     neg            ;force positive
  6043.     ld    (hl),'-'
  6044. opn620:    inc    hl        ;bump buffer pointer
  6045.     and    7fh        ;strip sign
  6046.     call    zhex        ;convert to hex
  6047.     ld    a,9
  6048.     cp    d
  6049.     jp    nc,opn020
  6050.     ld    (hl),'h'
  6051.     inc    hl
  6052.     jp    opn020        ;output    closed paren
  6053.  
  6054.  
  6055.  
  6056.  
  6057. opn700:    ld    hl,(zasmpc)
  6058.     ld    a,(hl)        ;fetch restart instruction
  6059.     ex    de,hl        ;de - buffer   hl instruction pointer
  6060.     and    38h
  6061.     call    zhex        ;convert restart number    to ascii
  6062.     ld    (hl),'H'
  6063.     jp    opn020
  6064.  
  6065.  
  6066.  
  6067. opn800:    call    zndx
  6068.     jr    nz,opn810    ;nz - not ddcb or fdcb instruction
  6069.     inc    de
  6070.     inc    de
  6071.     inc    de        ;
  6072.     ld    a,(de)        ;byte 4    of ix or iy bit    instruction
  6073.     jr    opn820
  6074. opn810:    cp    10h        ;weed out interrupt mode instructions
  6075.     ld    a,(de)        ;second    byte of    instruction regardless
  6076.     jr    nz,opn820    ;nz - cb bit instruction
  6077.     xor    046h        ;
  6078.     jr    z,opn830    ;z - interrupt mode zero
  6079.     sub    8
  6080. opn820:    rra
  6081.     rra
  6082.     rra
  6083.     and    07        ;leave only bit    number
  6084. opn830:    call    zhex20        ;convert to ascii
  6085.     jp    opn030
  6086.     page
  6087. ;******************************************************************************
  6088. ;*
  6089. ;*             disassembler utility subroutines
  6090. ;*
  6091. ;*    zndx:      determines if    fd dd ed or cb instruction
  6092. ;*          caller uses returned values on an individual basis
  6093. ;*
  6094. ;*           z  -    dd fd
  6095. ;*          nz  -    neither    of the above
  6096. ;*          current instruction pointer bumped if    cb or ed instruction
  6097. ;*
  6098. ;*    zhex:      convert to byte in the accumulator to ascii with leading zero
  6099. ;*          store    in buffer
  6100. ;*          d - reg destroyed
  6101. ;*
  6102. ;*    zhex10:      no leading zero permitted
  6103. ;*    zhex20:      convert lo order nibble only
  6104. ;*
  6105. ;******************************************************************************
  6106.  
  6107. zndx:    ld    hl,(zasmpc)    ;fetch current instruction pointer
  6108.     ex    de,hl        ;de - instruction pointer   hl - buffer
  6109.     ld    a,(de)
  6110.     add    a,-0fdh        ;iy check
  6111.     ret    z
  6112.     sub    0ddh-0fdh    ;ix check
  6113.     ret    z
  6114.     cp    10h        ;ed check
  6115.     jr    z,zndx00
  6116.     cp    0eeh        ;cb check
  6117.     ld    a,0        ;clear
  6118.     ret    nz
  6119. zndx00:    inc    de        ;cb or ed - bump instruction pointer
  6120.     cpl
  6121.     and    a        ;ensure    nz set
  6122.     cpl
  6123.     ret
  6124.  
  6125.  
  6126.  
  6127. zhex:    ld    d,a
  6128.     cp    0a0h        ;test byte to convert
  6129.     jr    c,zhex00    ;starts    with decimal digit - 86    the lead zero
  6130.     ld    (hl),'0'
  6131.     inc    hl
  6132.     jr    zhex10
  6133. zhex00:    cp    10
  6134.     jr    c,zhex20
  6135. zhex10:    rrca
  6136.     rrca
  6137.     rrca
  6138.     rrca
  6139.     and    0fh
  6140.     add    a,90h
  6141.     daa
  6142.     adc    a,40h
  6143.     daa            ;a - ascii digit
  6144.     ld    (hl),a
  6145.     inc    hl
  6146.     ld    a,d        ;lo nibble conversion
  6147. zhex20:    and    0fh
  6148.     add    a,90h
  6149.     daa
  6150.     adc    a,40h
  6151.     daa
  6152.     ld    (hl),a
  6153.     inc    hl
  6154.     ret
  6155.  
  6156.  
  6157.  
  6158. zmqf:    ld    hl,zmflag    ;check interactive disassembly flag
  6159.     ld    a,(hl)
  6160.     ld    (hl),0        ;clear regardless
  6161.     ld    hl,(zasmpc)    ;fetch current disassembly address
  6162.     add    a,a        ;check sign - on means interactive
  6163.     ret
  6164.  
  6165.  
  6166. zascii:    cp    ' '
  6167.     ret    c
  6168.     and    a
  6169.     ret    m
  6170.     cp    7fh        ;rubout?
  6171.     jr    z,zasc10
  6172.     cp    quote
  6173.     jr    nz,zasc20
  6174. zasc10:    and    a        ;set nz - conversion not done
  6175.     ret
  6176. zasc20:    ex    de,hl
  6177.     ld    (hl),quote    ;defb -    quoted character
  6178.     inc    hl
  6179.     or    80h        ;hi bit on - no case conversion for this guy
  6180.     ld    (hl),a
  6181.     inc    hl
  6182.     ld    (hl),quote
  6183.     cp    a
  6184.     ret
  6185.  
  6186.  
  6187.  
  6188. fadr:    push    bc
  6189.     push    hl
  6190.     ld    hl,(06)        ;fetch top of tpa - start of symbol table
  6191.     ld    bc,(maxlen)
  6192.     add    hl,bc        ;point to start of symbol name
  6193.     inc    hl
  6194. fadr00:    ld    a,(hl)        ;first byte of symbol name
  6195.     dec    a        ;check validity
  6196.     jp    m,fadr30    ;end of    table
  6197.     add    hl,bc
  6198.     ld    a,(hl)        ;fetch hi order    address    from table
  6199.     cp    d
  6200.     jp    nz,fadr10
  6201.     dec    hl
  6202.     ld    a,(hl)
  6203.     inc    hl
  6204.     cp    e
  6205.     jp    z,fadr20
  6206. fadr10:    inc    hl
  6207.     jp    fadr00
  6208. fadr20:    ex    de,hl        ;return pointer in de
  6209.     ld    a,c
  6210.     cpl
  6211.     and    e
  6212.     ld    e,a
  6213.     xor    a
  6214. fadr30:    pop    hl
  6215.     pop    bc
  6216.     ret
  6217.  
  6218. xsym:
  6219.     ld    a,(maxlen)
  6220.     dec    a
  6221.     ld    c,a
  6222. xsym00:    ld    a,(de)
  6223.     and    a
  6224.     ret    z
  6225.     ld    (hl),a
  6226.     inc    hl
  6227.     inc    de
  6228.     dec    c
  6229.     jr    nz,xsym00
  6230.     ret
  6231.     page
  6232. ;******************************************************************************
  6233. ;*
  6234. ;*    bcde:  query user for 3    arguments: source address
  6235. ;*                       destination address
  6236. ;*                       byte    count
  6237. ;*
  6238. ;*           used by move, verify, and yfil routines
  6239. ;*
  6240. ;*           return: bc - byte count
  6241. ;*               de - destination
  6242. ;*               hl - source pointer
  6243. ;*            z - no errors
  6244. ;*
  6245. ;*               nz - no input entered
  6246. ;*              - untable to evaluate argument
  6247. ;*              - destination    address    < source
  6248. ;*
  6249. ;******************************************************************************
  6250.  
  6251. bcde:    call    iedtbc
  6252.     ret    m        ;no input is treated as    error
  6253.     call    iarg        ;read in starting block    address
  6254.     ret    nz
  6255.     ex    de,hl
  6256.     call    iarg
  6257.     ret    nz
  6258.     sbc    hl,de        ;end - start = byte count - 1
  6259.     ret    c
  6260.     ld    b,h
  6261.     ld    c,l
  6262.     inc    bc
  6263.     call    in00        ;read in destination block address
  6264.     ret    nz
  6265.     ex    de,hl        ;set regs right
  6266.     ret
  6267.  
  6268.     page
  6269. ;******************************************************************************
  6270. ;*
  6271. ;*               console i/o routines
  6272. ;*
  6273. ;*   "physical"    i/o routines: ttyi - keyboard input
  6274. ;*                  ttyo - console output
  6275. ;*                  ttyq - console status
  6276. ;*
  6277. ;*   logical input routines:  inchar - input character processing
  6278. ;*                       control characters echoed with ^    
  6279. ;*
  6280. ;*   logical output routines: crlf   - output carriage return/line feed
  6281. ;*                  cret   - output carriage return only
  6282. ;*                 space   - output space
  6283. ;*                spaces   - output number of    spaces in passed in c
  6284. ;*                outhex   - output hex byte in a
  6285. ;*                othxsp   - output hex byte in a followed by    space
  6286. ;*                outadr   - output 16 bit hex value in hl followed
  6287. ;*                       by space    - hl preserved
  6288. ;*                 print   - output string - address in de
  6289. ;*                       string terminated by null
  6290. ;*                printb   - output string - address in hl
  6291. ;*                               byte count in c
  6292. ;*                               end at first null
  6293. ;*
  6294. ;******************************************************************************
  6295.  
  6296.     if    ASMB
  6297. ttyq:
  6298.     else
  6299. ttyq::
  6300.     endif
  6301.     push    bc
  6302.     push    de
  6303.     push    hl
  6304.     ld    c,11
  6305.     call    bdos
  6306.     and    a
  6307.     ld    c,6
  6308.     ld    e,0ffh
  6309.     call    nz,bdos
  6310.     pop    hl
  6311.     pop    de
  6312.     pop    bc
  6313.     and    7fh
  6314.     ret
  6315.  
  6316.     if not compact
  6317.     org    ttyq+32
  6318.     endif
  6319.  
  6320.     if    ASMB
  6321. ttyi:
  6322.     else
  6323. ttyi::
  6324.     endif
  6325.     push    bc
  6326.     push    de
  6327.     push    hl
  6328.     if    ASMB
  6329. ttyi00:
  6330.     else
  6331. ttyi00::
  6332.     endif
  6333.     ld    c,6
  6334.     ld    e,0ffh
  6335.     call    bdos
  6336.     and    7fh
  6337.     jr    z,ttyi00
  6338.     pop    hl
  6339.     pop    de
  6340.     pop    bc
  6341.     ret
  6342.  
  6343.     if not compact
  6344.     org    ttyi+32
  6345.     endif
  6346.  
  6347.     if    ASMB
  6348. ttyo:
  6349.     else
  6350. ttyo::
  6351.     endif
  6352.     push    af
  6353.     push    bc
  6354.     push    de
  6355.     push    hl
  6356. ttyo00:
  6357.     and    7Fh        ;+ eg 3.3.1 (but this instruction will be
  6358.                 ;         patched during initialisation
  6359.                 ;         according to value stored at
  6360.                 ;         coMask: [3.4])
  6361.     ld    e,a
  6362.     if    jterm        ;My terminal uses tab as cursor position
  6363.     ld    c,6        ;lead-in and I don't want the bdos to expand
  6364.     else            ;the tab to a string of spaces.
  6365.     ld    c,2
  6366.     endif
  6367.     call    bdos
  6368.     pop    hl
  6369.     pop    de
  6370.     pop    bc
  6371.     pop    af
  6372.     ret
  6373.  
  6374.     if not compact
  6375.     org    ttyo+32
  6376.     endif
  6377.  
  6378. inchar:    call    ttyi
  6379.     cp    ctlc
  6380.     jp    z,00
  6381.     cp    cr
  6382.     ret    z
  6383.     cp    tab
  6384.     ret    z
  6385.     cp    lf
  6386.     ret    z
  6387.     cp    bs
  6388.     ret    z
  6389.     cp    ctlx
  6390.     ret    z
  6391.     cp    ' '
  6392.     jr    nc,ttyo
  6393.     push    af
  6394.     ld    a,'^'
  6395.     call    ttyo
  6396.     pop    af
  6397.     xor    40h
  6398.     call    ttyo
  6399.     xor    40h
  6400.     ret
  6401.  
  6402.  
  6403. ilcs:    cp    'A'
  6404.     ret    c
  6405.     cp    'Z'+1
  6406.     ret    nc
  6407.     or    20h
  6408.     ret
  6409.  
  6410.  
  6411.  
  6412. ixlt:    cp    'a'
  6413.     ret    c
  6414.     cp    'z'+1
  6415.     ret    nc
  6416.     sub    20h
  6417.     ret
  6418.  
  6419.     page
  6420. crlf:    ld    a,lf
  6421.     call    ttyo
  6422. cret:    ld    a,cr
  6423.     jp    ttyo
  6424.  
  6425. othxsp:    call    outhex
  6426.  
  6427. space:    ld    a,' '
  6428.     jp    ttyo
  6429.  
  6430. space5:    ld    c,5
  6431.  
  6432. spaces:    call    space
  6433.     dec    c
  6434.     jr    nz,spaces
  6435.     ret
  6436.  
  6437.  
  6438.  
  6439. newlin:    call    crlf
  6440.     ex    de,hl
  6441.     call    outadr
  6442.     ex    de,hl
  6443.     ret
  6444.  
  6445.     
  6446. outadr:    ld    a,h
  6447.     call    outhex
  6448.     ld    a,l
  6449.     call    othxsp
  6450.     jr    space
  6451.  
  6452.  
  6453.  
  6454. outhex:    push    af
  6455.     call    binx
  6456.     call    ttyo
  6457.     pop    af
  6458.     call    binx00
  6459.     jp    ttyo
  6460.  
  6461.  
  6462.  
  6463. binx:    rrca
  6464.     rrca
  6465.     rrca
  6466.     rrca
  6467. binx00:    and    0fh
  6468.     add    a,90h
  6469.     daa
  6470.     adc    a,40h
  6471.     daa
  6472.     ret
  6473.     page
  6474. ilin:    push    bc
  6475.     push    de
  6476.     ld    b,inbfsz
  6477.     ld    c,0
  6478.     call    in
  6479.     pop    de
  6480.     pop    bc
  6481.     ret
  6482.  
  6483.  
  6484. istr:    push    bc
  6485.     push    de
  6486.     ld    b,1
  6487.     ld    c,' '
  6488.     call    iedt
  6489.     pop    de
  6490.     pop    bc
  6491.     ret
  6492.  
  6493.         
  6494.                 ;resume input after reading in one char
  6495.  
  6496. irsm:    push    bc
  6497.     push    de
  6498.     ld    b,inbfsz-1    ;max input size less one char already read in
  6499.     ld    c,' '        ;this is terminator char
  6500.     ld    d,1        ;preset byte count
  6501.     ld    a,d
  6502.     ld    (strngf),a    ;set nz - this is string function
  6503.     ld    hl,inbf+1    ;init buffer pointer
  6504.     call    iedt05
  6505.     xor    a
  6506.     ld    (strngf),a    ;this is no longer string function
  6507.     or    d
  6508.     call    p,in00
  6509.     pop    de
  6510.     pop    bc
  6511.     ret
  6512.  
  6513.  
  6514.  
  6515. in:    call    iedt
  6516.     ret    m
  6517. in00:    xor    a
  6518.     ld    (argbc),a
  6519.     ld    hl,argbf
  6520.     ld    (argbpt),hl
  6521. in10:    call    iarg
  6522.     ret    nz
  6523.     and    a
  6524.     jr    nz,in10
  6525.     ret
  6526.  
  6527.  
  6528.  
  6529. iarg:    push    bc
  6530.     push    de
  6531.     call    parg
  6532.     ld    a,(delim)
  6533.     pop    de
  6534.     pop    bc
  6535.     ret
  6536.     page
  6537. parg:    call    prsr        ;extract next argument
  6538.     ret    nz        ;parse error
  6539.     ld    a,(quoflg)    ;test for ascii    literal
  6540.     and    a
  6541.     jr    z,parg10    ;quote character not found
  6542.     xor    a
  6543.     or    b        ;test for balanced quotes
  6544.     ret    m        ;error - unbalanced quotes
  6545.     ld    a,(de)        ;first character of parse buffer
  6546.     sub    quote
  6547.     jr    nz,parg50    ;invalid literal string but may be expression
  6548.                 ;involving a literal
  6549.     ld    l,b        ;l - character count of    parse buffer
  6550.     ld    h,a        ;clear
  6551.     add    hl,de        ;
  6552.     dec    hl        ;hl - pointer to last char in parse buffer
  6553.     ld    a,(hl)        ;
  6554.     sub    quote        ;ensure    literal    string ends with quote
  6555.     jr     nz,parg50
  6556.     ld    (hl),a        ;clear trailing quote
  6557.     ld    c,b        ;c - character count of    parse buffer
  6558.     ld    b,a        ;clear
  6559.     dec    c        ;subtract the quote characters from the    count
  6560.     dec    c
  6561.     dec    c        ;extra dec set error flag nz for '' string
  6562.     ret    m        ;inform    caller of null string
  6563.     inc    c        ;c - actual string length
  6564.     ld    a,c        ;spare copy
  6565.     inc    de        ;point to second character of parse buffer
  6566.     ld    hl,(argbpt)    ;caller    wants evaluated    arg stored here
  6567.     ex    de,hl
  6568.     ldir
  6569.     ex    de,hl
  6570.     dec    hl
  6571.     ld    e,(hl)
  6572.     dec    hl
  6573.     ld    d,(hl)
  6574.     inc    hl
  6575.     inc    hl        ;point to where to store next arg
  6576.     dec    a        ;argument length 1?
  6577.     jr    nz,parg00
  6578.     ld    d,a
  6579. parg00:    ld    c,a
  6580.     inc    c        ;account for increment
  6581.     ld    a,(argbc)    ;fetch current argument byte counter
  6582.     add    a,c
  6583.     jr    parg90
  6584. parg10:    call    mreg        ;check for register specified
  6585.     jr    nz,parg50    ;nz - invalid register name
  6586.     ld    a,c
  6587.     add    a,a
  6588.     jr    c,parg60    ;sign bit reset    - 16 bit register pair
  6589. parg50:    ld    hl,00
  6590.     ld    b,l
  6591.     ld    de,prsbf    ;reinit    starting address of parse buffer
  6592.     call    xval
  6593.     jr    z,parg70
  6594.     ret
  6595. parg60:    ld    a,(hl)
  6596.     dec    hl
  6597.     ld    l,(hl)
  6598.     ld    h,a
  6599.     ld    a,(prsbf)    ;check paren flag for indirection
  6600.     and    a
  6601.     jr    nz,parg65    ;nz - parens not removed
  6602.     inc    de        ;bump past trailing null
  6603.     ld    a,(hl)
  6604.     inc    hl
  6605.     ld    h,(hl)
  6606.     ld    l,a
  6607. parg65:    ld    b,80h
  6608.     call    xval
  6609.     ret    nz
  6610. parg70:    ex    de,hl
  6611.     ld    hl,(argbpt)
  6612.     ld    a,(argbc)
  6613.     inc    d
  6614.     dec    d
  6615.     jr    z,parg80
  6616.     ld    (hl),d
  6617.     inc    hl
  6618.     inc    a
  6619. parg80:    ld    (hl),e
  6620.     inc    hl
  6621.     inc    a
  6622. parg90:    ld    (argbc),a
  6623.     ld    (argbpt),hl
  6624.     ex    de,hl
  6625.     xor    a
  6626.     ret
  6627.     page
  6628. outbyt:    ld    b,a        ;save spare copy    
  6629.     call    othxsp        ;hex - display
  6630.     call    space
  6631.     ld    a,b        ;display byte in ascii
  6632.     call    asci        ;display ascii equivalent
  6633.     ld    c,3
  6634.     jp    spaces        ;solicit input three spaces right
  6635.  
  6636. byte:    call    istr
  6637.     ld    a,(inbfnc)    ;number    of chars in input buffer
  6638.     dec    a        ;test for input    buffer count of    zero
  6639.     inc    de        ;assume    zero - examine next
  6640.     ret    m        ;no input means examine next
  6641.     dec    de        ;incorrect assumption
  6642.     ld    a,(inbf)    ;check first char of input buffer
  6643.     cp    '.'
  6644.     ret    z        ;period    ends command
  6645.     cp    '='        ;new address?
  6646.     jr    nz,byte10
  6647.     xor    a        ;clear equal sign so prsr ignores it
  6648.     ld    (inbf),a
  6649.     call    irsm        ;fetch new address to examine
  6650.     jr    nz,byte30    ;error
  6651.     ld    a,(inbfnc)
  6652.     sub    2
  6653.     jr    c,byte30    ;c - error - equal sign was only char of input
  6654.     ex    de,hl        ;return new address in de
  6655.     scf            ;ensure nz set for caller - no replacement data
  6656.                 ;was entered
  6657.     sbc    a,a
  6658.     ret
  6659. byte10:    cp    '^'        ;
  6660.     jr    nz,byte15    ;nz - not up arrow means need more input
  6661.     dec    de        ;dec current memory pointer
  6662.     scf             ;set nz - no replacement data entered
  6663.     sbc    a,a
  6664.     ret
  6665. byte15:    call    irsm        ;resume    input from console
  6666.     ret    z        ;no errors on input
  6667.     ld    a,(inbfnc)    ;check number of chars input
  6668.     and    a        
  6669.     jr    z,byte        ;none - user hit control x or backspaced to
  6670.                 ;beginning of buffer
  6671. byte30:    call    e???
  6672.     scf
  6673.     sbc    a,a        ;set nz - no replacement
  6674.     ret
  6675.     page
  6676. ;******************************************************************************
  6677. ;*
  6678. ;*    bdos function 10 replacement to    make romming this program easier since
  6679. ;*    only two console i/o routines (ttyi and    ttyo) are required. this
  6680. ;*    routine    supports backspace, line delete, and tab expansion.
  6681. ;*
  6682. ;*    all input stored in input buffer inbf.
  6683. ;*
  6684. ;*
  6685. ;*    iedtbc:    solicit    console    for new    input and initialize b and c registers
  6686. ;*        for max    size and input and no special line terminator.
  6687. ;*
  6688. ;*
  6689. ;*    iedt:    solicit    console    for new    input using non-default    byte count for
  6690. ;*        buffer or non-standard terminator.
  6691. ;*
  6692. ;*        called:     b - max number    of characters to receive
  6693. ;*             c - special terminator    other than carriage return
  6694. ;*
  6695. ;*
  6696. ;*    iedt00:    resume input - used by routines    which call iedt    with a buffer
  6697. ;*        count of 1 to check for    special    character as the first char
  6698. ;*        received (such as exam looking for period).
  6699. ;*
  6700. ;*        called:     b - max number    of characters to receive
  6701. ;*             c - special terminator    other than carriage return
  6702. ;*
  6703. ;******************************************************************************
  6704.  
  6705.  
  6706. iedtbc:    ld    b,inbfsz
  6707.     xor    a
  6708.     ld    c,a
  6709.     ld    (strngf),a
  6710. iedt:    xor    a
  6711.     ld    d,inbfsz
  6712.     ld    hl,inbf
  6713. iedt00:    ld    (hl),a
  6714.     inc    hl
  6715.     dec    d
  6716.     jr    nz,iedt00
  6717.     ld    (argbc),a    ;init number of    arguments tally
  6718.     ld    hl,argbf
  6719.     ld    (argbpt),hl    ;init pointer to start of buffer
  6720. iedt03:    ld    hl,inbf        ;start of input    buffer
  6721.     ld    (quoflg),a
  6722. iedt05:    call    inchar        ;read char from    console
  6723.     ld    (trmntr),a    ;assume line terminator until proven otherwise
  6724.     cp    cr        ;end of    line?
  6725.     jp    z,iedt90    ;z - end (jr changed to jp:  eg 3.3.8a)
  6726.     ld    e,a
  6727.     cp    quote
  6728.     ld    a,(quoflg)
  6729.     jr    nz,iedt10
  6730.     xor    quote
  6731.     ld    (quoflg),a
  6732.     ld    a,quote
  6733.     jr    iedt60
  6734. iedt10:    and    a        ;quote flag on?
  6735.     ld    a,e        ;recover input character
  6736.     jr    z,iedt15    ;off - check terminator
  6737.     ld    a,(lcmd)
  6738.     call    ixlt
  6739.     cp    'R'
  6740.     ld    a,e
  6741.     jr    nz,iedt20
  6742. iedt15:    cp    c        ;compare with auxiliary terminator
  6743.     jr    z,iedt90    ;z - end
  6744. iedt20:    cp    tab
  6745.     jr    nz,iedt35    ;nz - not tab check backspace
  6746. iedt25:    call    space        ;space out until char position mod 8 = zero
  6747.     ld    (hl),a        ;store space in buffer as we expand tab
  6748.     inc    hl 
  6749.     inc    d
  6750.     ld    a,7
  6751.     and    d
  6752.     jr    nz,iedt25
  6753.     ld    (hl),0        ;set end of line null    
  6754.     jr    iedt70
  6755. iedt35:    ld    e,1        ;assume    one backspace required
  6756.     cp    bs
  6757.     jr    z,iedt40    ;z - correct assumption
  6758.     cp    ctlx        ;erase line?
  6759.     jr    nz,iedt60    ;nz - process normal input character
  6760.  
  6761.     xor    a        ;+ eg 3.3.8b
  6762.     or    d        ;+ See if ^X with empty buffer
  6763.     jp    z,z8e        ;+ Abandon current command if so
  6764.  
  6765.     ld    e,d        ;backspace count is number of chars in buffer
  6766.  
  6767.     jr    iedt50        ;+
  6768.  
  6769. iedt40:    xor    a        ;test if already at beginning of buffer
  6770.     or    d
  6771.     jr    z,iedt05    ;z - at    beginning so leave cursor as is
  6772. iedt50:    call    bksp        ;transmit bs - space - bs string
  6773.     dec    d        ;sub one from input buffer count
  6774.     dec    hl        ;rewind    buffer pointer on notch
  6775.     ld    a,(hl)        ;check for control characters
  6776.     ld    (hl),0
  6777.     cp    quote        ;check for backspacing over a quote
  6778.     jr    nz,iedt55
  6779.     ld    a,(quoflg)    ;toggle quote flag so we keep track of balance
  6780.                 ;factor
  6781.     xor    quote
  6782.     ld    (quoflg),a
  6783.     jr    iedt58
  6784. iedt55:    cp    ' '
  6785.     call    c,bksp        ;c - control char requires extra bs for caret
  6786. iedt58:    dec    e        ;dec backspace count
  6787.     jr    nz,iedt50    ;more backspacing
  6788.     ld    a,(strngf)    ;string    function flag on?
  6789.     and    a
  6790.     jr    z,iedt05    ;off - get next    input char
  6791.     xor    a        ;did we    backspace to start of buffer?
  6792.     or    d        ;test via character count
  6793.     jr    nz,iedt05    ;not rewound all the way
  6794.     ld    (inbfnc),a    ;set a zero byte count so caller knows
  6795.     dec    d        ;something is fishy
  6796.     ret
  6797. iedt60:    ld    (hl),a        ;store char in inbf
  6798.     inc    hl        ;bump inbf pointer
  6799.     ld    (hl),0        ;end of line
  6800.     inc    d        ;bump number of    chars in buffer
  6801. iedt70:    ld    a,d        ;current size
  6802.     sub    b        ;versus    max size requested by caller
  6803.     jp    c,iedt05    ;more room in buffer
  6804. iedt90:    ld    hl,inbfnc    ;store number of characters received ala
  6805.                 ;bdos function 10
  6806.     ld    (hl),d
  6807.     inc    hl        ;point to first    char in    buffer
  6808.     dec    d        ;set m flag if length is zero
  6809.     ret            ;sayonara
  6810.  
  6811.  
  6812.  
  6813.  
  6814. bksp:    call    bksp00
  6815.     call    space
  6816. bksp00:    ld    a,bs
  6817.     jp    ttyo
  6818.  
  6819.  
  6820. asci:    and    7fh        ;Convert contents of accumulator to ascii   
  6821.     if    hazeltine    ;Hazeltine terminal?
  6822.     cp    tilde        ;    check for tilde or del
  6823.     jr    nc,asci00    ;    yes - translate to '.'
  6824.     else            ;Non-hazeltine terminal
  6825.     cp    del        ;    check for del
  6826.     jr    z,asci00    ;    yes - translate to '.'
  6827.     endif            ;Any terminal - other characters
  6828.     cp    20h        ;    check for control character
  6829.     jp    nc,ttyo        ;    no - output as is
  6830. asci00:                ;    yes - translate to '.'
  6831. ;    if    hazeltine
  6832.     ld    a,'.'        ;Non-printables replaced with dot
  6833. ;    else
  6834. ;    ld    a,tilde        ;Non-printables replaced with squiggle
  6835. ;    endif
  6836.            jp    ttyo
  6837.  
  6838.  
  6839.  
  6840. bcdx:    call    bcdx00
  6841.     ret    nz
  6842. bcdx00:    rld
  6843.     ex    de,hl
  6844.     add    hl,hl
  6845.     ld    b,h
  6846.     ld    c,l
  6847.     add    hl,hl
  6848.     add    hl,hl
  6849.     add    hl,bc
  6850.     ld    c,a
  6851.     ld    a,9
  6852.     cp    c
  6853.     ret    c
  6854.     xor    a
  6855.     ld    b,a
  6856.     add    hl,bc
  6857.     ex    de,hl
  6858.     adc    a,a
  6859.     ret
  6860.  
  6861.  
  6862.  
  6863. nprint:    call    crlf
  6864. print:    ld    a,(de)
  6865.     and    a
  6866.     ret    z
  6867.     call    ttyo
  6868.     inc    de
  6869.     jr    print
  6870.  
  6871.  
  6872. printb:    ld    a,(hl)
  6873.     and    a
  6874.     ret    z
  6875.     call    ttyo
  6876.     inc    hl
  6877.     dec    c
  6878.     jr    nz,printb
  6879.     ret
  6880.  
  6881.  
  6882.  
  6883. home:    ld    bc,00
  6884.  
  6885.  
  6886. ;----------------------------------------------------------------------------
  6887. ;
  6888. ;    xycp:    Cursor-positioning routine.
  6889. ;
  6890. ;    Two versions are supplied and either can be selected during
  6891. ;    assembly according to the setting of ATERM.
  6892. ;
  6893. ;    aterm    equ    TRUE        Selects ANSI screen driver
  6894. ;    aterm    equ    FALSE        Selects default screen driver
  6895. ;
  6896. ;    In either  case, this routine is invoked with the row in B and
  6897. ;    the column in C.
  6898. ;
  6899. ;----------------------------------------------------------------------------
  6900.  
  6901.     if    ASMB
  6902. xycp:
  6903.     else
  6904. xycp::
  6905.     endif
  6906.  
  6907.     if aterm
  6908.  
  6909. ;    ANSI screen driver - jrs - 27 May 87
  6910. ;    Tested and corrected 29 Dec 88 - jrs
  6911.  
  6912.     push    de
  6913.     push    hl
  6914.     inc    b        ;Add 1 to row and column
  6915.     inc    c
  6916.     push    bc
  6917.  
  6918.     ld    a,1Bh        ;Send ESC
  6919.     call    ttyo
  6920.     ld    a,'['        ;Send [
  6921.     call    ttyo
  6922.     pop    bc        ;Send row (Y) coordinate
  6923.     push    bc
  6924.     ld    a,b
  6925.     call    xycp00
  6926.     ld    a,';'        ;Send ;
  6927.     call    ttyo
  6928.     pop    bc        ;Send column (X) coordinate
  6929.     push    bc
  6930.     ld    a,c
  6931.     call    xycp00
  6932.     ld    a,'H'        ;Send H
  6933.     call    ttyo
  6934.  
  6935.     pop    bc
  6936.     pop    hl
  6937.     pop    de
  6938.     ret
  6939.  
  6940. xycp00:
  6941.     ex    af,af'
  6942.     xor    a
  6943.     ex    af,af'
  6944. xycp10:
  6945.     ex    af,af'
  6946.     inc    a
  6947.     ex    af,af'
  6948.     sub    10
  6949.     jr    nc,xycp10
  6950.     ex    af,af'
  6951.     dec    a
  6952.     jr    z,xycp20
  6953.     add    a,'0'
  6954.     call    ttyo
  6955. xycp20:
  6956.     ex    af,af'
  6957.     add    a,'0'+10
  6958.     call    ttyo
  6959.     ret
  6960.  
  6961.     else
  6962.  
  6963. ;    Default screen driver - ras
  6964.  
  6965.     push    bc        ;Enter with row in b and column in c
  6966.     push    de
  6967.     push    hl
  6968.     ld    hl,mxycp
  6969.     ld    a,(row)        ;Add in row offset
  6970.     add    a,b
  6971.     ld    b,a        ;Save row character
  6972.     ld    a,(column)    ;Add column bias
  6973.     add    a,c
  6974.     ld    c,a
  6975.     ld    e,(hl)        ;Number of chars in cursor addressing string
  6976. xycp00:
  6977.     inc    hl
  6978.     ld    a,(hl)
  6979.     call    ttyo
  6980.     dec    e
  6981.     jr    nz,xycp00
  6982.     ld    a,(rowb4?)
  6983.     and    a
  6984.     jr    nz,xycp10
  6985.     ld    a,b
  6986.     ld    b,c
  6987.     ld    c,a
  6988. xycp10:
  6989.     ld    a,b
  6990.     call    ttyo
  6991.     ld    a,c
  6992.     call    ttyo
  6993.     pop    hl
  6994.     pop    de
  6995.     pop    bc
  6996.     ret
  6997.  
  6998.     endif
  6999.  
  7000.     if    not compact            ;..then leave room for patching
  7001.     org    xycp+128        ;  the object code
  7002.     endif
  7003.  
  7004. nrel:                    ;end of    relocatable code
  7005.     page
  7006.  
  7007. zopnm:
  7008.     defb    'HL'
  7009.     defb    'A '
  7010.     defb    'H '
  7011.     defb    'L '
  7012.     defb    'D '
  7013.     defb    'E '
  7014.     defb    'B '
  7015.     defb    'C '
  7016. ix.:    defb    'IX'
  7017.     defb    'SP'
  7018.     defb    'P '
  7019.     defb    'R '
  7020.     defb    'I '
  7021.     defb    'AF'
  7022.     defb    'BC'
  7023.     defb    'DE'
  7024. iy.:    defb    'IY'
  7025.     defb    'Z '
  7026.     defb    'NC'
  7027.     defb    'NZ'
  7028.     defb    'PE'
  7029.     defb    'PO'
  7030.     defb    'M '
  7031.     defb    'PC'
  7032.  
  7033. ix..    equ    (ix.-zopnm)/2        ;relative position - ix
  7034. iy..    equ    (iy.-zopnm)/2        ;             iy
  7035.  
  7036. zopnml    equ    ($-zopnm)/2
  7037.  
  7038. zopjtb    equ     $-nrel            ;nrel to jump table bias for loader
  7039.  
  7040. zoprjt:
  7041.     defw    opn600            ;18 - hl/ix/iy test
  7042.     defw    opn400            ;19 - register specified in bits 0-2
  7043.     defw    opn400            ;1a - register specified in bits 3-5
  7044.     defw    opn100            ;1b - relative jump
  7045.     defw    opn200            ;1c - nn
  7046.     defw    opn300            ;1d - nnnn
  7047.     defw    opn700            ;1e - restart
  7048.     defw    opn800            ;1f - bit number
  7049.  
  7050. zasmio:    defw    zasmbf
  7051.  
  7052. zopjtl    equ    ($-zoprjt)/2        ;length    of operand jump    table
  7053.  
  7054. jtcmd:
  7055.     defw    ifcb            ; i
  7056.     defw    asmblr            ; a
  7057.     defw    usym            ; u
  7058.     defw    nprt            ; n
  7059.     defw    jdbg            ; j
  7060.     defw    zasm            ; z
  7061.     defw    exam            ; e
  7062.     defw    rgst            ; r
  7063.     defw    go            ; g
  7064.     defw    yfil            ; y
  7065.     defw    movb            ; m
  7066.     defw    verify            ; v
  7067.     defw    pswDsp            ; p
  7068.     defw    break            ; b
  7069.     defw    cbreak            ; c
  7070.     defw    find            ; f
  7071.     defw    hsym            ; h
  7072.     defw    step            ; s
  7073.     defw    obreak            ; o
  7074.     defw    lldr            ; l
  7075.     defw    dump            ; d
  7076.     defw    qprt            ; q
  7077.     defw    xreg            ; x
  7078.     defw    kdmp            ; k
  7079.     defw    writ            ; w
  7080.     defw    cuser            ; >
  7081.     defw    qeval            ; ?
  7082. ;    defw    gadr            ; #
  7083. cmd:
  7084. ;    defb    '#?>WKXQDLOSHFCB'
  7085.     defb    '?>WKXQDLOSHFCB'
  7086.     defb    'PVMYGREZJNUAI'
  7087. ncmd    equ    $-cmd        ;number    of commands
  7088.  
  7089. bpemsg:
  7090.     defb    '*ERROR*'
  7091. bpmsg:
  7092.     defb    '*BP* @ '
  7093.     defb    0
  7094. prompt:
  7095.     defb    '*',' ',bs,0
  7096.  
  7097. mrrow:    defb    '=','>'        ;backspaces taken out
  7098.     defb    00
  7099.  
  7100. m????:    defb    '??'
  7101. m??:    defb    ' ??  '
  7102.  
  7103.  
  7104. asmflg:    defb    ' '
  7105.     defb    0
  7106.  
  7107. lcmd:    defb    ' '
  7108. em???:    defb    ' ??'
  7109.     defb    0
  7110.  
  7111. mldg:
  7112.     defb    'Loading: '
  7113.     defb    0
  7114.  
  7115. mfilnf:
  7116.     defb    'File Not Found'
  7117.     defb    cr,lf,00
  7118.  
  7119.  
  7120. mlodm:
  7121.     defb    'Loaded:  '
  7122.     defb    0
  7123. mlodpg:
  7124.  
  7125.     defb    'Pages:   '
  7126.     defb    0
  7127.  
  7128. msntx:
  7129.     defb    'Syntax Error'
  7130.     defb    cr,lf,0
  7131.  
  7132. mmem??:    defb    'Out Of Memory'
  7133.     defb    0
  7134.  
  7135. mcntu:    defb    ' - Continue? '
  7136.     defb    0
  7137.  
  7138. mireg:
  7139.     defb    'IR: '
  7140.     defb    0
  7141.     page
  7142.  
  7143. z80fd:    defb    009h,019h,02bh
  7144.     defb    023h,029h,039h,0e1h
  7145.     defb    0e3h,0e5h,0e9h,0f9h
  7146. z80fdl    equ    $-z80fd
  7147.  
  7148. z80f4:    defb    021h,022h,02ah,036h,0cbh
  7149. z80f4l    equ    $-z80f4
  7150.  
  7151.  
  7152. z801:    defb    0c0h,0e9h,0c9h,0d8h
  7153.     defb    0d0h,0c8h,0e8h,0e0h
  7154.     defb    0f8h,0f0h
  7155. z801l    equ    $-z801
  7156.  
  7157.  
  7158. z802:    defb    036h,0c6h,0ceh,0d3h
  7159.     defb    0d6h,0dbh,0deh,0e6h
  7160.     defb    0eeh,0f6h,0feh
  7161. z802c:    defb    018h,038h,030h
  7162.     defb    028h,020h,010h
  7163. z802l    equ    $-z802
  7164. z802cl    equ    $-z802c
  7165.  
  7166.  
  7167. z80r:
  7168. z803:    defb    001h,011h,021h,022h
  7169.     defb    02ah,031h,032h,03ah
  7170.  
  7171. z803s:    defb    0cdh
  7172.     defb    0dch,0d4h,0cch,0c4h
  7173.     defb    0ech,0e4h,0fch,0f4h
  7174.  
  7175. z803sl    equ    $-z803s            ;number    of call    instructions
  7176.  
  7177. z803c:    defb    0c3h
  7178.     defb    0dah,0d2h,0cah,0c2h
  7179.     defb    0eah,0e2h,0fah,0f2h
  7180.  
  7181. z803l    equ    $-z803            ;number    of 3 byte instructions
  7182. z803cl    equ    $-z803s            ;number    of 3 byte pc mod instructions
  7183.  
  7184. z80ed:    defb    043h,04bh,053h
  7185.     defb    05bh,073h,07bh
  7186.  
  7187. z80edl    equ    $-z80ed
  7188.  
  7189. z80rl    equ    $-z80r            ;number    relocatable z80    instructions
  7190.  
  7191. z80f3:
  7192.     defb    034h,035h,046h,04eh
  7193.     defb    056h,05eh,066h,06eh
  7194.     defb    070h,071h,072h,073h
  7195.     defb    074h,075h,077h,07eh
  7196.     defb    086h,08eh,096h,09eh
  7197.     defb    0a6h,0aeh,0b6h,0beh
  7198. z80f3l    equ    $-z80f3
  7199.     page
  7200. ;***********************************************************************
  7201. ;*
  7202. ;*
  7203. ;*
  7204. ;*
  7205. ;*
  7206. ;***********************************************************************
  7207.  
  7208.     org    ($+3) and 0fffch
  7209. zopcpt:
  7210.     defb    022h,01ch,01ch,015h    ;nop    ld    ld    inc    00 - 03
  7211.     defb    015h,00ch,01ch,031h    ;inc    dec    ld    rlca    04 - 07
  7212.     defb    010h,000h,01ch,00ch    ;ex    add    ld    dec    08 - 0b
  7213.     defb    015h,00ch,01ch,036h    ;inc    dec    ld    rrca    0c - 0f
  7214.     defb    00eh,01ch,01ch,015h    ;djnz    ld    ld    inc    10 - 13
  7215.     defb    015h,00ch,01ch,02fh    ;inc    dec    ld    rla    14 - 17
  7216.     defb    01bh,000h,01ch,00ch    ;jr    add    ld    dec    18 - 1b
  7217.     defb    015h,00ch,01ch,034h    ;inc    dec    ld    rra    1c - 1f
  7218.     defb    01bh,01ch,01ch,015h    ;jr    ld    ld    inc    20 - 23
  7219.     defb    015h,00ch,01ch,00bh    ;inc    dec    ld    daa    24 - 27
  7220.     defb    01bh,000h,01ch,00ch    ;jr    add    ld    dec    28 - 2b
  7221.     defb    015h,00ch,01ch,00ah    ;inc    dec    ld    cpl    2c - 2f
  7222.     defb    01bh,01ch,01ch,015h    ;jr    ld    ld    inc    30 - 33
  7223.     defb    015h,00ch,01ch,03ah    ;inc    dec    ld    scf    34 - 37
  7224.     defb    01bh,000h,01ch,00ch    ;jr    add    ld    dec    38 - 3b
  7225.     defb    015h,00ch,01ch,004h    ;inc    dec    ld    ccf    3c - 3f
  7226.  
  7227.  
  7228.     defb    014h,026h,039h,01ch    ;in    out    sbc    ld    ed 40
  7229.     defb    021h,02dh,013h,01ch    ;neg    retn    im    ld
  7230.     defb    014h,026h,001h,01ch    ;in    out    adc    ld
  7231.     defb    022h,02ch,022h,01ch    ;....    reti    ...    ld
  7232.     defb    014h,026h,039h,01ch    ;in    out    sbc    ld
  7233.     defb    022h,022h,013h,01ch    ;...    ...    im    ld
  7234.     defb    014h,026h,001h,01ch    ;in    out    adc    ld
  7235.     defb    022h,022h,013h,01ch    ;...    ...    im    ld
  7236.     defb    014h,026h,039h,022h    ;in    out    sbc    ...
  7237.     defb    022h,022h,002h,037h    ;...    ...    ...    rrd
  7238.     defb    014h,026h,001h,022h    ;in    out    adc    ...
  7239.     defb    044h,045h,046h,032h    ;defb*    defw*    ddb*    rld
  7240.     defb    043h,047h,039h,01ch    ;org*    equ*    sbc    ld    ed 70
  7241.     defb    022h,022h,022h,022h    ;...    ...    ...    ...
  7242.     defb    014h,026h,001h,01ch    ;in    out    adc    ld
  7243.     defb    022h,022h,022h,022h    ;...    ...    ...    ...    ed 7f
  7244.  
  7245.  
  7246.     defb    01fh,008h,018h,028h    ;ldi    cpi    ini    outi
  7247.     defb    022h,022h,022h,022h    ;...    ...    ...    ...
  7248.     defb    01dh,006h,016h,027h    ;ldd    cpd    ind    outd
  7249.     defb    022h,022h,022h,022h    ;...    ...    ...    ...
  7250.     defb    020h,009h,019h,025h    ;ldir    cpir    inir    otir
  7251.     defb    022h,022h,022h,022h    ;...    ...    ...    ...
  7252.     defb    01eh,007h,017h,024h    ;lddr    cpdr    indr    otdr
  7253.     defb    022h,022h,022h,044h    ;...    ....    ....    defb*
  7254.  
  7255.  
  7256.     defb    02bh,029h,01ah,01ah    ;ret    pop    jp    jp    c0 - c3
  7257.     defb    003h,02ah,000h,038h    ;call    push    add    rst    c4 - c7
  7258.     defb    02bh,02bh,01ah,022h    ;ret    ret    jp    ...    c8 - cb
  7259.     defb    003h,003h,001h,038h    ;call    call    adc    rst    cc - cf
  7260.     defb    02bh,029h,01ah,026h    ;ret    pop    jp    out    d0 - d3
  7261.     defb    003h,02ah,03eh,038h    ;call    push    sub    rst    d4 - d7
  7262.     defb    02bh,011h,01ah,014h    ;ret    exx    jp    in    d8 - db
  7263.     defb    003h,022h,039h,038h    ;call    ...    sbc    rst    dc - df
  7264.     defb    02bh,029h,01ah,010h    ;ret    pop    jp    ex    e0 - e3
  7265.     defb    003h,02ah,002h,038h    ;call    push    and    rst    e4 - e7
  7266.     defb    02bh,01ah,01ah,010h    ;ret    jp    jp    ex    e8 - eb
  7267.     defb    003h,022h,03fh,038h    ;call    ...    xor    rst    ec - ef
  7268.     defb    02bh,029h,01ah,00dh    ;ret    pop    jp    di    f0 - f3
  7269.     defb    003h,02ah,023h,038h    ;call    push    or    rst    f4 - f7
  7270.     defb    02bh,01ch,01ah,00fh    ;ret    ld    jp    ei    f8 - fb
  7271.     defb    003h,022h,005h,038h    ;call    ...    cp    rst    fc - ff
  7272.  
  7273.     defb    000h,001h,03eh,039h    ;add    adc    sub    sbc
  7274.     defb    002h,03fh,023h,005h    ;and    xor    or    cp
  7275.  
  7276.  
  7277.     defb    030h,035h,02eh,033h    ;rlc    rrc    rl    rr
  7278.     defb    03bh,03ch,022h,03dh    ;sla    sra    ...    srl
  7279.     defb    022h,040h,041h,042h    ;...    bit    res    set
  7280.  
  7281.  
  7282.     defb    022h,022h,022h,012h    ;...    ...    ...    halt
  7283.  
  7284.  
  7285.     defb    01ch,01ch,01ch,01ch    ;ld    ld    ld    ld
  7286.     defb    01ch,01ch,01ch,01ch    ;ld    ld    ld    ld
  7287.  
  7288.     page
  7289. ;****************************************************************************
  7290. ;*
  7291. ;*            table of first operands
  7292. ;*
  7293. ;****************************************************************************
  7294.  
  7295. zopnd1:
  7296.     defb    0ffh,00eh,08eh,00eh    ;00 - 03
  7297.     defb    006h,006h,006h,0ffh    ;04 - 07
  7298.     defb    00dh,018h,001h,00eh    ;08 - 0b
  7299.     defb    007h,007h,007h,0ffh    ;0c - 0f
  7300.     defb    01bh,00fh,08fh,00fh    ;10 - 13
  7301.     defb    004h,004h,004h,0ffh    ;14 - 17
  7302.     defb    01bh,018h,001h,00fh    ;18 - 1b
  7303.     defb    005h,005h,005h,0ffh    ;1c - 1f
  7304.     defb    013h,018h,09dh,018h    ;20 - 23
  7305.     defb    002h,002h,002h,0ffh    ;24 - 27
  7306.     defb    011h,018h,018h,018h    ;28 - 2b
  7307.     defb    003h,003h,003h,0ffh    ;2c - 2f
  7308.     defb    012h,009h,09dh,009h    ;30 - 33
  7309.     defb    098h,098h,098h,0ffh    ;34 - 37
  7310.     defb    007h,018h,001h,009h    ;38 - 3b
  7311.     defb    001h,001h,001h,0ffh    ;3c - 3f
  7312.  
  7313.     defb    006h,087h,000h,09dh    ;40 - 43
  7314.     defb    0ffh,0ffh,01fh,00ch    ;44 - 47
  7315.     defb    007h,087h,000h,00eh    ;48 - 4b
  7316.     defb    0ffh,0ffh,0ffh,00bh    ;4c - 4f
  7317.     defb    004h,087h,000h,09dh    ;50 - 53
  7318.     defb    0ffh,0ffh,01fh,001h    ;54 - 57
  7319.     defb    005h,087h,000h,00fh    ;58 - 5b
  7320.     defb    0ffh,0ffh,01fh,001h    ;5c - 5f
  7321.     defb    002h,087h,000h,0ffh    ;60 - 63
  7322.     defb    0ffh,0ffh,0ffh,0ffh    ;64 - 67
  7323.     defb    003h,087h,000h,0ffh    ;68 - 6b
  7324.     defb    01ch,01dh,01dh,0ffh    ;6c - 6f    defb  defw  ddb
  7325.     defb    01dh,01dh,000h,09dh    ;70 - 73    org   equ
  7326.     defb    0ffh,0ffh,0ffh,0ffh    ;74 - 77
  7327.     defb    001h,087h,000h,009h    ;78 - 7b
  7328.     defb    0ffh,0ffh,0ffh,0ffh    ;7c - 7f
  7329.  
  7330.     defb    0ffh,0ffh,0ffh,0ffh    ;a0 - bf
  7331.     defb    0ffh,0ffh,0ffh,0ffh    ;a4 - a7
  7332.     defb    0ffh,0ffh,0ffh,0ffh    ;a8 - ab
  7333.     defb    0ffh,0ffh,0ffh,0ffh    ;ac - af
  7334.     defb    0ffh,0ffh,0ffh,0ffh    ;b0 - b3
  7335.     defb    0ffh,0ffh,0ffh,0ffh    ;b4 - b7
  7336.     defb    0ffh,0ffh,0ffh,0ffh    ;b8 - bb
  7337.     defb    0ffh,0ffh,00fh,0ffh    ;bc - bf
  7338.  
  7339.     defb    013h,00eh,013h,01dh    ;c0 - c3
  7340.     defb    013h,00eh,001h,01eh    ;c4 - c7
  7341.     defb    011h,0ffh,011h,0ffh    ;c8 - cb
  7342.     defb    011h,01dh,001h,01eh    ;cc - cf
  7343.     defb    012h,00fh,012h,09ch    ;d0 - d3
  7344.     defb    012h,00fh,01ch,01eh    ;d4 - d7
  7345.     defb    007h,0ffh,007h,001h    ;d8 - db
  7346.     defb    007h,0ffh,001h,01eh    ;dc - df
  7347.     defb    015h,018h,015h,089h    ;e0 - e3
  7348.     defb    015h,018h,01ch,01eh    ;e4 - e7
  7349.     defb    014h,098h,014h,00fh    ;e8 - eb
  7350.     defb    014h,0ffh,01ch,01eh    ;ec - ef
  7351.     defb    00ah,00dh,00ah,0ffh    ;f0 - f3
  7352.     defb    00ah,00dh,01ch,01eh    ;f4 - f7
  7353.     defb    016h,009h,016h,0ffh    ;f8 - fb
  7354.     defb    016h,0ffh,01ch,01eh    ;fc - ff
  7355.  
  7356.  
  7357.     defb    001h,001h,019h,001h    ;8 bit logic and arithmetic
  7358.     defb    019h,019h,019h,019h    ;
  7359.  
  7360.  
  7361.     defb    019h,019h,019h,019h    ;shift and rotate
  7362.     defb    019h,019h,019h,019h    ;
  7363.     defb    0ffh,01fh,01fh,01fh    ;bit - res - set
  7364.  
  7365.     defb    0ffh,0ffh,0ffh,0ffh    ;filler
  7366.  
  7367.     defb    01ah,01ah,01ah,01ah    ;8 bit load
  7368.     defb    01ah,01ah,01ah,01ah    ;
  7369.  
  7370.     page
  7371. ;***********************************************************************
  7372. ;*
  7373. ;*            table of second    operands
  7374. ;*
  7375. ;***********************************************************************
  7376.  
  7377.  
  7378. zopnd2:
  7379.     defb    0ffh,01dh,001h,0ffh    ;00 - 03
  7380.     defb    0ffh,0ffh,01ch,0ffh    ;04 - 07
  7381.     defb    00dh,00eh,08eh,0ffh    ;08 - 0b
  7382.     defb    0ffh,0ffh,01ch,0ffh    ;0c - 0f
  7383.     defb    0ffh,01dh,001h,0ffh    ;10 - 13
  7384.     defb    0ffh,0ffh,01ch,0ffh    ;14 - 17
  7385.     defb    0ffh,00fh,08fh,0ffh    ;18 - 1b
  7386.     defb    0ffh,0ffh,01ch,0ffh    ;1c - 1f
  7387.     defb    01bh,01dh,018h,0ffh    ;20 - 23
  7388.     defb    0ffh,0ffh,01ch,0ffh    ;24 - 27
  7389.     defb    01bh,018h,09dh,0ffh    ;28 - 2b
  7390.     defb    0ffh,0ffh,01ch,0ffh    ;2c - 2f
  7391.     defb    01bh,01dh,001h,0ffh    ;30 - 33
  7392.     defb    0ffh,0ffh,01ch,0ffh    ;34 - 37
  7393.     defb    01bh,009h,09dh,0ffh    ;38 - 3b
  7394.     defb    0ffh,0ffh,01ch,0ffh    ;3c - 3f
  7395.  
  7396.  
  7397.     defb    087h,006h,00eh,00eh    ;40 - 43
  7398.     defb    0ffh,0ffh,0ffh,001h    ;44 - 47
  7399.     defb    087h,007h,00eh,09dh    ;48 - 4b
  7400.     defb    0ffh,0ffh,0ffh,001h    ;4c - 4f
  7401.     defb    087h,004h,00fh,00fh    ;50 - 53
  7402.     defb    0ffh,0ffh,0ffh,00ch    ;54 - 57
  7403.     defb    087h,005h,00fh,09dh    ;58 - 5b
  7404.     defb    0ffh,0ffh,0ffh,00bh    ;5c - 5f
  7405.     defb    087h,002h,000h,0ffh    ;60 - 63
  7406.     defb    0ffh,0ffh,0ffh,0ffh    ;64 - 67
  7407.     defb    087h,003h,000h,0ffh    ;68 - 6b
  7408.     defb    0ffh,0ffh,0ffh,0ffh    ;6c - 6f
  7409.     defb    0ffh,0ffh,009h,009h    ;70 - 73
  7410.     defb    0ffh,0ffh,0ffh,0ffh    ;74 - 77
  7411.     defb    087h,001h,009h,09dh    ;78 - 7b
  7412.     defb    0ffh,0ffh,0ffh,0ffh
  7413.  
  7414.     defb    0ffh,0ffh,0ffh,0ffh    ;a0 - bf
  7415.     defb    0ffh,0ffh,0ffh,0ffh    ;a4 - a7
  7416.     defb    0ffh,0ffh,0ffh,0ffh    ;a8 - ab
  7417.     defb    0ffh,0ffh,0ffh,0ffh    ;ac - af
  7418.     defb    0ffh,0ffh,0ffh,0ffh    ;b0 - b3
  7419.     defb    0ffh,0ffh,0ffh,0ffh    ;b4 - b7
  7420.     defb    0ffh,0ffh,0ffh,0ffh    ;b8 - bb
  7421.     defb    0ffh,0ffh,00fh,0ffh    ;bc - bf
  7422.  
  7423.     defb    0ffh,0ffh,01dh,0ffh    ;c0 - c3
  7424.     defb    01dh,0ffh,01ch,0ffh    ;c4 - c7
  7425.     defb    0ffh,0ffh,01dh,0ffh    ;c8 - cb
  7426.     defb    01dh,0ffh,01ch,0ffh    ;cc - cf
  7427.     defb    0ffh,0ffh,01dh,001h    ;d0 - d3
  7428.     defb    01dh,0ffh,0ffh,0ffh    ;d4 - d7
  7429.     defb    0ffh,0ffh,01dh,09ch    ;d8 - db
  7430.     defb    01dh,0ffh,01ch,0ffh    ;dc - df
  7431.     defb    0ffh,0ffh,01dh,018h    ;e0 - e3
  7432.     defb    01dh,0ffh,0ffh,0ffh    ;e4 - e7
  7433.     defb    0ffh,0ffh,01dh,000h    ;e8 - eb
  7434.     defb    01dh,0ffh,0ffh,0ffh    ;ec - ef
  7435.     defb    0ffh,0ffh,01dh,0ffh    ;f0 - f3
  7436.     defb    01dh,0ffh,0ffh,0ffh    ;f4 - f7
  7437.     defb    0ffh,018h,01dh,0ffh    ;f8 - fb
  7438.     defb    01dh,0ffh,0ffh,0ffh    ;fc - ff
  7439.  
  7440.     defb    019h,019h,0ffh,019h    ;8 bit logic and arithmetic
  7441.     defb    0ffh,0ffh,0ffh,0ffh    ;
  7442.  
  7443.     defb    0ffh,0ffh,0ffh,0ffh    ;shift and rotate
  7444.     defb    0ffh,0ffh,0ffh,0ffh    ;
  7445.     defb    0ffh,019h,019h,019h    ;bit - res - set
  7446.  
  7447.     defb    0ffh,0ffh,0ffh,0ffh
  7448.  
  7449.     defb    019h,019h,019h,019h    ;8 bit load
  7450.     defb    019h,019h,019h,019h
  7451.     page
  7452.  
  7453. ;***********************************************************************
  7454. ;*
  7455. ;*            table of op code names
  7456. ;*
  7457. ;***********************************************************************
  7458.  
  7459.  
  7460. zopcnm:
  7461.     defb    'ADD ADC AND CALL'
  7462.     defb    'CCF CP  CPD CPDR'
  7463.     defb    'CPI CPIRCPL DAA '
  7464.     defb    'DEC DI  DJNZEI  '
  7465.     defb    'EX  EXX HALTIM  '
  7466.     defb    'IN  INC IND INDR'
  7467.     defb    'INI INIRJP  JR  '
  7468.     defb    'LD  LDD LDDRLDI '
  7469.     defb    'LDIRNEG NOP OR  '
  7470.     defb    'OTDROTIROUT OUTD'
  7471.     defb    'OUTIPOP PUSHRET '
  7472.     defb    'RETIRETNRL  RLA '
  7473.     defb    'RLC RLCARLD RR  '
  7474.     defb    'RRA RRC RRCARRD '
  7475.     defb    'RST SBC SCF SLA '
  7476.     defb    'SRA SRL SUB XOR '
  7477.     defb    'BIT RES SET ORG '
  7478.     defb    'DEFBDEFWDDB EQU '
  7479.  
  7480.  
  7481.  
  7482.  
  7483. op1000:
  7484.     defb     0fdh,0ddh,0edh,0cbh
  7485.  
  7486.  
  7487.  
  7488. pswbit:    defb    10001000b        ;minus
  7489.     defb    10000000b        ;positive
  7490.     defb    00001100b        ;even parity
  7491.     defb    00000100b        ;odd parity
  7492.     defb    01001000b        ;zero
  7493.     defb    01000000b        ;not zero
  7494.     defb    00001001b        ;carry
  7495.     defb    00000001b        ;no carry
  7496.  
  7497. pswmap:    defb    18,07,19,17,21,20,10,22
  7498. pswcnt    equ    $-pswmap
  7499.  
  7500.  
  7501. regmap:
  7502.     defb    87h,01h,07h,06h,05h,04h
  7503.     defb    03h,02h,95h,93h,91h,18h
  7504.     defb    19h,81h,83h,85h,97h
  7505.  
  7506. regptr:
  7507.     defb    0dh,0eh,0fh,00h
  7508.     defb    8dh,8eh,8fh,80h
  7509.     defb    0ah,09h,08h,10h
  7510.  
  7511. siotbl:    defb    0f5h,0f7h
  7512.  
  7513. symflg:    defb    0ffh        ;symbol    table flag   00    - table    present
  7514.                 ;             ff    - no table
  7515.  
  7516. bsiz:                ;dump block size storage
  7517. bsizlo:    defb    0        ;     lo order
  7518. bsizhi:    defb    1        ;     hi order
  7519. blkptr:    defw    100h        ;dump block address
  7520.  
  7521. loadb:    defw    100h        ;z8e load bias for lldr command
  7522. loadn:    defw    00        ;end of load address
  7523.  
  7524. asmbpc:                ;next pc location for assembly
  7525. zasmpc:    defw    100h        ;next pc location for disassemble
  7526.                 ;default at load time: start of    tpa
  7527. zasmfl:    defw    00        ;first disassembled address on jdbg screen
  7528.  
  7529.  
  7530. from:
  7531. oprn01:
  7532. rlbias:
  7533. lines:
  7534. exampt:
  7535. endw:
  7536. zasmnx:    defb    0        ;address of next instruction to    disassemble
  7537. oprx01:    defb    0
  7538. bias:
  7539. biaslo:
  7540. zasmct:    defb    0        ;disassembly count
  7541. biashi:
  7542. oprn02:    defb    0
  7543. oprx02:
  7544. zasmwt:    defw    0        ;disassembly count - working tally
  7545. opnflg:    defb    0        ;00 - operand 1   ff - operand 2   zasm
  7546.                 ;and input character storage for interactive
  7547.                 ;disassembly 
  7548. quoflg:    defb    0
  7549. wflag:    defb    0ffh        ;trace subroutine flag:    nz - trace subs
  7550.                 ;             z - no    trace
  7551.  
  7552. nstep:
  7553. nstepl:    defb    0
  7554. nsteph:    defb    0
  7555.  
  7556. sbps:    defb    0        ;number    of step    breakpoints
  7557. bps:    defb    0        ;number    of normal breakpoints
  7558.  
  7559. zmflag:    defb    0
  7560. zasmf:    defb    0
  7561. execbf:                ;execute buffer    for relocated code
  7562. jlines:
  7563. parenf:    
  7564. nument:    defb    0        ;number    of digits entered
  7565. delim:    defb    0        ;argument delimeter character
  7566.     defb    0
  7567. base10:    defb    0
  7568. jmp2jp:    defb    0
  7569. jmp2:    defb    0
  7570. dwrite:
  7571. cflag:    defb    0
  7572.  
  7573. ikey:
  7574. zasmkv:
  7575. jmp:    defb    0
  7576. mexp:
  7577. jmplo:    defb    0
  7578. strngf:
  7579. jmphi:    defb    0
  7580. timer:
  7581. first:    defb    0
  7582. regtrm:    defb    0
  7583. trmntr: defb    0
  7584. isympt:    defw    0
  7585.  
  7586. jropnd:
  7587. pass2:    defw    0
  7588.  
  7589. fndsym:    defw    0
  7590.  
  7591.     if    ASMB
  7592. maxlen:
  7593.     else
  7594. maxlen::
  7595.     endif
  7596.     defw    14
  7597.  
  7598. maxlin:    defw    62
  7599.  
  7600. fwndow:    defb    00
  7601.  
  7602. nlmask:    defb    00    
  7603.     
  7604.     if    ASMB
  7605. case:
  7606.     else
  7607. case::
  7608.     endif
  7609.     defb    0ffh        ;flag to indicate case of output
  7610.                 ;nz - lower   z - upper
  7611.  
  7612. jstepf:    defb    0ffh        ;00 -   screen is intact, if user wants j 
  7613.                 ;       single step no need to repaint screen, 
  7614.                 ;       just move arrow.
  7615.                 ;01   - user wants single-step j command
  7616.                 ;else - j screen corrupted by non-j command
  7617.  
  7618. lastro:    defb    03
  7619.  
  7620.     if    ASMB
  7621. rowb4?:
  7622.     else
  7623. rowb4?::
  7624.     endif
  7625.     if jterm            ;my terminal uses xy addressing
  7626.     defb    0
  7627.     else            ;most others use yx
  7628.     defb    1
  7629.     endif
  7630.  
  7631.     if    ASMB
  7632. mxycp:
  7633.     else
  7634. mxycp::
  7635.     endif
  7636.     if jterm
  7637.     defb    1,9        ;jrs special (Datapoint 8227)
  7638.     else
  7639.     if aterm
  7640.         defb    4,ESC,'[2J'
  7641.     else
  7642.     defb    2,1bh,'='    ;ADM 3a in "standard" version
  7643.     defb    0,0,0,0,0,0,0,0
  7644.     endif
  7645.     endif
  7646.  
  7647. xyrow:    defb    0
  7648. xycol:    defb    0
  7649.  
  7650.     if    ASMB
  7651. row:
  7652.     else
  7653. row::
  7654.     endif
  7655.     if jterm                ;my terminal uses no bias for
  7656.     defb    0            ;cursor coordinates
  7657.     else
  7658.     defb    ' '            ;bias for most other terminals
  7659.     endif
  7660.     if    ASMB
  7661. column:
  7662.     else
  7663. column::
  7664.     endif
  7665.     if jterm                ;see above
  7666.     defb    0
  7667.     else
  7668.     defb    ' '
  7669.     endif
  7670.  
  7671. wnwtab:    defw    0
  7672. wnwsiz:    defw    0
  7673.  
  7674. port:    defw    0
  7675.  
  7676. brktbl:    defs    (maxbp+2)*3
  7677. psctbl:    defs    maxbp*2
  7678.  
  7679.  
  7680. regcon:
  7681. afreg:
  7682. freg:    defb    00
  7683.     defb    00
  7684. bcreg:    defw    00
  7685. dereg:    defw    00
  7686. hlreg:    defw    00
  7687. afpreg:    defw    00
  7688. bcpreg:    defw    00
  7689. depreg:    defw    00
  7690. hlpreg:    defw    00
  7691. pcreg:
  7692. pcregl:    defb    00
  7693. pcregh:    defb    01
  7694. spreg:    defw    00
  7695. ixreg:    defw    00
  7696. iyreg:    defw    00
  7697.  
  7698. regsiz    equ    $-regcon
  7699.  
  7700. rreg:    defb    00
  7701. ireg:    defb    00
  7702.  
  7703.  
  7704. fstart:    defw    0
  7705. argbc:    defw    0
  7706. argbpt:    defw    argbf
  7707.  
  7708. regsav    equ    $        ;storage for register contents in between bps
  7709.                 ;while jdbg is in control
  7710.  
  7711. window    equ    regsav+regsiz    ;memory window save area
  7712.  
  7713. argbsz    equ    62
  7714.  
  7715. argbf:    defs    argbsz
  7716.  
  7717. fcb    equ     argbf+argbsz-36 ;cp/m file control block
  7718. fcbnam    equ    fcb+1        ;start of file name in fcb
  7719. fcbtyp    equ    fcbnam+8    ;start of file type in fcb
  7720. fcbext    equ    fcbtyp+3    ;current extent    number
  7721. nfcb    equ    $        ;last byte of fcb plus one
  7722.  
  7723. gpbsiz    equ    164        ;size of general purpose buffer
  7724.  
  7725. symbuf:
  7726. objbuf:                ;object    code buffer
  7727.     rept    gpbsiz
  7728.     defb    0
  7729.     endm
  7730. inbfsz    equ    gpbsiz/2
  7731. inbfmx    equ    objbuf+4    ;input buffer -    max byte count storage
  7732. inbfnc    equ    inbfmx+1    ;          -    number chars read in
  7733. inbf    equ    inbfnc+1    ;          -    starting address
  7734. inbfl    equ    inbfsz-1    ;          -    last relative position
  7735. ninbf    equ    inbf+inbfl    ;          -    address    of last    char
  7736.  
  7737. prsbfz    equ    gpbsiz/2
  7738. prsbf    equ    inbf+inbfsz    ;parse buffer -    starting address
  7739. lprsbf    equ    prsbf+prsbfz-1    ;          -    last char of parse buf
  7740. nprsbf    equ    lprsbf+1    ;          -    end address plus one
  7741.  
  7742. nzasm    equ    $        ;end of disassembly buffer
  7743. zasmbf    equ    nzasm-128    ;start of disassembly buffer
  7744.  
  7745.     defs    40
  7746. stack:
  7747. nmem    equ    ((($+255) and 0ff00h)-z8eorg) and 0ff00h
  7748. ;    was    (256*(($+255)/256)-z8eorg) and 0ff00h
  7749.  
  7750.     if M80
  7751.     .list            ;enable printer output for symbol table
  7752.     endif
  7753.     end
  7754.