home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / a / debug.lbr / DEBUG.ZZ0 / DEBUG.Z80
Encoding:
Text File  |  1993-10-26  |  51.4 KB  |  1,838 lines

  1.     TITLE    'AMYX DEBUG     3/6/85     1346'
  2. ;
  3. ;    *********************************************
  4. ;    *                        *
  5. ;    *               AMYX DEBUG                  *
  6. ;    *                        *
  7. ;    *   An assembly language debugger for Z80   *
  8. ;       *   CP/M.  Written by                *
  9. ;    *                        *      
  10. ;    *      Richard Amyx                *
  11. ;    *      994 North Second Street        *
  12. ;    *       San Jose, CA  95112            *
  13. ;    *      (408) 287-8572            *
  14. ;    *                        *
  15. ;    *   Given to  Micro Cornucopia for inclu-   *
  16. ;    *   sion in its  public  domain  library.   *
  17. ;    *   May not  be reproduced or distributed   *
  18. ;    *   for profit.                    *
  19. ;    *                        *
  20. ;    *********************************************
  21. ;
  22. ;****************************************************************************
  23. ;
  24. ;     TEST VERSION FOR MICRO C USE ONLY 3/6/85.
  25. ;     ----------NOT FOR DISTRIBUTION----------
  26. ;
  27. ;****************************************************************************
  28. ;    
  29. ;
  30.     ORG    100H 
  31. ;
  32. ;----------------------------------------------------------------------------
  33. ;   RELOCATION AND INITIALIZATION ROUTINE
  34. ;----------------------------------------------------------------------------
  35. ;
  36.     LD    (SYSSP),SP    ; SAVE SYSTEM SP
  37.     LD    SP,LOCSP    ; USE LOCAL STACK HERE
  38.     LD    HL,CODBEG    ; SOURCE
  39.     LD    DE,DESTIN    ; DESTINATION
  40.     LD    BC,CODSIZ    ; BYTE COUNT
  41.     LDIR            ; WHOOSH!
  42.     LD    HL,BRKTBL+O    ; ZERO ALL BREAKPOINTS
  43.     LD    B,12        ; 12 BYTES FOR 6 ADDRESSES
  44. BRKZER:    LD    (HL),0
  45.     INC    HL
  46.     DJNZ    BRKZER    
  47.     CALL    NEWLIN+O    ; DROP CURSOR A LINE
  48.     LD    DE,MOVED    ; POINT TO MOVED MESSAGE
  49.     CALL    MSGOUT+O    ; PRINT IT
  50.     CALL    NEWLIN+O    ; DROP CURSOR A LINE
  51.     LD    DE,XMES
  52.     CALL    MSGOUT+O
  53.     CALL    NEWLIN+O
  54.     LD    DE,INVOK0    ; PRINT FIRST PART OF INVOKE
  55.     CALL    MSGOUT+O    ; MESSAGE
  56.     LD    HL,DESTIN    ; PRINT START ADDRESS
  57.     LD    A,H
  58.     CALL    HX2ASC+O
  59.     LD    A,L
  60.     CALL    HX2ASC+O
  61.     LD    DE,INVOK1    ; PRINT SECOND PART OF INVOKE MESSAGE
  62.     CALL    MSGOUT+O
  63.     LD    HL,RELTOP    ; TOP OF RELOCATED CODE
  64.     LD    A,H        ; PRINT ADDRESS
  65.     CALL    HX2ASC+O
  66.     LD    A,L
  67.     CALL    HX2ASC+O
  68.     LD    DE,INVOK2    ; PRINT LAST PART OF INVOKE MESSAGE
  69.     CALL    MSGOUT+O
  70.     LD    HL,38H        ; PUT JUMP
  71.     LD    (HL),0C3H    ;  CODE AT 38H
  72.     LD    HL,DESTIN    ; PUT DEBUG ADDRESS
  73.     LD    (39H),HL    ;  IN CP/M JUMP TO DDT LOCATION
  74.     CALL    NEWLIN+O    ; DROP A LINE
  75.     LD    SP,(SYSSP)    ; GET SYSTEM SP BACK
  76.     RET            ; RELOCATED; RETURN TO CCP
  77.                 ; WITHOUT WARM BOOT
  78. ;
  79. ;
  80. RELTOP:    EQU    0C000H        ; TOP OF RELOCATED CODE
  81. ;
  82. MOVED:    DEFM    'AMYX DEBUG Version 1.0$'
  83. XMES:    DEFM    'Test version for Micro C 3/6/85$'
  84. INVOK0:    DEFM    'Loaded and relocated to $'
  85. INVOK1:    DEFM    'H - $'
  86. INVOK2:    DEFM    'H.$'
  87. ;
  88. ;----------------------------------------------------------------------------
  89. ;   BEGIN ACTUAL DEBUG CODE
  90. ;----------------------------------------------------------------------------
  91. ;
  92. CODBEG:    JP    ENTRY+O        ; BEGINNING OF CODE TO RELOCATED
  93. ;
  94. ;
  95. ;   BIOS EQUATES
  96. ;
  97. WBOOT    EQU     0
  98. BDOS    EQU    5
  99. CONIN    EQU    1        ; CHARACTER IN FROM KEYBOARD
  100. CONOUT    EQU    2        ; SINGLE CHARACTER TO CONSOLE
  101. PSTR    EQU    9        ; PRINT STRING ON CONSOLE
  102. LININ    EQU    10        ; READ CONSOLE BUFFER
  103. ;
  104. ;
  105. ;   CHARACTERS
  106. ;
  107. BELL    EQU    7
  108. BS    EQU    8
  109. LF    EQU    10
  110. CR    EQU    13
  111. SPACE    EQU    20H
  112. CLRSCR    EQU    26        ; KAYPRO ^Z CLEAR SCREEN CHAR
  113. HOME:    EQU    30        ; KAYPRO HOME CURSOR CHAR
  114. ;
  115. ;
  116. ;   KAYPRO CURSOR POSITIONS
  117. ;
  118. COMCUR:    EQU    3720H        ; COMMAND LINE HEX CURSOR POSITION
  119. ERRCUR:    EQU    3742H        ; ERROR MESSAGE HEX CURSOR POSITION
  120. BRKCUR:    EQU    3520H        ; BREAKPOINT LINE CURSOR POSITION
  121. MODCUR:    EQU    3729H        ; MEMORY MODIFY INPUT CURSOR
  122. MEMCUR:    EQU    2D26H        ; MEMORY DISPLAY CURSOR POS
  123. ;
  124. ;
  125. ;   MESSAGES
  126. ;
  127. MAF:    DEFM    'AF : $'
  128. MBC:    DEFM    'BC : $'
  129. MDE:    DEFM    'DE : $'
  130. MHL:    DEFM    'HL : $'
  131. MAFP:    DEFM    'AF'': $'
  132. MBCP:    DEFM    'BC'': $'
  133. MDEP:    DEFM    'DE'': $'
  134. MHLP:    DEFM    'HL'': $'
  135. MIX:    DEFM    'IX : $'
  136. MIY:    DEFM    'IY : $'
  137. MSP:    DEFM    'SP : $'
  138. MPC:    DEFM    'PC : $'
  139. MCOM:    DEFM    'Command? $'
  140. BADCOM:    DEFM    'BAD COMMAND!$'
  141. BRKMSG:    DEFM    'Breakpoints:  $'
  142. BRKFUL: DEFM    'BREAKPOINTS FULL!$'
  143. NOTFND:    DEFM    'STRING NOT FOUND.$'
  144. MODMSG:    DEFM    'Modify:  $'
  145. BLANK:    DEFM    '                          $'    ;26 SPACES
  146. COMCHR:    DEFM    'IHLSPXY'        ; OK COM BUFF CHARS 
  147. PTR:    DEFM    '=> $'
  148. ;
  149. ;
  150. ;   VARIABLES
  151. ;
  152. SYSSP:    DEFW    0        ; SYSTEM STACK POINTER
  153. SYSPC:    DEFW    0        ; SYSTEM PROGRAM COUNTER
  154. MEMSEL:    DEFW    0100H        ; DEFAULT MEM DISPLAY ADDRESS
  155. CBUFCT:    DEFB    0        ; COMMAND BUFFER COUNTER
  156. COMBUF:    DEFS    32        ; 32-CHARACTER COMMAND BUFFER
  157. TMPWRD:    DEFW    0        ; TEMPORARY STORAGE AS NEEDED
  158. LINECT:    DEFB    8        ; LINE COUNTER FOR DISMEM
  159. CURSOR:    DEFW    0        ; CURSOR SAVE FOR DISMEM
  160. BRKTBL:    DEFS    12        ; SPACE FOR 6 BREAKPOINT ADDRESSES
  161. CODSAV:    DEFS    6        ; THE CODE REPLACED BY BREAKPOINTS
  162. BRKCNT:    DEFB    0        ; COUNTER FOR BREAKPOINT TABLES
  163. START:    DEFW    0        ; ALL-PURPOSE START ADDRESS
  164. ENDADD:    DEFW    0        ; ALL-PURPOSE END ADDRESS
  165. BYTCNT:    DEFW    0        ; ALL-PURPOSE BYTE COUNT
  166. SCHSTR:    DEFS    11        ; 11-BYTE SEARCH STRING BUFFER
  167. MODFLG:    DEFB    0        ; MODIFY MEMORY FLAG
  168. COMFLG:    DEFB    0        ; NZ = COMMAND IN PROGRESS
  169. ;
  170. ;----------------------------------------------------------------------------
  171. ;   START MAIN PROGRAM
  172. ;----------------------------------------------------------------------------
  173. ;
  174. ENTRY:    LD    (SYSSP+O),SP    ; SAVE CALLING PROGRAM SP
  175.     LD    SP,LOCSP+O    ; SET UP THE LOCAL STACK
  176.     PUSH    AF        ; NOW SAVE EVERYTHING IN LOCAL STACK.
  177.     PUSH    BC        ; AF = LOCSP-17 & 18; BC = LOCSP-19 & 20
  178.     PUSH    DE        ; DE = LOCSP-15 & 16   { HIGH BYTE IS AT }
  179.     PUSH    HL        ; HL = LOCSP-13 & 14   { LOWER ADDRESS   }
  180.     EX    AF,AF'            ; EXCHANGE REGISTERS
  181.     EXX
  182.     PUSH    AF        ; AF' = LOCSP-11 & 12
  183.     PUSH    BC        ; BC' = LOCSP-9 & 10
  184.     PUSH    DE        ; DE' = LOCSP-7 & 8
  185.     PUSH    HL        ; HL' = LOCSP-5 & 6
  186.     PUSH    IX        ; IX = LOCSP-3 & 4
  187.     PUSH    IY        ; IY = LOCSP-1 & 2
  188.     LD    HL,(SYSSP+O)    ; SYSTEM SP TO HL
  189.     LD    C,(HL)        ; PC LOW AT SP TO C
  190.     INC    HL        ; SP+1 IS HIGH BYTE OF USER PC
  191.     LD    B,(HL)        ; PC HIGH TO B
  192.     LD    (SYSPC+O),BC    ; SAVE USER PC HERE    
  193.     LD    (TMPWRD+O),SP    ; PRESERVE CURRENT LOCAL SP
  194.     LD    SP,(SYSSP+O)    ; DISCARD DEBUG-CAUSED USER
  195.     POP    HL        ; PC FROM BOTTOM OF SYSTEM STACK
  196.     LD    (SYSSP+O),SP    ; SAVE ADJUSTED SP
  197.     LD    SP,(TMPWRD+O)    ; RESTORE CURRENT LOCAL SP
  198.     LD    E,27        ; SAVE
  199.     CALL    CHROUT+O    ;  USER
  200.     LD    E,'B'        ;   CURSOR
  201.     CALL    CHROUT+O    ;    POSITION
  202.     LD    E,'6'
  203.     CALL    CHROUT+O
  204. ;
  205. ;
  206. ;   CHECK FOR BREAKPOINTS AND INSTALL IF SET
  207. ;
  208.     LD    HL,BRKTBL+O    ; POINT TO BREAKPOINT TABLE
  209.     LD    B,6        ; NUMBER OF BREAKPOINTS TO CHECK
  210.     XOR    A        ; ZERO THE
  211.     LD    (BRKCNT+O),A    ; BREAKPOINT COUNTER
  212. CHKBR1:    LD    E,(HL)        ; LOW BKPT BYTE IN E
  213.     INC    HL        ; POINT TO HIGH BYTE
  214.     LD    D,(HL)        ; HIGH BKPT BYTE IN D
  215.     LD    A,D        ; SEE IF CONTENTS OF TABLE ENTRY
  216.     OR    E        ; IS ZERO
  217.     CALL    NZ,SETBRK+O    ; IF NOT, INSTALL IT
  218.     INC    HL        ; POINT TO NEXT LOW BYTE
  219.     LD    A,(BRKCNT+O)    ; BUMP BREAKPOINT
  220.     INC    A        ; COUNTER
  221.     LD    (BRKCNT+O),A
  222.     DJNZ    CHKBR1        ; GO UNTIL SIX CHECKED 
  223. ;
  224. ;
  225. ;   FIX BREAKPOINT ON ENTRY FOR CORRECT PC & SP DISPLAYS,
  226. ;   AND FOR CORRECT EXECUTION ON GO.  FIRST, CHECK TO SEE
  227. ;   WHETHER ENTRY TO DEBUG CAME FROM A BREAKPOINT OR A
  228. ;   CODED RST 38H.
  229. ;
  230.     LD    DE,(SYSPC+O)    ; GET THE SYSTEM PC
  231.     DEC    DE        ; ONE LESS IF FROM BKPT
  232.     CALL    MATCH+O        ; SEE IF IT'S A BREAKPOINT
  233.     JR    NZ,ENTRY0    ; IT ISN'T, SO GO TO DISPLAY
  234.     LD    B,0        ; IT IS--FIRST FIX CODE
  235.     LD    A,(BRKCNT+O)    ; PUT BREAKPOINT COUNTER
  236.     LD    C,A        ; IN BC
  237.     LD    HL,CODSAV+O    ; POINT TO SAVED CODE TABLE
  238.     ADD    HL,BC        ; ADD OFFSET
  239.     LD    A,(HL)        ; SAVED CODE TO A
  240.     LD    (DE),A        ; THEN TO PROGRAM ADDRESS
  241.     LD    (SYSPC+O),DE    ; SAVE THE ADJUSTED PC
  242. ;
  243. ;
  244. ;   BEGIN OPENING SCREEN DISPLAY
  245. ;
  246. ENTRY0:    LD    E,CLRSCR    ; CLEAR SCREEN
  247.     CALL    CHROUT+O
  248. ENTRY1:    LD    DE,MAF+O    ; POINT TO AF MESSAGE
  249.     CALL    MSGOUT+O    ; SEND IT
  250.     LD    (TMPWRD+O),SP    ; PUT LOCAL SP IN IX--NOTHING SHOULD BE
  251.     LD    IX,(TMPWRD+O)    ; PUSHED OR CALLED AT THIS POINT.
  252.     CALL    DISPAF+O    ; DISPLAY AF HEX VALUES AND
  253.                 ; FLAG INDICATIONS
  254.     CALL    NEWLIN+O    ; MOVE CURSOR TO NEXT LINE
  255.     LD    DE,MBC+O    ; POINT TO BC MESSAGE
  256.     CALL    MSGOUT+O    ; SEND IT
  257.     CALL    DISPBC+O    ; DISPLAY HEX VALUES, INDIRECTS,
  258.                 ; AND ASCII REPRESENTATIONS.
  259.     CALL    NEWLIN+O    ; DROP CURSOR FOR NEXT LINE
  260.     LD    DE,MDE+O    ; POINT TO DE MESSAGE
  261.     CALL    MSGOUT+O    ; SEND IT
  262.     CALL    DISPDE+O    ; DISPLAY DE VALUES
  263.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  264.     LD    DE,MHL+O    ; POINT TO HL MESSAGE
  265.     CALL    MSGOUT+O    ; SEND IT
  266.     CALL    DISPHL+O    ; DISPLAY HL VALUES
  267.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  268.     LD    DE,MAFP+O    ; POINT TO AF' MESSAGE
  269.     CALL    MSGOUT+O    ; SEND IT 
  270.     CALL    DISAFP+O    ; DISPLAY AF' VALUES
  271.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  272.     LD    DE,MBCP+O    ; POINT TO BC' MESSAGE
  273.     CALL    MSGOUT+O    ; SEND IT
  274.     CALL    DISBCP+O    ; DISPLAY BC' VALUES
  275.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  276.     LD    DE,MDEP+O    ; POINT TO DE' MESSAGE
  277.     CALL    MSGOUT+O    ; SEND IT
  278.     CALL    DISDEP+O    ; DISPLAY DE' VALUES
  279.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  280.     LD    DE,MHLP+O    ; POINT TO HL' MESSAGE
  281.     CALL    MSGOUT+O    ; SEND IT
  282.     CALL    DISHLP+O    ; DISPLAY HL' VALUES
  283.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  284.     LD    DE,MIX+O    ; POINT TO IX MESSAGE
  285.     CALL    MSGOUT+O    ; SEND IT
  286.     CALL    DISPIX+O    ; DISPLAY IX VALUES
  287.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  288.     LD    DE,MIY+O    ; POINT TO IY MESSAGE
  289.     CALL    MSGOUT+O    ; SEND IT
  290.     CALL    DISPIY+O    ; DISPLAY IY VALUES
  291.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  292.     LD    DE,MSP+O    ; POINT TO SP MESSAGE
  293.     CALL    MSGOUT+O    ; SEND IT
  294.     CALL    DISPSP+O    ; DISPLAY SP VALUES
  295.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  296.     LD    DE,MPC+O    ; POINT TO PC MESSAGE
  297.     CALL    MSGOUT+O    ; SEND IT
  298.     CALL    DISPPC+O    ; DISPLAY PC CONTENTS
  299.     LD    HL,(MEMSEL+O)    ; GET ADDRESS OF MEMORY FOR DISPLAY
  300.     CALL    DISMEM+O    ; GO DISPLAY 128 BYTES OF MEMORY
  301.     CALL    NEWLIN+O    ; CURSOR TO NEXT LINE
  302.     CALL    DISBRK+O    ; DISPLAY BREAKPOINTS
  303.     JP    COMRET+O    ; AND HEAD FOR COMMAND ENTRY
  304. ;
  305. ;
  306. ;   BEGIN COMMAND PROCESSING MODULE
  307. ;
  308. COMAND:    LD    BC,COMCUR    ; GET HEX COMMAND CURSOR POS
  309.     CALL    POSCUR+O    ; POSITION CURSOR
  310.     LD    DE,MCOM+O    ; POINT AT "Command?" MESSAGE
  311.     CALL    MSGOUT+O  
  312. KEYIN:    XOR    A        ; CLEAR A
  313.     LD    (CBUFCT+O),A    ; ZERO COUNTER
  314.     LD    HL,COMBUF+O-1    ; SET BUFFER POINTER FOR 1ST CHAR
  315. KEYIN1:    CALL    KBD+O        ; GET A CHARACTER
  316. ;
  317. ;
  318. ;   CHECK FOR IMMEDIATE COMMANDS
  319. ;
  320.     CP    'Q'        ; CANCEL COMMAND? (ALWAYS ACTIVE)
  321.     JP    Z,COMRET+O    ; YES, WIPE LINE & START OVER
  322.     LD    C,A        ; SAVE CHAR IN C
  323.     LD    A,(COMFLG+O)    ; IS A COMMAND IN PROGRESS?
  324.     OR    A        ; NZ = YES 
  325.     LD    A,C        ; GET CHAR BACK
  326.     JP    NZ,CKCHAR+O    ; YES, SKIP TO CHAR CHECK
  327.     CP    '+'        ; PAGE MEMORY FORWARD?
  328.     JP    Z,MPAGE+O    ; YES, GO TO MEMORY PAGE
  329.     CP    '='        ; TREAT SAME AS +
  330.     JR    NZ,CFM        ; NOT '='--CHECK FOR -
  331.     LD    A,'+'        ; MAKE = A + FOR 2ND COMPARE
  332.     JP    MPAGE+O        ; AND GO TO PAGE MEM        
  333. CFM:    CP    '-'        ; PAGE MEMORY BACKWARD?
  334.     JP    Z,MPAGE+O    ; YES, GO TO MEMORY PAGE
  335.     CP    'G'        ; CONTINUE FROM BREAKPOINT?
  336.     JP    Z,DBEND+O    ; YES, GO TO END
  337.     CP    'O'        ; SINGLE-STEP?
  338.     JP    Z,SSTEP+O    ; SIMON SAYS TAKE ONE STEP
  339.     CP    'Z'        ; CLEAR ALL BREAKPOINTS?
  340.     JP    Z,CLRBRK+O    ; YES, GO DO IT.
  341. ;
  342. ;
  343. ;   NOT AN IMMEDIATE COMMAND--PUT CHAR IN COMMAND BUFFER IF OK
  344. ;
  345.     LD    (COMFLG+O),A    ; INDICATES COMMAND IN PROCESS
  346.     CP    'D'        ; DISPLAY MEMORY?
  347.     JP    Z,AD2BUF+O    ; D OK; ADD TO BUFFER
  348.     CP    'M'        ; MODIFY MEMORY?
  349.     JP    Z,AD2BUF+O    ; M OK; ADD TO BUFFER
  350.     CP    'B'        ; SET BREAKPOINT?
  351.     JP    Z,AD2BUF+O    ; B OK; ADD TO BUFFER
  352.     CP    'F'        ; FIX (CLEAR) ONE BKPT?
  353.     JP    Z,AD2BUF+O    ; F OK; ADD TO BUFFER
  354.     CP    'J'        ; JUMP TO ADDRESS?
  355.     JP    Z,AD2BUF+O    ; J OK; ADD TO BUFFER
  356.     CP    'L'        ; FILL MEMORY?
  357.     JP    Z,AD2BUF+O    ; L OK; ADD TO BUFFER
  358.     CP    'R'        ; MODIFY REGISTER?
  359.     JP    Z,AD2BUF+O    ; R OK; ADD TO BUFFER
  360.     CP    'T'        ; BLOCK MOVE?
  361.     JP    Z,AD2BUF+O    ; T OK; ADD TO BUFFER
  362.     CP    'S'        ; SEARCH STRING?
  363.     JP    Z,AD2BUF+O    ; S OK; ADD TO BUFFER
  364.     CP    'H'        ; HEX ARITHMETIC?
  365.     JP    Z,AD2BUF+O    ; H OK; ADD TO BUFFER
  366.     JP    BADCHR+O    ; BEEP AND IGNORE
  367. ;
  368. ;
  369. ;   CHECK CHARACTERS BEFORE ADDING TO BUFFER
  370. ;   MUST BE HEX DIGIT, REGISTER IDENTIFIER,
  371. ;   PERIOD, BS, OR CR.  SPACE OK BUT NOT ADDED
  372. ;   TO BUFFER.
  373. ;
  374. CKCHAR:    OR    A        ; CLEAR CARRY FLAG
  375.     CP    '0'        ; BELOW 0?
  376.     JR    NC,CK1        ; 0 OR ABOVE, KEEP GOING
  377.     CP    '.'        ; IS IT A PERIOD
  378.     JR    Z,AD2BUF    ; YES, ADD IT TO BUFFER
  379.     CP    '-'        ; IS IT MINUS SIGN?
  380.     JR    Z,AD2BUF    ; YES, ADD IT TO BUFFER
  381.     CP    '+'        ; IS IT PLUS SIGN?
  382.     JR    Z,AD2BUF    ; YES, ADD IT TO BUFFER
  383.     CP    39        ; IS IT AN APOSTROPHE?
  384.     JR    Z,AD2BUF    ; YES, ADD IT TO BUFFER
  385.     CP    32        ; IS IT SPACE?
  386.     JP    Z,KEYIN1+O    ; OK, BUT DON'T PUT IN BUFFER
  387.     CP    13        ; IS IT CR?
  388.     JP    Z,COMDEC+O    ; YES, END ENTRY, DECODE COMMAND
  389.     CP    8        ; IS IT BACKSPACE?
  390.     JR    NZ,BADCHR    ; NO, IT'S A BOO-BOO
  391.     LD    A,(CBUFCT+O)    ; GET BUFFER COUNT
  392.     OR    A        ; IS THE BUFFER EMPTY?
  393.     JR    Z,BADCHR    ; YES, DON'T BACK UP ANY MORE
  394.     DEC    A        ; DECREMENT BUFFER COUNTER
  395.     LD    (CBUFCT+O),A    ; SAVE NEW VALUE    
  396.     DEC    HL        ; DECREMENT BUFFER POINTER
  397.     JP    KEYIN1+O    ; GO FOR NEW CHARACTER
  398. CK1:    CP    58        ; 0 TO 9?
  399.     JR    NC,CK2        ; ABOVE 9, KEEP GOING
  400.     JR    AD2BUF        ; BETWEEK 0 & 9, ADD TO BUFFER
  401. CK2:    CP    'A'        ; BETWEEN 9 AND A?
  402.     JR    NC,CK3        ; ABOVE A, KEEP GOING
  403.     JR    BADCHR        ; BETWEEN 9 & A, NO GOOD
  404. CK3:    CP    'G'        ; ABOVE F?
  405.     JR    NC,CK4        ; YES, ONE MORE CHECK
  406.     JR    AD2BUF        ; NO, PUT IT IN BUFFER 
  407. CK4:    PUSH    HL        ; SAVE BUFFER TABLE LOCATION
  408.     LD    HL,COMCHR+O    ; POINT TO CHARACTER TABLE
  409.     LD    BC,7        ; 7 CHARS TO CHECK
  410.     CPIR            ; IHLSPXY?
  411.     POP    HL        ; BUFFER TABLE LOCATION BACK
  412.     JR    Z,AD2BUF    ; YES, ADD TO BUFFER
  413. BADCHR:    CALL    BEEP+O        ; BEEP KEYBOARD
  414.     LD    E,BS        ; PRINT A
  415.     CALL    CHROUT+O    ;  BACKSPACE
  416.     JP    KEYIN1+O    ; THEN GO FOR NEW CHAR
  417. ;
  418. ;
  419. ;   COMMAND OR CHARACTER OK--ADD IT TO COMMAND BUFFER
  420. ;
  421. AD2BUF:    LD    C,A        ; SAVE CHAR IN C
  422.     LD    A,(CBUFCT+O)    ; GET BUFFER COUNT
  423.     INC    A        ; BUMP COUNT
  424.     CP    33        ; BUFFER FULL?
  425.     JR    NC,BADCHR    ; YES, BEEP & IGNORE
  426.     LD    (CBUFCT+O),A    ; SAVE COUNT
  427.     LD    A,C        ; GET CHAR BACK
  428.     INC    HL        ; BUMP BUFFER POINTER
  429.      LD    (HL),A        ; PUT CHAR IN BUFFER
  430.     JP    KEYIN1+O    ; GO FOR NEXT CHARACTER
  431. ;
  432. ;
  433. ;   COMMAND DECODE
  434. ;
  435. COMDEC:    LD    A,(MODFLG+O)    ; ARE WE DOING MODIFY MEMORY?
  436.     OR    A        ;  (1 = YES)
  437.     JP    NZ,MODME2+O    ; YES, GO STRAIGHT TO IT
  438.     LD    HL,COMBUF+O    ; POINT TO COMMAND BUFFER
  439.     LD    A,(HL)        ; GET COMMAND
  440.     LD    E,A        ; SAVE IT IN E
  441.     LD    A,(CBUFCT+O)    ; GET BUFFER COUNT
  442.     DEC    A        ; SUBTRACT ONE CHARACTER
  443.     LD    (CBUFCT+O),A    ; SAVE NEW COUNT
  444.     INC    HL        ; POINT TO NEXT BUFFER CHARACTER
  445.     LD    A,E        ; GET COMMAND BACK
  446.     CP    'D'        ; IS IT DISPLAY?
  447.     JP    Z,DSPLAY+O    ; YES, GO DO IT
  448.     CP    'M'        ; IS IT MODIFY MEMORY?
  449.     JP    Z,MODMEM+O    ; YES, GO DO IT
  450.     CP    'B'        ; IS IT SET BREAKPOINT?
  451.     JP    Z,BRAKPT+O    ; YES, GO DO IT
  452.     CP    'F'        ; IS IT CLEAR ONE BKPT?
  453.     JP    Z,FIXBRK+O    ; YES, GO DO IT
  454.     CP    'J'        ; IS IT JUMP TO ADDRESS?
  455.     JP    Z,JUMP+O    ; YES, GO DO IT
  456.     CP    'L'        ; IS IT FILL MEMORY?
  457.     JP    Z,FILL+O    ; YES, GO DO IT
  458.     CP    'R'        ; IS IT MODIFY REGISTER?
  459.     JP    Z,REGMOD+O    ; YES, GO DO IT
  460.     CP    'T'        ; IS IT BLOCK MOVE
  461.     JP    Z,MOVE+O    ; YES, GO DO IT
  462.     CP    'S'        ; IS IT SEARCH STRING?
  463.     JP    Z,SEARCH+O    ; YES, GO DO IT
  464.     CP    'H'        ; IS IT HEX ARITHMETIC?
  465.     JP    Z,HARITH+O    ; YES, GO DO IT
  466. ;
  467. ;----------------------------------------------------------------------------
  468. ;   COMMAND ACTION
  469. ;----------------------------------------------------------------------------
  470. ;    
  471. ;   PAGE MEMORY FORWARD OR BACK
  472. ;
  473. MPAGE:    LD    HL,(MEMSEL+O)    ; CURRENTLY SELECTED MEMORY TO HL
  474.     LD    BC,80H        ; ONE PAGE TO BC
  475.     CP    '+'        ; IS IT FORWARD?
  476.     JR    Z,MPAGE1    ; YES, ADD TO ADDRESS
  477.     SBC    HL,BC        ; IF NO, MUST BE BACK
  478.     JR    MPAGE2
  479. MPAGE1:    ADD    HL,BC
  480. MPAGE2:    LD    (MEMSEL+O),HL    ; PUT NEW ADDR IN MEMSEL
  481.     CALL    DISMEM+O    ; GO DISPLAY IT
  482.     JP    COMRET+O
  483. ;
  484. ;
  485. ;   DISPLAY SELECTED ADDRESS, WITH THAT ADDRESS IN CENTER
  486. ;   OF DISPLAY.  
  487. ;
  488. DSPLAY:    CALL    GETWRD+O    ; GET DISPLAY ADDR FROM COM BUF
  489.     CALL    COMCHK+O    ; BE SURE COMMAND WAS OK
  490.     JP    NZ,COMRET+O    ; GET OUT IF BAD COMMAND
  491.     EX    DE,HL        ; PUT ADDRESS IN HL
  492.     LD    BC,30H        ; PUT SELECTED ADDR IN
  493.     SBC    HL,BC        ; MIDDLE OF DISPLAY
  494.     LD    (MEMSEL+O),HL    ; SAVE IT AS CURRENT
  495.     CALL    DISMEM+O    ; DISPLAY IT
  496.     JP    COMRET+O    ; DONE; GO BACK     
  497. ;
  498. ;
  499. ;   MODIFY SELECTED BYTE OF MEMORY
  500. ;
  501. MODMEM:    LD    BC,COMCUR    ; COMMAND LINE CURSOR POS
  502.     CALL    POSCUR+O    ; POSITION CURSOR
  503.     LD    DE,MODMSG+O    ; POINT TO MODIFY MESSAGE
  504.     CALL    MSGOUT+O    ; PRINT IT
  505.     CALL    GETWRD+O    ; GET ADDRESS TO MODIFY
  506.     PUSH    DE        ; SAVE IT A SEC
  507.     CALL    GETBYT+O    ; GET NEW BYTE
  508.     LD    C,E        ; SAVE IT IN C
  509.     POP    DE        ; GET ADDR BACK
  510.     CALL    COMCHK+O    ; BE SURE COMMAND WAS OK
  511.     JP    NZ,COMRET+O    ; GET OUT IF NOT
  512.     LD    A,C        ; GET BYTE BACK
  513.     EX    DE,HL        ; PUT ADDR IN HL
  514.     PUSH    HL        ; SAVE UNADJUSTED ADDR
  515.     LD    (HL),A        ; LOAD MODIFIED BYTE
  516.     LD    BC,30H        ; ADJUST FOR
  517.     SBC    HL,BC        ;  CENTER OF DISPLAY
  518.     LD    (MEMSEL+O),HL    ; SAVE THE ADDRESS AS SELECTED MEMORY
  519.     CALL    DISMEM+O    ; PRINT NEW MEMORY DISPLAY
  520.     LD    A,1        ; SET MODIFY
  521.     LD    (MODFLG+O),A    ;  MEMORY FLAG
  522. MODME1:    LD    BC,MODCUR    ; MODIFY CURSOR POSITION
  523.     CALL    POSCUR+O    ; POSITION CURSOR
  524.     LD    DE,BLANK+O    ; BLANK LAST
  525.     CALL    MSGOUT+O    ;  ENTRY
  526.     LD    BC,MODCUR    ; PUT CURSOR BACK TO
  527.     CALL    POSCUR+O    ;  MODIFY POSITION
  528.     POP    HL        ; GET LAST MODIFIED ADDR
  529.     INC    HL        ; UPDATE IT
  530.     PUSH    HL        ; SAVE IT AGAIN
  531.     LD    A,H        ; PRINT
  532.     CALL    HX2ASC+O    ;  IT
  533.     LD    A,L
  534.     CALL    HX2ASC+O
  535.     LD    E,SPACE        ; PRINT A
  536.     CALL    CHROUT+O    ;  SPACE
  537.     JP    KEYIN+O        ; GET NEXT BYTE FROM KBD
  538. MODME2:    LD    HL,COMBUF+O    ; POINT TO COMMAND BUFFER
  539.     LD    A,(HL)        ; GET FIRST CHARACTER
  540.     CP    '.'        ; END OF COMMAND?
  541.     JP    Z,COMRET+O    ; YUP
  542.     CALL    GETBYT+O    ; DECODE BYTE
  543.     POP    HL        ; GET ADDR TO MODIFY
  544.     LD    (HL),E        ; CHANGE IT
  545.     PUSH    HL        ; SAVE ADDR AGAIN
  546.     LD    HL,(MEMSEL+O)    ; GET DISPLAY MEM ADDR
  547.     CALL    DISMEM+O    ; UPDATE DISPLAY
  548.     JR    MODME1        ; GO FOR NEXT BYTE
  549. ;
  550. ;
  551. ;   SET BREAKPOINT FROM KEYBOARD ENTRY
  552. ;
  553. BRAKPT:    CALL    GETWRD+O    ; GET BREAKPOINT ADDRESS
  554.     CALL    COMCHK+O    ; MAKE SURE COMMAND WAS OK
  555.     JP    NZ,COMRET+O    ; GET OUT IF NOT
  556.     LD    HL,BRKTBL+O    ; SEE IF THERE'S A ZERO ENTRY
  557.     LD    B,6        ; WE CAN USE IN THE
  558.     XOR    A        ; BREAKPOINT TABLE
  559.     LD    (BRKCNT+O),A
  560.     PUSH    DE        ; SAVE THE BKPT ADDR
  561. BRAKP1:    LD    E,(HL)        ; GET A LOW BYTE
  562.     INC    HL        ; POINT TO HIGH BYTE
  563.     LD    A,(HL)        ; PUT IT IN A
  564.     OR    E        ; IS IT EMPTY?
  565.     JR    Z,BRAKP2    ; YES, GO FILL IT
  566.     LD    A,(BRKCNT+O)    ; NOT ZERO, SO
  567.     INC    A        ; BUMP BREAKPOINT COUNTER AND
  568.     LD    (BRKCNT+O),A    ; SET UP TABLE POINTER FOR
  569.     INC    HL        ; NEXT LOW BYTE,
  570.     DJNZ    BRAKP1        ; THEN GO CHECK IT.
  571.     CALL    BEEP+O        ; NO ROOM IF LOOP FINISHES
  572.     POP    DE        ; RESTORE STACK
  573.     LD    BC,ERRCUR    ; GET ERROR CURSOR POSITION
  574.     CALL    POSCUR+O    ; PLACE CURSOR
  575.     LD    DE,BRKFUL+O    ; POINT TO BREAKPOINT FULL MSG
  576.     CALL    MSGOUT+O    ; PRINT IT
  577.     CALL    DELAY+O        ; WAIT THREE SECONDS
  578.     JP    COMRET+O    ; AND GO FOR NEXT COMMAND
  579. BRAKP2:    POP    DE        ; GET BKPT ADDR BACK
  580.     LD    (HL),D        ; HIGH BKPT BYTE TO TABLE
  581.     DEC    HL        ; MOVE TO LOW BYTE ADDR
  582.     LD    (HL),E        ; LOW BKPT BYTE TO TABLE
  583.     CALL    SETBRK+O    ; INSTALL BKPT AND SAVE CODE
  584.     LD    BC,BRKCUR    ; POSITION CURSOR FOR
  585.     CALL    POSCUR+O    ; BREAKPOINT DISPLAY
  586.     CALL    DISBRK+O    ; WRITE IT
  587.     JP    COMRET+O    ; DONE; GO FOR NEW COMMAND.
  588. ;
  589. ;
  590. ;   SINGLE-STEP ROUTINE
  591. ;   FIRST, CHECK FOR JUMP INSTRUCTIONS
  592. ;
  593. SSTEP:    LD    HL,(SYSPC+O)    ; GET USER PC ADDR 
  594.     LD    D,(HL)        ; SAVE (PC) IN D
  595.     LD    A,D        ; BRING IT TO A
  596.     CP    0C3H        ; JP UNCONDITIONAL?
  597.     JR    NZ,SSTE01    ; NO, GO ON
  598.     JP    SETSS2+O    ; SET BKPT AND GO
  599. SSTE01:    LD    (TMPWRD+O),SP    ; GET SP--NOTHING ON STACK
  600.     CP    0E9H        ; JP (HL)? (DISP=12)
  601.     JR    NZ,SSTE02    ; NO, GO ON
  602.     LD    HL,(TMPWRD+O)    ; SP TO HL
  603.     LD    BC,12        ; HL DISPLACEMENT
  604.     ADD    HL,BC        ; HERE'S USER HL
  605.     JP    SETSS3+O    ; SET BKPT AND GO
  606. SSTE02:    CP    0DDH        ; JP (IX)? (DISP=2)
  607.     JR    NZ,SSTE03    ; NO, GO ON
  608.     INC    HL        ; NEXT USER PROGRAM ADDR
  609.     LD    A,(HL)        ; GET THE BYTE
  610.     CP    0E9H        ; ONE MORE TEST
  611.     JR    Z,SSTE18    ; YES, JP (IX). 
  612.     DEC    HL        ; NOT A JUMP--RETURN HL
  613.     LD    A,D        ; GET BYTE BACK IN A
  614.     JP    SSTEP0+O    ; GO TO REGULAR S-S
  615. SSTE18:    LD    HL,(TMPWRD+O)    ; SP TO HL
  616.     LD    BC,2        ; IX DISPLACEMENT
  617.     ADD    HL,BC        ; HERE'S USER IX
  618.     JP    SETSS3+O    ; SET BKPT AND GO
  619. SSTE03:    CP    0FDH        ; JP (IY)? (DISP=0)
  620.     JR    NZ,SSTE04    ; NO, GO ON
  621.     INC    HL        ; NEXT USER PROGRAM ADDR
  622.     LD    A,(HL)        ; GET THE BYTE
  623.     CP    0E9H        ; ONE MORE TEST
  624.     JR    Z,SSTE19    ; YES, JP (IY).
  625.     DEC    HL        ; NO JUMP--RETURN HL
  626.     LD    A,D        ; GET BYTE BACK IN A
  627.     JP    SSTEP0+O    ; GO TO REGULAR S-S
  628. SSTE19:    LD    HL,(TMPWRD+O)    ; SP TO HL--IT IS USER IY
  629.     JP    SETSS3+O    ; SET BKPT AND GO
  630. SSTE04:    LD    IX,(TMPWRD+O)    ; SP TO IX--SET UP FOR JR
  631.     LD    C,(IX+18)    ; FLAGS TO C
  632.     CP    0C2H        ; JP NZ?
  633.     JR    NZ,SSTE05    ; NO, GO ON
  634.     BIT    6,C        ; Z FLAG SET?
  635.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  636.     JP    SETSS2+O    ; SET BKPT AND GO
  637. SSTE05:    CP    0CAH        ; JP Z?
  638.     JR    NZ,SSTE06    ; NO, GO ON
  639.     BIT    6,C        ; Z FLAG SET?
  640.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  641.     JP    SETSS2+O    ; SET BKPT AND GO
  642. SSTE06:    CP    0D2H        ; JP NC?
  643.     JR    NZ,SSTE07    ; NO, GO ON
  644.     BIT    0,C        ; C FLAG SET?
  645.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  646.     JP    SETSS2+O    ; SET BKPT AND GO
  647. SSTE07:    CP    0DAH        ; JP C?
  648.     JR    NZ,SSTE08    ; NO, GO ON
  649.     BIT    0,C        ; C FLAG SET
  650.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  651.     JP    SETSS2+O    ; SET BKPT AND GO
  652. SSTE08:    CP    0E2H        ; JP PO?
  653.     JR    NZ,SSTE09    ; NO, GO ON
  654.     BIT    2,C        ; P FLAG SET
  655.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  656.     JP    SETSS2+O    ; SET BKPT AND GO
  657. SSTE09:    CP    0EAH        ; JP PE?
  658.     JR    NZ,SSTE10    ; NO, GO ON
  659.     BIT    2,C        ; P FLAG SET?
  660.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  661.     JP    SETSS2+O    ; SET BKPT AND GO
  662. SSTE10:    CP    0F2H        ; JP P?
  663.     JR    NZ,SSTE11    ; NO, GO ON
  664.     BIT    7,C        ; S FLAG SET?
  665.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  666.     JP    SETSS2+O    ; SET BKPT AND GO
  667. SSTE11:    CP    0FAH        ; JP M?
  668.     JR    NZ,SSTE12    ; NO, GO ON
  669.     BIT    7,C        ; S FLAG SET?
  670.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  671.     JP    SETSS2+O    ; SET BKPT AND GO
  672. SSTE12:    CP    18H        ; JR UNCONDITIONAL?
  673.     JR    NZ,SSTE13    ; NO, GO ON
  674.     JP    SETJR+O        ; GET ADDR FOR JR
  675. SSTE13:    CP    38H        ; JR C?
  676.     JR    NZ,SSTE14    ; NO, GO ON
  677.     BIT    0,C        ; C FLAG SET?
  678.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  679.     JP    SETJR+O        ; GET ADDR FOR JR
  680. SSTE14:    CP    30H        ; JR NC?
  681.     JR    NZ,SSTE15    ; NO, GO ON
  682.     BIT    0,C        ; C FLAG SET?
  683.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  684.     JP    SETJR+O        ; GET ADDR FOR JR
  685. SSTE15:    CP    28H        ; JR Z?
  686.     JR    NZ,SSTE16    ; NO, GO ON
  687.     BIT    6,C        ; Z FLAG SET?
  688.     JP    Z,SSTEP0+O    ; NO, NO JUMP
  689.     JP    SETJR+O        ; GET ADDR FOR JR
  690. SSTE16:    CP    20H        ; JR NZ?
  691.     JR    NZ,SSTE17    ; NO, GO ON
  692.     BIT    6,C        ; Z FLAG SET?
  693.     JP    NZ,SSTEP0+O    ; YES, NO JUMP
  694.     JR    SETJR        ; GET ADDR FOR JR
  695. SSTE17:    CP    10H        ; DJNZ?
  696.     JR    NZ,SSTEP0    ; NO JUMP
  697.     OR    B        ; B=0?
  698.     JR    Z,SSTEP0    ; YES, NO JUMP
  699. SETJR:    PUSH    BC        ; IN CASE OF DJNZ
  700.     LD    B,0        ; ZERO B
  701.     INC    HL        ; NEXT INSTRUCTION ADDR
  702.     LD    A,(HL)        ; REL JUMP TO A
  703.     CP    82H        ; NEGATIVE JUMP?
  704.     JR    NC,JRNEG    ; YES, NEGATIVE
  705.     LD    C,A        ; POSITIVE JUMP
  706.     ADD    HL,BC        ; JUMP ADDR-1 NOW IN HL
  707.     JR    SETJR1
  708. JRNEG:    CPL            ; MAKE RELATIVE
  709.     ADD    A,1        ;  JUMP POSITIVE
  710.     LD    C,A        ; POSITIVE AMOUNT TO C
  711.     SBC    HL,BC        ; THEN SUBTRACT
  712. SETJR1:    INC    HL        ; ADJ FOR -2 IN JR
  713.     POP    BC        ; GET BC BACK
  714.     EX    DE,HL        ; PUT JUMP ADDR IN DE
  715.     JP    SETSS4        ; SET BKPT AND GO
  716. ;
  717. ;   NO JUMPS, SO FIND OUT HOW LONG THE INSTRUCTION IS
  718. ;
  719. SSTEP0:    INC    HL        ; NEXT ADDRESS
  720.     LD    E,(HL)        ; SAVE (PC+1) IN E
  721.     LD    A,D        ; GET (PC) BACK
  722.     LD    HL,TAB21+O    ; POINT TO 1ST 2-BYTE TABLE
  723.     LD    BC,LENT21    ; NO. BYTES TO CHECK
  724.     CPIR            ; SEE IF (PC) IS 2-BYTE INST
  725.     JR    Z,ENDTWO    ; YES, A 2-BYTE INST
  726.     CP    0DDH        ; NOT SURE YET--IS IT DD?
  727.     JR    Z,CK22        ; IT'S DD--TEST NEXT BYTE
  728.     CP    0EDH        ; NOT SURE YET--IS IT ED?
  729.     JR    Z,CK22        ; IT'S ED--TEST NEXT BYTE
  730.     CP    0FDH        ; NOT SURE YET-IS IT FD?
  731.     JR    NZ,SSTEP1    ; NOT FD--TRY 3-BYTE INST
  732. CK22:    LD    A,E        ; 2ND INST BYTE TO A
  733.     LD    HL,TAB22+O    ; POINT TO 2ND 2-BYTE TABLE
  734.     LD    BC,LENT22    ; NO. BYTES TO CHECK
  735.     CPIR            ; SEE IF (PC+1) IS 2-BYTE INST
  736.     JR    NZ,SSTEP1    ; NOT 2 BYTES; TRY 3
  737. ENDTWO:    LD    B,2        ; IT'S A 2-BYTE INST
  738.     JP    SETSS+O        ; GO SET IT UP
  739. SSTEP1:    LD    A,D        ; GET (PC) BACK
  740.     LD    HL,TAB31+O    ; POINT TO 1ST 3-BYTE TABLE
  741.     LD    BC,LENT31    ; NO. BYTES TO CHECK
  742.     CPIR            ; SEE IF (PC) IS 3-BYTE INST
  743.     JR    Z,ENDTHR    ; YES, A 3-BYTE INST
  744.     CP    0DDH        ; NOT SURE YET--IS IT DD?
  745.     JR    Z,CK32        ; IT'S DD--TEST NEXT BYTE
  746.     CP    0EDH        ; NOT SURE YET--IS IT ED?
  747.     JR    Z,CK32        ; IT'S ED--TEST NEXT BYTE
  748.     CP    0FDH        ; NOT SURE YET--IS IT FD?
  749.     JR    NZ,SSTEP2    ; NOT FD--TRY 4-BYTE INST
  750. CK32:    LD    A,E        ; 2ND INST BYTE TO A
  751.     LD    HL,TAB32+O    ; POINT TO 2ND 3-BYTE TABLE
  752.     LD    BC,LENT32    ; NO. BYTES TO CHECK
  753.     CPIR            ; SEE IF (PC+1) IS 3-BYTE INST
  754.     JR    NZ,SSTEP2    ; NOT 3 BYTES; TRY 4
  755. ENDTHR:    LD    B,3        ; IT'S A 3-BYTE INST
  756.     JP    SETSS+O        ; GO SET IT UP
  757. SSTEP2:    LD    A,D        ; GET (PC) BACK
  758.     CP    0DDH        ; LOOKING FOR 4-BYTE INST
  759.     JR    Z,CK42        ; IT'S DD--TEST NEXT BYTE
  760.     CP    0EDH        ; IS IT ED?
  761.     JR    Z,CK42        ; IT'S ED--TEST NEXT BYTE
  762.     CP    0FDH        ; IS IT FD?
  763.     JR    NZ,ONEBYT    ; NO, MUST BE 1-BYTE INST
  764. CK42:    LD    A,E        ; 2ND INST BYTE TO A
  765.     LD    HL,TAB42+O    ; POINT TO 4-BYTE TABLE
  766.     LD    BC,LENT42    ; NO. BYTES TO CHECK
  767.     CPIR            ; SEE IF (PC+1) IS 4-BYTE INSTR
  768.     JR    NZ,ONEBYT    ; NOT 4; MUST BE 1
  769.     LD    B,4        ; IT'S A 4-BYTE INST
  770.     JR    SETSS        ; GO SET IT UP
  771. ONEBYT:    LD    B,1        ; IT'S A 1-BYTE INST
  772. ;   WE'VE FOUND OUT WHERE THE NEXT INSTRUCTION IS.
  773. ;   NOW INSTALL IT AS A BREAKPOINT, USING THE
  774. ;   FIRST BREAKPOINT TABLE ADDRESS.
  775. SETSS:    LD    DE,(SYSPC+O)    ; PUT USER PC IN DE
  776. SETSS1:    INC    DE        ; MOVE TO NEXT ADDR ACCORDING
  777.     DJNZ    SETSS1        ;  TO THE INSTRUCTION LENGTH 
  778.     JR    SETSS4        ; THEN SET BKPT AND GO
  779. SETSS2:    INC    HL        ; NEXT ADDRESS
  780. SETSS3:    LD    E,(HL)        ; LOW JUMP BYTE TO E
  781.     INC    HL        ; NEXT ADDRESS
  782.     LD    D,(HL)        ; HIGH JUMP BYTE TO D
  783. SETSS4:    LD    HL,BRKTBL+O    ; POINT TO THE BKPT TABLE
  784.     LD    (HL),E        ; LOW ADDR BYTE TO TABLE
  785.     INC    HL        ; BUMP TABLE ADDRESS
  786.     LD    (HL),D        ; HIGH ADDR BYTE TO TABLE
  787.     XOR    A        ; ZERO
  788.     LD    (BRKCNT+O),A    ;  BREAKPOINT COUNTER
  789.     CALL    SETBRK+O    ; SET BKPT AT NEXT INST
  790.     JP    DBEND+O        ; THEN EXECUTE A "GO"    
  791. ;
  792. ;
  793. ;   CLEAR (ZERO) ALL BREAKPOINTS
  794. ;   FIRST RESTORE USER PROGRAM CODE
  795. ;
  796. CLRBRK:    LD    B,6        ; CHECK 6 TABLE ENTRIES
  797.     LD    HL,BRKTBL+O    ; POINT TO BREAK TABLE
  798.     XOR    A        ; ZERO
  799.     LD    (BRKCNT+O),A    ;  BREAKPOINT COUNTER
  800. CLRBR1:    LD    E,(HL)        ; LOW BKPT BYTE TO E
  801.     INC    HL        ; NEXT ADDR
  802.     LD    A,(HL)        ; HIGH BKPT BYTE TO A
  803.     OR    E        ; IS THERE AN ENTRY HERE?
  804.     JR    Z,CLRBR2    ; NO, CHECK NEXT ENTRY
  805.     LD    D,(HL)        ; BKPT ADDR NOW IN DE
  806.     CALL    REPBRK+O    ; RESTORE USER CODE
  807. CLRBR2:    LD    A,(BRKCNT+O)    ; BUMP
  808.     INC    A        ;  BREAKPOINT
  809.     LD    (BRKCNT+O),A    ;   COUNTER
  810.     INC    HL        ; NEXT TABLE ENTRY
  811.     DJNZ    CLRBR1        ; GO UNTIL 6 CHECKED
  812. ;   THEN ZERO BREAKPOINT TABLE
  813.     LD    DE,BRKTBL+O    ; START ADDR AT BREAK TABLE
  814.     LD    HL,BRKTBL+O+11    ; 12 ADDRESSES TO CLEAR
  815.     XOR    A        ; ZERO A
  816.     CALL    LOAD+O        ; ZERO THE TABLE
  817.     LD    BC,BRKCUR    ; GET BKPT LINE CURSOR POS
  818.     CALL    POSCUR+O    ; POSITION CURSOR
  819.     CALL    DISBRK+O    ; SHOW CLEARED BKPTS
  820.     JP    COMRET+O    ; DONE
  821. ;
  822. ;
  823. ;   CLEAR (ZERO) A SPECIFIED BREAKPOINT
  824. ;
  825. FIXBRK:    CALL    GETWRD+O    ; GET BKPT ADDR TO FIX
  826.     CALL    COMCHK+O    ; BE SURE COMMAND WAS OK
  827.     JP    NZ,COMRET+O    ; GET OUT IF BAD COMMAND
  828.     CALL    MATCH+O        ; SEE IF IT'S A VALID BKPT
  829.     LD    A,(BRKCNT+O)    ; GET BREAKPOINT COUNTER
  830.     CP    6        ; DID WE TRY ALL W/ NO MATCH?
  831.     JR    NZ,FIXBR1    ; NO, THERE'S A MATCH
  832.     CALL    COMCH1+O    ; NO MATCH--DO BAD COMMAND
  833.     JP    COMRET+O    ; AND GET OUT
  834. FIXBR1:    LD    (HL),0        ; HIGH ADDR BYTE FROM COMPARE
  835.     DEC    HL
  836.     LD    (HL),0        ; LOW ADDR BYTE FROM COMPARE
  837.     CALL    REPBRK+O    ; RESTORE USER CODE
  838.     LD    BC,BRKCUR    ; GET BKPT LINE CURSOR POS
  839.     CALL    POSCUR+O    ; POSITION CURSOR
  840.     CALL    DISBRK+O    ; SHOW CLEARED BKPT
  841.     JP    COMRET+O    ; AND RETURN     
  842. ;
  843. ;
  844. ;   JUMP TO SPECIFIED ADDRESS
  845. ;
  846. JUMP:    CALL    GETWRD+O    ; GET JUMP ADDRESS
  847.     CALL    COMCHK+O    ; BE SURE COMMAND IS OK
  848.     JP    NZ,COMRET+O    ; GET OUT IF NOT
  849.     LD    (SYSPC+O),DE    ; MAKE JUMP ADDR USER PC
  850.     JP    DBEND+O        ; THEN DO A "GO"
  851. ;
  852. ;
  853. ;   FILL DESIGNATED AREA OF MEMORY WITH SPECIFIED BYTE
  854. ;
  855. FILL:    CALL    GETWRD+O    ; GET FILL START ADDRESS
  856.     LD    (START+O),DE    ; SAVE START
  857.     CALL    GETWRD+O    ; GET FILL END ADDRESS
  858.     LD    (ENDADD+O),DE    ; SAVE END ON STACK
  859.     CALL    GETBYT+O    ; GET FILL BYTE
  860.     LD    C,E        ; SAVE IT IN C DURING CHECK
  861.     CALL    COMCHK+O    ; BE SURE COMMAND WAS OK
  862.     JP    NZ,COMRET+O    ; GET OUT IF NOT
  863.     LD    HL,(ENDADD+O)    ; GET END ADDR BACK
  864.     LD    DE,(START+O)    ; GET START ADDR BACK
  865.     LD    A,C        ; GET FILL BYTE BACK
  866.     CALL    LOAD+O        ; FILL THE MEMORY AREA
  867.     JP    COMRET+O    ; DONE
  868. ;
  869. ;
  870. ;   MODIFY REGISTER CONTENTS
  871. ;
  872. REGMOD:    LD    B,(HL)        ; NEXT CHAR TO B
  873.     CALL    NXTCHR+O    ; POINT TO NEXT CHAR
  874.     LD    A,(HL)        ; NEXT CHAR TO A
  875.     ADD    A,B        ; "HASH" REG IDENTIFIER
  876.     CP    163        ; SP?
  877.     JR    NZ,REGM01    ; NO, TRY PC
  878.     LD    C,0FFH        ; DUMMY DISPLACEMENT FOR SP
  879.     JR    REGM03        ; GO FOR NEW REG CONTENTS
  880. REGM01:    CP    147        ; PC?
  881.     JR    NZ,REGM02    ; NO, TRY REGULAR REGISTERS
  882.     LD    C,0FEH        ; DUMMY DISPLACEMENT FOR PC
  883.     JR    REGM03        ; GO FOR NEW REG CONTENTS
  884. REGM02:    PUSH    HL        ; SAVE COM BUFF POINTER
  885.     LD    HL,REGTAB+O    ; POINT TO REG ID TABLE
  886.     LD    BC,10        ; 10 VALUES TO CHECK
  887.     CPIR            ; CHECK THEM
  888.     POP    HL        ; GET COM BUFF POINTER BACK
  889.     JR    NZ,BADREG    ; NO MATCH; BAD COMMAND
  890.     SLA    C        ; TIMES 2 FOR DISPLACEMENT
  891. REGM03:    LD    A,(CBUFCT+O)    ; PREPARE
  892.     DEC A            ;  FOR
  893.     LD    (CBUFCT+O),A    ;   CALL TO
  894.     INC    HL        ;    GETWRD 
  895.     CALL    GETWRD+O    ; GET NEW REG WORD
  896.     CALL    COMCHK+O    ; BE SURE ADDRESS WAS OK
  897.     JP    NZ,COMRET+O    ; GET OUT IF NOT
  898.     LD    A,C        ; CHECK FOR SP & PC
  899.     CP    0FFH        ; SP?
  900.     JR    NZ,REGM04    ; NO, TRY PC
  901.     LD    (SYSSP+O),DE    ; CHANGE USER SP
  902.     JR    REGM99        ; END COMMAND
  903. REGM04:    CP    0FEH        ; PC?
  904.     JR    NZ,REGM05    ; NO, REGULAR REGISTER
  905.     LD    (SYSPC+O),DE    ; CHANGE USER PC
  906.     JR    REGM99        ; END COMMAND
  907. REGM05:    LD    (TMPWRD+O),SP    ; SP TO HL--NOTHING
  908.     LD    HL,(TMPWRD+O)    ;  ON STACK HERE
  909.     LD    B,0        ; ZERO B
  910.     ADD    HL,BC        ; ADD DISPLACEMENT
  911.     LD    (HL),E        ; LOW BYTE TO STACK
  912.     INC    HL
  913.     LD    (HL),D        ; HIGH BYTE TO STACK
  914. REGM99:    LD    E,HOME        ; HOME
  915.     CALL    CHROUT+O    ;  CURSOR
  916.     JP    ENTRY1+O    ; THAT'S ALL FOR REGMOD
  917. BADREG:    CALL    COMCH1+O    ; BAD COMMAND
  918.     JP    COMRET+O    ; GET OUT
  919. ;
  920. ;
  921. ;   BLOCK MOVE--START ADDR, END ADDR, DESTINATION
  922. ;
  923. MOVE:    CALL    GETWRD+O    ; GET MOVE START ADDR
  924.     LD    (START+O),DE    ; SAVE START
  925.     CALL    GETWRD+O    ; GET MOVE END ADDR
  926.     LD    (TMPWRD+O),HL    ; SAVE COM BUF POSITION
  927.     EX    DE,HL        ; END ADDR NOW IN HL
  928.     LD    DE,(START+O)    ; START ADDR IN DE
  929.     SBC    HL,DE        ; GOING FOR BYTE COUNT
  930.     CALL    C,COMCH1+O    ; OOPS--START>END
  931.     JP    C,COMRET+O    ;  SO GET OUT
  932.     INC    HL        ; HERE'S BYTE COUNT
  933.     PUSH    HL        ; "EX BC,HL"
  934.     POP    BC        ; BYTE COUNT IN BC
  935.     LD    HL,(TMPWRD+O)    ; GET COM BUF POINTER BACK
  936.     CALL    GETWRD+O    ; GET DEST ADDR
  937.     CALL    COMCHK+O    ; CHECK COMMAND
  938.     JP    NZ,COMRET+O    ; GET OUT IF BAD
  939.     LD    HL,(START+O)    ; SOURCE TO HL
  940.     LDIR            ; MOVE 'EM
  941.     JP    COMRET+O    ; AND DONE 
  942.  
  943. ;
  944. ;
  945. ;   SEARCH FOR STRING IN MEMORY--START, END, UP TO 11 BYTES
  946. ;
  947. SEARCH:    LD    A,(HL)        ; GET 1ST COM BUF CHAR
  948.     CP    '.'        ; REPEAT LAST SEARCH?
  949.     JR    NZ,SEARC9    ; NO, DECODE COMMAND
  950.     LD    HL,(TMPWRD+O)    ; YES, GET LAST FOUND ADDR
  951.     LD    BC,(BYTCNT+O)    ; GET STRING LENGTH
  952.     ADD    HL,BC        ; HL NOW PAST LAST FIND
  953.     LD    (START+O),HL    ; MAKE THIS THE NEW START
  954.     JR    SEARC8        ; NOW GO TO SEARCH
  955. SEARC9:    CALL    GETWRD+O    ; GET SEARCH START ADDR
  956.     LD    (START+O),DE    ; SAVE START ADDRESS
  957.     CALL    GETWRD+O    ; GET SEARCH END ADDR
  958.     LD    (ENDADD+O),DE    ; SAVE END ADDR
  959.     LD    BC,0        ; ZERO BC
  960.     LD    DE,SCHSTR+O-1    ; POINT TO STRING BUFFER
  961. SEARC1:    LD    A,(HL)        ; GET NEXT COMMAND BYTE
  962.     CP    '.'        ; END OF STRING?
  963.     JR    Z,SEARC2    ; YES, START SEARCH
  964.     PUSH    DE        ; I NEED A REGISTER!
  965.     LD    E,A        ; SAVE CHARACTER
  966.     LD    A,(CBUFCT+O)    ; GET BUFFER COUNTER
  967.     CP    0        ; IF IT'S NEGATIVE, USER
  968.     LD    A,E        ;    {GET CHAR BACK}
  969.     POP    DE        ;    {GET DE BACK}
  970.     CALL    M,COMCH1+O    ; FORGOT THE END PERIOD
  971.     JP    M,COMRET+O    ; SO GET OUT
  972.     INC    DE        ; ELSE GO TO NEXT STRING SPACE
  973.     PUSH    DE        ; SAVE STRING POINTER
  974.     CALL    GETBYT+O    ; GET NEXT STRING BYTE
  975.     LD    A,E        ; PUT THE BYTE IN A
  976.     POP    DE        ; GET STRING POINTER BACK
  977.     LD    (DE),A        ; PUT IT IN STRING BUFFER
  978.     INC    BC        ; BUMP BYTE COUNT
  979.     JR    SEARC1        ; GO FOR NEXT BYTE
  980. SEARC2:    LD    A,(CBUFCT+O)    ; ADJUST BUFFER COUNT
  981.     DEC    A        ;  FOR
  982.     LD    (CBUFCT+O),A    ;   THE PERIOD
  983.     CALL    COMCHK+O    ; THEN CHECK COMMAND
  984.     JP    NZ,COMRET+O    ; GET OUT IF BAD
  985.     LD    (BYTCNT+O),BC    ; SAVE STRING LENGTH
  986. SEARC8:    LD    HL,(START+O)    ; POINT TO START ADDR
  987.     DEC    HL        ; PREP FOR INC
  988. SEARC3:    LD    DE,SCHSTR+O    ; POINT TO STRING
  989.     LD    BC,(BYTCNT+O)    ; GET STRING LENGTH
  990.     LD    A,(DE)        ; GET 1ST STRING BYTE
  991. SEARC4:    INC    HL        ; NEXT MEMORY ADDR
  992.     CALL    ENDTST+O    ; PAST END POINT?
  993.     JR    C,SEARC6    ; YES, STOP
  994.     CP    (HL)        ; MATCH?
  995.     JR    NZ,SEARC4    ; NO, TRY NEXT MEM ADDR
  996.     LD    (TMPWRD+O),HL    ; YES, SAVE "FOUND" ADDR
  997. SEARC5:    INC    HL        ; NEXT MEMORY ADDR
  998.     DEC    BC        ; ONE FOUND
  999.     LD    A,B        ; TEST FOR
  1000.     OR    C        ;  ZERO
  1001.     JR    Z,SEARC7    ; ALL FOUND; STOP
  1002.     CALL    ENDTST+O    ; PAST END?
  1003.     JR    C,SEARC6    ; YES, STOP
  1004.     INC    DE        ; NEXT STRING POSITION
  1005.     LD    A,(DE)        ; GET STRING BYTE
  1006.     CP    (HL)        ; MATCH?
  1007.     JR    Z,SEARC5    ; YES, TRY NEXT
  1008.     DEC    HL        ; LAST MISS COULD BE 1ST HIT
  1009.     JR    SEARC3        ; START STRING OVER
  1010. SEARC6:    LD    BC,ERRCUR    ; ERROR MESSAGE POSITION
  1011.     CALL    POSCUR+O    ; POSITION CURSOR
  1012.     LD    DE,NOTFND+O    ; POINT TO NOT FOUND MSG
  1013.     CALL    MSGOUT+O    ; PRINT IT
  1014.     CALL    BEEP+O        ; BEEP KEYBOARD
  1015.     CALL    DELAY+O        ; HOLD MSG 3 SEC
  1016.     JP    COMRET+O    ; BYE-BYE
  1017. SEARC7:    LD    HL,(TMPWRD+O)    ; GET FOUND ADDR
  1018.     LD    BC,30H        ; ADJUST
  1019.     SBC    HL,BC        ;  FOR DISPLAY
  1020.     LD    (MEMSEL+O),HL    ; SET IT UP FOR DISPLAY
  1021.     CALL    DISMEM+O    ; DISPLAY FOUND POSITION
  1022.     JP    COMRET+O    ; AND DONE
  1023. ;
  1024. ;   TEST FOR END OF STRING SEARCH AREA
  1025. ;
  1026. ENDTST:    PUSH    HL        ; SAVE CURRENT MEMORY POINTER
  1027.     PUSH    DE        ;  AND STRING POSITION
  1028.     EX    DE,HL        ; MEMORY POINTER TO DE
  1029.     LD    HL,(ENDADD+O)    ; SEARCH END ADDR
  1030.     SBC    HL,DE        ; PAST END?
  1031.     POP    DE        ; GET CURRENT
  1032.     POP    HL        ;  CONDITIONS BACK
  1033.     RET            ; CALLER CHECKS FLAG 
  1034. ;
  1035. ;
  1036. ;   PERFORM HEX ADDITION AND SUBTRACTION FOR USER
  1037. ;
  1038. HARITH:    CALL    GETWRD+O    ; GET THE FIRST NUMBER
  1039.     PUSH    DE        ; SAVE IT ON STACK
  1040.     LD    A,(HL)        ; ARITHMETIC OPERATOR
  1041.     LD    (TMPWRD+O),A    ; SAVE IT HERE
  1042.     CALL    NXTCHR+O    ; ADJ FOR OPERATOR
  1043.     CALL    GETWRD+O    ; GET SECOND NUMBER
  1044.     POP    HL        ; 1ST NO. NOW IN HL
  1045.     CALL    COMCHK+O    ; CHECK COMMAND
  1046.     JP    NZ,COMRET+O    ; GET OUT IF BAD
  1047.     LD    A,(TMPWRD+O)    ; GET OPERATOR BACK
  1048.     CP    '-'        ; SUBTRACT?
  1049.     JR    Z,HARIT1    ; YES, GO DO IT
  1050.     ADD    HL,DE        ; NO, ADD
  1051.     JR    HARIT2
  1052. HARIT1:    SBC    HL,DE        ; SUBTRACT.
  1053. HARIT2:    LD    BC,COMCUR+20    ; CURSOR POSITION
  1054.     CALL    POSCUR+O    ;  FOR ANSWER
  1055.     LD    E,'='        ; PRINT
  1056.     CALL    CHROUT+O    ;  EQUAL SIGN
  1057.     LD    E,SPACE        ; PRINT
  1058.     CALL    CHROUT+O    ;  A SPACE
  1059.     LD    A,H        ; PRINT
  1060.     CALL    HX2ASC+O    ;  THE
  1061.     LD    A,L        ;   ANSWER
  1062.     CALL    HX2ASC+O
  1063.     CALL    KBD+O        ; WAIT FOR KEYPRESS
  1064.     JP    COMRET+O    ; THEN GO HOME
  1065. ;
  1066. ;
  1067. ;   RETURN TO COMMAND LINE FROM COMMAND ACTION
  1068. ;
  1069. COMRET:    LD    BC,COMCUR    ; GET COMMAND CURSOR POSITION
  1070.     CALL    POSCUR+O    ; POSITION CURSOR
  1071.     LD    B,3        ; 3 TIMES TO CLEAR 1 LINE
  1072. COMRE1:    LD    DE,BLANK+O    ; POINT TO BLANK LINE
  1073.     CALL    MSGOUT+O    ; BLANK COMMAND LINE
  1074.     DJNZ    COMRE1
  1075.     XOR    A        ; ZERO A
  1076.     LD    (MODFLG+O),A    ; CLEAR MODIFY MEMORY FLAG
  1077.     LD    (COMFLG+O),A    ; CLEAR COMMAND FLAG
  1078.     JP    COMAND+O    ; GO TO START OF COMMAND MODULE
  1079.         
  1080. ;
  1081. ;----------------------------------------------------------------------------
  1082. ;   RETURN TO USER PROGRAM
  1083. ;   END OF DEBUG MAIN PROGRAM CODE
  1084. ;----------------------------------------------------------------------------
  1085. ;
  1086. DBEND:    LD    E,27        ; RESTORE
  1087.     CALL    CHROUT+O    ;  USER
  1088.     LD    E,'C'        ;   CURSOR
  1089.     CALL    CHROUT+O    ;    POSITION
  1090.     LD    E,'6'
  1091.     CALL    CHROUT+O
  1092.     LD    (TMPWRD+O),SP    ; PRESERVE CURRENT LOCAL SP
  1093.     LD    HL,(SYSPC+O)    ; REPLACE CORRECT RETURN ADDR
  1094.     LD    SP,(SYSSP+O)    ;  ON BOTTOM OF USER
  1095.     PUSH    HL        ;   STACK
  1096.     LD    (SYSSP+O),SP    ; SAVE NEW SYSTEM SP
  1097.     LD    SP,(TMPWRD+O)    ; RESTORE CURRENT LOCAL SP
  1098.     POP    IY        ; RESTORE ALL REGISTERS
  1099.     POP    IX
  1100.     POP    HL        ; FIRST THE PRIME REGISTERS
  1101.     POP    DE
  1102.     POP    BC
  1103.     POP    AF
  1104.     EX    AF,AF'        ; THEN THE REGULAR REGISTERS
  1105.     EXX
  1106.     POP    HL
  1107.     POP    DE
  1108.     POP    BC
  1109.     POP    AF
  1110.     LD    SP,(SYSSP+O)    ; RESTORE THE SYSTEM SP
  1111. ;
  1112. ;   RETURN TO CALLING PROGRAM
  1113. ;
  1114.     RET            ; TO CALLING PROGRAM
  1115. ;
  1116. ;
  1117. ;----------------------------------------------------------------------------
  1118. ;   DEBUG-SPECIFIC SUBROUTINES
  1119. ;----------------------------------------------------------------------------
  1120. ;
  1121. ;   DISPLAY AF HEX VALUES AND FLAG REPRESENTATIONS
  1122. ;
  1123. DISPAF:    LD    H,(IX+19)    ; PUT ENTRY A REGISTER IN A
  1124.     LD    L,(IX+18)    ; ENTRY F REGISTER IN L
  1125. DPRIM:    CALL    ONLYRG+O    ; PRINT REGISTER HEX VALUES
  1126.     LD    E,SPACE        ; PRINT TWO SPACES
  1127.     CALL    CHROUT+O
  1128.     CALL    CHROUT+O
  1129.     LD    A,L        ; FLAGS INTO A
  1130.     BIT    7,A        ; CHECK SIGN FLAG
  1131.     JR    Z,DISAF1    ; PRINT DASH IF ZERO
  1132.     LD    E,'S'        ; PRINT S IF SET
  1133.     JR    DISAF2
  1134. DISAF1:    LD    E,'-'        ; PRINT HYPHEN IF NOT SET
  1135. DISAF2:    CALL    CHROUT+O
  1136.     LD    A,L        ; GET FLAGS AGAIN
  1137.     BIT    6,A        ; CHECK ZERO FLAG
  1138.     JR    Z,DISAF3    ; PRINT DASH IF ZERO
  1139.     LD    E,'Z'        ; PRINT Z IF SET
  1140.     JR    DISAF4
  1141. DISAF3:    LD    E,'-'
  1142. DISAF4:    CALL    CHROUT+O
  1143.     LD    E,'x'        ; BIT 5 NOT USED--DON'T CARE
  1144.     CALL    CHROUT+O
  1145.     LD    A,L        ; GET FLAGS AGAIN
  1146.     BIT    4,A        ; CHECK HALF-CARRY FLAG
  1147.     JR    Z,DISAF5    ; PRINT DASH IF ZERO
  1148.     LD    E,'H'        ; PRINT H IF SET
  1149.     JR    DISAF6
  1150. DISAF5:    LD    E,'-'
  1151. DISAF6:    CALL    CHROUT+O
  1152.     LD    E,'x'        ; BIT 3 NOT USED--DON'T CARE
  1153.     CALL    CHROUT+O
  1154.     LD    A,L        ; GET FLAGS AGAIN
  1155.     BIT    2,A        ; CHECK PARITY/OVERFLOW FLAG
  1156.     JR    Z,DISAF7    ; PRINT DASH IF ZERO
  1157.     LD    E,'P'        ; PRINT P IF SET
  1158.     JR    DISAF8
  1159. DISAF7:    LD    E,'-'
  1160. DISAF8:    CALL    CHROUT+O
  1161.     LD    A,L        ; GET FLAGS AGAIN
  1162.     BIT     1,A        ; CHECK NEGATIVE FLAG
  1163.     JR    Z,DISAF9    ; PRINT DASH IF ZERO
  1164.     LD    E,'N'        ; PRINT N IF SET
  1165.     JR    DISAF0
  1166. DISAF9    LD    E,'-'
  1167. DISAF0    CALL    CHROUT+O
  1168.     LD    A,L        ; GET FLAGS ONE LAST TIME
  1169.     BIT    0,A        ; CHECK CARRY FLAG
  1170.     JR    Z,DISAFA    ; PRINT DASH IF ZERO
  1171.     LD    E,'C'        ; PRINT C IF SET
  1172.     JR    DISAFB
  1173. DISAFA:    LD    E,'-'
  1174. DISAFB:    CALL    CHROUT+O
  1175.     RET            ; FLAG REPRESENTATIONS DONE
  1176. ;
  1177. ;
  1178. ;   DISPLAY HEX CONTENTS OF BC, INDIRECTS, AND ASCII REPRESENTATIONS
  1179. ;
  1180. DISPBC:    LD    H,(IX+17)    ; PUT ENTRY B REGISTER IN H
  1181.     LD    L,(IX+16)    ; PUT ENTRY C REGISTER IN L
  1182.     JP    REGRET+O
  1183. ;
  1184. ;   DISPLAY HEX CONTENTS OF DE,INDIRECTS, AND ASCII REPRESENTATIONS
  1185. ;
  1186. DISPDE:    LD    H,(IX+15)    ; PUT ENTRY D REGISTER IN H
  1187.     LD    L,(IX+14)    ; PUT ENTRY C REGISTER IN L
  1188.     JP    REGRET+O
  1189. ;
  1190. ;   DISPLAY HEX CONTENTS OF HL
  1191. ;
  1192. DISPHL:    LD    H,(IX+13)    ; ENTRY H TO H
  1193.     LD    L,(IX+12)    ; ENTRY L TO L
  1194.     JP    REGRET+O
  1195. ;
  1196. ;   DISPLAY AF' VALUES
  1197. ;
  1198. DISAFP:    LD    H,(IX+11)    ; ENTRY A' TO H
  1199.     LD    L,(IX+10)    ; ENTRY F' TO L
  1200.     JP    DPRIM+O
  1201. ;
  1202. ;   DISPLAY BC' VALUES
  1203. ;
  1204. DISBCP:    LD    H,(IX+9)    ; ENTRY B' TO H
  1205.     LD    L,(IX+8)    ; ENTRY C' TO L
  1206.     JP    REGRET+O
  1207. ;
  1208. ;   DISPLAY DE' VALUES
  1209. ;
  1210. DISDEP:    LD    H,(IX+7)    ; ENTRY D' TO H
  1211.     LD    L,(IX+6)    ; ENTRY E' TO L
  1212.     JP    REGRET+O
  1213. ;
  1214. ;   DISPLAY HL' VALUES
  1215. ;
  1216. DISHLP:    LD    H,(IX+5)    ; ENTRY H' TO H
  1217.     LD    L,(IX+4)    ; ENTRY L' TO L
  1218.     JP    REGRET+O
  1219. ;
  1220. ;   DISPLAY IX VALUES
  1221. ;
  1222. DISPIX:    LD    H,(IX+3)    ; ENTRY IXH TO H
  1223.     LD    L,(IX+2)    ; ENTRY IXL TO L
  1224.     JP    REGRET+O
  1225. ;
  1226. ;   DISPLAY IY VALUES
  1227. ;
  1228. DISPIY:    LD    H,(IX+1)    ; ENTRY IYH TO H
  1229.     LD    L,(IX)        ; ENTRY IYL TO L
  1230.     JP    REGRET+O
  1231. ;
  1232. ;   DISPLAY SP VALUES
  1233. ;
  1234. DISPSP:    LD    HL,(SYSSP+O)    ; SYSTEM SP TO HL
  1235.     JP    REGRET+O
  1236. ;
  1237. ;   DISPLAY PC CONTENTS
  1238. ;
  1239. DISPPC:    LD    HL,(SYSPC+O)    ; SYSTEM PC TO HL
  1240.     JP    REGRET+O
  1241. ;
  1242. ;
  1243. ;   DISPLAY THE SELECTED AREA OF MEMORY
  1244. ;   ON ENTRY, STARTING ADDRESS IS IN HL
  1245. ;
  1246. DISMEM: LD    A,8        ; SET UP LINE COUNTER
  1247.     LD    (LINECT+O),A
  1248.     LD    BC,MEMCUR    ; GET DISPLAY CURSOR POS
  1249. DISME1:    LD    (CURSOR+O),BC    ; SAVE CURSOR POSITION
  1250.     CP    5        ; ARE WE ON SELECTED LINE?
  1251.     JR    NZ,DISME2    ; NO, GO ON
  1252.     DEC    C        ; MOVE CURSOR
  1253.     DEC    C        ;  BACK 3
  1254.     DEC    C        ;   POSITIONS
  1255.     CALL    POSCUR+O    ; POSITION CURSOR
  1256.     LD    DE,PTR+O    ; POINT TO POINTER
  1257.     CALL    MSGOUT+O    ; PRINT IT
  1258.     JR    DISME3        ; THEN GO TO NUMBERS
  1259. DISME2:    CALL    POSCUR+O    ; PUT THE CURSOR THERE
  1260. DISME3:    LD    A,H        ; HIGH ADDR BYTE TO A
  1261.     CALL    HX2ASC+O    ; PRINT HEX VALUE
  1262.     LD    A,L        ; LOW ADDR BYTE TO A
  1263.     CALL    HX2ASC+O    ; PRINT HEX VALUE
  1264.     CALL    DISREG+O    ; PRINT THE ADDRESS CONTENTS
  1265.      LD    A,(LINECT+O)    ; GET LINE COUNT
  1266.     DEC    A        ; ONE LINE DONE
  1267.     RET    Z        ; RETURN IF DONE
  1268.     LD    (LINECT+O),A    ; SAVE NEW LINE COUNT
  1269.     LD    BC,(CURSOR+O)    ; GET THE CURSOR POSITION
  1270.     INC    B        ; MOVE IT DOWN ONE LINE
  1271.     JR    DISME1        ; GO FOR NEXT LINE
  1272. ;
  1273. ;
  1274. ;   DISPLAY REGISTER CONTENTS AND INDIRECTS;
  1275. ;   RETURN TO REGISTER CALLING POINT
  1276. ;
  1277. REGRET:    CALL    ONLYRG+O    ; DISPLAY REGISTER CONTENTS
  1278.     CALL    DISREG+O    ; DISPLAY REGISTER INDIRECTS
  1279.     RET    
  1280. ;
  1281. ;
  1282. ;   DISPLAY CONTENTS OF ACTUAL REGISTER ONLY.  ON ENTRY, 
  1283. ;   CONTENTS OF SELECTED REGISTER ARE IN HL.
  1284. ;
  1285. ONLYRG:    LD    A,H        ; MOVE REG HIGH BYTE TO A
  1286.     CALL    HX2ASC+O    ; PRINT ITS HEX REPRESENTATION
  1287.     LD    E,SPACE        ; PRINT A SPACE
  1288.     CALL     CHROUT+O
  1289.     LD    A,L        ; MOVE REG LOW BYTE TO A
  1290.     CALL    HX2ASC+O    ; PRINT HEX REPRESENTATION
  1291.     RET            ; THAT'S ALL WE NEED HERE
  1292. ;
  1293. ;
  1294. ;   PRINTS THE SIXTEEN INDIRECT VALUES AND ASCII CHARACTERS
  1295. ;   ON ENTRY, THE REGISTER TO BE DISPLAYED MUST BE IN HL
  1296. ;
  1297. DISREG:    LD    E,'-'        ; PRINT A HYPHEN
  1298.     CALL    CHROUT+O
  1299.     LD    E,'>'        ; AND A RIGHT CARET
  1300.     CALL    CHROUT+O
  1301.     LD    BC,16        ; BYTE COUNT
  1302. LOOP01:    LD    A,(HL)        ; GET A BYTE
  1303.     CALL    HX2ASC+O    ; PRINT IT
  1304.     LD    E,SPACE        ; PRINT A SPACE
  1305.     CALL    CHROUT+O
  1306.     INC    HL        ; PREPARE FOR NEXT BYTE
  1307.     DEC    C        ; DECREMENT BYTE COUNT
  1308.     LD    A,C        ; NEED TO DO A COMPARE
  1309.     CP    8        ; HAVE WE JUST DONE THE 8TH BYTE?
  1310.     JR    NZ,DISRG1    ; NO, GO ON
  1311.     LD    E,SPACE        ; YES, PRINT A SPACE
  1312.     CALL    CHROUT+O
  1313.     JR    LOOP01        ; AND GO FOR ANOTHER BYTE
  1314. DISRG1:    OR    A        ; ARE WE DONE?
  1315.     JR    NZ,LOOP01    ; NO, GO FOR ANOTHER BYTE
  1316.     LD    E,SPACE        ; YES, PRINT ANOTHER SPACE
  1317.     CALL    CHROUT+O
  1318.     LD    BC,16        ; GET THE BYTE COUNT AGAIN
  1319.     SBC    HL,BC        ; SET HL BACK TO WHERE WE STARTED
  1320. LOOP02:    LD    A,(HL)        ; GET A CHARACTER
  1321.     CP    32        ; IS IT A CONTROL CHARACTER?
  1322.     JR    C,DISRG5    ; YES, PRINT A PERIOD
  1323.     CP    127        ; IS IT A GRAPHICS CHARACTER?
  1324.     JR    NC,DISRG5    ; YES, PRINT A PERIOD
  1325.     JR    DISRG2        ; NO, IT HAS AN ASCII REPRESENTATION
  1326. DISRG5:    LD    E,'.'        ; YES, PRINT A PERIOD
  1327.     JR    DISRG3        ; 
  1328. DISRG2:    LD    E,A        ; ASCII CHARACTER TO E
  1329. DISRG3:    CALL    CHROUT+O    ; PRINT PERIOD OR CHARACTER
  1330.     INC    HL        ; PREPARE FOR NEXT CHARACTER
  1331.     DEC    C        ; DECREMENT BYTE COUNT
  1332.     LD    A,C        ; FOR THE COMPARES
  1333.     CP    8        ; DID WE JUST PRINT THE 8TH CHARACTER?
  1334.     JR    NZ,DISRG4    ; NO, JUST CONTINUE
  1335.     LD    E,SPACE        ; YES, PRINT A SPACE
  1336.     CALL    CHROUT+O
  1337.     JR    LOOP02        ; AND GO FOR ANOTHER BYTE
  1338. DISRG4:    OR    A        ; WELL, THEN, ARE WE DONE?
  1339.     JR    NZ,LOOP02    ; NO, GO FOR ANOTHER
  1340.     RET            ; YES, RETURN
  1341. ;
  1342. ;
  1343. ;   DISPLAY BREAKPOINTS
  1344. ;
  1345. DISBRK:    LD    DE,BRKMSG+O    ; POINT TO BREAKPOINT MSG
  1346.     CALL    MSGOUT+O    ; PRINT IT
  1347.     LD    HL,BRKTBL+O    ; POINT TO BREAKPOINT TABLE
  1348.     LD    B,6        ; NUMBER OF ADDRESSES TO DISPLAY
  1349. DISBR1:    INC    HL        ; HIGH BYTE OF BREAKPOINT ADDR
  1350.     LD    A,(HL)        ; INTO A
  1351.     CALL    HX2ASC+O    ; PRINT IT
  1352.     DEC    HL        ; LOW BYTE OF BREAKPOINT ADDR
  1353.     LD    A,(HL)        ; INTO A
  1354.     CALL    HX2ASC+O    ; PRINT IT
  1355.     LD    E,SPACE        ; PRINT A SPACE
  1356.     CALL    CHROUT+O
  1357.     INC    HL        ; MOVE TO NEXT BREAKPOINT
  1358.     INC    HL
  1359.     DJNZ    DISBR1        ; GO FOR IT IF NOT DONE
  1360.     RET            ; ELSE RETURN        
  1361. ;
  1362. ;
  1363. ;   THESE SUBROUTINES DECODE 4-CHARACTER ASCII ADDRESSES FROM
  1364. ;   THE COMMAND BUFFER.  GETWRD RETURNS A 2-BYTE (ONE WORD)
  1365. ;   VALUE IN DE; GETBYT RETURNS A 1-BYTE VALUE (TREATED AS A
  1366. ;   "LOW" BYTE) IN THE E REGISTER.  ON ENTRY, THE COMMAND
  1367. ;   BUFFER POINTER (ADDRESS) IS IN HL.
  1368. ;
  1369. GETWRD:    CALL    GETBYT+O    ; GET THE FIRST (HIGH) BYTE
  1370.     LD    D,A        ; AND PUT IT IN D; THEN FALL
  1371.                 ; THROUGH FOR 2ND (LOW) BYTE
  1372. GETBYT:    PUSH    BC        ; PRESERVE BC
  1373.     LD    A,(HL)        ; GET 1ST CHARACTER
  1374.     CALL    NXTCHR+O    ; ADJUST COUNTER & POINTER
  1375.     CALL    ASC2HX+O    ; CHANGE FROM ASCII TO HEX
  1376.     SLA    A        ; SHIFT IT TO BITS 7-4
  1377.     SLA    A        ; TO BECOME THE HIGH
  1378.     SLA    A        ; NIBBLE OF THE HEX NUMBER
  1379.     SLA    A
  1380.     LD    B,A        ; SAVE IT IN B
  1381.     LD    A,(HL)        ; GET 2ND CHARACTER  
  1382.     CALL    NXTCHR+O    ; ADJUST COUNTER & POINTER
  1383.     CALL    ASC2HX+O    ; CHANGE FROM ASCII TO HEX
  1384.     ADD    A,B        ; COMBINE WITH HIGH NIBBLE
  1385.     LD    E,A        ; PUT 2ND (LOW) BYTE IN E
  1386.     POP    BC        ; RETRIEVE BC
  1387.     RET            ; ONE BYTE DONE
  1388. ;
  1389. ;
  1390. ;   ADJUST COMMAND BUFFER COUNTER AND POINT TO NEXT
  1391. ;   CHARACTER IN THE COMMAND BUFFER
  1392. ;
  1393. NXTCHR:    PUSH    BC        ; SAVE BC
  1394.     LD    C,A        ; SAVE CHAR IN C
  1395.     LD    A,(CBUFCT+O)    ; GET BUFFER COUNTER
  1396.     DEC    A        ; SUBTRACT 1 FOR THIS CHARACTER
  1397.     LD    (CBUFCT+O),A    ; SAVE NEW COUNT
  1398.     LD    A,C        ; GET CHAR BACK
  1399.     INC    HL        ; POINT TO NEXT CHAR
  1400.     POP    BC        ; GET BC BACK AGAIN
  1401.     RET            ; AND RETURN
  1402. ;
  1403. ;
  1404. ;   CHECKS COMMANDS AFTER DECODING BY SPECIFIC COMMAND
  1405. ;   MODULES TO BE SURE THERE ARE NO MISSING OR EXTRA
  1406. ;   CHARACTERS.  THE COMMAND BUFFER COUNTER SHOULD BE 0
  1407. ;   AFTER ANY COMMAND HAS BEEN DECODED.
  1408. ;
  1409. COMCHK:    LD    A,(CBUFCT+O)    ; GET COMMAND BUFFER COUNT
  1410.     OR    A        ; SHOULD BE 0 IF COMMAND OK
  1411.     RET    Z        ; RETURN OK
  1412. COMCH1:    PUSH    AF        ; SAVE NZ FLAG FOR RETURN
  1413.     CALL    BEEP+O        ; BEEP KEYBOARD
  1414.     LD    BC,ERRCUR    ; POSITION CURSOR
  1415.     CALL    POSCUR+O    ; FOR ERROR MESSAGE
  1416.     LD    DE,BADCOM+O    ; POINT TO BAD COMMAND MESSAGE
  1417.     CALL    MSGOUT+O    ; SEND IT
  1418.     CALL    DELAY+O        ; WAIT 3 SECONDS
  1419.     POP    AF        ; GET NZ FLAG BACK
  1420.     RET            ; RETURN WITH BAD NEWS
  1421. ;
  1422. ;
  1423. ;   SET BREAKPOINT IN CODE.  BREAKPOINT ADDRESS IS IN DE ON ENTRY
  1424. ;
  1425. SETBRK:    PUSH    BC        ; WE'LL NEED THESE
  1426.     PUSH    HL        ; FOR A BIT
  1427.     LD    B,0        ; ZERO B
  1428.     LD    A,(BRKCNT+O)    ; GET BREAKPOINT COUNTER
  1429.     LD    C,A        ; PUT IT IN C
  1430.     LD    HL,CODSAV+O    ; POINT TO CODE SAVE TABLE
  1431.     ADD    HL,BC        ; ADD OFFSET
  1432.     LD    A,(DE)        ; PROGRAM CODE TO A
  1433.     CP    0FFH        ; IS IT ALREADY A BREAK?
  1434.     JR    Z,SETBR1    ; YES, DON'T PUT IN CODSAV
  1435.     LD    (HL),A        ; THEN TO SAVE TABLE
  1436.     EX    DE,HL        ; BKPT ADDR TO HL
  1437.     LD    (HL),0FFH    ; BKPT INSTALLED
  1438. SETBR1:    POP    HL        ; RESTORE
  1439.     POP    BC        ; REGISTERS
  1440.     RET            ; AND RETURN 
  1441. ;
  1442. ;
  1443. ;   LOOK FOR ADDRESS IN BREAKPOINT TABLE
  1444. ;   ADDRESS TO TEST IS IN DE ON ENTRY
  1445. ;
  1446. MATCH:    LD    HL,BRKTBL+O    ; POINT TO BREAKPOINT TABLE
  1447.     LD    B,6        ; MAX 6 ENTRIES TO CHECK
  1448.     XOR    A        ; ZERO BREAKPOINT
  1449.     LD    (BRKCNT+O),A    ; COUNTER
  1450. MATCH1:    LD    A,(HL)        ; TABLE ENTRY LOW BYTE TO A
  1451.     CP    E        ; CHECK AGAINST BKPT LOW BYTE
  1452.     JR    NZ,MATCH2    ; NO LB MATCH; GO TO NEXT ENTRY
  1453.     INC    HL        ; LOW BYTE MATCHES
  1454.     LD    A,(HL)        ; SO TRY HIGH
  1455.     CP    D
  1456.     RET    Z        ; THIS IS THE ONE; RETURN
  1457.     JR    MATCH3        ; NO HIGH BYTE MATCH
  1458. MATCH2:    INC    HL        ; NO LOW BYTE MATCH
  1459. MATCH3:    LD    A,(BRKCNT+O)    ; INCREMENT
  1460.     INC    A        ;  BREAKPOINT
  1461.     LD    (BRKCNT+O),A    ;   COUNTER
  1462.     INC    HL        ; AND TABLE POINTER
  1463.     DJNZ    MATCH1        ; CONTINUE
  1464.     RET            ; FROM HERE IF NO MATCH AT ALL
  1465. ;
  1466. ;
  1467. ;   LOAD SPECIFIED AREA OF MEMORY WITH SPECIFIED BYTE
  1468. ;   ON ENTRY, START ADDRESS IS IN DE, END ADDRESS IS IN HL,
  1469. ;   AND BYTE IS IN A
  1470. ;
  1471. LOAD:    LD    (DE),A        ; LOAD BYTE INTO START ADDR
  1472.     INC    DE        ; NEXT ADDR TO LOAD
  1473.     PUSH    HL        ; DON'T LOSE END ADDR
  1474.     SBC    HL,DE        ; FILLED ALL YET?
  1475.     POP    HL        ; GET IT BACK
  1476.     JR    NC,LOAD        ; NO, DO NEXT
  1477.     RET            ; YES, DONE
  1478. ;
  1479. ;
  1480. ;   RESTORE USER CODE TO PROGRAM FOR
  1481. ;   CLEAR BREAKPOINT ROUTINES
  1482. ;   ON ENTRY, BREAKPOINT ADDRESS IS IN DE
  1483. ;
  1484. REPBRK:    PUSH    BC        ; SAVE CALLER COUNTER
  1485.     PUSH    HL        ; AND BKPT TABLE ADDR
  1486.     LD    B,0        ; ZERO B
  1487.     LD    A,(BRKCNT+O)    ; GET BREAKPOINT COUNTER
  1488.     LD    C,A        ; PUT IT IN C
  1489.     LD    HL,CODSAV+O    ; POINT TO SAVED CODE TABLE
  1490.     ADD    HL,BC        ; ADD OFFSET
  1491.     LD    A,(HL)        ; GET SAVED CODE BYTE
  1492.     LD    (DE),A        ; AND PUT IT BACK IN PROGRAM
  1493.     POP    HL        ; GET BKPT ADDR BACK
  1494.     POP    BC        ; AND CALLER COUNTER
  1495.     RET
  1496. ;
  1497. ;
  1498. ;----------------------------------------------------------------------------
  1499. ;   GENERAL SUBROUTINES/PRIMITIVES
  1500. ;----------------------------------------------------------------------------
  1501. ;
  1502. ;   GENERAL RETURN SUBROUTINE FOR BDOS FUNCTIONS
  1503. ;
  1504. GENRET:    POP    HL        ; ONE RETURN FOR ALL THE
  1505.     POP    DE        ; ROUTINES THAT PUSH THESE
  1506.     POP    BC        ; REGISTERS    
  1507.     RET
  1508. ;
  1509. ;
  1510. ;   GET CHARACTER FROM KEYBOARD
  1511. ;
  1512. KBD:    PUSH    BC        ; PUSH REGISTERS
  1513.     PUSH    DE        ; FOR BDOS CALL
  1514.     PUSH    HL
  1515.     LD    C,CONIN        ; GET CHAR FROM KEYBOARD
  1516.     CALL    BDOS
  1517.     CP    96        ; LOWER CASE?
  1518.     JR    C,KBD2        ; NO, GO AHEAD
  1519.     SUB    32        ; MAKE IT UPPER CASE
  1520. KBD2:    JR    GENRET        ; RETURN
  1521.  
  1522. ;
  1523. ;
  1524. ;   ONE CHARACTER TO SCREEN--ON ENTRY, CHARACTER MUST BE IN E REG
  1525. ;
  1526. CHROUT:    PUSH    BC        ; SAVE THE REGISTERS
  1527.     PUSH    DE
  1528.     PUSH    HL
  1529.     LD    C,CONOUT    ; CONSOLE OUT FUNCTION
  1530.     CALL    BDOS        ; SEND CHAR TO SCREEN
  1531.     JP    GENRET+O    ; POP REGISTERS AND RETURN
  1532. ;
  1533. ;
  1534. ;   MESSAGE TO SCREEN--ON ENTRY, MESSAGE ADDRESS MUST BE IN DE
  1535. ;
  1536. MSGOUT:    PUSH    BC        ; SAVE THE REGISTERS
  1537.     PUSH    DE
  1538.     PUSH    HL
  1539.     LD    C,PSTR        ; CONSOLE STRING OUT FUNCTION
  1540.     CALL    BDOS        ; SENT MESSAGE TO SCREEN
  1541.     JP    GENRET+O    ; POP REGISTERS AND RETURN
  1542. ;
  1543. ;
  1544. ;   CONVERT HEX VALUE TO ASCII REPRESENTATION
  1545. ;   ON ENTRY, CHARACTER MUST BE IN A REGISTER
  1546. ;
  1547. HX2ASC:    PUSH    BC        ; PRESERVE BC
  1548.     LD    B,A        ; SAVE HEX NO. IN B
  1549.     SRL    A
  1550.     SRL    A
  1551.     SRL    A
  1552.     SRL    A        ; BITS 4-7 NOW IN 0-3
  1553.     CALL    HX2AS1+O    ; SEND HIGH HEX NIBBLE TO SCREEN
  1554.     LD    A,B        ; GET HEX NO. BACK
  1555.     AND    0FH        ; MASK OFF LOW NIBBLE
  1556.     CALL    HX2AS1+O    ; SEND LOW HEX NIBBLE TO SCREEN
  1557.     POP    BC        ; RESTORE BC
  1558.     RET            ; SUBROUTINE DONE
  1559. ;   TRANSLATE HEX NIBBLE TO ASCII CHARACTER
  1560. HX2AS1:    CP    10        ; IS THE NIBBLE > 10?
  1561.     JR    NC,LETTER    ; IT'S A LETTER IF IT IS
  1562.     ADD    A,48        ; MAKE IT ASCII FOR A NUMBER
  1563.     JR    NIBOUT        ; AND PRINT IT
  1564. LETTER: ADD    A,55        ; MAKE IT ASCII FOR A LETTER
  1565. NIBOUT:    LD    E,A        ; REALLY GO PRINT IT NOW
  1566.     CALL    CHROUT+O
  1567.     RET            ; HEX. CHAR PRINTED
  1568. ;
  1569. ;
  1570. ;   CONVERT ONE ASCII CHARACTER TO ITS HEX VALUE;
  1571. ;   I.E., 'F' BECOMES 0FH.  THE CHARACTERS COMING
  1572. ;   IN HERE HAVE ALREADY BEEN CHECKED FOR PROPER
  1573. ;   RANGE IN THE COMMAND ENTRY MODULE
  1574. ;
  1575. ASC2HX:    CP    58        ; IS IT A DIGIT?
  1576.     JR    NC,ASC2H1    ; NO, MUST BE A LETTER
  1577.     SUB    30H        ; ADJUST FOR DIGIT
  1578.     RET
  1579. ASC2H1:    SUB    37H        ; ADJUST FOR LETTER
  1580.     RET
  1581. ;
  1582. ;
  1583. ;   PRINT CR LF
  1584. ;
  1585. NEWLIN:    LD    E,CR
  1586.     CALL    CHROUT+O
  1587.     LD    E,LF
  1588.     CALL    CHROUT+O
  1589.     RET
  1590. ;
  1591. ;
  1592. ;   KAYPRO PROTOCOL TO POSITION CURSOR--
  1593. ;   CURSOR HEX Y AND X POSITIONS ARE PASSED IN BC
  1594. ;
  1595. POSCUR:    LD    E,27        ; KAYPRO CURSOR POSITION PROTOCOL--
  1596.     CALL    CHROUT+O    ; PRINT ESC '=' 'Y' 'X'
  1597.     LD    E,'='
  1598.     CALL    CHROUT+O
  1599.     LD    E,B        ; CURSOR Y POSITION
  1600.     CALL    CHROUT+O
  1601.     LD    E,C        ; CURSOR X POSITION
  1602.     CALL    CHROUT+O
  1603.     RET            ; CURSOR NOW IN POSITION
  1604. ;
  1605. ;
  1606. ;   BEEP KEYBOARD
  1607. ;
  1608. BEEP:    PUSH    DE        ; DON'T LOSE DE
  1609.     LD    E,BELL        ; PRINT BELL
  1610.     CALL    CHROUT+O
  1611.     POP    DE        ; DE BACK
  1612.     RET
  1613. ;
  1614. ;
  1615. ;   DELAY APPROX 0.5 SEC FOR EACH COMPLETION OF 0FFFFH
  1616. ;   COUNT IN HL
  1617. ;
  1618. DELAY:    LD    B,6        ; DO INNER LOOP 6 TIMES
  1619. DELAY1:    LD    HL,0FFFFH    ; APPROX 0.5 SEC FOR
  1620. DELAY2:    DEC    HL        ; THE INNER LOOP
  1621.     LD    A,H
  1622.     OR    L        ; HL = 0?
  1623.     JR    NZ,DELAY2    ; NO, GO AGAIN
  1624.     DJNZ    DELAY1        ; GO UNTIL B=0.
  1625.     RET
  1626. ;
  1627. ;----------------------------------------------------------------------------
  1628. ;   TABLES
  1629. ;---------------------------------------------------------------------------- 
  1630. ;
  1631. ;   "HASHED" REGISTER IDENTIFIERS FOR MODIFY REGISTER
  1632. ;   CONTENTS COMMAND
  1633. ;
  1634. REGTAB:    DEFB    135        ; AF
  1635.     DEFB    133        ; BC
  1636.     DEFB    137        ; DE
  1637.     DEFB    148        ; HL
  1638.     DEFB    104        ; AF'
  1639.     DEFB    105        ; BC'
  1640.     DEFB    107        ; DE'
  1641.     DEFB    111        ; HL'
  1642.     DEFB    161        ; IX
  1643.     DEFB    162        ; IY
  1644. ;
  1645. ;
  1646. ;   BYTE TABLES FOR SINGLE-STEPPING
  1647. ;
  1648. TAB21:    DEFB    0CBH        ; IF THE INSTRUCTION BYTE
  1649.     DEFB    06H        ; IS ANY OF
  1650.     DEFB    0EH        ; TAB21
  1651.     DEFB    10H        ; THEN IT'S A
  1652.     DEFB    16H        ; 2-BYTE
  1653.     DEFB    18H        ; INSTRUCTION
  1654.     DEFB    1EH
  1655.     DEFB    20H
  1656.     DEFB    26H
  1657.     DEFB    28H
  1658.     DEFB    2EH
  1659.     DEFB    30H
  1660.     DEFB    36H
  1661.     DEFB    38H
  1662.     DEFB    3EH
  1663.     DEFB    0C6H
  1664.     DEFB    0D3H
  1665.     DEFB    0D6H
  1666.     DEFB    0DBH
  1667.     DEFB    0DEH
  1668.     DEFB    0E6H
  1669.     DEFB    0EEH
  1670.     DEFB    0F6H
  1671.     DEFB    0FEH
  1672. T21END:    EQU    $        ; FOR CHANGES AND CALCULATION
  1673. ;
  1674. ;
  1675. TAB22:    DEFB    09H        ; IF THE 1ST INSTRUCTION
  1676.     DEFB    19H        ; BYTE IS DD, ED, OR FD
  1677.     DEFB    23H        ; AND THE NEXT
  1678.     DEFB    29H        ; BYTE IS ONE OF
  1679.     DEFB    2BH        ; TAB22,
  1680.     DEFB    39H        ; THEN IT'S A
  1681.     DEFB    0E1H        ; 2-BYTE
  1682.     DEFB    0E3H        ; INSTRUCTION.
  1683.     DEFB    0E5H
  1684.     DEFB    0E9H
  1685.     DEFB    0F9H
  1686.     DEFB    40H
  1687.     DEFB    41H
  1688.     DEFB    42H
  1689.     DEFB    44H
  1690.     DEFB    45H
  1691.     DEFB    46H
  1692.     DEFB    47H
  1693.     DEFB    48H
  1694.     DEFB    49H
  1695.     DEFB    4AH
  1696.     DEFB    4DH
  1697.     DEFB    50H
  1698.     DEFB    51H
  1699.     DEFB    52H
  1700.     DEFB    56H
  1701.     DEFB    57H
  1702.     DEFB    58H
  1703.     DEFB    59H
  1704.     DEFB    5AH
  1705.     DEFB    5EH
  1706.     DEFB    60H
  1707.     DEFB    61H
  1708.     DEFB    62H
  1709.     DEFB    67H
  1710.     DEFB    68H
  1711.     DEFB    69H
  1712.     DEFB    6AH
  1713.     DEFB    6FH
  1714.     DEFB    72H
  1715.     DEFB    78H
  1716.     DEFB    79H
  1717.     DEFB    7AH
  1718.     DEFB    0A0H
  1719.     DEFB    0A1H
  1720.     DEFB    0A2H
  1721.     DEFB    0A3H
  1722.     DEFB    0A8H
  1723.     DEFB    0A9H
  1724.     DEFB    0AAH
  1725.     DEFB    0ABH
  1726.     DEFB    0B0H
  1727.     DEFB    0BAH
  1728.     DEFB    0B2H
  1729.     DEFB    0B3H
  1730.     DEFB    0B8H
  1731.     DEFB    0B9H
  1732.     DEFB    0BAH
  1733.     DEFB    0BBH
  1734. T22END:    EQU    $        ; FOR CHANGES AND CALCULATION
  1735. ;
  1736. ;
  1737. TAB31:    DEFB    01H        ; IF THE INSTRUCTION BYTE
  1738.     DEFB    11H        ; IS ANY OF
  1739.     DEFB    21H        ; TAB31,
  1740.     DEFB    22H        ; THEN IT'S A
  1741.     DEFB    2AH        ; 3-BYTE
  1742.     DEFB    31H        ; INSTRUCTION.
  1743.     DEFB    32H
  1744.     DEFB    3AH
  1745.     DEFB    0C2H
  1746.     DEFB    0C3H
  1747.     DEFB    0C4H
  1748.     DEFB    0CAH
  1749.     DEFB    0CCH
  1750.     DEFB    0CDH
  1751.     DEFB    0D2H
  1752.     DEFB    0D4H
  1753.     DEFB    0DAH
  1754.     DEFB    0DCH
  1755.     DEFB    0E2H
  1756.     DEFB    0E4H
  1757.     DEFB    0EAH
  1758.     DEFB    0ECH
  1759.     DEFB    0F2H
  1760.     DEFB    0F4H
  1761.     DEFB    0FAH
  1762.     DEFB    0FCH
  1763. T31END:    EQU    $        ; FOR CHANGES AND CALCULATION
  1764. ;
  1765. TAB32:    DEFB    34H        ; IF THE 1ST INSTRUCTION
  1766.     DEFB    35H        ; BYTE IS DD, ED, OR FD
  1767.     DEFB    46H        ; AND THE NEXT BYTE
  1768.     DEFB    4EH        ; IS ONE OF
  1769.     DEFB    56H        ; TAB32,
  1770.     DEFB    5EH        ; THEN IT'S A
  1771.     DEFB    66H        ; 3-BYTE
  1772.     DEFB    6EH        ; INSTRUCTION
  1773.     DEFB    70H
  1774.     DEFB    71H
  1775.     DEFB    72H
  1776.     DEFB    73H
  1777.     DEFB    74H
  1778.     DEFB    75H
  1779.     DEFB    77H
  1780.     DEFB    7EH
  1781.     DEFB    86H
  1782.     DEFB    8EH
  1783.     DEFB    96H
  1784.     DEFB    9EH
  1785.     DEFB    0A6H
  1786.     DEFB    0AEH
  1787.     DEFB    0B6H
  1788.     DEFB    0BEH
  1789. T32END:    EQU    $        ; FOR CHANGES AND CALCULATION
  1790. ;
  1791. ;
  1792. TAB42:    DEFB    21H        ; IF THE 1ST INSTRUCTION
  1793.     DEFB    22H        ; BYTE IS DD, ED, OR FD
  1794.     DEFB    2AH        ; AND THE NEXT BYTE
  1795.     DEFB    36H        ; IS ONE OF 
  1796.     DEFB    0CBH        ; TAB42,
  1797.     DEFB    43H        ; THEN IT'S A
  1798.     DEFB    4BH        ; 4-BYTE
  1799.     DEFB    53H        ; INSTRUCTION
  1800.     DEFB    5BH
  1801.     DEFB    73H
  1802.     DEFB    7BH
  1803. T42END:    EQU    $        ; FOR CHANGES AND CALCULATION
  1804. ;
  1805. ;   TABLE LENGTHS FOR CPIR
  1806. ;
  1807. LENT21:    EQU    T21END-TAB21    ; LENGTH OF 1ST 2-BYTE TABLE
  1808. LENT22:    EQU    T22END-TAB22    ; LENGTH OF 2ND 2-BYTE TABLE
  1809. LENT31:    EQU    T31END-TAB31    ; LENGTH OF 1ST 3-BYTE TABLE
  1810. LENT32:    EQU    T32END-TAB32    ; LENGTH OF 2ND 3-BYTE TABLE
  1811. LENT42:    EQU    T42END-TAB42    ; LENGTH OF 4-BYTE TABLE
  1812. ;
  1813. ;----------------------------------------------------------------------------
  1814. ;   STACK
  1815. ;----------------------------------------------------------------------------
  1816. ;
  1817. ;   SET LOCAL STACK SPACE
  1818. ;
  1819.     DEFS    64        ; 32-WORD LOCAL STACK
  1820. LOCSP:    DEFB    0        ; START OF STACK
  1821. ;
  1822. ;----------------------------------------------------------------------------
  1823. ;   ABSOLUTE END OF DEBUG CODE
  1824. ;----------------------------------------------------------------------------
  1825. CODEND    EQU    $
  1826. ;
  1827. ;
  1828. ;----------------------------------------------------------------------------
  1829. ;   CALCULATIONS/EQUATES FOR RELOCATION AND OFFSET
  1830. ;----------------------------------------------------------------------------
  1831. ;
  1832. CODSIZ    EQU    CODEND-CODBEG    ; AMOUNT OF CODE TO RELOCATE
  1833. DESTIN    EQU    RELTOP-CODSIZ-2    ; RELOCATION DESTINATION
  1834. O    EQU    DESTIN-CODBEG    ; OFFSET FOR CALLS AND JUMPS
  1835. ;
  1836. ;----------------------------------------------------------------------------
  1837.     END            ; OF DEBUG
  1838.