home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol075 / upg80.asm < prev    next >
Assembly Source File  |  1984-04-29  |  58KB  |  2,804 lines

  1. ;    TITLE      'UPG80 MONITOR SPECIAL SYSTEM VERSION 3-1   31/8/79'
  2. ;
  3. ;****    FOR S100 SYSTEMS WITH JADE I/O BOARDS.
  4. ;
  5. ;
  6. ;*************************************************************
  7. ;
  8. ;    UPG80 MONITOR :-
  9. ;    MODIFIED VERSION OF AMSAT'S AMS80 V2:0 MONITOR
  10. ;    BY H.J.HARVEY
  11. ;
  12. ; THIS MONITOR IS A MINIMUM 8080 SYSTEM MONITOR TO PROVIDE
  13. ; THE BASIC STRUCTURE NECESSARY FOR 8080 DEBUG AND CONTROL.
  14. ;
  15. ; THE ROUTINES ALLOW FOR MEMORY EXAMINE AND MODIFY,
  16. ; TARGET PROGRAM BREAKPOINTING UNDER MONITOR CONTROL,
  17. ; USER INTERRUPTS OR RST VECTORS (RST3-RST7),
  18. ; SIMPLE ASSEMBLY AND DISASSEMBLY, INPUT AND OUTPUT,
  19. ; AND PROVIDE VARIOUS TELETYPE SUPPORT ROUTINES TO LOAD
  20. ; AND DUMP MEMORY IN STANDARD 8080 HEX-BINARY.
  21. ;
  22. ;   THE MONITOR INCLUDES AN EXTENSIVE VECTOR TABLE STARTING
  23. ; AT (ROM-ORIGIN + 40H) TO ALLOW USER ACCESS TO A NUMBER
  24. ; OF USEFUL SPECIFIC ROUTINES.
  25. ;
  26. ;*************************************************************
  27. ;
  28. ;    DEFINE CONSOLE CONTROL CHRS
  29. ;
  30. CR    EQU    0DH    ;ASCII CARRIAGE-RETURN
  31. LF    EQU    0AH    ;ASCII LINE-FEED
  32. ;
  33. ;    THE FOLLOWING EQUATES ARE USED TO DEFINE THE COLUMN WIDTH
  34. ;    OF THE DISPLAY CONSOLE.
  35. ;    'R' COMMAND NEEDS 58 COLUMNS FOR A 1-LINE DISPLAY
  36. ;    'D' COMMAND NEEDS 53 COLUMNS FOR 16-BYTE DISPLAY
  37. ;    'P' COMMAND NEEDS 43 COLUMNS FOR 16-BYTE GROUP
  38. ;    COLSW=1 IF MONITOR <58 COLUMNS/LINE
  39. ;    COLSW=0 IF MONITOR >57 COLUMNS/LINE
  40. ;
  41. COLSW    EQU    0
  42. ;
  43.     IF    NOT COLSW
  44. ;
  45. ;    58+ COLUMN CONSTANTS
  46. ;
  47. OSET    EQU    16    ;16 BYTES PER LINE
  48.     ENDIF
  49.     IF    COLSW
  50. ;
  51. ;    <58 COLUMN CONSTANTS
  52. ;
  53. OSET    EQU    8    ;8 BYTES PER LINE
  54.     ENDIF
  55. ;
  56. ;
  57. ;
  58. ;    THE FOLLOWING EQUATES ARE DESIGNED FOR CONSOLE CONTROL
  59. ;    OF THE S100 CARD-SET WITH JADE SPI/O BOARDS.
  60. ;    ER SYSTEMS WILL REQUIRE DIFFERENT EQUATES, DEPENDING
  61. ;    UPON THE SELECTION OF I/O PORTS AND CONTROL SETUPS.
  62. ;
  63. CNCTL    EQU    081H    ;SYSTEM I/O CONSTANTS
  64. CONST    EQU    081H
  65. CNIN    EQU    001H
  66. CNOUT    EQU    001H
  67. CSCTL    EQU    080H    ;CASSETTE CONTROL
  68. CSST    EQU    080H    ;CASSETTE STATUS CHANNEL
  69. CSIN    EQU    000H    ;CASSETTE INPUT PORT
  70. CSOUT    EQU    000H    ;CASSETTE OUTPUT PORT
  71. MODE    EQU    0FFH    ;MM5303 UART MODE SELECT
  72. TRDY    EQU    080H    ;TRANSMIT READY BIT
  73. RBR    EQU    010H    ;READER READY BIT
  74. TMOUT    EQU    10000    ;10000 MILLISECOND (10 SECS) TIMEOUT
  75. ONEMS    EQU    130    ;CONSTANT FOR 1 MILLISECOND LOOP (F/N DELAY)
  76. RAM    EQU    03F00H    ;START OF 256 BYTE RAM.
  77. ;
  78. ;    ROM AND RAM AREAS CAN NOW BE DEFINED.
  79. ;
  80. ROMSW    EQU    1    ;ROMSW=1 IF ROM > 0 , OTHERWISE ROMSW=0
  81. ROM    EQU    08000H    ;ROM STARTS HERE
  82. REGS    EQU    RAM+256-48    ;REGISTER STORE (IN RAM) STARTS HERE
  83. STACK    EQU    REGS    ;TOP OF STACK INITIALIZE
  84. ;
  85. ;    START OF SYSTEM
  86. ;
  87.     ORG    ROM
  88. ;
  89. ;    SET UP SERIAL DATA MODE.
  90. ;
  91. PART1:
  92.     DI        ;DISABLE ALL INTERRUPTS.
  93.     MVI    A,MODE    ;SERIAL I/O MODE.
  94.     JMP    PART2
  95.     DW    RAM
  96. ;
  97. ;    EXECUTIVE ENTRY ON RST1
  98. ;    THIS ENTRY POINT IS USED WHENEVER AN RST1 (CODE CF)
  99. ;    IS EXECUTED.
  100. ;
  101. EXEC:
  102.     SHLD    SVHL    ;SAVE HL
  103.     POP    H    ;POP THE CALL ADDRESS INTO HL
  104.     RAR        ;PUT CARRY INTO B7 OF ACC
  105.     JMP    BEGIN    ;GO ON NOW.
  106. ;
  107. ;    BREAKPOINT SERVICING INPUT AS RESULT OF 'RST 2'
  108. ;    ROUTINE BPAT IS CALLED TO LET THE USER KNOW.
  109. ;
  110. BPIN:
  111.     SHLD    SVHL    ;SAVE HL
  112.     POP    H    ;GRAB BREAKPOINT ADDRESS
  113.     RAR        ;ROTATE RIGHT PUTS CARRY INTO ACC B7
  114.     JMP    BPAT    ;GO SERVICE IT.
  115. ;
  116. ;    DEFINE USER INT/SR VECTORS
  117. ;    RST3 THROUGH RST7 MAY BE USED EITHER AS HARDWARE
  118. ;    OR SOFTWARE INTERRUPT VECTORS.
  119. ;    THE ORRESPONDING ADDRESS FOR SERVICE MUST BE
  120. ;    SET UP IN THE APPROPRIATE LOCATIONS IN RAM.
  121. ;    THESE ADDRESSES CAN BE FOUND BY REFERENCE TO THE LABELS
  122. ;    RST3 - RST7 AT THE END OF THIS MONITOR.
  123. ;
  124. ;****    NOTE THAT THESE CODE GROUPS ARE TO BE LINKED FROM RAM
  125. ;    IN PAGE ZERO IF THE MONITOR IS NOT ZERO ORGED.
  126. ;
  127. RS3:
  128.     PUSH    H    ;SAVE HL
  129.     LHLD    RST3    ;FETCH USER VECTOR
  130.     XTHL        ;PUT ON STACK RESTORING HL
  131.     RET        ;GO TO USER
  132.     DW    ROM    ;PAD - ROM START ADDRESS
  133. RS4:
  134.     PUSH    H    ;SAVE HL
  135.     LHLD    RST4    ;FETCH USER VECTOR
  136.     XTHL        ;PUT ON STACK RESTORING HL
  137.     RET        ;GO TO USER
  138.     DW    RAM    ;PAD - RAM START ADDRESS
  139. RS5:
  140.     PUSH    H    ;SAVE HL
  141.     LHLD    RST5    ;FETCH USER VECTOR
  142.     XTHL        ;PUT ON STACK RESTORING HL
  143.     RET        ;GO TO USER
  144.     DW    REGS    ;PAD - END OF REG STORE (ALSO T.O.S.)
  145. RS6:
  146.     PUSH    H    ;SAVE HL
  147.     LHLD    RST6    ;FETCH USER VECTOR
  148.     XTHL        ;PUT ON STACK RESTORING HL
  149.     RET        ;GO TO USER
  150.     DW    SVA    ;PAD - START OF REG STORE.
  151. RS7:
  152.     PUSH    H    ;SAVE HL
  153.     LHLD    RST7    ;FETCH USER VECTOR
  154.     XTHL        ;PUT ON STACK RESTORING HL
  155.     RET        ;GO TO USER
  156.     DW    ENDROM    ;PAD - END OF ROM DATA
  157. ;
  158. ;    MONITOR SUPPORT SR VECTORS
  159. ;    USER UTILITY SR'S
  160. ;
  161. ; THE FOLLOWING SET OF JUMPS ARE PROVIDED SOTHAT USER
  162. ; PROGRAMS CAN REFERENCE COMMON ENTRY POINTS TO THE VARIOUS
  163. ; ROUTINES. THESE LOCATIONS WILL REMAIN CONSTANT WHILE THE
  164. ; ACTUAL LOCATION OF EACH ROUTINE MAY CHANGE AS DIFFERENT
  165. ; MONITOR REVISIONS OCCUR.
  166. ;
  167. ;    THE CALLING SEQUENCE FOR EACH SUBROUTIN EMAINS THE
  168. ; SAME AS DEFINED IN THE LISTING, WITH ONLY A SLIGHT EXECUTION
  169. ; TIME OVERHEAD DUE TO THE EXTRA JUMP.
  170. ;
  171. ZTYPE:    JMP    TYPE    ;TYPE CHR IN 'A'
  172. ZGETCH:    JMP    GETCH    ;GET CHR IN 'A' (PARITY, NO ECHO)
  173. ZCHIN:    JMP    CHIN    ; "   "  "   "  (ECHO, NO PARITY)
  174. ZCHINX:    JMP    CHINX    ; "   "  "   "  (ECHO/NO ECHO, NO PARITY)
  175. ZMSG:    JMP    MSG    ;TYPE MESSAGE, PTR IN HL. TERM 0FFH
  176. ZCRLF:    JMP    CRLF    ;TYPE CR/LF
  177. ZSPACE:    JMP    BLANK    ;TYPE " "
  178. ZTHXN:    JMP    THXN    ;TYPE HEX 'A' B3-B0
  179. ZTHXB:    JMP    THXB    ; " "  "   "  B7-B0
  180. ZTHXW:    JMP    THXW    ; " "  " 'HL'
  181. ZGHXN:    JMP    GHXN    ;GET HEX 'A' B3-B0
  182. ZGHXB:    JMP    GHXB    ; "   "   "  B7-B0
  183. ZGHXW:    JMP    GHXW    ; "   "  'HL'
  184. ZSTORE:    JMP    STORE    ;STORE A IN (HL) AND CHECK
  185. ZNEGDE:    JMP    NEGDE    ;NEGATE DE REG
  186. ZPWAIT:    JMP    PWAIT    ;TYPE 'PAUSE' THEN AWAIT ANY CHR
  187. ZOKQ:    JMP    OKQ    ;TYPE 'OK?', AWAIT CHR, CONTINUE IF ' '
  188. ZECHO:    JMP    ECHCN    ;ECHO CONTROL (A=0 MEANS OFF)
  189. ZCNVBN:    JMP    CNVBN    ;CONVERT CHARACTER TO BINARY NYBBLE.
  190. ZCSTS:    JMP    CSTS    ;LOOK FOR CONSOLE K/B STRIKE.
  191. ;
  192. ;    UART INITIALIZATION CODE: PART 2.
  193. ;    SEND OUT THE COMMAND WORD.
  194. ;
  195. PART2:
  196.     OUT    CSCTL    ;SET UP CASSETTE I/O
  197.     OUT    CNCTL    ;AND CONSOLE I/O.
  198. ;
  199. ;    ZERO OUT THE CURRENT ADDRESS FOR BREAKPOINT.
  200. ;    (NECESSARY TO ALLOW UPDATING)
  201. ;
  202.     LXI    H,0    ;LOAD 16 BIT ZERO
  203.     SHLD    BPADD    ;PUT ALL ZEROS IN BPADD
  204. ;
  205. ;    BEGIN MONITOR.
  206. ;    ENTER HERE FOLLOWING A HARDWARE/SOFTWARE RST1
  207. ;
  208. BEGIN:
  209.     SHLD    SVPC    ;STORE CALLING PC
  210.     STA    TMPA    ;AND CARRY (IN B7)
  211.     RAL        ;THEN ROTATE BACK THE ACC.
  212.     LXI    H,0    ;NOW TRANSFER THE SP TO HL BY DOING A DUMMY
  213.     DAD    SP    ;ADD TO HL. (N.B. CLEARS CARRY)
  214.     SHLD    SVSP    ;SAVE THE CALLER SP.
  215.     LXI    SP,SVA+1    ;PICK UP REG STORE POINTER
  216.     PUSH    PSW    ;TO SAVE PSW
  217.     PUSH    B    ;AND BC
  218.     PUSH    D    ;AND DE. (HL ALREADY SAVED)
  219.     LXI    H,SVF    ;GET THE PSB BYTE
  220.     LDA    TMPA    ;PICK UP THE CARRY HOLDER,
  221.     RAL        ;ROTATE IT BACK TO CARRY.
  222.     JNC    BGN1    ;SKIP IF CARRY NOT SET,
  223.     INR    M    ;OTHERWISE RESET CARRY.
  224. BGN1:
  225.     LXI    H,M0    ;TYPE MONITOR ENTRY MESSAGE
  226.     JMP    NEXT1
  227. ;
  228. ;    NEXT MONITOR COMMAND PLEASE.
  229. ;    ENTER HERE WHENEVER A NEW COMMAND IS EXPECTED.
  230. ;
  231. NEXT:
  232.     LXI    H,M1    ;TYPE PROMPT MESSAGE
  233. NEXT1:
  234.     LXI    SP,STACK    ;SET STACK POINTER FIRST.
  235.     CALL    MSG
  236.     CALL     CHIN    ;GET COMMAND CHARACTER INTO 'A'
  237.     MOV    B,A    ;AND SAVE IT IN 'B'
  238. ;
  239. ;    SEARCH OP TABLE
  240. ;    (IF CALLING COMMAND BYTE IS REQUIRED, IT IS IN 'B')
  241. ;
  242.     LXI    H,OPTAB    ;HEAD-OF-TABLE VECTOR
  243.     SUI    'A'    ;REDUCE CODE TO OFFSET
  244.     CPI    1AH    ;SEE IF IT EXCEEDS 'Z' COMMAND.
  245.     JNC    TEND    ;IF SO, MAY HAVE BEEN SPECIAL.
  246.     ADD    A    ;ALL O.K. MULTIPLY BY 2 (2 BYTES PER ADDR)
  247.     MOV    E,A    ;PUT VALUE*2 INTO E
  248.     MVI    D,0    ;AND GET ZERO TO CLEAR 'D'
  249.     DAD    D    ;ADD OFFSET TO HL (ADDRESS REQUIRED AT <HL>)
  250.     MOV    E,M    ;GET LOWER BYTE OF REQUIRED ADDR
  251.     INX    H    ;AND THEN GET THE UPPER
  252.     MOV    D,M    ;BYTE BEFORE TRANSFERRING
  253.     XCHG        ;IT TO HL.
  254.     PCHL        ;FINALLY JUMP TO ROUTINE CALLED.
  255. ;
  256. ;    OPERATION ADDRESS TABLE.
  257. ;    CONTAINS AN ADDRESS DESTINATION FOR EACH CHARACTER OF THE
  258. ;    ALPHABET (A-Z IN ASCENDING ORDER.)
  259. ;
  260. OPTAB:
  261.     DW    GETAD    ;A - GET ADDRESS
  262.     DW    BPT    ;B - BREAKPOINT SETTER/CLEARER
  263.     DW    CONT    ;C - CONTINUE AFTER B/P
  264.     DW    DISP    ;D - DISPLAY MEMORY DATA
  265.     DW    PEND    ;E - END OF FILE PUNCH
  266.     DW    FILL    ;F - FILL MEMORY WITH DATA
  267.     DW    GOTO    ;G - PROGRAM GO: NO REGISTER RESTORE.
  268.     DW    ASM80    ;H - LINE ASSEMBLER
  269.     DW    INPT    ;I - INPUT PORT DATA
  270.     DW    JUMP    ;J - PROGRAM JUMP: REGISTER RESTORE.
  271.     DW    KOMP    ;K - K(C)OMPARE MEMORY AREAS
  272.     DW    LOAD    ;L - LOAD HEX-BINARY TAPE
  273.     DW    MOVE    ;M - MOVE MEMORY BLOCK
  274.     DW    NULL    ;N - PUNCH NULL BLOCK
  275.     DW    OUTPT    ;O - OUTPUT PORT DATA.
  276.     DW    PUNCH    ;P - PUNCH HEX-BINARY DATA
  277.     DW    ILLEG
  278.     DW    REGEX    ;R - REGISTER EXAMINE/MODIFY
  279.     DW    SEARCH    ;S - SEARCH MEMORY FOR BYTE
  280.     DW    ILLEG
  281.     DW    USER    ;U - USER DEFINE/USE
  282.     DW    ILLEG
  283.     DW    ILLEG
  284.     DW    GETXA    ;X - SET UP XEQ ADDRESS
  285.     DW    DIS80    ;Y - 8080 DISASSEMBLY.
  286.     DW    ZERO    ;Z - ZERO OUT MEMORY
  287. ;
  288. ;    N.B.    COMMANDS <CR> <LF> . AND - ARE CHECKED
  289. ;        BY ROUTINE 'TEND'
  290. ;
  291. ;
  292. ;    INPUT ONE CHR AND STRIP PARITY
  293. ;    ALTERNATIVE ENTRY POINTS ARE:-
  294. ;
  295. ;        CALL    CHIN
  296. ;        ....        ;RESULT IN 'A'
  297. ;    THE INPUT IS ECHO'D IF DATA IS PRINTABLE.
  298. ;
  299. ;        MVI    A,XX    ;XX=0 NO ECHO.
  300. ;        CALL    CHINX
  301. ;        ....        ;RESULT IN 'A'
  302. ;    ECHO CONTROLLED EACH CALL.
  303. ;
  304. ;        CALL    CHINN
  305. ;        ....        ;RESULT IN 'A'
  306. ;    ECHO CONTROLLED BY PREVIOUS 'CALL ECHCN'
  307. ;
  308. CHIN:
  309.     MVI    A,0FFH    ;SET ECHO FLAG ON
  310. CHINX:
  311.     CALL    ECHCN    ;CALL THE CONTROLLER.
  312. CHINN:
  313.     CALL    GETCH    ;GET CHARACTER FROM CONSOLE,
  314.     ANI    7FH    ;STRIP ANY PARITY
  315.     PUSH    PSW    ;SAVE DATA
  316.     LDA    ECHO    ;SEE IF ECHO REQU'D
  317.     ANA    A    ;THIS INSTRUCTION SIMPLY SETS FLAGS
  318.     JNZ    CHN1    ;TEST FOR ZERO/NON-ZERO CONTROL
  319.     POP    PSW    ;NO ECHO. SIMPLY RETURN
  320.     RET
  321. CHN1:
  322.     POP    PSW    ;GET DATA AND ECHO
  323.     CPI    ' '    ;IF NOT CONTROL CHR
  324.     CNC    TYPE
  325.     RET        ;BEFORE RETURNING
  326. ;
  327. ;    MESSAGE PRINT
  328. ;    ALLOWS USER TO PRINT A MESSAGE ON THE CONSOLE OUTPUT
  329. ;    BY HAVING A STRING OF CHARACTERS FOLLOWED
  330. ;    BY DELIMITING 0FFH (-1)
  331. ;
  332. ;    CALLING SEQUENCE:-
  333. ;        LXI    H,ADDRESS
  334. ;        CALL    MSG
  335. ;        ....
  336. ;
  337. MSG:
  338.     PUSH    PSW    ;SAVE PSW
  339.     PUSH    H    ;AND HL
  340. MNXT:
  341.     MOV    A,M    ;GET NEXT BYTE
  342.     INX    H    ;BUMP BYTE POINTER.
  343.     CPI    0FFH    ;CHECK FOR 0FFH (-1) TERMINATOR
  344.     CNZ    TYPE    ;NO. TYPE IT
  345.     JNZ    MNXT    ;NOW READY FOR ANOTHER TRY
  346.     POP    H    ;MESSAGE FINISHED. RESTORE HL
  347.     POP    PSW    ;AND PSW
  348.     RET        ;BEFORE GOING HOME
  349. ;
  350. ;    TYPE CR/LF
  351. ;    (THE EASY WAY TO START A NEW LINE)
  352. ;
  353. ;    CALLING SEQUENCE:-
  354. ;        CALL    CRLF
  355. ;        ....
  356. ;
  357. CRLF:
  358.     PUSH    H    ;SAVE HL
  359.     LXI    H,M2    ;GET CR/LF MESSAGE
  360.     CALL    MSG    ;TYPE MESSAGE
  361.     POP    H    ;RESTORE HL
  362.     RET        ;RETURN
  363. ;
  364. ;
  365. ;    TYPE ONE SPACE
  366. ;
  367. ;    CALLING SEQUENCE:-
  368. ;    CALL    BLANK
  369. ;    ....
  370. ;
  371. BLANK:
  372.     PUSH    PSW    ;SAVE PSW
  373.     MVI    A,' '    ;GET SPACE
  374.     CALL    TYPE    ;TYPE IT
  375.     POP    PSW    ;RESTORE PSW
  376.     RET        ;THEN RETURN
  377. ;
  378. ;    TYPE 'A' IN HEX
  379. ;    OUTPUTS THE 2-BIT HEX VALUE OF ACCUMULATOR
  380. ;    TO CONSOLE
  381. ;
  382. ;    CALLING SEQUENCE:-
  383. ;        LDA    DATA
  384. ;        CALL    THXB
  385. ;        ....
  386. ;
  387. THXB:
  388.     PUSH    PSW    ;SAVE PSW
  389.     RRC        ;SHIFT THE LEFT NYBBLE
  390.     RRC        ;INTO THE RIGHT NYBBLE
  391.     RRC        ;BY DOING 4 ROTATE RIGHTS.
  392.     RRC
  393.     CALL    THXN    ;TYPE HEX NYBBLE
  394.     POP    PSW    ;RESTORE DATA
  395. ;
  396. ;    TYPE 'A' B3-B0 IN ASCII
  397. ;    TYPES THE 1-BIT HEX VALUE OF THE BOTTOM 4 BITS
  398. ;    OF ACCUMULATOR.
  399. ;
  400. ;    CALLING SEQUENCE:-
  401. ;        LDA    DATA
  402. ;        CALL     THXN
  403. ;        ....
  404. ;
  405. THXN:
  406.     PUSH    PSW    ;SAVE PSW
  407.     ANI    0FH    ;ISOLATE B3-B0 (THROW AWAY B7-B4)
  408.     ADI    090H    ;ADJUST
  409.     DAA        ;NOW
  410.     ACI    040H    ;TO
  411.     DAA        ;ASCII
  412.     CALL    TYPE    ;BEFORE TYPING
  413.     POP    PSW    ;RESTORE PSW
  414.     RET        ;THEN RETURN
  415. ;
  416. ;
  417. ;    TYPE A WORD IN HEX
  418. ;    TYPES THE 4-BIT HEX VALUE OF THE 16-BIT VALUE
  419. ;    HELD IN THE HL REGISTER PAIR.
  420. ;
  421. ;    CALLING SEQUENCE:-
  422. ;        LHLD    WORD
  423. ;        CALL    THXW
  424. ;        ....
  425. ;
  426. THXW:
  427.     PUSH    PSW    ;SAVE PSW
  428.     MOV    A,H    ;GET HIGH BYTE FROM 'H'
  429.     CALL    THXB    ;AND TYPE IT
  430.     MOV    A,L    ;GET LOW BYTE FROM 'L' AND
  431.     CALL    THXB    ;TYPE IT TOO.
  432.     POP    PSW    ;RESTORE PSW
  433.     RET        ;I'M GOIN HOME
  434. ;
  435. ;    GET HEX CHR FROM CONSOLE
  436. ;    ROUTINE TO GET A SINGLE HEX NYBBLE FROM THE CONSOLE
  437. ;    IF THE DIGIT IS VALID (I.E. 0-9,A-F) THEN THE BINARY
  438. ;    VALUE IS RETURNED IN 'A' AND THE CARRY IS RESET.
  439. ;
  440. ;    HOWEVER, IF THE RESULT IS NON-HEX, THE BAD CHARACTER
  441. ;    WILL BE IN 'A' AND CARRY WILL BE SET.
  442. ;
  443. ;    CALLING SEQUENCE:-
  444. ;    CALL    GHXN
  445. ;    JC    NONHX        ;ERROR IF CARRY SET
  446. ;
  447. GHXN:
  448.     MVI    A,0FH    ;MASK TO KEEP ONLY THE RIGHT NYBBLE
  449.     JMP    GHB1
  450. ;
  451. ;    GET HEX BYTE FROM CONSOLE
  452. ;    SIMILAR TO GHXN, BUT RETURNS BYTE VALUE IF O.K.
  453. ;
  454. ;    CALLING SEQUENCE:-
  455. ;        CALL    GHXB
  456. ;        JC    NONHX    ;CHECK NO HEX I/P
  457. ;
  458. GHXB:
  459.     MVI    A,0FFH    ;MASK TO KEEP WHOLE BYTE.
  460. GHB1:
  461.     PUSH    H    ;SAVE HL
  462.     CALL    GHXW    ;GET HEX DATA VIA GHXW
  463.     JC    GHB2    ;PROVIDED THERE HAS BEEN NO ERROR,
  464.     ANA    L    ;WE CAN MASK THE NYBBLE/BYTE.
  465. GHB2:
  466.     POP    H    ;RESTORE HL
  467.     RET        ;RETURN TO CALLER
  468. ;
  469. ;    GET HEX WORD FROM CONSOLE
  470. ;    SIMILAR TO GHXN, BUT RETURNS BINARY WORD (16-BIT)
  471. ;    IN HL REG PAIR IF O.K.
  472. ;
  473. ;    CALLING SEQUENCE:-
  474. ;        CALL    GHXW
  475. ;        JC    NONHX    ;TEST NON HEX I/P
  476. ;        ....        ;RESULT IN HL
  477. ;
  478. GHXW:
  479.     PUSH    PSW    ;SAVE PSW
  480.     LXI    H,0    ;ZERO OUT THE  HL STORE
  481.     CALL    CHINN    ;GET FIRST CHARACTER, CONTROLLED ECHO
  482.     CALL    CNVBN    ;CONVERT IT TO BINARY NYBBLE
  483.     JC    GHW3    ;ANY NON-HEX IS ERROR FIRST TIME.
  484.     MOV    L,A    ;SAVE FIRST DIGIT
  485. GHW1:
  486.     CALL    CHINN    ;GET ANOTHER CHARACTER
  487.     CALL    CNVBN    ;AND CONVERT TO BINARY NYBBLE
  488.     JC    GHW2    ;AFTER FIRST DIGIT, CHECK FOR DELIMITER.
  489.     DAD    H    ;HL*2    ;WE WANT 1-NYBBLE LEFT SHIFT
  490.     DAD    H    ;HL*4    ;SO WE DOUBLE ADD HL
  491.     DAD    H    ;HL*8    ;TO ITSELF FOUR TIMES.
  492.     DAD    H    ;HL*16    ;N.B. TOP DIGIT IS LOST.
  493.     ADD    L    ;ALL DONE. ADD DIGIT TO LOWER BYTE
  494.     MOV    L,A    ;UPDATE THE LOWER BYTE.
  495.     JMP    GHW1    ;NEXT DIGIT PLEASE.
  496. GHW2:
  497.     CPI    CR    ;COMPARE WITH CR
  498.     JZ    GHW4
  499.     CPI    ' '    ;AND SPACE
  500.     JZ    GHW4    ;EITHER IS VALID DELIMITER.
  501. GHW3:
  502.     INX    SP    ;NON-HEX BAD BYTE IS RETURNED
  503.     INX    SP    ;IN A, WITH CARRY SET.
  504.     STC
  505.     RET
  506. GHW4:
  507.     POP    PSW    ;NORMAL EXIT, RESTORE PSW
  508.     ORA    A    ;WITH CARRY CLEARED.
  509.     RET
  510. ;
  511. ;    CNVBN:    CONVERT ASCII TO BINARY NYBBLE,
  512. ;        IS COMMON TO GHXN,GHXB,GHXW
  513. ;
  514. CNVBN:
  515.     CPI    '0'    ;FIRST SEE IF <'0'
  516.     RC
  517.     CPI    '9'+1    ;NOW SEE IF NUMERIC
  518.     JC    CNVB1    ;IT IS IF CARRY ON.
  519.     CPI    'A'    ;NOW TRY A-F
  520.     RC        ;ERROR RETURN IF CARRY SET
  521.     CPI    'F'+1    ;CHECK FOR >F
  522.     CMC        ;INVERT CARRY
  523.     RC        ;RETURN IF NOT OK.
  524.     SUI    7    ;A-F CHR FOUND. SUBTRACT 7
  525. CNVB1:
  526.     SUI    '0'    ;NOW MAKE INTO BINARY
  527.     RET        ;THEN RETURN
  528. ;
  529. ;    STORE BYTE IN MEMORY, WITH READ CHECK.
  530. ;    IF READ-BACK DOES NOT AGREE WITH STORE REQUEST AN
  531. ;    APPROPRIATE ERROR MESSAGE IS ISSUED.
  532. ;
  533. ;    CALLING SEQUENCE:-
  534. ;                ;DATA IN 'A', ADR IN 'HL'
  535. ;        CALL STORE
  536. ;        ....        ;RETURNS HERE IF O.K.
  537. ;                ;OTHERWISE RETURNS TO MONITOR.
  538. ;
  539. STORE:
  540.     MOV    M,A    ;STORE BYTE INTO MEMORY
  541.     CMP    M    ;COMPARE MEMORY WITH A
  542.     RZ        ;RETURN IF O.K.
  543.     PUSH    H    ;SUMTHIN IS WRONG.
  544.     LXI    H,M4    ;ISSUE ERROR MESSAGE
  545.     CALL    MSG    ;TO ADVISE USER
  546.     POP    H    ;RESTORE HL
  547.     JMP    RXAR    ;INDICATE ERROR LOC'N
  548. ;
  549. ;
  550. ;    MEMORY EXAMINE/MODIFY.
  551. ;
  552. ;    ENTER FROM MONITOR BY USING:-
  553. ;    A 1234
  554. ;    SETS 'ADR' TO '1234H', TYPES CURRENT CONTENTS THEN AWAITS :-
  555. ;
  556. ;    (1) VALID BYTE TO STORE, THEN BUMPS 'ADR'
  557. ;    (2) LF TO SIMPLY BUMP 'ADR'
  558. ;    (3) -  TO SIMPLY DECREMENT 'ADR'
  559. ;    (4) CR TO RETURN TO MONITOR
  560. ;    (5) .  TO RETYPE CURRENT ADR
  561. ;
  562. ;    IN ADDITION, AT ANY TIME THE USER MAY DIRECTLY
  563. ;    ENTER THIS ROUTINE WITH:-
  564. ;    (1) .  TO TYPE CONTENTS OF CURRENT 'ADR'
  565. ;    (2) -  TO TYPE CONTENTS OF PREVIOUS 'ADR'
  566. ;    (3) LF TO TYPE CONTENTS OF NEXT 'ADR'
  567. ;    ROUTINE THEN CONTINUES AS ABOVE.
  568. ;
  569. GETAD:
  570.     CALL    PUWA    ;GET ADR REQUIRED
  571.     XCHG
  572. ;
  573. GTA1:
  574.     SHLD    ADR    ;SAVE ADR
  575. LOCAT:
  576.     CALL    CRLF    ;CR/LF
  577.     LHLD    ADR    ;FETCH CURRENT ADR
  578.     CALL    THXW    ;TYPE CURRENT ADR
  579.     CALL    BLANK    ;FOLLOWED BY SPACE
  580.     MOV    A,M    ;FOLLOWED BY BYTE CONTENT
  581.     CALL    THXB
  582.     CALL    BLANK    ;YET ANOTHER SPACE
  583.     CALL    GHXB    ;LOOK FOR NEW BYTE
  584.     JC    NONHX    ;CHECK NON-HEX I/P
  585.     CALL    STORE    ;TRY TO STORE DATA BYTE
  586. NXLOC:
  587.     LHLD    ADR    ;PICK UP CURRENT ADR
  588.     INX    H    ;BUMP 1
  589.     JMP    GTA1    ;RESTART PROCESS OF ADR ACCESS.
  590. ;
  591. ;    ROUTINE 'TEND' IS CALLED FROM MONITOR OP-TAB
  592. ;    TABLE END ROUTINE
  593. ;
  594. TEND:
  595.     MOV    A,B    ;SET 'A' TO COMMAND
  596. NONHX:
  597.     CPI    LF    ;SEE IF CHARACTER WAS LF
  598.     JZ    NXLOC    ;IF SO, GET NEXT LOC'N
  599.     CPI    '.'    ;MAYBE IT WAS '.'
  600.     JZ    LOCAT    ;IF SO, GET SAME LOC'N
  601.     CPI    '-'    ;OR EVEN '-'
  602.     JZ    LSTLC    ;IN WHICH CASE, BACK UP 1 LOC'N
  603. NONH1:
  604.     CPI    CR    ;FINAL CHANCE IS CR
  605.     JZ    NEXT    ;WHICH MEANS EXIT THE COMMAND
  606. ;
  607. ;    IN THE EVENT THAT THE COMMAND IS NO GOOD,
  608. ;    ENTER HERE.
  609. ;
  610. ILLEG:
  611.     LXI    H,M3    ;ILLEGAL CALL, SEND QUERY MESSAGE.
  612. ILLG1:
  613.     CALL    MSG    ;TYPE IT, THEN
  614.     JMP    NEXT    ;'AVE ANOTHER GO.
  615. ;
  616. ;    PREVIOUS LOCATION REQUEST.
  617. ;
  618. LSTLC:
  619.     LHLD    ADR    ;BACKUP 1 BYTE
  620.     DCX    H
  621.     JMP    GTA1    ;AND TRY AGAIN.
  622. ;
  623. ;    NEGATE (2'S COMPLEMENT) 'DE' REG PAIR
  624. ;
  625. ;    CALLING SEQUENCE:-
  626. ;        ....        ;SET UP DE
  627. ;        CALL    NEGDE
  628. ;        ....        ;NOW DE=-DE
  629. ;
  630. NEGDE:
  631.     PUSH    PSW    ;SAVE PSW
  632.     MOV    A,D    ;FETCH D
  633.     CMA        ;COMPLEMENT IT
  634.     MOV    D,A    ;RESTORE
  635.     MOV    A,E    ;FETCH E
  636.     CMA        ;COMPLEMENT IT TOO
  637.     MOV    E,A    ;THE RESTORE
  638.     INX    D    ;NOW ADD 1 TO GET 2'S COMPL
  639.     POP    PSW    ;RESTORE PSW
  640.     RET        ;TAKE RESULTS HOME
  641. ;
  642. ;    DISPLAY BLOCK OF MEMORY ON CONSOLE.
  643. ;    CALLED FROM MONITOR AS:-
  644. ;    D XXXX YYYY
  645. ;    AFTER THE FIRST LINE, PRINTS XXXX TO YYYY IN
  646. ;    8/16 BYTE GROUPS STARTING WITH ADR,MOD 8/16
  647. ;    IF XXXX > YYYY ONLY PRINTS CONTENTS OF XXXX
  648. ;
  649. DISP:
  650.     CALL    PICKUP    ;GET ADDRESS RANGE.
  651. DMRET:
  652.     CALL    CRLF    ;NEW LINE
  653.     CALL    THXW    ;VECTOR ADR TO CONSOLE
  654. DMNXT:
  655.     CALL    BLANK    ;1 SPACE
  656.     MOV    A,M    ;GET DATA
  657.     CALL    THXB    ;TYPE IT
  658.     CALL    LAST    ;ALL DONE?
  659.     CALL    HOLD    ;NO. SEE IF HOLD REQUEST.
  660.     MOV    A,L    ;ADR MOD8/16?
  661.     ANI    OSET-1
  662.     JNZ    DMNXT    ;NO.
  663.     JMP    DMRET    ;YES. NEW LINE.
  664. ;
  665. ;    LOCAL ROUTINE TO TEST FOR HOLD REQUEST.
  666. ;    RETURNS IF NO CHARACTER IN INPUT BUFFER.
  667. ;    PUTS HOLD ON OUTPUT IF <SP> IS TYPED.
  668. ;    OTHERWISE RETURNS TO MONITOR.
  669. ;
  670. HOLD:
  671.     CALL    CSTS    ;GET CONSOLE STATUS.
  672.     RZ        ;ZERO. RETURN.
  673.     XRA    A    ;NON-ZERO.
  674.     CALL    CHINX    ;GET CHARACTER, NO ECHO.
  675.     CPI    ' '    ;TEST FOR SPACE
  676.     JNZ    NEXT    ;NO SPACE. PANIC.
  677.     JMP    GETCH    ;SPACE. AWAIT CONTINUE.
  678. ;
  679. ;    LOCAL ROUTINE TO PICK UP TWO ADDRESSES,
  680. ;    PUTTING THE FIRST ADDRESS INTO HL
  681. ;    AND THE NEGATED SECOND ADDRESS INTO DE
  682. ;
  683. PICKUP:
  684.     CALL    PUWA    ;FROM ADDRESS INTO DE
  685.     CALL    PUWA    ;FROM ADDRESS INTO HL,
  686.     JMP    NEGDE    ;NEGATED TO ADDRESS IN DE
  687. ;
  688. ;    JUMP TO ADDRESS WITH REG'S SET
  689. ;
  690. ;    CALLED FROM MONITOR BY:-
  691. ;    J 1234    JUMP TO SPECIFIED HEX ADR
  692. ;    J <CR>    JUMP TO ADR FROM LAST RST1
  693. ;    (USED AS BREAKPOINT IN PROGRAMS)
  694. ;    J <LF>    JUMP TO ADR SET UP BY 'X' COMMAND
  695. ;    J .    JUMP TO ADR SET BY LAST USE OF 'A' COMMAND
  696. ;
  697. ;    RESTORES REGISTERS TO STATE AS SAVED IN RAM ON ENTRY
  698. ;    TO THE MONITOR.
  699. ;    RESPONSES J <CR> , J <LF> AND J .   WILL TYPE
  700. ;    THE STORED ADDRESS BEFORE ASKING FOR OK TO PROCEED.
  701. ;
  702. ;    REMEMBER IF RST1 WAS USED, THAT THE RETURN ADDRESS MAY
  703. ;    NEED TO BE RESET WITH THE 'RP=' COMMAND TO GET YOU
  704. ;    BACK TO THE CALLING POINT.
  705. ;
  706. ;
  707. ;    GO DIRECT TO ADR FROM MONITOR.
  708. ;    IDENTICAL TO 'J' COMMAND, BUT DOES
  709. ;    NOT RESTORE REGISTERS.
  710. ;
  711. JUMP:
  712. GOTO:
  713.     PUSH    B    ;SAVE INPUT COMMAND
  714.     CALL    PUWB    ;GET ADR
  715.     JNC    JMP4    ;HEX ADR GIVEN
  716. JMP2:
  717.     LHLD    SVPC    ;ASSUME SAVED PC REQUIRED.
  718.     CPI    CR    ;SEE IF CR
  719.     JZ    JMP3
  720.     LHLD    XEQAD    ;NO. ASSUME 'X' ADDRESS REQUEST.
  721.     CPI    LF    ;TRY LF
  722.     JZ    JMP3    ;IF NOT,
  723.     LHLD    ADR    ;ONLY ALTERNATIVE IS 'ADR'
  724.     CPI    '.'    ;MUST BE '.'
  725.     JNZ    ILLEG    ;NO. PANIC.
  726. JMP3:
  727.     CALL    THXW    ;TYPE HEX ADR
  728. JMP4:
  729.     CALL    OKQ    ;IS THIS WHERE WE REALLY WANT TO GO?
  730.     SHLD    GOGO+1    ;YES. SET UP JUMP ADR
  731.     MVI    A,0C3H    ;THIS IS 'JMP' COMMAND
  732.     STA    GOGO    ;WHICH WE SET UP IN RAM
  733.     POP    PSW    ;RECOVER COMMAND CHARACTER.
  734.     CPI    'G'    ;WAS IT 'G' ?
  735.     JZ    GOGO    ;YES. IMMEDIATE JUMP TO PROGRAM.
  736.     LXI    SP,SVE    ;NO. RESTORE SP
  737.     POP    D    ;AND REGS
  738.     POP    B
  739.     POP    PSW
  740.     LHLD    SVSP    ;SAVED SP
  741.     SPHL        ;SET NEW SP
  742.     LHLD    SVHL    ;AND HL
  743.     JMP    GOGO    ;CUNNINGLY EXECUTE BUILT-UP JUMP
  744. ;
  745. ;    SET UP EXECUTION ADR FROM MONITOR BY:-
  746. ;    X 1234
  747. ;
  748. GETXA:
  749.     CALL    PUWA    ;GET ADR
  750.     XCHG        ;INTO HL
  751.     SHLD    XEQAD    ;PUT INTO XEQAD
  752.     JMP    NEXT    ;BACK TO MONITOR
  753. ;
  754. ;    LOCAL ROUTINE TO CHECK FOR LAST OPERATION.
  755. ;
  756. LAST:
  757.     PUSH    H    ;SAVE MEM VECTOR
  758.     DAD    D    ;ADD NEGATIVE ADDRESS
  759.     JC    NEXT    ;FINITO IF CARRY SET
  760.     POP    H    ;NO. RESTORE
  761.     INX    H    ;BUMP ADR
  762.     RET        ;RETURN
  763. ;
  764. ;    COMPARE TWO MEMORY BLOCKS, PRINT ANY DIFFERENCES.
  765. ;    USES 'MOVE' TO ALLOCATE THE BLOCK ADDRESSES.
  766. ;
  767. ;    MOVE MEMORY BLOCK FROM MONITOR BY:-
  768. ;    M XXXX YYYY ZZZZ
  769. ;
  770. ;    MOVES BLOCK XXXX TO YYYY INTO ZZZZ ONWARDS
  771. ;    TAKE CARE. WILL RESULT IN OVERWRITES IF ZZZZ IS
  772. ;    IN THE RANGE XXXX+1 TO YYYY
  773. ;    CAN BE USED AS A 'FILL' OPERATION BY PUTTING
  774. ;    ZZZZ=XXXX+1. LAST FILL OCCURS AT YYYY+1.
  775. ;
  776. KOMP:
  777. MOVE:
  778.     CALL    PUWA    ;GET XXXX
  779.     PUSH    D    ;SAVE ON STACK
  780.     CALL    PUWA    ;GET YYYY IN DE
  781.     CALL    PUWA    ;GET ZZZZ IN DE, YYYY GOES TO HL
  782.     XCHG        ;DE=Y HL=Z STACK=X
  783.     XTHL        ;DE=Y STACK=Z HL=X
  784.     CALL    NEGDE    ;NEGATE DE
  785.     MOV    A,B    ;GET COMMAND AND SEE
  786.     CPI    'M'    ;IF IT WAS 'M'
  787.     JNZ    KOMP1    ;JUMP IF IT WAS NOT.
  788.     CALL    OKQ    ;MOVE. ARE YOU SURE, USER?
  789. MOV1:
  790.     MOV    A,M    ;GET THRU X
  791.     XTHL        ;HL=Z STACK=X
  792.     CALL    STORE    ;STORE  AND CHECK
  793.     INX    H    ;BUMP Z
  794.     XTHL        ;RESTORE
  795.     CALL    LAST    ;END YET?
  796.     JMP    MOV1    ;NO.
  797. ;
  798. ;    REGISTER MODIFY/EXAMINE. FROM MONITOR BY:-
  799. ;
  800. ;    R <CR>    TYPE ALL REG CONTENTS
  801. ;    RA    ACCUMULATOR
  802. ;    RF    FLAGS,PSB
  803. ;    RB    REG B
  804. ;    RC    REG C
  805. ;    RD    REG D
  806. ;    RE    REG E
  807. ;    RH    REG H
  808. ;    RL    REG L
  809. ;    RS    STACK POINTER        ***
  810. ;    RP    PC IF MONITOR 'CALLED'    ***
  811. ;
  812. ; ***    NOTE:    RS, RP GIVE AND EXPECT 4-HEX DIGITS
  813. ;
  814. RXLST:    DB    'AFBCDEHL',0    ;REGISTER LIST
  815. ;
  816. REGEX:
  817.     CALL    CHIN    ;GET REGISTER IDENTIFIER
  818.     CPI    CR    ;IS IT CR?
  819.     JZ    REXAL    ;YEP.
  820.     PUSH    PSW    ;NO. SAVE PSW
  821.     MVI    A,'='
  822.     CALL    TYPE    ;TYPE A '='
  823.     POP    PSW    ;RESTORE IDENT
  824.     LXI    D,SVPC    ;ADR OF P.C.
  825.     CPI    'P'    ;SEE IF PC REQUEST
  826.     JZ    RX2    ;YES.
  827.     INX    D    ;POINT TO SP
  828.     INX    D
  829.     CPI    'S'    ;IS IT 'S'
  830.     JZ    RX2    ;YES.
  831.     MOV    B,A    ;NO. SAVE ID IN B
  832.     LXI    H,RXLST    ;LIST VECTOR ADR
  833.     LXI    D,SVA    ;ADR OF 'A' STORE
  834. RX0:
  835.     MOV    A,M    ;GET TABLE ID
  836.     ANA    A    ;CHECK FOR END (0)
  837.     JZ    ILLEG    ;YES. ILLEGAL REQUEST
  838.     CMP    B    ;COMPARE WITH REQUEST
  839.     JZ    RX1    ;FOUND?
  840.     INX    H    ;NO. NEXT ENTRY
  841.     DCX    D    ;NEXT REG
  842.     JMP    RX0    ;NEXT TRY.
  843. ;
  844. RX1:
  845.     LDAX    D    ;GET REG
  846.     CALL    THXB    ;TYPE IT OUT
  847.     CALL    BLANK    ;FOLLOWED BY SPACE
  848.     CALL    GHXB    ;GET RESPONSE
  849.     JC    NONH1    ;NON-HEX. TRY CR LATER
  850.     STAX    D    ;STORE INPUT IN REG
  851.     JMP    NEXT    ;BACK HOME, JAMES.
  852. ;
  853. RX2:
  854.     XCHG        ;REG ADR TO HL
  855.     MOV    E,M    ;LOW S OR P
  856.     INX    H    ;BUMP VECTOR
  857.     MOV    D,M    ;HI S OR P
  858.     XCHG        ;REG VAL IN HL
  859.     CALL    THXW    ;TYPE HEX WORD
  860.     CALL    PUWB    ;GET CHANGE.
  861.     JC    NONH1    ;NON-HEX JUMP
  862.     XCHG        ;RESTORE RAM VECTOR
  863.     MOV    M,D    ;STORE HI S OR P
  864.     DCX    H    ;DROP VECTOR
  865.     MOV    M,E    ;STORE LO S OR P
  866.     JMP    NEXT    ;RETURN
  867. RXTSE:
  868.     CALL    BLANK    ;SPACE
  869.     CALL    TYPE    ;TYPE THE ID.
  870.     MVI    A,'='
  871.     JMP    TYPE    ;EQUALS
  872. ;
  873. REXAL:
  874.     LXI    D,SVA    ;ADR OF 'A'
  875.     LXI    H,RXLST    ;ID LIST
  876. RXA1:
  877.     MOV    A,M    ;GET ID
  878.     ANA    A    ;LAST YET? (0)
  879.     JZ    RXA2    ;YES
  880. ;
  881. ;    THIS LITTLE BIT OF CODE GOES IN ONLY IF WE ARE MAKING
  882. ;    A 32 COLUMN CONFIGURED DISPLAY MONITOR.
  883. ;
  884.     IF    COLSW
  885.     CPI    'E'    ;SEE IF NEXT REGISTER IS 'E'
  886.     CZ    CRLF    ;IF SO, NEXT LINE PLEASE,
  887.     ENDIF
  888. ;
  889. ;    THE ALTERNATIVE IS A 5-BYTE DUMMY PATCH.
  890. ;
  891.     IF    NOT COLSW
  892.     NOP
  893.     NOP
  894.     NOP
  895.     NOP
  896.     NOP
  897.     ENDIF
  898. ;
  899.     CALL    RXTSE    ;TYPE ' ',ID,'='
  900.     LDAX    D    ;GET REG
  901.     DCX    D    ;DROP REG PTR
  902.     INX    H    ;BUMP LIST PTR
  903.     CALL    THXB    ;TYPE CONTENTS
  904.     JMP    RXA1    ;NEXT PLEASE.
  905. RXA2:
  906.     MVI    A,'P'    ;DO PC
  907.     CALL    RXTSE
  908.     LHLD    SVPC    ;GET PC
  909.     CALL    THXW    ;TYPE PC
  910.     MVI    A,'S'    ;NOW DO SP
  911.     CALL    RXTSE
  912.     LHLD    SVSP    ;GET SP
  913. RXAR:
  914.     CALL    THXW    ;TYPE VALUE
  915.     JMP    NEXT    ;RETURN TO MOM.
  916. ;
  917. ;    HEX WORD PICKUPS.
  918. ;    PUWA GETS WORD, AND RETURNS TO MONITOR IF ERROR.
  919. ;    IF NOT PUTS RESULT IN 'DE'.
  920. ;
  921. PUWA:
  922.     CALL    PUWB    ;GET A HEX WORD
  923.     JC    ILLEG    ;BADDY OUT HERE
  924.     XCHG        ;SAVE INTO DE
  925.     RET        ;RETURN
  926. ;
  927. ;    PUWB GETS WORD INTO 'HL' WITHOUT CHECK.
  928. ;
  929. PUWB:
  930.     CALL    BLANK    ;TYPE A BLANK FIRST.
  931.     JMP    GHXW    ;NOW GET THE WORD.
  932. ;
  933. ;    PAUSE GENERATOR.
  934. ;    TYPES THE MESSAGE 'PAUSE' THEN AWAITS ANY KEYSTRIKE
  935. ;    (NO ECHO) BEFORE CONTINUING.
  936. ;
  937. PWAIT:
  938.     PUSH    H    ;SAVE HL
  939.     LXI    H,M5    ;MESSAGE 'PAUSE'
  940.     CALL    MSG
  941.     POP    H    ;RECOVER
  942.     JMP    GETCH    ;ANY RESPONSE WILL DO.
  943. ;
  944. ;    MONITOR OR USER VERIFY ROUTINE OK?
  945. ;    CALLING SEQUENCE:-
  946. ;        CALL    OKQ
  947. ;        ....        ;GOES HERE IF RESPONSE IS SP
  948. ;                ;OTHERWISE ABORTS.
  949. ;
  950. OKQ:
  951.     PUSH    PSW    ;SAVE PSW
  952.     PUSH    H    ;AND HL
  953.     LXI    H,M7    ;ADR OF 'OK?' MESSAGE
  954.     CALL    MSG    ;PRINT IT
  955.     LXI    H,M8    ;PREPARE TO ABORT
  956.     CALL    GETCH    ;USER'S REPLY
  957.     ANI    7FH    ;MASK OUT PARITY.
  958.     CPI    ' '    ;TRY ' '
  959.     JNZ    ILLG1    ;NO. ABORT
  960.     POP    H    ;YES. RESTORE HL
  961.     POP    PSW    ;AND PSW
  962.     RET        ;AND GO ON.
  963. ;
  964. ;    ECHO ON/OFF CONTROLLER.
  965. ;
  966. ;    CALLING SEQUENCE:-
  967. ;        MVI    A,XX    ;XX=0 FOR OFF
  968. ;                ;XX<>0 FOR ON
  969. ;        CALL    ECHCN
  970. ;        ....        ;NOW SET/RESET.
  971. ;
  972. ECHCN:
  973.     STA    ECHO    ;STORE REQUIRED VALUE
  974.     RET
  975. ;
  976. ;    SYSTEM I/O ROUTINES
  977. ;
  978. ;******* THIS VERSION SUITS JADE PSI/O SYSTEM HARDWARE *******
  979. ;
  980. ;    USER MUST PUT HIS OWN CONSOLE DRIVER IN HERE
  981. ;    IF DIFFERENT TO THE VERSION SHOWN
  982. ;
  983. ;
  984. ;    TYPE A CHARACTER.
  985. ;    CALLING SEQUENCE:-
  986. ;        LDA    CHR
  987. ;        CALL    TYPE    ;TYPE IT
  988. ;        ....
  989. ;
  990. ;
  991. ;    ROUTINE CO IS A PATCH FOR SBC80/SDK80 SYSTEMS
  992. ;    WHICH PASS ARGUMENT IN 'C'
  993. ;
  994. CO:
  995.     MOV    A,C    ;PUT ARGUMENT INTO A
  996. TYPE:
  997.     PUSH    PSW    ;SAVE CONTENTS OF 'A'
  998. TYP1:
  999.     IN    CONST    ;GET CONSOLE STATUS
  1000.     ANI    TRDY    ;ZERO INDICATES BUSY.
  1001.     JZ    TYP1    ;IF SO, TRY AGAIN.
  1002.     POP    PSW    ;CLEAR. RESTORE 'A'
  1003.     OUT    CNOUT    ;OUTPUT TO 'CNOUT'
  1004.     RET
  1005. ;
  1006. ;    RETRIEVE CHARACTER FROM CONSOLE
  1007. ;    PARITY IS KEPT, BUT NO ECHO GIVEN.
  1008. ;    CALLING SEQUENCE:-
  1009. ;        CALL    GETCH    ;GET CHARACTER
  1010. ;        ....        ;CHARACTER IN 'A'
  1011. ;
  1012. ;
  1013. ;    NOTE: THIS IS ALSO THE ENTRY POINT FOR SDK80/SBC80
  1014. ;    ROUTINE CI.
  1015. ;
  1016. CI:
  1017. GETCH:
  1018.     CALL    CSTS    ;GET CONSOLE STATUS
  1019.     JZ    GETCH    ;IF SO, TRY AGAIN.
  1020.     IN    CNIN    ;READY. GET A CHARACTER.
  1021.     RET        ;RETURN WITH CHAR IN 'A'
  1022. ;
  1023. ;    CONSOLE STATUS ROUTINE. CALLED BY DISP AND PUNCH
  1024. ;    TO ALLOW STOPPING OF OUTPUT BY TYPING ANY CHAR.
  1025. ;    THE BREAK CHARACTER IS THE FIRST CHARACTER INPUT
  1026. ;    TO THE MONITOR AFTER RETURN.
  1027. ;    (IDEAL BREAK CHARACTER IS <SP>. RESULTS IN MONITOR QUERY)
  1028. ;
  1029. CSTS:
  1030.     IN    CONST    ;GET CONSOLE STATUS
  1031.     ANI    RBR    ;INPUT BUFFER READY?
  1032.     RET        ;RETURN
  1033. ;
  1034. ;
  1035. ;    SYSTEM MESSAGES.
  1036. ;
  1037. M0:    DB    CR,LF,'UPG80 V3:1'
  1038. M1:    DB    CR,LF,'* ',0FFH
  1039. M2:    DB    CR,LF,0FFH
  1040. M3:    DB    ' ??',0FFH
  1041. M4:    DB    CR,LF,'MEMORY ERR @ ',0FFH
  1042. M5:    DB    ' PAUSE ',0FFH
  1043. M7:    DB    ' OK? ',0FFH
  1044. M8:    DB    'ABORT',0FFH
  1045.     ORG    ROM+0400H
  1046. ;
  1047. M6:    DB    ' CKS ERR @ ',0FFH
  1048. M10:    DB    CR,LF,'B/P @ ',0FFH
  1049. ;
  1050. ;    SEARCH MEMORY FOR A GIVEN BYTE.
  1051. ;    CALLED FROM MONITOR BY:-
  1052. ;    S XXXX YYYY VV
  1053. ;
  1054. ;    WHERE   XXXX=  STARTING ADDRESS FOR SEARCH
  1055. ;        YYYY=  FINISHING ADDRESS FOR SEARCH
  1056. ;          VV=  BYTE TO BE FOUND
  1057. ;
  1058. ;
  1059. SEARCH:
  1060.     CALL    PICKUP    ;GET BLOCK ADDRESSES.
  1061.     CALL    GBYTE    ;NOW SPACE AND BYTE REF.
  1062.     MOV    B,A    ;SAVE IT IN 'B'
  1063.     CALL    SRC4    ;START A NEW LINE
  1064. SRC1:
  1065.     CALL    HOLD    ;SEE IF HOLD CALLED.
  1066.     MOV    A,M    ;GET COMPARE.
  1067.     CMP    B    ;COMPARE BYTE WITH MEMORY
  1068.     CZ    SRC3    ;PRINT ADDRESS IF EQUAL.
  1069. SRC2:
  1070.     CALL    LAST    ;NOW SEE IF ALL DONE.
  1071.     JMP    SRC1    ;IF NOT, CONTINUE SEARCH
  1072. ;
  1073. ;    SRC3    PRINTS ADDRESS
  1074. ;    SRC4    SETS UP FOR NEW LINE.
  1075. ;
  1076. SCNT    EQU    OSET/2
  1077. ;
  1078. SRC3:
  1079.     CALL    BLANK    ;ONE SPACE PLEASE,
  1080.     CALL    THXW    ;FOLLOWED BY THE ADDRESS.
  1081.     DCR    C    ;DECREMENT THE LINE COUNT
  1082.     RNZ        ;RETURN PRONTO IF NOT FULL.
  1083. SRC4:
  1084.     CALL    CRLF    ;START ON NEW LINE,
  1085.     MVI    C,SCNT    ;LOAD SEARCH COUNTER.
  1086.     RET        ;THEN CONTINUE ON OUR MERRY WAY.
  1087. ;
  1088. ;    COMPARE MEMORY. STARTED OUT IN 'MOVE' FUNCTION WHERE
  1089. ;    IT GOT THE ADDRESSES.
  1090. ;    CALLED FROM THE MONITOR BY:-
  1091. ;    K XXXX YYYY ZZZZ
  1092. ;        WHERE XXXX=START ADDR OF FIRST BLOCK
  1093. ;              YYYY=STOP ADDR OF FIRST BLOCK
  1094. ;              ZZZZ=START ADDR OF SECOND BLOCK
  1095. ;    PRINTS OUT ALL OCCURRENCES OF INEQUALITY.
  1096. ;
  1097. KOMP1:
  1098.     CALL    HOLD    ;SEE IF HOLD REQUESTED.
  1099.     MOV    A,M    ;GET FIRST BLOCK BYTE.
  1100.     XTHL        ;SWAP HL AND T.O.S.
  1101.     CMP    M    ;NOW COMPARE WITH SECOND BYTE
  1102.     JZ    KOMP2    ;SKIP IF ALL THE SAME.
  1103.     CALL    SRC4    ;NEW LINE FIRST
  1104.     XTHL        ;SWAP POINTERS
  1105.     CALL    KOMP3    ;FIRST ADDR/BYTE
  1106.     XTHL        ;SWAP THEM BACK
  1107.     MOV    A,M    ;SECOND BYTE IN.
  1108.     CALL    KOMP3    ;PRINT THEM TOO.
  1109. KOMP2:
  1110.     INX    H    ;BUMP THE SECOND ADDRESS
  1111.     XTHL        ;BACK WHERE WE STARTED.
  1112.     CALL    LAST    ;SEE IF ALL DONE.
  1113.     JMP    KOMP1
  1114. KOMP3:
  1115.     CALL    SRC3    ;PRINT SPACE AND ADDRESS.
  1116.     CALL    BLANK    ;A SPACE
  1117.     JMP    THXB    ;THEN BYTE VALUE
  1118. ;
  1119. ;
  1120. ;    ZERO OUT A BLOCK OF MEMORY.
  1121. ;    CALLED FROM MONITOR BY:-
  1122. ;    Z XXXX YYYY
  1123. ;    (THE VALUE VV=0 FOR THIS FUNCTION)
  1124. ;
  1125. ;
  1126. ;    FILL BLOCK WITH A VALUE. MONITOR CALL BY:-
  1127. ;
  1128. ;    F XXXX YYYY VV
  1129. ;
  1130. ;    CAUSES MEMORY LOCATIONS XXXX THRU YYYY TO BE
  1131. ;    SET TO THE VALUE VV.
  1132. ;
  1133. ZERO:
  1134. FILL:
  1135.     CALL    PICKUP    ;GET BLOCK ADDRESSES.
  1136.     MOV    A,B    ;GRAB THE COMMAND BYTE (F OR Z)
  1137.     CPI    'Z'    ;COMPARE WITH 'Z'
  1138.     MVI    A,0    ;ASSUME ZERO REQUESTED, THEN
  1139.     JZ    FILL0    ;JUMP IF TRUE.
  1140.     CALL    GBYTE    ;ELSE GET THE FILLING BYTE.
  1141. FILL0:
  1142.     CALL    OKQ    ;VERIFY FILL/ZERO REQUEST
  1143. FILL1:
  1144.     CALL    STORE    ;STORE AND CHECK
  1145.     CALL    LAST    ;END IN SIGHT?
  1146.     JMP    FILL1    ;NOT YET.
  1147. ;
  1148. ;****    GET BYTE WITH TEST.
  1149. ;
  1150. GBYTE:
  1151.     CALL    BLANK    ;LEADING BLANK
  1152.     CALL    GHXB    ;THEN THE BYTE.
  1153.     JC    ILLEG    ;TEST LEGALITY.
  1154.     RET
  1155. ;
  1156. ;    USER DEFINABLE ROUTINES.
  1157. ;    CALLED FROM MONITOR BY:-
  1158. ;    U XXXX        ;DEFINE USER CALL ADDRESS.
  1159. ;    U <SP>        ;GO TO USER ADDRESS.
  1160. ;    (IF XXXX=0 THEN USER CALL IS CLEARED)
  1161. ;
  1162. USER:
  1163.     CALL    BLANK    ;PUT IN A SPACE,
  1164.     CALL    GHXW    ;THEN GO FOR THE ADDRESS, IF ANY.
  1165.     JC    USER2    ;SEE IF CARRY SET (BAD DATA?)
  1166.     SHLD    USERA    ;NO. ADDRESS SET.
  1167.     JMP    NEXT
  1168. USER2:
  1169.     CPI    ' '    ;CARRY SET. SEE IF USER CALL REQUEST.
  1170.     JNZ    ILLEG    ;IF NOT, PANIC
  1171.     LHLD    USERA    ;YES. GET THE ADDRESS.
  1172.     MOV    A,L    ;NOW SEE IF LEGAL ADDRESS BY
  1173.     ORA    H    ;LOOKING FOR NON-ZERO ADDRESS.
  1174.     JZ    ILLEG
  1175.     PCHL        ;ALL O.K. GO THERE.
  1176. ;
  1177. ;
  1178. ;
  1179. ;    ROUTINES TO PUNCH AND LOAD MEMORY.
  1180. ;    INTEL STANDARD HEX OBJECT TAPE FORMAT IS USED.
  1181. ;
  1182. ;    RECORD START    :
  1183. ;    BYTE COUNT    2-CHARS
  1184. ;    LOAD ADR    4-CHARS
  1185. ;    RECORD TYPE    2-CHARS    0=DATA 1=EOF
  1186. ;    DATA BYTES    (2-CHARS/BYTE)
  1187. ;    CHECKSUM FROM BYTE-COUNT TO END OF DATA
  1188. ;    (ALL CHARACTERS MUST BE HEX LEGITIMATE  0-9,A-F)
  1189. ;
  1190. ;    EOF RECORD MAY CONTAIN EXECUTION ADR.
  1191. ;    LOADER GOES TO ADR IF NON-ZERO
  1192. ;
  1193. PUNCH:
  1194.     CALL    PUWA    ;FROM ADR
  1195.     CALL    PUWA    ;TO ADR
  1196.     CALL    PWAIT    ;AWAIT READINESS
  1197. ;
  1198. ;    HL=FIRST ADR    DE=LAST ADR
  1199. ;
  1200. PN0:
  1201.     MOV    A,L    ;GET LOW PART OF START ADR
  1202.     ADI    OSET    ;INCREMENT BY 8/16
  1203.     MOV    C,A    ;HOLD IN 'C'
  1204.     MOV    A,H    ;GET HIGH PART OF START ADR
  1205.     ACI    0    ;TAKE CARE OF ANY O'FLOW
  1206.     MOV    B,A    ;HOLD IN 'B'
  1207.     MOV    A,E    ;NOW LOW PART OF FINAL ADR
  1208.     SUB    C    ;SUBTRACT LOW START
  1209.     MOV    C,A    ;PUT IN 'C'
  1210.     MOV    A,D    ;HIGH PART END ADR.
  1211.     SBB    B    ;SUBTRACT FROM START.
  1212.     JC    PN1    ;JUMP IF <OSET LEFT.
  1213.     MVI    A,OSET
  1214.     JMP    PN2
  1215. PN1:
  1216.     MOV    A,C    ;SET UP FINAL COUNT.
  1217.     ADI    OSET+1    ;WENT NEGATIVE, ADD 9/17
  1218. PN2:
  1219.     ORA    A    ;SET FLAGS.
  1220.     JZ    PDONE
  1221.     PUSH    D    ;SAVE HI
  1222.     MOV    E,A    ;LENGTH IN E
  1223.     CALL    PN3    ;PUNCH HEADER RECORD PARTS.
  1224.     JMP    PN4
  1225. PN3:
  1226.     CALL    CCRLF
  1227.     MVI    D,0    ;CLEAR CKSUM COUNTER.
  1228.     MVI    A,':'    ;PUNCH HEADER
  1229.     CALL    CTYPE
  1230.     MOV    A,E
  1231.     CALL    PBYTE    ;PUNCH LENGTH
  1232.     MOV    A,H
  1233.     CALL    PBYTE    ;PUNCH ADR HI
  1234.     MOV    A,L
  1235.     JMP    PBYTE    ;PUNCH ADR LO
  1236. PN4:
  1237.     XRA    A    ;CLEAR A
  1238.     CALL    PBYTE    ;RECORD TYPE=0
  1239. PN5:
  1240.     MOV    A,M    ;GET DATA
  1241.     INX    H
  1242.     CALL    PBYTE    ;FOR PUNCHING
  1243.     DCR    E    ;DROP COUNT BY 1
  1244.     JNZ    PN5    ;NOT DONE YET
  1245.     XRA    A    ;NOW FIND CKSUM
  1246.     SUB    D    ;AS 2'S COMPL OF 8-BIT SUM
  1247.     CALL    PBYTE    ;PUNCH IT
  1248.     POP    D    ;RESTORE HI ADR
  1249.     JMP    PN0    ;GO AGAIN
  1250. ;
  1251. ;    BYTE PUNCHER.
  1252. ;
  1253. PBYTE:
  1254.     PUSH    PSW    ;HOLD ONTO A,PSB
  1255.     CALL    CSTS    ;SEE IF USER PANICED.
  1256.     JNZ    NEXT
  1257.     POP    PSW    ;IF NOT, GO ON.
  1258.     CALL    CTHXB
  1259.     ADD    D    ;UPDATE CKSUM
  1260.     MOV    D,A
  1261.     RET        ;GO AGAIN
  1262. ;
  1263. ;    ALL DONE NOW.
  1264. ;
  1265. PDONE:
  1266.     CALL    CCRLF
  1267. PDON1:
  1268.     JMP    NEXT    ;RETURN TO MOMMA
  1269. ;
  1270. ;    PUNCH AN END OF FILE.
  1271. ;
  1272. PEND:
  1273.     CALL    PUWB    ;ADR OR CR
  1274.     JNC    PEND1    ;GO IF ADR
  1275.     LXI    H,0    ;ASSUME CR, PUT ADR=0
  1276.     CPI    CR    ;WAS IT CR?
  1277.     JNZ    ILLEG    ;IF NOT, ITS ILLEGAL
  1278. PEND1:
  1279.     CALL    PWAIT    ;AWAIT PROMPT
  1280.     MVI    E,0    ;ZERO LENGTH
  1281.     CALL    PN3
  1282.     MVI    A,1    ;RECORD TYPE=1
  1283.     CALL    PBYTE
  1284.     XRA    A
  1285.     SUB    D    ;CALCULATE THE CKSUM
  1286.     CALL    PBYTE    ;PUNCH IT.
  1287. ;
  1288. ;    PUNCH 100 NULLS
  1289. ;
  1290. NULLS:
  1291.     MVI    C,100    ;WE WILL PUNCH 100 NULLS (10 INCHES)
  1292.     XRA    A
  1293. NLS1:
  1294.     CALL    CTYPE
  1295.     DCR    C
  1296.     JNZ    NLS1    ;MORE TO GO?
  1297.     JMP    PDON1    ;NO. RETURN
  1298. ;
  1299. NULL:
  1300.     CALL    PWAIT    ;THIS ENTRY VIA COMMAND 'N'
  1301.     JMP    NULLS    ;FOLLOWED RAPIDLY BY NULLS.
  1302. ;
  1303. ;    LOAD HEX OBJECT TAPE.
  1304. ;
  1305. ;    MONITOR COMMAND 'L'
  1306. ;    LOAD A HEX-BINARY TAPE AS PRODUCED BY THE 'P'
  1307. ;    COMMAND.
  1308. ;    MAY CONTAIN AN OFFSET VALUE, ALLOWING THE DATA TO
  1309. ;    BE LOADED INTO A DIFFERENT LOCATION TO THAT SPECIFIED
  1310. ;    BY THE LOAD ADDRESS.
  1311. ;    E.G.    L 1000   WILL CAUSE THE LOADED DATA TO BE
  1312. ;    1000H LOCATIONS HIGHER THAN THAT SPECIFIED BY
  1313. ;    THE BLOCK LOAD ADDRESS.
  1314. ;
  1315. ;
  1316. LOAD:
  1317.     CALL    PUWB    ;GET THE OFFSET, IF ANY.
  1318.     JNC    LD4
  1319.     CPI    CR    ;ERROR MAY ONLY BE <CR>
  1320.     JNZ    ILLEG
  1321. LD4:
  1322.     XRA    A    ;PREPARE TO
  1323.     CALL    ECHCN    ;RESET ECHO.
  1324.     CALL    CRLF    ;NEW LINE PLEASE.
  1325.     PUSH    H    ;SAVE BIAS ADR
  1326. LD5:
  1327.     POP    H    ;GET BIAS
  1328.     PUSH    H    ;AND RESTORE
  1329.     CALL    RIX    ;GET INPUT
  1330.     MVI    B,':'    ;WAIT FOR ':'
  1331.     SUB    B
  1332.     JNZ    LD5    ;TRY AGAIN
  1333.     MOV    D,A    ;CLEAR CKSUM
  1334.     CALL    BYTE    ;GET LENGTH
  1335.     JZ    LD7    ;ZERO MEANS ALL DONE
  1336.     MOV    E,A    ;SAVE LENGTH
  1337.     CALL    BYTE
  1338.     PUSH    PSW    ;SAVE HI ADR
  1339.     CALL    BYTE
  1340.     POP    B    ;FETCH MSBYTE
  1341.     MOV    C,A    ;BC NOW HAS ADR
  1342.     PUSH    B    ;SAVE IT
  1343.     XTHL        ;INTO HL
  1344.     SHLD    BLKAD    ;SAVE BLOCK ADR
  1345.     XTHL        ;IN CASE OF ERROR
  1346.     POP    B
  1347.     DAD    B    ;RESTORE AND ADD BIAS
  1348.     CALL    BYTE    ;RECORD TYPE INPUT
  1349. LD6:
  1350.     CALL    BYTE    ;GET DATA BYTES
  1351.     CALL    STORE    ;STORE
  1352.     INX    H
  1353.     DCR    E
  1354.     JNZ    LD6    ;GO ON.
  1355.     CALL    BYTE    ;GET CKSUM
  1356.     JZ    LD5
  1357. LDERR:
  1358.     LXI    H,M6    ;CKSUM ERROR
  1359.     CALL    MSG
  1360.     LHLD    BLKAD    ;ADR OF THIS BLOCK IS
  1361.     JMP    RXAR    ;NOW GIVEN
  1362. LD7:
  1363.     CALL    BYTE    ;MSB OF XEQAD
  1364.     MOV    H,A
  1365.     CALL    BYTE
  1366.     MOV    L,A
  1367.     ORA    H
  1368.     JZ    NEXT    ;MONITOR IF ADR=0
  1369.     PCHL        ;OTHERWISE EXECUTE
  1370. ;
  1371. RIX:
  1372.     CALL    RI
  1373.     JC    ILLEG    ;ON ERROR, PRINT '??'
  1374.     ANI    7FH    ;REMOVE PARITY
  1375.     RET
  1376. ;
  1377. ;    ROUTINE RI
  1378. ;    GETS A CHARACTER FROM THE CASSETTE READER INPUT
  1379. ;
  1380. ;
  1381. RI:
  1382.     PUSH    B    ;SAVE BC
  1383.     LXI    B,TMOUT    ;GET TIMEOUT (MILLISECONDS)
  1384. RI10:
  1385.     CALL    CASTS    ;GET READER STATUS
  1386.     JNZ    RI15    ;READY ON NON-ZERO
  1387.     CALL    DELAY    ;IF NOT, DELAY 1 MS
  1388.     DCX    B    ;DECREMENT DELAY COUNT
  1389.     MOV    A,B    ;SEE IF IT
  1390.     ORA    C    ;IS ZERO YET.
  1391.     JNZ    RI10    ;TRY AGAIN IF NOT DONE
  1392.     STC        ;SET ERROR CARRY
  1393.     POP    B    ;RESTORE BC
  1394.     RET        ;TROUBLED RETURN
  1395. RI15:
  1396.     CALL    CGETCH    ;GET DATA.
  1397.     ORA    A    ;CLEAR CARRY ONLY.
  1398.     POP    B    ;RESTORE BC
  1399.     RET        ;SIMPLY RETURN
  1400. ;
  1401. BYTE:
  1402.     PUSH    B    ;SAVE BC
  1403.     CALL    RIX    ;READ ASCII
  1404.     CALL    CNVBN    ;CONVERT TO HEX
  1405.     JC    LDERR    ;ERROR DETECTOR.
  1406.     RLC        ;SHIFT LEFT 4 BITS
  1407.     RLC
  1408.     RLC
  1409.     RLC
  1410.     MOV    B,A    ;SAVE THEM A WHILE
  1411.     CALL    RIX    ;GET SECOND BYTE
  1412.     CALL    CNVBN    ;CONVERT TO HEX
  1413.     JC    LDERR    ;ERROR DETECTOR
  1414.     ORA    B    ;OR IN THE SAVED NYBBLE
  1415.     MOV    C,A    ;HOLD BYTE A WHILE.
  1416.     ADD    D    ;ADD TO CKSUM
  1417.     MOV    D,A    ;UPDATE CKSUM
  1418.     MOV    A,C    ;RESTORE BYTE
  1419.     POP    B    ;RESTORE BC
  1420.     RET
  1421. ;
  1422. ; FUNCTION DELAY.
  1423. ;    CAUSES THE SYSTEM TO DELAY FOR 1 MS.
  1424. ;
  1425. DELAY:
  1426.     PUSH    B    ;SAVE BC
  1427.     MVI    B,ONEMS    ;GET ONE MS LOOP COUNT
  1428. DEL2:
  1429.     DCR    B    ;DECREMENT LOOP COUNT
  1430.     JNZ    DEL2    ;NOT YET DONE.
  1431.     POP    B    ;ALL DONE. GET BC
  1432.     RET        ;RETURN TO PATIENT WAITER.
  1433. ;    ENTER HERE FOLLOWING A SOFTWARE RST2
  1434. ;    I.E. BREAKPOINT SETTING.
  1435. ;
  1436. BPAT:
  1437.     SHLD    SVPC    ;STORE CALLING PC
  1438.     STA    TMPA    ;AND CARRY (IN B7)
  1439.     RAL        ;THEN ROTATE BACK THE ACC.
  1440.     LXI    H,0    ;NOW TRANSFER THE SP TO HL BY DOING A DUMMY
  1441.     DAD    SP    ;ADD TO HL. (N.B. CLEARS CARRY)
  1442.     SHLD    SVSP    ;SAVE THE CALLER SP.
  1443.     LXI    SP,SVA+1    ;PICK UP REG STORE POINTER
  1444.     PUSH    PSW    ;TO SAVE PSW
  1445.     PUSH    B    ;AND BC
  1446.     PUSH    D    ;AND DE. (HL ALREADY SAVED)
  1447.     LXI    H,SVF    ;GET THE PSB BYTE
  1448.     LDA    TMPA    ;PICK UP THE CARRY HOLDER,
  1449.     RAL        ;ROTATE IT BACK TO CARRY.
  1450.     JNC    BP1    ;SKIP IF CARRY NOT SET,
  1451.     INR    M    ;OTHERWISE RESET CARRY.
  1452. BP1:
  1453.     LXI    SP,STACK    ;SET SP TO MONITOR STACK
  1454.     LXI    H,M10    ;TYPE BREAKPOINT MESSAGE
  1455.     CALL    MSG
  1456.     LHLD    SVPC    ;PICK-UP THE BREAK ADDRESS + 1
  1457.     DCX    H    ;MAKE IT THE REAL ADDRESS.
  1458.     SHLD    SVPC    ;RESET THE SAVED PC STORE
  1459.     CALL    THXW    ;TELL THE USER WHERE HE BROKE.
  1460.     CALL    CRLF    ;NEXT LINE PLEASE.
  1461.     JMP    REXAL    ;NOW PRINT THE REGISTER DATA.
  1462. ;
  1463. ;
  1464. ;
  1465. ;    CONTINUE AFTER A BREAKPOINT HALT
  1466. ;
  1467. ;    ASSUMES THAT THE LOCATION OF THE B/P HAS BEEN ALTERED
  1468. ;    BY A PRIOR
  1469. ;        B XXXX    COMMAND.
  1470. ;    CONTINUE CAN ONLY BE USED TO RETURN THE MONITOR TO
  1471. ;    A PROGRAM WHICH HAS BEEN HALTED BY EXECUTION
  1472. ;    OF A 'RST 2' INSTRUCTION (0D7H) AT A LOCATION WHOSE CONTENTS
  1473. ;    ARE SAVED IN 'BPDAT'.
  1474. ;
  1475. CONT:
  1476.     LHLD    SVPC    ;GET PSEUDO-RESTART.
  1477.     MOV    A,L    ;PUT LOW PART IN ACC.
  1478.     ORA    H    ;RESULT WILL BE ZERO IF ALL
  1479.     JZ    ILLEG    ;BITS ARE ZERO. I.E. NO B/P.
  1480.     CALL    BLANK    ;PRINT A SPACE
  1481.     CALL    THXW    ;FOLLOWED BY THE ADDRESS.
  1482.     XCHG        ;PUT OLD ADDRESS IN DE
  1483.     LHLD    BPADD    ;NOW GET CURRENT ADDRESS.
  1484.     CALL    NEGDE    ;NEGATE THE PC ADDRESS.
  1485.     DAD    D    ;D.P. ADD TO B/P ADDRESS.
  1486.     MOV    A,L    ;LO RESULT TO ACC,
  1487.     ORA    H    ;OR IT WITH HI RESULT,
  1488.     LHLD    SVPC    ;RECOVER PC (MAY NEED IT)
  1489.     JNZ    CON3    ;SEE IF DE=HL (I.E. ZERO RESULT)
  1490.     LXI    H,BPDAT    ;GET START ADDRESS OF SAVED INSTRUCTION.
  1491. CON3:
  1492.     MVI    A,CR    ;<CR> FORCES 'J' CONTINUE.
  1493.     PUSH    PSW    ;SAVE SIMULATED 'J' COMMAND
  1494.     JMP    JMP4    ;NOW ENTER 'JUMP'.
  1495. ;
  1496. ;
  1497. ;    BREAK-POINT THE PROGRAM AT LOCATION XXXX
  1498. ;    B XXXX
  1499. ;
  1500. ;    MAY ALSO BE USED TO CLEAR A PREVIOUS B/P BY
  1501. ;    B (CRTN)
  1502. ;
  1503. ;    BPT SAVES THE ADDRESS XXXX AND ITS CONTENTS
  1504. ;    IT THEN REPLACES THE CONTENTS OF XXXX WITH D7 ( RST 2 ).
  1505. ;    THIS FORCES THE PROGRAM TO SAVE ALL DATA AND RETURN
  1506. ;    TO THE MONITOR. THE PROGRAM MAY BE RESTARTED FROM
  1507. ;    XXXX BY A CONTINUE ( C ) COMMAND AFTER IT HAS HALTED.
  1508. ;
  1509. BPT:
  1510. ;
  1511. ;****    THIS CONDITIONAL CODE INSERTS THE RST2 JUMP IN RAM IF
  1512. ;    THE MONITOR IS NOT IN PAGE ZERO.
  1513. ;
  1514. ;        ORG    0010H
  1515. ;        JMP    BPIN
  1516. ;
  1517.     IF    ROMSW
  1518.     MVI    A,JMP    ;GET A 'JMP'
  1519.     STA    0010H    ;PUT IT AT 0010H
  1520.     LXI    H,BPIN    ;GET ADDRESS OF 'BPIN'
  1521.     SHLD    0011H    ;STORE IT AT 0011H
  1522.     ENDIF
  1523.     CALL    PUWB    ;GET ADDRESS
  1524.     JNC    BPT1    ;GOT AN ADDRESS - SO PROCEED
  1525.     CPI    CR    ;NOT AN ADDRESS - WAS IT A CRTN
  1526.     JNZ    ILLEG    ;NO SO BOMB OUT
  1527.     LXI    H,0    ;YES SO SIMULATE AN ADDRESS OF ZERO
  1528. ;
  1529. ;    BPT WILL REMOVE THE OLD B/P (IF ANY )
  1530. ;
  1531. BPT1:
  1532.     PUSH    H    ;COME HERE WITH ADDRESS IN HL. SAVE IT ON THE STACK
  1533.     LHLD    BPADD    ;IS THE PREVIOUS B/P ADDRESS = 0
  1534.     MOV    A,L    ;PUT LO PART OF ADDRESS IN ACC
  1535.     ORA    H    ;THEN 'OR' WITH HI PART
  1536.     JZ    BPT2    ;IT WAS ZERO SO SAVE XXXX AND (XXX)
  1537.     LXI    H,BPDAT    ;POINT TO THE SAVED DATA FROM THE LAST B/P
  1538.     MOV    A,M    ;GET IT IN A
  1539.     LHLD    BPADD    ;GET THE LAST B/P ADDRESS IN HL
  1540.     CALL    STORE    ;AND RESTORE THE DATA THERE
  1541. ;
  1542. ;    BREAKPOINT MAKER.
  1543. ;    CREATES A GAP IN THE TARGET PROGRAM BY INSERTING AN 'RST 2'
  1544. ;    IN PLACE OF THE FIRST BYTE OF THE INSTRUCTION.
  1545. ;    THE INSTRUCTION (ALL BYTES, COUNT COMPUTED) IS PLACED
  1546. ;    IN A TEMPORARY STORE, ALONG WITH A JUMP TO THE NEXT
  1547. ;    INSTRUCTION IN THE TARGET PROGRAM.
  1548. ;
  1549. BPT2:
  1550.     POP    H    ;RETRIEVE B/P ADDRESS FROM STACK.
  1551.     SHLD    BPADD    ;SAVE IT FOR FUTURE RETURN.
  1552.     MOV    A,H    ;SEE IF THIS IS
  1553.     ORA    L    ;ONLY CLEARING
  1554.     JZ    NEXT    ;THE BREAKPOINT.
  1555.     MOV    A,M    ;LOAD ITS FIRST BYTE.
  1556.     LXI    H,TAB1    ;GET START ADDRESS OF TABLE 1
  1557.     CPI    40H    ;SEE IF THE BYTE IS IN TABLE 1
  1558.     JC    BPT3    ; I.E. LESS THAN 40H
  1559.     LXI    H,TAB2    ;GET START OF TABLE 2.
  1560.     SUI    0C0H    ;SEE IF IT IS IN TABLE 2
  1561.     JNC    BPT3    ; I.E. >0BFH
  1562.     MVI    A,1    ;THE GROUP 40H TO 0BFH IS 1-BYTE
  1563.     JMP    BPT5    ;IN LENGTH.
  1564. BPT3:
  1565.     MOV    D,A    ;RANGE OF BYTE IS NOW 0 TO 64
  1566.     RRC        ;WE MUST PACK THIS RANGE DOWN
  1567.     RRC        ;TO 0 TO 15 BYTES OFFSET.
  1568.     MVI    B,0    ;AND THEN MAKE UP THE
  1569.     ANI    0FH    ;TRUE ADDRESS BY
  1570.     MOV    C,A    ;ADDING THE OFFSET TO THE
  1571.     DAD    B    ;START ADDRESS IN THE TABLE.
  1572.     MVI    A,3    ;WE MUST ALSO KNOW WHERE IN
  1573.     ANA    D    ;THE BYTE THE INSTRUCTION SIZE
  1574.     MOV    D,A    ;IS TO BE FOUND. (SEE NOTE ABOVE TABLE)
  1575.     MOV    A,M    ;GET THE KEY BYTE.
  1576. BPT4:
  1577.     DCR    D    ;FIND THE KEY POSSY.
  1578.     JM    BPT5    ;BY DECREMENTING THE 'D' REGISTER UNTIL IT
  1579.     RRC        ;GOES NEGATIVE. IF NOT FOUND, ROTATE THE KEY
  1580.     RRC        ;BYTE 2 POSITIONS RIGHT
  1581.     JMP    BPT4    ;AND TRY AGAIN
  1582. BPT5:
  1583.     ANI    3    ;WE CAN NOW COMPUTE THE BYTE COUNT.
  1584.     JZ    ILLEG    ;(OF COURSE 0 IS ILLEGAL)
  1585.     MOV    C,A    ;SAVE THE COUNT IN C
  1586.     LXI    H,BPDAT    ;DATA STORE ADDRESS
  1587.     XCHG        ;PUT IT INTO DE
  1588.     LHLD    BPADD    ;GET THE SOURCE ADDRESS.
  1589. BPT6:
  1590.     MOV    A,M    ;PICK UP THE DATA BYTE AND
  1591.     INX    H    ;THEN BUMP ADDRESS.
  1592.     XCHG        ;AFTER SWAPPING HL ADDRESSES,
  1593.     MOV    M,A    ;PUT IT IN THE BUFFER.
  1594.     INX    H    ;NOW BUMP STORE ADDRESS,
  1595.     XCHG        ;BEFORE RESTORING THE ADDRESSES.
  1596.     DCR    C    ;DECREMENT BYTE COUNTER.
  1597.     JNZ    BPT6    ;TRY AGAIN IF STILL DATA.
  1598.     XCHG        ;RETRIEVE THE STORE ADDRESS.
  1599.     MVI    M,JMP    ;PUT 'JMP' (0C3H) IN STORE.
  1600.     INX    H    ;BUMP STORE ADDRESS.
  1601.     MOV    M,E    ;LOW ORDER RETURN ADDRESS.
  1602.     INX    H    ;BUMP YET AGAIN.
  1603.     MOV    M,D    ;HIGH ORDER RETURN ADDRESS.
  1604.     LHLD    BPADD    ;FINALLY REPLACE THE
  1605.     MVI    M,0D7H    ;B/P WITH AN 'RST 2'
  1606.     JMP    NEXT
  1607. ;
  1608. ;    BREAKPOINT DATA TABLE.
  1609. ;    CONSISTS OF A SERIES OF DATA BYTES WHICH DEFINE THE
  1610. ;    NUMBER OF BYTES IN AN INSTRUCTION, BASED ON THE
  1611. ;    VALUE OF ITS FIRST BYTE.
  1612. ;
  1613. ;    THE TABLE HAS 2 SECTIONS.
  1614. ; TAB1    CONTAINS DATA FOR BYTES 000H TO 03FH
  1615. ; TAB2    CONTAINS DATA FOR BYTES 0C0H TO 0FFH
  1616. ;    EACH BYTE CONTAINS 4 KEYS REPRESENTING THE SIZE OF
  1617. ;    4 INSTRUCTIONS (RANGE 0-3, 0 IS ILLEGAL)
  1618. ;    SUCH THAT THE BOTTOM 2 BITS OF THE INSTRUCTION BYTE KEY TO
  1619. ;    THE TABLE BYTE AS FOLLOWS:-
  1620. ;    00    BITS B1,B0
  1621. ;    01    BITS B3,B2
  1622. ;    10    BITS B5,B4
  1623. ;    11    BITS B7,B6
  1624. ;
  1625. B00    EQU    0    ;KEY 0 DATA BITS
  1626. B01    EQU    1
  1627. B02    EQU    2
  1628. B03    EQU    3
  1629. B10    EQU    0    ;KEY 1 DATA BITS
  1630. B11    EQU    B01*4
  1631. B12    EQU    B02*4
  1632. B13    EQU    B03*4
  1633. B20    EQU    0    ;KEY 2 DATA BITS
  1634. B21    EQU    B11*4
  1635. B22    EQU    B12*4
  1636. B23    EQU    B13*4
  1637. B30    EQU    0    ;KEY 3 DATA BITS
  1638. B31    EQU    B21*4
  1639. B32    EQU    B22*4
  1640. B33    EQU    B23*4
  1641. ;
  1642. TAB1:
  1643.     DB    B01+B13+B21+B31
  1644.     DB    B01+B11+B22+B31
  1645.     DB    B00+B11+B21+B31
  1646.     DB    B01+B11+B22+B31
  1647.     DB    B00+B13+B21+B31
  1648.     DB    B01+B11+B22+B31
  1649.     DB    B00+B11+B21+B31
  1650.     DB    B01+B11+B22+B31
  1651.     DB    B01+B13+B23+B31
  1652.     DB    B01+B11+B22+B31
  1653.     DB    B00+B11+B23+B31
  1654.     DB    B01+B11+B22+B31
  1655.     DB    B01+B13+B23+B31
  1656.     DB    B01+B11+B22+B31
  1657.     DB    B00+B11+B23+B31
  1658.     DB    B01+B11+B22+B31
  1659. TAB2:
  1660.     DB    B01+B11+B23+B33
  1661.     DB    B03+B11+B22+B31
  1662.     DB    B01+B11+B23+B30
  1663.     DB    B03+B13+B22+B31
  1664.     DB    B01+B11+B23+B32
  1665.     DB    B03+B11+B22+B31
  1666.     DB    B01+B10+B23+B32
  1667.     DB    B03+B10+B22+B31
  1668.     DB    B01+B11+B23+B31
  1669.     DB    B03+B11+B22+B31
  1670.     DB    B01+B11+B23+B31
  1671.     DB    B03+B10+B22+B31
  1672.     DB    B01+B11+B23+B31
  1673.     DB    B03+B11+B22+B31
  1674.     DB    B01+B11+B23+B31
  1675.     DB    B03+B10+B22+B31
  1676. ;
  1677. ;****    CASSETTE I/O HANDLING ROUTINES.
  1678. ;
  1679. ;
  1680. ;****    CASSETTE OUTPUT CHARACTER.
  1681. ;
  1682. CTYPE:
  1683.     PUSH    PSW    ;SAVE PSW
  1684. CTYP1:
  1685.     IN    CSST    ;STATUS
  1686.     ANI    TRDY    ;READY?
  1687.     JZ    CTYP1
  1688.     POP    PSW    ;YES. PRINT
  1689.     OUT    CSOUT    ;AT CASSETTE.
  1690.     RET
  1691. ;
  1692. ;****    GET CHARACTER
  1693. ;
  1694. CSI:
  1695. CGETCH:
  1696.     CALL    CASTS    ;GET STATUS
  1697.     JZ    CSI
  1698.     IN    CSIN    ;GET CHR
  1699.     RET
  1700. ;
  1701. ;****    CASSETTE INPUT STATUS
  1702. ;
  1703. CASTS:
  1704.     IN    CSST    ;STATUS BYTE
  1705.     ANI    RBR    ;MASKED
  1706.     RET
  1707. ;
  1708. ;****    CASSETTE BYTE PUT.
  1709. ;
  1710. CTHXB:
  1711.     PUSH    PSW    ;SAVE DATA
  1712.     RRC        ;ROTATE
  1713.     RRC        ;THE
  1714.     RRC        ;BYTE
  1715.     RRC        ;4 BITS.
  1716.     CALL    CTHXN    ;PRINT 1ST NYBBLE
  1717.     POP    PSW    ;RECOVER
  1718. ;
  1719. ;****    CASSETTE NYBBLE PUT.
  1720. ;
  1721. CTHXN:
  1722.     PUSH    PSW    ;SAVED
  1723.     ANI    0FH    ;BOTTOM 4 BITS
  1724.     ADI    90H    ;MAKE THE
  1725.     DAA        ;NYBBLE
  1726.     ACI    40H    ;INTO AN
  1727.     DAA        ;ASCII CHR 0-F
  1728.     CALL    CTYPE    ;PUT IT.
  1729.     POP    PSW
  1730.     RET
  1731. ;
  1732. ;****    CASSETTE WORD OUTPUT.
  1733. ;
  1734. CTHXW:
  1735.     PUSH    PSW    ;SAVE PSW
  1736.     MOV    A,H    ;DO TOP
  1737.     CALL    CTHXB    ;BYTE
  1738.     MOV    A,L    ;THEN BOTTOM
  1739.     CALL    CTHXB    ;BYTE
  1740.     POP    PSW
  1741.     RET
  1742. ;
  1743. ;****    CASSETTE CRLF OUTPUT.
  1744. ;
  1745. CCRLF:
  1746.     PUSH    H    ;SAVE HL
  1747.     LXI    H,M2    ;GET MESSAGE
  1748.     CALL    CMSG    ;PRINT IT.
  1749.     POP    H
  1750.     RET
  1751. ;
  1752. ;****    CASSETTE MESSAGE.
  1753. ;
  1754. CMSG:
  1755.     PUSH    PSW
  1756.     PUSH    H    ;SAVE PSW AND HL
  1757. CMNXT:
  1758.     MOV    A,M    ;GET BYTE
  1759.     INX    H    ;BUMP PTR.
  1760.     CPI    0FFH    ;END FLAG?
  1761.     CNZ    CTYPE
  1762.     JNZ    CMNXT    ;MORE.
  1763.     POP    H    ;RECOVER HL
  1764.     POP    PSW    ;AND PSW
  1765.     RET
  1766. ;
  1767. ;****    CASSETTE BLANK.
  1768. ;
  1769. CBLANK:
  1770.     PUSH    PSW
  1771.     MVI    A,' '    ;A SPACE
  1772.     CALL    CTYPE    ;IS SENT.
  1773.     POP    PSW
  1774.     RET
  1775. ;
  1776. ;****    GET HEX NYBBLE.
  1777. ;
  1778. CGHXN:
  1779.     MVI    A,0FH    ;ONLY BOTTOM NYBBLE
  1780.     JMP    CGHB1
  1781. ;
  1782. ;****    GET HEX BYTE.
  1783. ;
  1784. CGHXB:
  1785.     MVI    A,0FFH    ;ALL BYTE NEEDED.
  1786. CGHB1:
  1787.     PUSH    H    ;SAVE HL
  1788.     CALL    CGHXW    ;GET A WORD.
  1789.     JC    CGHB2    ;ERROR?
  1790.     ANA    L    ;NYBBLE/BYTE ONLY.
  1791. CGHB2:
  1792.     POP    H
  1793.     RET
  1794. ;
  1795. ;****    GET HEX WORD FROM CASSETTE.
  1796. ;
  1797. CGHXW:
  1798.     PUSH    PSW    ;SAVE PSW
  1799.     LXI    H,0    ;START WITH NOTHING.
  1800.     CALL    CGETCH    ;GET CHARACTER
  1801.     ANI    7FH    ;AND MASK IT.
  1802.     CALL    CNVBN    ;CONVERT TO BINARY.
  1803.     JC    GHW3
  1804.     MOV    L,A    ;SAVE IT IF O.K.
  1805. CGHW1:
  1806.     CALL    CGETCH    ;AND ANOTHER
  1807.     ANI    7FH    ;MASKED.
  1808.     CALL    CNVBN    ;THEN CONVERTED.
  1809.     JC    GHW2
  1810.     DAD    H    ;*2
  1811.     DAD    H    ;*4
  1812.     DAD    H    ;*8
  1813.     DAD    H    ;*16
  1814.     ADD    L    ;ADD LO BYTE.
  1815.     MOV    L,A    ;UPDATE
  1816.     JMP    CGHW1
  1817. ;
  1818. ;
  1819. ;
  1820. ;
  1821. ;
  1822.     ORG    ROM + 07DCH
  1823. ;
  1824. ;****    JUMP TABLE FOR CASSETTE ROUTINES.
  1825. ;
  1826. ZCTYPE:    JMP    CTYPE
  1827. ZCGETC:    JMP    CGETCH
  1828. ZCMSG:    JMP    CMSG
  1829. ZCCRLF:    JMP    CCRLF
  1830. ZCSPAC:    JMP    CBLANK
  1831. ZCTHXN:    JMP    CTHXN
  1832. ZCTHXB:    JMP    CTHXB
  1833. ZCTHXW:    JMP    CTHXW
  1834. ZCGHXN:    JMP    CGHXN
  1835. ZCGHXB:    JMP    CGHXB
  1836. ZCGHXW:    JMP    CGHXW
  1837. ZCASTS:    JMP    CASTS
  1838. ;
  1839.     ORG    ROM+0800H
  1840. ;
  1841. QIN:    EQU    0DBH
  1842. QOUT:    EQU    0D3H
  1843. QRET:    EQU    0C9H
  1844. ;
  1845. ;****    INPUT AND OUTPUT PORT DATA ROUTINES.
  1846. ;
  1847. INPT:
  1848. OUTPT:
  1849.     MVI    A,QIN    ;ASSUME 'IN' COMMAND
  1850.     STA    BUFF
  1851.     CALL    GBYTE    ;GET PORT NUMBER.
  1852.     STA    BUFF+1    ;SAVE IT IN 'BUFF+1'
  1853.     MVI    A,QRET    ;GET 'RET'
  1854.     STA    BUFF+2
  1855.     MVI    A,'I'    ;SEE IF THIS IS 'IN' COMMAND.
  1856.     CMP    B
  1857.     JNZ    OUTER    ;MUST BE 'OUT'
  1858.     CALL    BUFF    ;GET INPUT DATA.
  1859.     CALL    BLANK    ;ONE SPACE,
  1860.     CALL    THXB    ;FOLLOWED BY THE BYTE.
  1861.     CALL    CRLF
  1862.     JMP    NEXT
  1863. OUTER:
  1864.     MVI    A,QOUT    ;REPLACE 'IN' WITH 'OUT'
  1865.     STA    BUFF
  1866.     CALL    GBYTE    ;OUTPUT BYTE REQUIRED.
  1867.     CALL    CRLF
  1868.     CALL    BUFF    ;OUTPUT IT.
  1869.     JMP    NEXT
  1870. ;
  1871. ;
  1872. ;***********************************************************
  1873. ;
  1874. ;    DISASSEMBLER PROGRAM FOR 8080 ROUTINES.
  1875. ;
  1876. ;***********************************************************
  1877. ;
  1878. ;
  1879. ;****    FIND START ADDRESS.
  1880. ;
  1881. DIS80:
  1882.     CALL    PUWB    ;GET START ADDRESS.
  1883.     JC    ILLEG    ;ERROR EXIT
  1884.     CALL    CRLF
  1885.     MOV    B,H
  1886.     MOV    C,L    ;BC NOW HAS MEMORY ADDR.
  1887. ;
  1888. ;****    GET BYTE.
  1889. ;
  1890. DIS1:
  1891.     MOV    H,B    ;PUT MEMORY ADDRESS
  1892.     MOV    L,C    ;INTO HL
  1893.     CALL    THXW    ;PRINT IT
  1894.     CALL    BLANK    ;AND A SPACE.
  1895.     LDAX    B    ;GET FIRST BYTE.
  1896. ;
  1897. ;****    FIND THE TABLE POSITION.
  1898. ;
  1899.     MOV    E,A    ;PUT OFFSET INTO C
  1900.     MVI    D,0    ;AND CLEAR HI BYTE
  1901. ;
  1902. ;    ADD OFFSET THREE TIMES.
  1903. ;
  1904.     LXI    H,ATAB1    ;TABLE START ADDRESS.
  1905.     DAD    D    ;ADD OFFSET
  1906.     DAD    D    ;THREE
  1907.     DAD    D    ;TIMES.
  1908. ;
  1909. ;****    READY TO PROCESS.
  1910. ;
  1911.     MOV    D,M    ;LOAD BYTE COUNT.
  1912.     MOV    A,D
  1913.     INX    H    ;BUMP PAST BYTE COUNTER.
  1914.     CALL    BPRNT    ;PRINT THE BYTES.
  1915.     MOV    E,M    ;GET OPCODE OFFSET
  1916.     MVI    D,0    ;INTO DE
  1917.     INX    H    ;BUMP TABLE POINTER.
  1918.     PUSH    H    ;AND SAVE IT
  1919.     LXI    H,ATAB2    ;ADD OFFSET
  1920.     DAD    D    ;TO THE
  1921.     DAD    D    ;TABLE HEADER
  1922.     DAD    D    ;FOUR
  1923.     DAD    D    ;TIMES.
  1924.     MVI    D,4
  1925.     CALL    PRNT    ;PRINT OPCODE.
  1926.     LXI    H,MSGBK    ;NOW PRINT
  1927.     CALL    MSG    ;4 SPACES
  1928.     POP    H    ;RETRIEVE PTR.
  1929.     MOV    E,M    ;DITTO FOR OPERAND(S).
  1930.     MVI    D,0
  1931.     LXI    H,ATAB3
  1932.     DAD    D
  1933.     DAD    D
  1934.     DAD    D
  1935.     MVI    D,3
  1936.     CALL    PRNT    ;PRINT OPERAND(S)
  1937.     PUSH    B    ;SAVE MEM PTR.
  1938.     MVI    H,0    ;ZERO OUT H
  1939.     MOV    L,A    ;PUT BYTE COUNT INTO L
  1940.     DAD    B    ;BUMP MEMORY ADDRESS.
  1941.     MOV    B,H    ;PUT BACK INTO
  1942.     MOV    C,L    ;BC
  1943.     POP    H    ;RETRIEVE MEMORY ADDRESS.
  1944.     DCR    A    ;TEST BYTE COUNT
  1945.     JZ    DISB1    ;FOR ONE
  1946.     DCR    A
  1947.     JZ    DISB2    ;OR TWO
  1948. DISB3:
  1949.     INX    H    ;GET AND
  1950.     MOV    E,M    ;PRINT
  1951.     INX    H    ;16 BIT
  1952.     MOV    D,M    ;DATA
  1953.     XCHG        ;WORD
  1954.     CALL    THXW    ;VALUE
  1955.     JMP    DISB1
  1956. DISB2:
  1957.     INX    H    ;GET AND
  1958.     MOV    A,M    ;PRINT 8 BIT
  1959.     CALL    THXB    ;DATA BYTE VALUE
  1960. DISB1:
  1961.     CALL    CRLF    ;NEW LINE PLEASE.
  1962.     CALL    HOLD    ;SEE IF HOLD REQUESTED.
  1963.     JMP    DIS1    ;NO.
  1964. ;
  1965. ;****    PRINT CURRENT BYTE IF VALID.
  1966. ;
  1967. BPRNT:
  1968.     PUSH    PSW    ;SAVE PSW.
  1969.     PUSH    B    ;SAVE CURRENT MEM PTR.
  1970.     MVI    E,3    ;PRINT 3 BYTES.
  1971. BPRT1:
  1972.     LDAX    B    ;GET CURRENT MEMORY BYTE.
  1973.     DCR    D    ;DECREMENT COUNTER.
  1974.     CP    THXB    ;PRINT IT,
  1975.     CM    BLANK    ;OR ELSE 2 SPACES.
  1976.     CM    BLANK
  1977.     CALL    BLANK    ;FOLLOWED BY SPACER.
  1978.     INX    B    ;FINALLY BUMP POINTER.
  1979.     DCR    E
  1980.     JNZ    BPRT1
  1981.     POP    B    ;RETRIEVE MEM PTR.
  1982.     POP    PSW    ;AND PSW.
  1983.     RET
  1984. ;
  1985. ;****    PRINT A STRING FOLLOWED BY A SPACE.
  1986. ;
  1987. PRNT:
  1988.     PUSH    PSW
  1989. PRNT1:
  1990.     MOV    A,M    ;GET DATA BYTE
  1991.     CALL    TYPE    ;PRINT IT.
  1992.     INX    H    ;READY FOR NEXT BYTE
  1993.     DCR    D    ;DECREMENT AND TEST
  1994.     JNZ    PRNT1    ;LOOP COUNT.
  1995.     CALL    BLANK
  1996.     POP    PSW
  1997.     RET
  1998. ;
  1999. ;
  2000. ;********************************************************
  2001. ;
  2002. ;    LINE ASSEMBLER PROGRAM.
  2003. ;    USES COMMON TABLES WITH DISASSEMBLER.
  2004. ;
  2005. ;********************************************************
  2006. ;
  2007. ;
  2008. ASM80:
  2009.     CALL    PUWB    ;GET START ADDRESS.
  2010.     JC    ILLEG
  2011.     CALL    CRLF
  2012. ASM1:
  2013.     CALL    THXW    ;TYPE CURRENT ADDRESS.
  2014.     SHLD    MEMADR    ;SAVE CURRENT ADDRESS.
  2015.     CALL    STRING    ;GET THE OPCODE STRING.
  2016.     LXI    H,ATAB2    ;OPCODE TABLE
  2017.     MVI    B,4    ;HAS 4 BYTES/ENTRY
  2018.     CALL    STCOMP    ;SCAN FOR THE GIVEN STRING.
  2019.     JC    ILLEG    ;CARRY SET ON ERROR.
  2020.     STA    OPCODE    ;SAVE OPCODE OFFSET.
  2021.     LXI    H,ATAB1+1    ;FIND A CODE
  2022. ASM2:
  2023.     CMP    M    ;WHICH MATCHES
  2024.     INX    H    ;SO THAT
  2025.     JZ    ASM3    ;WE CAN SEE
  2026.     INX    H    ;IF THE
  2027.     INX    H    ;THIRD BYTE IN
  2028.     JMP    ASM2    ;THE TABLE
  2029. ASM3:
  2030.     MOV    A,M    ;HAPPENS TO BE
  2031.     CPI    0    ;NON-ZERO.
  2032.     JZ    ASM4    ;I.E. NON-BLANK
  2033.     CALL    STRING    ;OPERAND STRING REQUIRED.
  2034.     LXI    H,ATAB3    ;LOOK FOR OPERAND STRING
  2035.     MVI    B,3    ;IN 3 BYTE/ENTRY OPERAND
  2036.     CALL    STCOMP    ;TABLE.
  2037.     JC    ILLEG
  2038.     CALL    BLANK    ;SPACE UP
  2039. ASM4:
  2040.     MOV    E,A    ;SAVE OPERAND CODE NUMBER
  2041.     LDA    OPCODE    ;AND ALSO
  2042.     MOV    D,A    ;OPCODE CODE NUMBER
  2043.     LXI    H,ATAB1+1    ;FIND DOUBLE MATCH
  2044.     MVI    C,0    ;IN THE OPCODE TABLE
  2045. ASM5:
  2046.     MOV    A,M    ;GET TEST BYTE.
  2047.     CPI    0FFH    ;SEE IF E.O.T.
  2048.     JZ    ILLEG    ;I.E. -1 BYTE.
  2049.     CMP    D    ;OPCODE MATCH?
  2050.     JNZ    ASM6
  2051.     INX    H
  2052.     MOV    A,M
  2053.     CMP    E    ;OPERAND MATCH?
  2054.     JZ    ASM7
  2055.     DCX    H
  2056. ASM6:
  2057.     INX    H    ;NO. BUMP
  2058.     INX    H    ;PAST THIS
  2059.     INX    H    ;ENTRY AND
  2060.     INR    C    ;INCREMENT TABLE COUNTER.
  2061.     JMP    ASM5
  2062. ASM7:
  2063.     DCX    H    ;GOT IT. GO BACK
  2064.     DCX    H    ;TWO BYTES AND
  2065.     MOV    D,M    ;GET BYTE COUNT.
  2066.     LHLD    MEMADR    ;RETRIEVE CURRENT MEM ADDR.
  2067.     MOV    A,C    ;STORE THE FIRST
  2068.     CALL    STORE    ;BYTE VALUE
  2069.     MOV    A,D    ;THEN LOOK AT
  2070.     SUI    2    ;SIZE OF INSTRUCTION.
  2071.     JM    ASB1    ;ONE BYTE
  2072.     LXI    H,MSGBK    ;OR MULTIBYTE.
  2073.     CALL    MSG
  2074.     CALL    GHXW    ;GET A NUMBER.
  2075.     JC    ILLEG
  2076.     ORA    A    ;RESET BYTE FLAG.
  2077.     JZ    ASB2    ;TWO BYTE.
  2078. ASB3:
  2079.     XCHG        ;NUMBER NOW IN DE.
  2080.     LHLD    MEMADR    ;GET MEMOR ADDR.
  2081.     INX    H    ;PUT LO BYTE
  2082.     MOV    A,E    ;INTO NEXT
  2083.     CALL    STORE    ;ADDRESS.
  2084.     INX    H    ;AND HI BYTE
  2085.     MOV    A,D    ;INTO 3RD BYTE
  2086.     CALL    STORE    ;ADDRESS.
  2087.     JMP    ASB1    ;FINISH OFF.
  2088. ASB2:
  2089.     MOV    A,L    ;PUT LO BYTE
  2090.     LHLD    MEMADR    ;ONLY INTO
  2091.     INX    H    ;INTO 2ND. BYTE
  2092.     CALL    STORE    ;ADDRESS.
  2093. ASB1:
  2094.     INX    H    ;BUMP TO NEXT ADDR.
  2095.     CALL    CRLF    ;NEW LINE,
  2096.     JMP    ASM1    ;START ALL OVER AGAIN.
  2097. ;
  2098. ;****    STRING INPUT ROUTINE.
  2099. ;    ON RETURN, FIRST 4 BYTES IN 'BUFF' WITH
  2100. ;    TRAILING BLANKS IF NECESSARY.
  2101. ;
  2102. STRING:
  2103.     LXI    H,MSGBK
  2104.     CALL    MSG
  2105.     LXI    H,2020H    ;PUT SPACES
  2106.     SHLD    BUFF    ;INTO 4 BYTE
  2107.     SHLD    BUFF+2    ;BUFFER.
  2108.     LXI    H,BUFF
  2109.     MVI    E,4
  2110. STR1:
  2111.     CALL    CHIN    ;LOOK FOR
  2112.     CPI    CR    ;<CR> TERMINATOR
  2113.     JZ    NEXT
  2114.     JMP    STR3
  2115. STR2:
  2116.     CALL    CHIN    ;GET A CHARACTER.
  2117. STR3:
  2118.     CPI    CR    ;LOOK FOR
  2119.     RZ        ;<CR> OR
  2120.     CPI    ' '    ;SPACE AS
  2121.     RZ        ;DELIMITER.
  2122.     DCR    E    ;ONLY THE FIRST
  2123.     JM    STR2    ;4 BYTES
  2124.     MOV    M,A    ;ARE STORED.
  2125.     INX    H
  2126.     JMP    STR2
  2127. ;
  2128. ;****    STRING COMPARE ROUTINE.
  2129. ;    ON INPUT, HL=START OF TEST TABLE
  2130. ;          B=BYTE COUNT PER ENTRY.
  2131. ;    GOOD OUTPUT, CARRY CLI, ACC=OFFSET VALUE.
  2132. ;     BAD OUTPUT, CARRY SET, ACC=0FFH.
  2133. ;
  2134. STCOMP:
  2135.     MVI    C,0    ;CLEAR COUNTER.
  2136. STC0:
  2137.     PUSH    B    ;SAVE COUNTER AND STRING SIZE.
  2138.     LXI    D,BUFF    ;GET BUFFER START.
  2139. STC1:
  2140.     LDAX    D    ;GET TEST BYTE.
  2141.     CMP    M    ;SEE IF DIFFERENT.
  2142.     JNZ    STC2
  2143.     DCR    B    ;OR IF ALL BYTES CHECK.
  2144.     JZ    STC5
  2145.     INX    D    ;BUMP POINTERS
  2146.     INX    H    ;AND THEN
  2147.     JMP    STC1    ;TRY AGAIN.
  2148. STC2:
  2149.     MOV    A,M    ;DIFFERENT. SAVE CURRENT BYTE.
  2150. STC3:
  2151.     DCR    B    ;BUMP
  2152.     INX    H    ;PAST
  2153.     JZ    STC4    ;THIS
  2154.     JMP    STC3    ;BYTE.
  2155. STC4:
  2156.     POP    B    ;RETRIEVE COUNTERS,
  2157.     INR    C    ;BUMP COUNTER,
  2158.     CPI    0FFH    ;SEE IF E.O.T.
  2159.     JZ    STC6
  2160.     JMP    STC0    ;TRY AGAIN.
  2161. STC5:
  2162.     POP    B    ;FOUND A MATCH.
  2163.     MOV    A,C    ;RETURN ENTRY
  2164.     ORA    A    ;IN ACC WITH
  2165.     RET        ;CARRY RESET.
  2166. STC6:
  2167.     STC        ;ERROR RETURN
  2168.     RET        ;SETS CARRY ONLY.
  2169. ;
  2170. MSGBK:    DB    '    ',0FFH
  2171. ;
  2172. ;****    OPERATION CODE TABLE.
  2173. ;    ARRANGED AS FOLLOWS, ACCORDING TO INSTRUCTION
  2174. ;    FIRST BYTE VALUE (0-255):-
  2175. ;
  2176. ;    FIRST BYTE IS INSTRUCTION SIZE (BYTES)
  2177. ;    NEXT 4 BYTES ARE OPCODE.
  2178. ;    NEXT BYTE IS ATAB3 ENTRY NUMBER.
  2179. ;
  2180. ATAB1:
  2181.     DB    1,0,0
  2182.     DB    3,1,1
  2183.     DB    1,2,1
  2184.     DB    1,6,1
  2185.     DB    1,8,1
  2186.     DB    1,9,1
  2187.     DB    2,30,1
  2188.     DB    1,10,0
  2189.     DB    1,88,0
  2190.     DB    1,14,1
  2191.     DB    1,3,1
  2192.     DB    1,7,1
  2193.     DB    1,8,2
  2194.     DB    1,9,2
  2195.     DB    2,30,2
  2196.     DB    1,11,0
  2197.     DB    1,88,0
  2198.     DB    3,1,3
  2199.     DB    1,2,3
  2200.     DB    1,6,3
  2201.     DB    1,8,3
  2202.     DB    1,9,3
  2203.     DB    2,30,3
  2204.     DB    1,12,0
  2205.     DB    1,88,0
  2206.     DB    1,14,3
  2207.     DB    1,3,3
  2208.     DB    1,7,3
  2209.     DB    1,8,4
  2210.     DB    1,9,4
  2211.     DB    2,30,4
  2212.     DB    1,13,0
  2213.     DB    1,85,0
  2214.     DB    3,1,5
  2215.     DB    3,4,0
  2216.     DB    1,6,5
  2217.     DB    1,8,5
  2218.     DB    1,9,5
  2219.     DB    2,30,5
  2220.     DB    1,15,0
  2221.     DB    1,88,0
  2222.     DB    1,14,5
  2223.     DB    3,5,0
  2224.     DB    1,7,5
  2225.     DB    1,8,6
  2226.     DB    1,9,6
  2227.     DB    2,30,6
  2228.     DB    1,16,0
  2229.     DB    1,86,0
  2230.     DB    3,1,9
  2231.     DB    3,17,0
  2232.     DB    1,6,9
  2233.     DB    1,8,7
  2234.     DB    1,9,7
  2235.     DB    2,30,7
  2236.     DB    1,19,0
  2237.     DB    1,88,0
  2238.     DB    1,14,9
  2239.     DB    3,18,0
  2240.     DB    1,7,9
  2241.     DB    1,8,8
  2242.     DB    1,9,8
  2243.     DB    2,30,8
  2244.     DB    1,20,0
  2245.     DB    1,21,11
  2246.     DB    1,21,12
  2247.     DB    1,21,13
  2248.     DB    1,21,14
  2249.     DB    1,21,15
  2250.     DB    1,21,16
  2251.     DB    1,21,17
  2252.     DB    1,21,18
  2253.     DB    1,21,19
  2254.     DB    1,21,20
  2255.     DB    1,21,21
  2256.     DB    1,21,22
  2257.     DB    1,21,23
  2258.     DB    1,21,24
  2259.     DB    1,21,25
  2260.     DB    1,21,26
  2261.     DB    1,21,27
  2262.     DB    1,21,28
  2263.     DB    1,21,29
  2264.     DB    1,21,30
  2265.     DB    1,21,31
  2266.     DB    1,21,32
  2267.     DB    1,21,33
  2268.     DB    1,21,34
  2269.     DB    1,21,35
  2270.     DB    1,21,36
  2271.     DB    1,21,37
  2272.     DB    1,21,38
  2273.     DB    1,21,39
  2274.     DB    1,21,40
  2275.     DB    1,21,41
  2276.     DB    1,21,42
  2277.     DB    1,21,43
  2278.     DB    1,21,44
  2279.     DB    1,21,45
  2280.     DB    1,21,46
  2281.     DB    1,21,47
  2282.     DB    1,21,48
  2283.     DB    1,21,49
  2284.     DB    1,21,50
  2285.     DB    1,21,51
  2286.     DB    1,21,52
  2287.     DB    1,21,53
  2288.     DB    1,21,54
  2289.     DB    1,21,55
  2290.     DB    1,21,56
  2291.     DB    1,21,57
  2292.     DB    1,21,58
  2293.     DB    1,21,59
  2294.     DB    1,21,60
  2295.     DB    1,21,61
  2296.     DB    1,21,62
  2297.     DB    1,21,63
  2298.     DB    1,21,64
  2299.     DB    1,76,0
  2300.     DB    1,21,66
  2301.     DB    1,21,67
  2302.     DB    1,21,68
  2303.     DB    1,21,69
  2304.     DB    1,21,70
  2305.     DB    1,21,71
  2306.     DB    1,21,72
  2307.     DB    1,21,73
  2308.     DB    1,21,74
  2309.     DB    1,22,1
  2310.     DB    1,22,2
  2311.     DB    1,22,3
  2312.     DB    1,22,4
  2313.     DB    1,22,5
  2314.     DB    1,22,6
  2315.     DB    1,22,7
  2316.     DB    1,22,8
  2317.     DB    1,23,1
  2318.     DB    1,23,2
  2319.     DB    1,23,3
  2320.     DB    1,23,4
  2321.     DB    1,23,5
  2322.     DB    1,23,6
  2323.     DB    1,23,7
  2324.     DB    1,23,8
  2325.     DB    1,24,1
  2326.     DB    1,24,2
  2327.     DB    1,24,3
  2328.     DB    1,24,4
  2329.     DB    1,24,5
  2330.     DB    1,24,6
  2331.     DB    1,24,7
  2332.     DB    1,24,8
  2333.     DB    1,25,1
  2334.     DB    1,25,2
  2335.     DB    1,25,3
  2336.     DB    1,25,4
  2337.     DB    1,25,5
  2338.     DB    1,25,6
  2339.     DB    1,25,7
  2340.     DB    1,25,8
  2341.     DB    1,26,1
  2342.     DB    1,26,2
  2343.     DB    1,26,3
  2344.     DB    1,26,4
  2345.     DB    1,26,5
  2346.     DB    1,26,6
  2347.     DB    1,26,7
  2348.     DB    1,26,8
  2349.     DB    1,27,1
  2350.     DB    1,27,2
  2351.     DB    1,27,3
  2352.     DB    1,27,4
  2353.     DB    1,27,5
  2354.     DB    1,27,6
  2355.     DB    1,27,7
  2356.     DB    1,27,8
  2357.     DB    1,28,1
  2358.     DB    1,28,2
  2359.     DB    1,28,3
  2360.     DB    1,28,4
  2361.     DB    1,28,5
  2362.     DB    1,28,6
  2363.     DB    1,28,7
  2364.     DB    1,28,8
  2365.     DB    1,29,1
  2366.     DB    1,29,2
  2367.     DB    1,29,3
  2368.     DB    1,29,4
  2369.     DB    1,29,5
  2370.     DB    1,29,6
  2371.     DB    1,29,7
  2372.     DB    1,29,8
  2373.     DB    1,42,0
  2374.     DB    1,66,1
  2375.     DB    3,43,0
  2376.     DB    3,40,0
  2377.     DB    3,44,0
  2378.     DB    1,67,1
  2379.     DB    2,31,0
  2380.     DB    1,77,0
  2381.     DB    1,45,0
  2382.     DB    1,39,0
  2383.     DB    3,46,0
  2384.     DB    1,88,0
  2385.     DB    3,47,0
  2386.     DB    3,41,0
  2387.     DB    2,32,0
  2388.     DB    1,78,0
  2389.     DB    1,48,0
  2390.     DB    1,66,3
  2391.     DB    3,49,0
  2392.     DB    2,72,0
  2393.     DB    3,50,0
  2394.     DB    1,67,3
  2395.     DB    2,33,0
  2396.     DB    1,79,0
  2397.     DB    1,51,0
  2398.     DB    1,88,0
  2399.     DB    3,52,0
  2400.     DB    2,73,0
  2401.     DB    3,53,0
  2402.     DB    1,88,0
  2403.     DB    2,34,0
  2404.     DB    1,80,0
  2405.     DB    1,54,0
  2406.     DB    1,66,5
  2407.     DB    3,55,0
  2408.     DB    1,68,0
  2409.     DB    3,56,0
  2410.     DB    1,67,5
  2411.     DB    2,35,0
  2412.     DB    1,81,0
  2413.     DB    1,57,0
  2414.     DB    1,69,0
  2415.     DB    3,58,0
  2416.     DB    1,70,0
  2417.     DB    3,59,0
  2418.     DB    1,88,0
  2419.     DB    2,36,0
  2420.     DB    1,82,0
  2421.     DB    1,60,0
  2422.     DB    1,66,10
  2423.     DB    3,61,0
  2424.     DB    1,74,0
  2425.     DB    3,62,0
  2426.     DB    1,67,10
  2427.     DB    2,37,0
  2428.     DB    1,83,0
  2429.     DB    1,63,0
  2430.     DB    1,71,0
  2431.     DB    3,64,0
  2432.     DB    1,75,0
  2433.     DB    3,65,0
  2434.     DB    1,88,0
  2435.     DB    2,38,0
  2436.     DB    1,84,0
  2437. ;
  2438. ;****    ATAB2 CONTAINS ALL OPCODES.
  2439. ;
  2440. ATAB2:
  2441.     DB    'NOP '
  2442.     DB    'LXI '
  2443.     DB    'STAX'
  2444.     DB    'LDAX'
  2445.     DB    'SHLD'
  2446.     DB    'LHLD'
  2447.     DB    'INX '
  2448.     DB    'DCX '
  2449.     DB    'INR '
  2450.     DB    'DCR '
  2451.     DB    'RLC '
  2452.     DB    'RRC '
  2453.     DB    'RAL '
  2454.     DB    'RAR '
  2455.     DB    'DAD '
  2456.     DB    'DAA '
  2457.     DB    'CMA '
  2458.     DB    'STA '
  2459.     DB    'LDA '
  2460.     DB    'STC '
  2461.     DB    'CMC '
  2462.     DB    'MOV '
  2463.     DB    'ADD '
  2464.     DB    'ADC '
  2465.     DB    'SUB '
  2466.     DB    'SBB '
  2467.     DB    'ANA '
  2468.     DB    'XRA '
  2469.     DB    'ORA '
  2470.     DB    'CMP '
  2471.     DB    'MVI '
  2472.     DB    'ADI '
  2473.     DB    'ACI '
  2474.     DB    'SUI '
  2475.     DB    'SBI '
  2476.     DB    'ANI '
  2477.     DB    'XRI '
  2478.     DB    'ORI '
  2479.     DB    'CPI '
  2480.     DB    'RET '
  2481.     DB    'JMP '
  2482.     DB    'CALL'
  2483.     DB    'RNZ '
  2484.     DB    'JNZ '
  2485.     DB    'CNZ '
  2486.     DB    'RZ  '
  2487.     DB    'JZ  '
  2488.     DB    'CZ  '
  2489.     DB    'RNC '
  2490.     DB    'JNC '
  2491.     DB    'CNC '
  2492.     DB    'RC  '
  2493.     DB    'JC  '
  2494.     DB    'CC  '
  2495.     DB    'RPO '
  2496.     DB    'JPO '
  2497.     DB    'CPO '
  2498.     DB    'RPE '
  2499.     DB    'JPE '
  2500.     DB    'CPE '
  2501.     DB    'RP  '
  2502.     DB    'JP  '
  2503.     DB    'CP  '
  2504.     DB    'RM  '
  2505.     DB    'JM  '
  2506.     DB    'CM  '
  2507.     DB    'POP '
  2508.     DB    'PUSH'
  2509.     DB    'XTHL'
  2510.     DB    'PCHL'
  2511.     DB    'XCHG'
  2512.     DB    'SPHL'
  2513.     DB    'OUT '
  2514.     DB    'IN  '
  2515.     DB    'DI  '
  2516.     DB    'EI  '
  2517.     DB    'HLT '
  2518.     DB    'RST0'
  2519.     DB    'RST1'
  2520.     DB    'RST2'
  2521.     DB    'RST3'
  2522.     DB    'RST4'
  2523.     DB    'RST5'
  2524.     DB    'RST6'
  2525.     DB    'RST7'
  2526.     DB    'RIM '
  2527.     DB    'SIM '
  2528. AT2E:    DB    0FFH,0FFH,0FFH,0FFH
  2529.     DB    '--- '
  2530. ;
  2531. ;****    ATAB3 CONTAINS ALL POSSIBLE OPERANDS.
  2532. ;
  2533. ATAB3:
  2534.     DB    '   '
  2535.     DB    'B  '
  2536.     DB    'C  '
  2537.     DB    'D  '
  2538.     DB    'E  '
  2539.     DB    'H  '
  2540.     DB    'L  '
  2541.     DB    'M  '
  2542.     DB    'A  '
  2543.     DB    'SP '
  2544.     DB    'PSW'
  2545.     DB    'B,B'
  2546.     DB    'B,C'
  2547.     DB    'B,D'
  2548.     DB    'B,E'
  2549.     DB    'B,H'
  2550.     DB    'B,L'
  2551.     DB    'B,M'
  2552.     DB    'B,A'
  2553.     DB    'C,B'
  2554.     DB    'C,C'
  2555.     DB    'C,D'
  2556.     DB    'C,E'
  2557.     DB    'C,H'
  2558.     DB    'C,L'
  2559.     DB    'C,M'
  2560.     DB    'C,A'
  2561.     DB    'D,B'
  2562.     DB    'D,C'
  2563.     DB    'D,D'
  2564.     DB    'D,E'
  2565.     DB    'D,H'
  2566.     DB    'D,L'
  2567.     DB    'D,M'
  2568.     DB    'D,A'
  2569.     DB    'E,B'
  2570.     DB    'E,C'
  2571.     DB    'E,D'
  2572.     DB    'E,E'
  2573.     DB    'E,H'
  2574.     DB    'E,L'
  2575.     DB    'E,M'
  2576.     DB    'E,A'
  2577.     DB    'H,B'
  2578.     DB    'H,C'
  2579.     DB    'H,D'
  2580.     DB    'H,E'
  2581.     DB    'H,H'
  2582.     DB    'H,L'
  2583.     DB    'H,M'
  2584.     DB    'H,A'
  2585.     DB    'L,B'
  2586.     DB    'L,C'
  2587.     DB    'L,D'
  2588.     DB    'L,E'
  2589.     DB    'L,H'
  2590.     DB    'L,L'
  2591.     DB    'L,M'
  2592.     DB    'L,A'
  2593.     DB    'M,B'
  2594.     DB    'M,C'
  2595.     DB    'M,D'
  2596.     DB    'M,E'
  2597.     DB    'M,H'
  2598.     DB    'M,L'
  2599.     DB    'M,M'
  2600.     DB    'M,A'
  2601.     DB    'A,B'
  2602.     DB    'A,C'
  2603.     DB    'A,D'
  2604.     DB    'A,E'
  2605.     DB    'A,H'
  2606.     DB    'A,L'
  2607.     DB    'A,M'
  2608.     DB    'A,A'
  2609. AT3E:    DB    0FFH,0FFH,0FFH
  2610. ;
  2611. ;    LOAD HEX OBJECT TAPE.
  2612. ;
  2613. ;    LOAD A HEX-BINARY TAPE AS PRODUCED BY THE 'P'
  2614. ;    COMMAND.
  2615. ;    MAY CONTAIN AN OFFSET VALUE, ALLOWING THE DATA TO
  2616. ;    BE LOADED INTO A DIFFERENT LOCATION TO THAT SPECIFIED
  2617. ;    BY THE LOAD ADDRESS.
  2618. ;
  2619. ;
  2620. SPORT    EQU    083H
  2621. DPORT    EQU    083H
  2622. SPKT    EQU    080H
  2623. ;
  2624.     ORG    ROM+0F40H
  2625. ;
  2626. LOADF:
  2627.     CALL    PUWB    ;GET THE OFFSET, IF ANY.
  2628.     JNC    LD4F
  2629.     CPI    CR    ;ERROR MAY ONLY BE <CR>
  2630.     JNZ    ILLEG
  2631. LD4F:
  2632.     CALL    CRLF    ;NEW LINE PLEASE.
  2633.     PUSH    H    ;SAVE BIAS ADR
  2634. LD5F:
  2635.     POP    H    ;GET BIAS
  2636.     PUSH    H    ;AND RESTORE
  2637.     CALL    RIXF    ;GET INPUT
  2638.     MVI    B,':'    ;WAIT FOR ':'
  2639.     SUB    B
  2640.     JNZ    LD5F    ;TRY AGAIN
  2641.     MOV    D,A    ;CLEAR CKSUM
  2642.     CALL    BYTEF    ;GET LENGTH
  2643.     JZ    LD7F    ;ZERO MEANS ALL DONE
  2644.     MOV    E,A    ;SAVE LENGTH
  2645.     CALL    BYTEF
  2646.     PUSH    PSW    ;SAVE HI ADR
  2647.     CALL    BYTEF
  2648.     POP    B    ;FETCH MSBYTE
  2649.     MOV    C,A    ;BC NOW HAS ADR
  2650.     PUSH    B    ;SAVE IT
  2651.     XTHL        ;INTO HL
  2652.     SHLD    BLKAD    ;SAVE BLOCK ADR
  2653.     XTHL        ;IN CASE OF ERROR
  2654.     POP    B
  2655.     DAD    B    ;RESTORE AND ADD BIAS
  2656.     CALL    BYTEF    ;RECORD TYPE INPUT
  2657. LD6F:
  2658.     CALL    BYTEF    ;GET DATA BYTES
  2659.     CALL    STORE    ;STORE
  2660.     INX    H
  2661.     DCR    E
  2662.     JNZ    LD6F    ;GO ON.
  2663.     CALL    BYTEF    ;GET CKSUM
  2664.     JZ    LD5F
  2665. LDERRF:
  2666.     LXI    H,M6    ;CKSUM ERROR
  2667.     CALL    MSG
  2668.     LHLD    BLKAD    ;ADR OF THIS BLOCK IS
  2669.     JMP    RXAR    ;NOW GIVEN
  2670. LD7F:
  2671.     CALL    BYTEF    ;MSB OF XEQAD
  2672.     MOV    H,A
  2673.     CALL    BYTEF
  2674.     MOV    L,A
  2675.     ORA    H
  2676.     JZ    NEXT    ;MONITOR IF ADR=0
  2677.     PCHL        ;OTHERWISE EXECUTE
  2678. ;
  2679. RIXF:
  2680.     CALL    RIF
  2681.     JC    ILLEG    ;ON ERROR, PRINT '??'
  2682.     ANI    7FH    ;REMOVE PARITY
  2683.     RET
  2684. ;
  2685. ;    ROUTINE RIF
  2686. ;    GETS A CHARACTER FROM THE FAST READER INPUT
  2687. ;    I.E. IT STARTS THE READER, AND EXPECTS QUICK REPLY.
  2688. ;
  2689. ;
  2690. RIF:
  2691.     PUSH    B    ;SAVE BC
  2692.     PUSH    D    ;AND DE
  2693. RIF05:
  2694.     MVI    C,SPKT    ;PRESET CURRENT STATUS
  2695.     LXI    D,0    ;TIMEOUT COUNT.
  2696. RIF10:
  2697.     IN    SPORT    ;GET STATUS.
  2698.     ANI    SPKT    ;LOOK AT SPROCKET ONLY.
  2699.     MOV    B,A    ;SAVE IT.
  2700.     MOV    A,C    ;OLD STATUS
  2701.     CMA        ;IS INVERTED
  2702.     ANA    B    ;SO THAT + EDGE IS FOUND.
  2703.     MOV    C,B    ;SAVE CURRENT STATUS.
  2704.     JNZ    RIF15    ;NON-ZERO=GOT IT.
  2705.     DCX    D    ;DROP T/O COUNT
  2706.     MOV    A,D    ;SEE IF
  2707.     ORA    E    ;COUNT IS
  2708.     JNZ    RIF10    ;ZERO YET.
  2709.     STC
  2710.     POP    D
  2711.     POP    B
  2712.     RET
  2713. RIF15:
  2714.     IN    DPORT    ;AND GET DATA.
  2715.     ORA    A    ;CLEAR CARRY ONLY.
  2716.     POP    D
  2717.     POP    B    ;RESTORE BC
  2718.     RET        ;SIMPLY RETURN
  2719. ;
  2720. BYTEF:
  2721.     PUSH    B    ;SAVE BC
  2722.     CALL    RIXF    ;READ ASCII
  2723.     CALL    CNVBN    ;CONVERT TO HEX
  2724.     JC    LDERR    ;ERROR DETECTOR.
  2725.     RLC        ;SHIFT LEFT 4 BITS
  2726.     RLC
  2727.     RLC
  2728.     RLC
  2729.     MOV    B,A    ;SAVE THEM A WHILE
  2730.     CALL    RIXF    ;GET SECOND BYTE
  2731.     CALL    CNVBN    ;CONVERT TO HEX
  2732.     JC    LDERR    ;ERROR DETECTOR
  2733.     ORA    B    ;OR IN THE SAVED NYBBLE
  2734.     MOV    C,A    ;HOLD BYTE A WHILE.
  2735.     ADD    D    ;ADD TO CKSUM
  2736.     MOV    D,A    ;UPDATE CKSUM
  2737.     MOV    A,C    ;RESTORE BYTE
  2738.     POP    B    ;RESTORE BC
  2739.     RET
  2740. ;
  2741. ;
  2742. ;    END OF ROM ROUTINES.
  2743. ;
  2744. ;
  2745. ENDROM    EQU    $
  2746. ;
  2747. ;
  2748. ;    SYSTEM RAM AREA DEFINITION.
  2749. ;
  2750. ;
  2751.     ORG    RAM
  2752. ;
  2753. ;    STACK GOES IN HERE, PACKING DOWN FROM
  2754. ;    STORAGE AREA.
  2755. ;
  2756.     ORG    REGS
  2757. ;
  2758. ;    MONITOR REG. SAVE AREA.
  2759. ;
  2760. SVPC:
  2761. SVPCL:    DS    1    ;SAVED PC LOW
  2762. SVPCH:    DS    1    ;SAVED PC HI
  2763. SVSP:
  2764. SVSPL:    DS    1    ;SAVED SP LOW
  2765. SVSPH:    DS    1    ;SAVED SP HI
  2766. SVHL:
  2767. SVL:    DS    1    ;SAVED L
  2768. SVH:    DS    1    ;SAVED H
  2769. SVE:    DS    1    ;SAVED E
  2770. SVD:    DS    1    ;SAVED D
  2771. SVC:    DS    1    ;SAVED C
  2772. SVB:    DS    1    ;SAVED B
  2773. SVF:    DS    1    ;SAVED PSB, FLAGS
  2774. SVA:    DS    1    ;SAVED ACC
  2775. ;
  2776. ;    SPECIALS USED BY MONITOR
  2777. ;
  2778. BUFF:
  2779. TMPA:
  2780. GOGO:    DS    3
  2781. DSA:    DS    2    ;START OF ROM DATA
  2782. OPCODE:
  2783. DFA:    DS    2    ;END OF ROM DATA
  2784. MEMADR:
  2785. ROMADR:    DS    2    ;PROM ADDRESS POINTER.
  2786. ECHO:    DS    1    ;CHARACTER ECHO FLAG 0=NO ECHO
  2787. ADR:    DS    2    ;EXAMINE/MODIFY ADR
  2788. XEQAD:    DS    2    ;'X' EXECUTION ADR
  2789. BLKAD:    DS    2    ;'L' BLOCK ADR
  2790. BPADD:    DS    2    ;BREAKPOINT SAVE ADDRESS
  2791. BPDAT:    DS    6    ;BREAKPOINT SAVE DATA
  2792. USERA:    DS    2    ;USER FUNCTION VECTOR ADDRESS
  2793. ;
  2794. ;    USER VECTORS RST3-RST7
  2795. ;
  2796. RST3:    DS    2
  2797. RST4:    DS    2
  2798. RST5:    DS    2
  2799. RST6:    DS    2
  2800. RST7:    DS    2
  2801. ;
  2802. ;
  2803.     END
  2804.