4E00H - DEBUG Entry (code 87H): Save the Program's Registers
SYS0/SYS's overlay call enters SYS5/SYS here with Register A = 87H. 400FH (RST 30H) and 440DH both jump to 44B4H, which pushes the program's Register Pair AF and executes RST 28H with Register A = 87H; 4BA2H-4BA3H drop the RST's own return address and 4BFBH CALLs 4E00H. So the stack holds, from the top: the overlay call's return address 4BFEH, the program's Register Pair AF, and the program counter DEBUG is to show (the address after a CALL 440DH or an RST 30H, the transfer address when 4C12H jumps to 400FH, or the interrupted address when BREAK leaves the interrupt through 4316H). Register Pairs BC, DE and HL, Index Registers IX and IY and the alternate registers are the program's. SYS5/SYS copies all of them to 4065H-407CH, takes away an RST 30H breakpoint it finds, and goes into its command loop on the program's own stack.
4E00
POP AF F1
POP Register Pair AF from the stack: this takes off the overlay call's return address 4BFEH and discards it, so SYS5/SYS never returns into SYS0/SYS. 4BFFH-4C01H, which would put back the BREAK vector byte that 4BEEH-4BF5H saved into 4C00H and cleared at 4315H, are therefore not executed.
4E01
POP AF F1
POP Register Pair AF from the stack: Register A and the flags as the program had them, pushed at 44B4H.
4E02
PUSH AF F5
Save Register Pair AF (the program's) onto the stack again. This copy becomes the word copied to 4079H-407AH, which 4E1FH then overwrites with the program's Stack Pointer.
4E03
PUSH IY FD E5
Save Index Register IY (the program's) onto the stack; it is copied to 4077H-4078H.
4E05
PUSH IX DD E5
Save Index Register IX (the program's) onto the stack; it is copied to 4075H-4076H.
4E07
EX AF,AF' 08
Exchange Register Pair AF with the alternate Register Pair AF', so the program's alternate Register Pair AF is in Register Pair AF for the PUSH at 4E0CH.
4E08
EXX D9
EXX: switch Register Pairs BC, DE and HL to the alternate set, so the program's alternate registers can be pushed by 4E09H-4E0BH.
4E09
PUSH HL E5
Save Register Pair HL (the program's alternate Register Pair HL') onto the stack; it is copied to 4073H-4074H.
4E0A
PUSH DE D5
Save Register Pair DE (the program's alternate Register Pair DE') onto the stack; it is copied to 4071H-4072H.
4E0B
PUSH BC C5
Save Register Pair BC (the program's alternate Register Pair BC') onto the stack; it is copied to 406FH-4070H.
4E0C
PUSH AF F5
Save Register Pair AF (the program's alternate Register Pair AF') onto the stack; it is copied to 406DH-406EH.
4E0D
EX AF,AF' 08
Exchange Register Pair AF with the alternate Register Pair AF' again: the program's main Register Pair AF is back in Register Pair AF.
4E0E
EXX D9
EXX: switch back from the alternate set, so Register Pairs BC, DE and HL hold the program's main registers again.
4E0F
PUSH HL E5
Save Register Pair HL (the program's) onto the stack; it is copied to 406BH-406CH.
4E10
PUSH DE D5
Save Register Pair DE (the program's) onto the stack; it is copied to 4069H-406AH.
4E11
PUSH BC C5
Save Register Pair BC (the program's) onto the stack; it is copied to 4067H-4068H.
4E12
PUSH AF F5
Save Register Pair AF (the program's) onto the stack; it is copied to 4065H-4066H. The stack now holds twelve words: AF, BC, DE, HL, AF', BC', DE', HL', IX, IY, AF and the program counter.
4E13
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, ready to take the value of the Stack Pointer.
4E16
ADD HL,SP 39
ADD the Stack Pointer to Register Pair HL (0000H): Register Pair HL = the address of the twelve words just pushed, the source of the copy.
4E17
LD DE,4065H 11 65 40
Point Register Pair DE to 4065H, the start of DEBUG's register save area, the destination of the copy.
4E1A
LD BC,0018H 01 18 00
Load Register Pair BC with 0018H, the byte count: 24 bytes, the twelve words on the stack.
4E1D
LDIR ED B0
Copy the twelve words: LDIR moves 18H bytes from (HL) (Register Pair HL = the stack) to (DE) (Register Pair DE = 4065H), incrementing both, until Register Pair BC = 0000H. 4065H-407CH now hold AF, BC, DE, HL, AF', BC', DE', HL', IX, IY, a second AF and the program counter; Register Pair HL ends 24 bytes higher, at the program's own Stack Pointer (the stack as it was before the program counter was pushed).
4E1F
LD (4079H),HL 22 79 40
Store Register Pair HL (the program's Stack Pointer) into 4079H, replacing the second copy of Register Pair AF: 4079H-407AH is the Stack Pointer the register display shows and the Go command restores.
4E22
LD SP,HL F9
Load the Stack Pointer from Register Pair HL (the program's Stack Pointer): the twelve words are discarded, and DEBUG runs on the program's own stack.
4E23
LD HL,(407BH) 2A 7B 40
Fetch the program counter from 407BH (the word that was at the bottom of the twelve) into Register Pair HL.
4E26
DEC HL 2B
DECrement Register Pair HL (the program counter) by 1, to the byte before it.
4E27
LD A,(HL) 7E
Fetch the byte before the program counter from (HL) (Register Pair HL = program counter minus 1) into Register A.
4E28
CP F7H FE F7
Compare Register A (that byte) against F7H, the RST 30H instruction DEBUG plants as a breakpoint. If Register A equals F7H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E2A
If the NZ FLAG is set (the byte is not F7H), JUMP to 4E2FH and keep the program counter as it is.
4E2C
LD (407BH),HL 22 7B 40
Store Register Pair HL (program counter minus 1, the address of the RST 30H) into 407BH: after a breakpoint the program counter shown and resumed is the breakpoint address, whose own byte 4E2FH-4E49H puts back.
4E2F
LD HL,405DH 21 5D 40
Remove the Breakpoints
Point Register Pair HL to 405DH, the first of the two 3-byte breakpoint entries (405DH-405FH and 4060H-4062H: the address, low byte first, then the byte that was there). 4FD1H also jumps here when a breakpoint cannot be planted.
4E32
LD B,02H 06 02
Load Register B with 02H, the number of breakpoint entries to process.
4E34
XOR A AF
Breakpoint Loop
Set Register A to ZERO and clear all flags; Register A (00H) is the value that clears an entry's address. 4E49H loops back here.
4E35
LD C,02H 0E 02
Load Register C with 02H. The value is never used: 5131H saves and restores Register C without testing it, and 4EAEH, 4F0BH, 4FB1H, 5015H and 507BH load Register C before any use.
4E37
LD E,(HL) 5E
Fetch the low byte of the breakpoint address from (HL) (Register Pair HL = 405DH or 4060H) into Register E.
4E38
LD (HL),A 77
Store Register A (00H) to (HL) (Register Pair HL = the low byte of the address), clearing it.
4E39
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the breakpoint address (405EH or 4061H).
4E3A
LD D,(HL) 56
Fetch the high byte of the breakpoint address from (HL) (Register Pair HL = 405EH or 4061H) into Register D: Register Pair DE = the breakpoint address.
4E3B
LD (HL),A 77
Store Register A (00H) to (HL) (Register Pair HL = the high byte of the address), clearing it: the entry's address is now 0000H.
4E3C
INC HL 23
INCrement Register Pair HL by 1, to the entry's saved byte (405FH or 4062H).
4E3D
LD A,E 7B
Copy the low byte of the breakpoint address from Register E into Register A.
4E3E
OR D B2
OR Register A (the low byte) with Register D (the high byte): the Z FLAG is set when the address is 0000H, an unused entry.
4E3F
If the Z FLAG is set (no breakpoint in this entry), JUMP to 4E48H to go to the next entry.
4E41
LD A,(DE) 1A
Fetch the byte now at the breakpoint address from (DE) (Register Pair DE = the breakpoint address) into Register A.
4E42
CP F7H FE F7
Compare Register A against F7H, the RST 30H that was planted there. If Register A equals F7H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E44
If the NZ FLAG is set (the planted RST 30H is no longer there), JUMP to 4E48H and leave that byte alone.
4E46
LD A,(HL) 7E
Fetch the byte that was at the breakpoint address before it was planted from (HL) (Register Pair HL = the entry's saved byte, 405FH or 4062H) into Register A.
4E47
LD (DE),A 12
Store Register A (the original byte) to (DE) (Register Pair DE = the breakpoint address), putting the program's instruction back.
4E48
INC HL 23
INCrement Register Pair HL by 1, to the next entry (4060H). 4E3FH and 4E44H come here.
4E49
Breakpoint Loop End
DECrement Register B (the entries left) and LOOP BACK to 4E34H until both entries are done. The entry at 405DH, which the Go command and the step commands fill second, is processed first, so two breakpoints planted at the same address are put back in the right order.
4E4BH - The Command Loop
Every command returns here: 4E60H-4E63H push 4E4BH as the return address, and the hex input routine at 51ADH jumps here when a key that is not a hexadecimal digit is typed. The stack is reset to the program's Stack Pointer, the display is drawn, and one key is read on the bottom line of the screen.
4E4B
LD SP,(4079H) ED 7B 79 40
Load the Stack Pointer from 4079H, the program's Stack Pointer saved at 4E1FH (or as changed by the R command), discarding whatever a command left on the stack.
4E4F
GOSUB to 4ECFH to draw the display: the registers and four lines of memory, or a full screen of memory when the S command chose it.
4E52
LD HL,3FC0H 21 C0 3F
Point Register Pair HL to 3FC0H, the first position of the bottom line of the screen (line 15).
4E55
LD (4020H),HL 22 20 40
Store Register Pair HL (3FC0H) into 4020H, the cursor position in the ROM's video control block, so the command key is echoed at the start of the bottom line.
4E58
GOSUB to 518AH to wait for a key and echo it; Register A returns the key (ENTER, space and comma return with the Z FLAG set).
4E5B
CP 47H FE 47
Compare Register A (the key) against 47H (ASCII: G). If Register A equals 47H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E5D
If the Z FLAG is set (G), JUMP to 4F80H for the Go command, which does not return.
4E60
LD HL,4E4BH 21 4B 4E
Point Register Pair HL to 4E4BH, the command loop, as the return address for the commands below.
4E63
PUSH HL E5
Save Register Pair HL (4E4BH) onto the stack: each command's RET comes back to the command loop.
4E64
CP 53H FE 53
Compare Register A (the key) against 53H (ASCII: S). If Register A equals 53H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E66
If the Z FLAG is set (S), JUMP to 4E9AH to store Register A (53H) as the display mode: a full screen of memory.
4E68
CP 3BH FE 3B
Compare Register A (the key) against 3BH (ASCII: ;). If Register A equals 3BH, the Z FLAG is set; otherwise the NZ FLAG is set.
4E6A
If the Z FLAG is set (;), JUMP to 4EAEH to move the memory display forward.
4E6C
CP 2DH FE 2D
Compare Register A (the key) against 2DH (ASCII: -). If Register A equals 2DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4E6E
If the Z FLAG is set (-), JUMP to 4EC6H to move the memory display back.
4E70
CP 41H FE 41
Compare Register A (the key) against 41H (ASCII: A). If Register A equals 41H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E72
If the Z FLAG is set (A), JUMP to 4ECBH to store Register A (41H) at 405DH: memory bytes are shown as characters.
4E74
CP 43H FE 43
Compare Register A (the key) against 43H (ASCII: C). If Register A equals 43H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E76
If the Z FLAG is set (C), JUMP to 4E82H, the JP Z,505DH below, which the Z FLAG still set takes: the C command goes to the step code with Register A = 43H.
4E78
CP 44H FE 44
Compare Register A (the key) against 44H (ASCII: D). If Register A equals 44H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E7A
If the Z FLAG is set (D), JUMP to 4EA8H to read a new display address.
4E7C
CP 48H FE 48
Compare Register A (the key) against 48H (ASCII: H). If Register A equals 48H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E7E
If the Z FLAG is set (H), JUMP to 4ECBH to store Register A (48H) at 405DH: memory bytes are shown in hexadecimal.
4E80
CP 49H FE 49
Compare Register A (the key) against 49H (ASCII: I). If Register A equals 49H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E82
If the Z FLAG is set (I, or C from 4E76H), JUMP to 505DH to execute one instruction of the program, with Register A = the letter.
4E85
CP 4DH FE 4D
Compare Register A (the key) against 4DH (ASCII: M). If Register A equals 4DH, the Z FLAG is set; otherwise the NZ FLAG is set.
4E87
If the Z FLAG is set (M), JUMP to 4FDBH to examine and change memory.
4E8A
CP 52H FE 52
Compare Register A (the key) against 52H (ASCII: R). If Register A equals 52H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E8C
If the Z FLAG is set (R), JUMP to 5011H to change a register.
4E8F
CP 55H FE 55
Compare Register A (the key) against 55H (ASCII: U). If Register A equals 55H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E91
If the Z FLAG is set (U), JUMP to 4E9EH to keep redrawing the display until a key is pressed.
4E93
CP 58H FE 58
Compare Register A (the key) against 58H (ASCII: X). If Register A equals 58H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E95
If the Z FLAG is set (X), JUMP to 4E99H to go back to the register display.
4E97
RST 28H EF
Any other key (ENTER and space included): execute RST 28H with Register A = the key. Its bit 7 is clear, so 4BA5H sends it to the hook at 4312H; 4BA2H-4BA3H have dropped the RST's return address, and the default hook at 4BA0H (XOR A / RET) returns through the 4E4BH pushed at 4E63H, which redraws the display. A program that has put its own address in 4313H-4314H gets the key in Register A.
4E98
RET C9
RETURN to the command loop at 4E4BH. Nothing returns to this byte: the RST 28H's return address (4E98H) is dropped by 4BA2H-4BA3H.
4E99H - X and S: Choose the Display
X stores 00H and S stores 53H at 405EH, the display mode: 00H shows the registers with four lines of memory, any other value a full screen of memory.
4E99
XOR A AF
X Command
Set Register A to ZERO and clear all flags: 00H, the display mode for the registers.
4E9A
LD (405EH),A 32 5E 40
S Command
Store Register A (00H from 4E99H, or 53H for the S command from 4E66H) into 405EH, the display mode that 4ECFH and 4EB4H test. 405EH is also the high byte of the breakpoint entry at 405DH-405FH, so 4E3BH clears it, and the register display returns, each time DEBUG is entered.
4E9D
RET C9
RETURN to the command loop at 4E4BH, which draws the display in the chosen mode.
4E9EH - U: Keep Redrawing Until a Key Is Pressed
The U command redraws the display over and over, so memory that changes while DEBUG waits (the clock bytes at 4040H-4046H, the screen, a buffer filled by interrupts) is seen changing. Any key stops it; the key itself is not used as a command.
4E9E
Update Loop
GOSUB to ROM routine at 002BH to scan the keyboard once through the keyboard control block at 4015H; Register A returns the key, or 00H when none is pressed. 4EA6H loops back here.
4EA1
OR A B7
OR Register A (the key) with itself: the NZ FLAG is set when a key was pressed.
4EA2
RET NZ C0
If the NZ FLAG is set (a key was pressed), RETURN to the command loop at 4E4BH.
4EA3
GOSUB to 4ECFH to draw the display again with the current contents of memory.
4EA6
Update Loop End
LOOP BACK to 4E9EH to scan the keyboard again.
4EA8H - D: Set the Display Address
The D command takes a hexadecimal address and makes it the start of the memory shown under the registers (or of the full screen, rounded down to a 256-byte page).
4EA8
GOSUB to 51A3H to read a hexadecimal number into Register Pair HL; the Z FLAG returns set when no digit was typed.
4EAB
RET Z C8
If the Z FLAG is set (no address typed), RETURN to the command loop at 4E4BH with the display address unchanged.
4EAC
JUMP to 4EC2H to store Register Pair HL (the address typed) as the display address.
4EAEH - ; and -: Move the Memory Display
The semicolon moves the display address forward and the minus sign moves it back: by 40H bytes (the four lines shown under the registers) in the register display, by 100H bytes (one full screen) when the S command chose the full screen of memory.
4EAE
LD BC,0040H 01 40 00
; Command
Load Register Pair BC with 0040H, 64 bytes forward, the four lines of 16 bytes under the registers.
4EB1
LD HL,(4063H) 2A 63 40
Fetch the display address from 4063H into Register Pair HL. 4EC9H comes here with Register Pair BC = FFC0H.
4EB4
LD A,(405EH) 3A 5E 40
Fetch the display mode from 405EH into Register A (00H for the registers, 53H for a full screen of memory).
4EB7
OR A B7
OR Register A (the display mode) with itself: the Z FLAG is set for the register display.
4EB8
If the Z FLAG is set (register display), JUMP to 4EC1H to move by Register Pair BC (0040H or FFC0H).
4EBA
LD C,00H 0E 00
Load Register C with 00H: Register Pair BC = 0000H for the semicolon or FF00H for the minus sign, a whole number of pages.
4EBC
LD A,B 78
Copy Register B (00H for the semicolon, FFH for the minus sign) into Register A.
4EBD
OR A B7
OR Register A with itself: the NZ FLAG is set for the minus sign (Register B = FFH).
4EBE
If the NZ FLAG is set (minus sign, Register Pair BC = FF00H, 256 back), JUMP to 4EC1H.
4EC0
INC B 04
INCrement Register B by 1 (from 00H to 01H): Register Pair BC = 0100H, 256 bytes forward for the semicolon.
4EC1
ADD HL,BC 09
ADD Register Pair BC (the step) to Register Pair HL (the display address). 4EB8H and 4EBEH come here.
4EC2
LD (4063H),HL 22 63 40
Store Register Pair HL (the new display address) into 4063H. 4EACH comes here with the address typed after D.
4EC5
RET C9
RETURN to the command loop at 4E4BH, which draws the display at the new address.
4EC6
LD BC,FFC0H 01 C0 FF
- Command
Load Register Pair BC with FFC0H, 64 bytes back (minus 40H).
4EC9
JUMP to 4EB1H to apply Register Pair BC to the display address.
4ECBH - A and H: Characters or Hexadecimal
A stores 41H and H stores 48H at 405DH. When 405DH holds 41H the memory lines show each byte as a character; otherwise they show it as two hexadecimal digits. 405DH is also the low byte of the breakpoint entry at 405DH-405FH, so 4E38H clears it, and hexadecimal returns, each time DEBUG is entered.
4ECB
LD (405DH),A 32 5D 40
Store Register A (41H for A, 48H for H) into 405DH, which 5144H-5147H test for 41H.
4ECE
RET C9
RETURN to the command loop at 4E4BH, which draws the memory in the chosen form.
4ECFH - Draw the Display
Called by the command loop (4E4FH), the U command (4EA3H) and the M command (4FE6H). With 405EH = 00H it shows the twelve saved registers on lines 0-11, each with its value and either the flags (AF and AF') or the 16 bytes it points to, then four lines of memory from the display address at 4063H. With any other value at 405EH it shows sixteen lines of memory, the 256-byte page holding the display address. Every character goes through the ROM display routine at 0033H, which keeps Register A, Register Pair BC and Register Pair HL and leaves Register Pair DE = 401DH.
4ECF
LD A,(405EH) 3A 5E 40
Fetch the display mode from 405EH into Register A (00H for the registers, 53H after the S command).
4ED2
OR A B7
OR Register A (the display mode) with itself: the NZ FLAG is set for a full screen of memory.
4ED3
If the NZ FLAG is set, JUMP to 4F45H to show a full screen of memory.
4ED5
LD A,1CH 3E 1C
Register Display
Load Register A with 1CH, the video control code that moves the cursor to the top left corner (3C00H).
4ED7
GOSUB to ROM routine at 0033H to send the control code in Register A (1CH) to the display.
4EDA
LD HL,4065H 21 65 40
Point Register Pair HL to 4065H, the first saved register (the program's Register Pair AF).
4EDD
PUSH HL E5
Save Register Pair HL (4065H, the pointer into the saved registers) onto the stack. The loop keeps one of its two pointers on the stack and swaps them with EX (SP),HL.
4EDE
LD HL,4F54H 21 54 4F
Point Register Pair HL to 4F54H, the table of register names, three characters each.
4EE1
LD B,0CH 06 0C
Load Register B with 0CH, the number of registers to show (twelve lines).
4EE3
JUMP to 4EEAH, skipping the carriage return for the first line.
4EE5
LD A,0DH 3E 0D
Register Loop
Load Register A with 0DH, a carriage return. 4F2CH loops back here.
4EE7
GOSUB to ROM routine at 0033H to send the carriage return in Register A to the display: the cursor moves to the next line, which the ROM blanks.
4EEA
GOSUB to 51F6H to display the three characters of the register's name from (HL) (Register Pair HL = the name table); Register Pair HL returns at the next name.
4EED
EX (SP),HL E3
Exchange Register Pair HL (the next name) with the top of the stack (Stack Pointer = the pointer into the saved registers): Register Pair HL = the saved register's address, and the name pointer is kept on the stack.
4EEE
LD E,(HL) 5E
Fetch the low byte of the saved register from (HL) (Register Pair HL = its address in 4065H-407CH) into Register E.
4EEF
INC HL 23
INCrement Register Pair HL by 1, to the saved register's high byte.
4EF0
LD D,(HL) 56
Fetch the high byte of the saved register from (HL) (Register Pair HL = its address plus 1) into Register D: Register Pair DE = the register's value.
4EF1
INC HL 23
INCrement Register Pair HL by 1, to the next saved register.
4EF2
PUSH HL E5
Save Register Pair HL (the next saved register's address) onto the stack, above the name pointer.
4EF3
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the register's value.
4EF4
LD A,3DH 3E 3D
Load Register A with 3DH (ASCII: =), shown after the name.
4EF6
GOSUB to ROM routine at 0033H to display the character in Register A (=).
4EF9
GOSUB to 51F2H to display a space after the equals sign, before the value.
4EFC
LD A,H 7C
Copy the high byte of the register's value from Register H into Register A.
4EFD
GOSUB to 51EFH to display Register A (the high byte) as two hexadecimal digits and a space.
4F00
LD A,L 7D
Copy the low byte of the register's value from Register L into Register A.
4F01
GOSUB to 51EFH to display Register A (the low byte) as two hexadecimal digits and a space.
4F04
LD A,B 78
Copy the line counter from Register B (0CH for the first line down to 01H for the last) into Register A.
4F05
AND 0BH E6 0B
AND Register A (the line counter) with 0BH: the result is 08H only for 0CH (AF) and 08H (AF').
4F07
CP 08H FE 08
Compare Register A against 08H. If Register A equals 08H (the line for AF or AF'), the Z FLAG is set; otherwise the NZ FLAG is set.
4F09
If the NZ FLAG is set (any other register), JUMP to 4F27H to show the 16 bytes the register points to.
4F0B
LD C,L 4D
Show the Flags
Copy the low byte of the value from Register L into Register C: Register C = the saved flag register F.
4F0C
PUSH BC C5
Save Register Pair BC (Register B = the line counter, Register C = the flags) onto the stack.
4F0D
LD HL,4F78H 21 78 4F
Point Register Pair HL to 4F78H, the eight flag letters SZ1H1PNC, one for each bit of Register C from bit 7 down.
4F10
LD B,08H 06 08
Load Register B with 08H, the number of flag bits.
4F12
SLA C CB 21
Flag Loop
Shift Register C (the flags) left: the highest flag bit not yet shown goes into the CARRY FLAG. 4F1DH loops back here.
4F14
LD A,(HL) 7E
Fetch the flag's letter from (HL) (Register Pair HL = the letter table) into Register A.
4F15
If the CARRY FLAG is set (the flag is set), JUMP to 4F19H to show its letter.
4F17
LD A,2DH 3E 2D
Load Register A with 2DH (ASCII: -), shown for a flag that is clear.
4F19
GOSUB to ROM routine at 0033H to display Register A (the letter or the minus sign). 4F15H comes here.
4F1C
INC HL 23
INCrement Register Pair HL by 1, to the next flag letter.
4F1D
Flag Loop End
DECrement Register B and LOOP BACK to 4F12H until all eight flags are shown.
4F1F
POP BC C1
Restore Register Pair BC (Register B = the line counter) from the stack.
4F20
LD A,ECH 3E EC
Load Register A with ECH, the video space compression code for 44 spaces (ECH minus C0H = 2CH). The line is then 62 characters long, as long as a line with 16 memory bytes, and the 44 spaces overwrite what the line held before: line 0 follows the home code, not a carriage return, so it was not blanked.
4F22
GOSUB to ROM routine at 0033H to display the space compression code in Register A (44 spaces).
4F25
JUMP to 4F2AH to go on to the next register, skipping the memory bytes for AF and AF'.
4F27
GOSUB to 5131H to display => and the 16 bytes from the address in Register Pair HL (the register's value). 4F09H comes here.
4F2A
POP HL E1
Restore Register Pair HL (the next saved register's address) from the stack. 4F25H comes here.
4F2B
EX (SP),HL E3
Exchange Register Pair HL with the top of the stack (Stack Pointer = the name pointer): Register Pair HL = the next name, and the saved register pointer goes back on the stack.
4F2C
Register Loop End
DECrement Register B (the line counter) and LOOP BACK to 4EE5H until all twelve registers are shown.
4F2E
POP HL E1
Restore Register Pair HL from the stack, discarding the saved register pointer.
4F2F
LD HL,(4063H) 2A 63 40
Memory Lines
Fetch the display address from 4063H into Register Pair HL, the first byte of the four lines of memory.
4F32
LD B,04H 06 04
Load Register B with 04H, four lines of 16 bytes.
4F34
LD A,C7H 3E C7
Memory Line Loop
Load Register A with C7H, the video space compression code for 7 spaces. In the register display the cursor stands two positions before the end of the line (each register line and each memory line is 62 characters), so the spaces finish that line and indent the next one by five, which puts its => under the => of the register lines. 4F42H loops back here, and 4F52H comes here with Register B = 10H.
4F36
GOSUB to ROM routine at 0033H to display the space compression code in Register A (7 spaces).
4F39
GOSUB to 51D4H to display Register Pair HL (the line's first address) as four hexadecimal digits.
4F3C
GOSUB to 51F2H to display a space between the address and the arrow.
4F3F
GOSUB to 5131H to display => and the 16 bytes from the address in Register Pair HL; Register Pair HL returns 16 bytes further on, at the next line's first address.
4F42
Memory Line Loop End
DECrement Register B (the lines left) and LOOP BACK to 4F34H until all the lines are shown.
4F44
RET C9
RETURN to the caller (4E4FH, 4EA3H or 4FE6H) with the display drawn.
4F45
LD HL,3BFFH 21 FF 3B
Full Screen of Memory
Point Register Pair HL to 3BFFH, the position just before the first character of the screen (3C00H). 4ED3H comes here.
4F48
LD (4020H),HL 22 20 40
Store Register Pair HL (3BFFH) into 4020H, the cursor position in the ROM's video control block. Each line is 64 characters (7 spaces, four digits, a space and the 52 characters of 5131H), so starting one position early (the first space goes to 3BFFH, outside the screen) places every line's address at the same column and the sixteen lines end at 3FFEH without scrolling.
4F4B
LD HL,(4063H) 2A 63 40
Fetch the display address from 4063H into Register Pair HL.
4F4E
LD L,00H 2E 00
Load Register L with 00H: Register Pair HL = the start of the 256-byte page holding the display address. The value at 4063H is not changed.
4F50
LD B,10H 06 10
Load Register B with 10H, sixteen lines of 16 bytes: the whole page.
4F52
JUMP to 4F34H to show the sixteen lines of the page in Register Pair HL.
4F54H - Register Names and Flag Letters (Data)
Data, not code: the twelve register names shown at the start of each line of the register display (three characters each, in the order of the save area at 4065H-407CH) and the eight letters shown for the bits of a flag register. The R command (5029H) searches the same name table.
4F54-4F56
DEFM "AF " 41 46 20
Name of the first register line, Register Pair AF, saved at 4065H-4066H.
4F57-4F59
DEFM "BC " 42 43 20
Name of Register Pair BC, saved at 4067H-4068H.
4F5A-4F5C
DEFM "DE " 44 45 20
Name of Register Pair DE, saved at 4069H-406AH.
4F5D-4F5F
DEFM "HL " 48 4C 20
Name of Register Pair HL, saved at 406BH-406CH.
4F60-4F62
DEFM "AF'" 41 46 27
Name of the alternate Register Pair AF', saved at 406DH-406EH.
4F63-4F65
DEFM "BC'" 42 43 27
Name of the alternate Register Pair BC', saved at 406FH-4070H.
4F66-4F68
DEFM "DE'" 44 45 27
Name of the alternate Register Pair DE', saved at 4071H-4072H.
4F69-4F6B
DEFM "HL'" 48 4C 27
Name of the alternate Register Pair HL', saved at 4073H-4074H.
4F6C-4F6E
DEFM "IX " 49 58 20
Name of Index Register IX, saved at 4075H-4076H.
4F6F-4F71
DEFM "IY " 49 59 20
Name of Index Register IY, saved at 4077H-4078H.
4F72-4F74
DEFM "SP " 53 50 20
Name of the Stack Pointer, saved at 4079H-407AH.
4F75-4F77
DEFM "PC " 50 43 20
Name of the program counter, saved at 407BH-407CH: the address the Go command resumes at.
4F78-4F7F
DEFM "SZ1H1PNC" 53 5A 31 48 31 50 4E 43
The flag letters for bits 7 to 0 of a flag register: S sign, Z zero, 1 for bit 5, H half carry, 1 for bit 3, P parity or overflow, N subtract, C carry. 4F12H-4F1DH show a letter for a set bit and a minus sign for a clear one.
4F80H - G: Go
The G command takes up to three hexadecimal numbers: a new program counter, then up to two breakpoint addresses, separated by spaces or commas and ended by ENTER. G with no number resumes at the saved program counter. Each breakpoint is planted as an F7H byte (RST 30H) and recorded in the entries at 4060H-4062H and 405DH-405FH; the BREAK vector is armed to re-enter DEBUG through 400FH; then every saved register is put back and the program continues. Execution reaches 400FH, and SYS5/SYS again, when a breakpoint's RST 30H executes or BREAK is pressed.
4F80
LD B,02H 06 02
Load Register B with 02H, the number of breakpoints that can be given.
4F82
LD DE,4062H 11 62 40
Point Register Pair DE to 4062H, the saved byte of the breakpoint entry at 4060H-4062H; 4FCAH fills the entries downward from here.
4F85
GOSUB to 51A3H to read a hexadecimal number into Register Pair HL: the Z FLAG returns set when no digit was typed, the CARRY FLAG set when ENTER ended it.
4F88
If the Z FLAG is set (no new program counter typed), JUMP to 4F8DH and keep the saved one.
4F8A
LD (407BH),HL 22 7B 40
Store Register Pair HL (the address typed) into 407BH, the saved program counter: execution will resume there.
4F8D
Breakpoint Loop
If the CARRY FLAG is set (ENTER ended the last number), JUMP to 4F99H to start the program. 4F88H comes here, and 4F97H loops back here with the flags of the last number restored.
4F8F
GOSUB to 51A3H to read a breakpoint address into Register Pair HL (Z FLAG: no digit typed; CARRY FLAG: ended by ENTER).
4F92
PUSH AF F5
Save Register Pair AF (the flags from 51A3H) onto the stack, so 4F8DH can test the CARRY FLAG after the breakpoint is planted.
4F93
If the NZ FLAG is set (an address was typed), GOSUB to 4FCAH to plant a breakpoint at the address in Register Pair HL and record it at (DE) (Register Pair DE = 4062H, then 405FH).
4F96
POP AF F1
Restore Register Pair AF (the flags from 51A3H) from the stack.
4F97
Breakpoint Loop End
DECrement Register B (the breakpoints left) and LOOP BACK to 4F8DH while another can be given.
4F99
LD HL,400FH 21 0F 40
Arm BREAK and Resume
Point Register Pair HL to 400FH, the RST 30H vector (JP 44B4H), which enters DEBUG. 4F8DH comes here.
4F9C
LD (4316H),HL 22 16 43
Store Register Pair HL (400FH) into 4316H, the address part of the BREAK vector.
4F9F
LD A,C3H 3E C3
Load Register A with C3H, the JP opcode, the byte that arms the BREAK vector.
4FA1
LD (4315H),A 32 15 43
Store Register A (C3H) into 4315H: the BREAK vector is now JP 400FH, so pressing BREAK while the program runs makes the interrupt handler (454FH) leave through 400FH with the interrupted address on the stack, and DEBUG is entered there.
4FA4
LD HL,407AH 21 7A 40
Put Back the Registers
Point Register Pair HL to 407AH, the high byte of the saved Stack Pointer, the top of the eleven words to push. The step commands jump here from 50B4H without arming BREAK.
4FA7
LD B,0BH 06 0B
Load Register B with 0BH, eleven words: SP, IY, IX, HL', DE', BC', AF', HL, DE, BC and AF.
4FA9
LD D,(HL) 56
Push Loop
Fetch the high byte of a saved word from (HL) (Register Pair HL = 407AH downward) into Register D. 4FAEH loops back here.
4FAA
DEC HL 2B
DECrement Register Pair HL by 1, to the low byte of the saved word.
4FAB
LD E,(HL) 5E
Fetch the low byte of the saved word from (HL) (Register Pair HL = the word's low byte) into Register E: Register Pair DE = the saved word.
4FAC
DEC HL 2B
DECrement Register Pair HL by 1, to the high byte of the word below.
4FAD
PUSH DE D5
Save Register Pair DE (the saved word) onto the stack (the Stack Pointer is the program's, set at 4E4BH, minus what the command pushed).
4FAE
Push Loop End
DECrement Register B and LOOP BACK to 4FA9H until the eleven words, from the saved Stack Pointer at 4079H down to Register Pair AF at 4065H, are on the stack.
4FB0
POP AF F1
POP Register Pair AF from the stack: the program's Register A and flags (from 4065H).
4FB1
POP BC C1
POP Register Pair BC from the stack: the program's Register Pair BC (from 4067H).
4FB2
POP DE D1
POP Register Pair DE from the stack: the program's Register Pair DE (from 4069H).
4FB3
POP HL E1
POP Register Pair HL from the stack: the program's Register Pair HL (from 406BH); 4FC6H loads it again after Register Pair HL is used.
4FB4
EX AF,AF' 08
Exchange Register Pair AF with the alternate Register Pair AF', to load the program's alternate Register Pair AF.
4FB5
EXX D9
EXX: switch Register Pairs BC, DE and HL to the alternate set, to load the program's alternate registers.
4FB6
POP AF F1
POP Register Pair AF from the stack: the program's alternate Register Pair AF' (from 406DH).
4FB7
POP BC C1
POP Register Pair BC from the stack: the program's alternate Register Pair BC' (from 406FH).
4FB8
POP DE D1
POP Register Pair DE from the stack: the program's alternate Register Pair DE' (from 4071H).
4FB9
POP HL E1
POP Register Pair HL from the stack: the program's alternate Register Pair HL' (from 4073H).
4FBA
EX AF,AF' 08
Exchange Register Pair AF with the alternate Register Pair AF' again: the program's main Register Pair AF is in place.
4FBB
EXX D9
EXX: switch back from the alternate set; Register Pairs BC and DE hold the program's main values.
4FBC
POP IX DD E1
POP Index Register IX from the stack: the program's Index Register IX (from 4075H).
4FBE
POP IY FD E1
POP Index Register IY from the stack: the program's Index Register IY (from 4077H).
4FC0
POP HL E1
POP Register Pair HL from the stack: the program's Stack Pointer (from 4079H).
4FC1
LD SP,HL F9
Load the Stack Pointer from Register Pair HL: the program's Stack Pointer, as saved or as changed with the R command.
4FC2
LD HL,(407BH) 2A 7B 40
Fetch the program counter from 407BH into Register Pair HL.
4FC5
PUSH HL E5
Save Register Pair HL (the program counter) onto the program's stack, for the RET below to take.
4FC6
LD HL,(406BH) 2A 6B 40
Fetch the program's Register Pair HL from 406BH into Register Pair HL (LD does not change the flags POPped at 4FB0H).
4FC9
RET C9
RETURN, which takes the program counter off the stack and jumps to it: the program continues with all its registers and its own Stack Pointer.
4FCAH - Plant a Breakpoint
Called by the Go command (4F93H) and the step commands (5095H, 50DBH) with Register Pair HL = the address and Register Pair DE = the saved byte of the next free breakpoint entry (4062H, then 405FH). The byte at the address is saved, an F7H (RST 30H) is written over it, and the address is recorded below the saved byte. If the memory does not keep the F7H (ROM, or no memory there), the command is abandoned at 4E2FH.
4FCA
LD A,(HL) 7E
Fetch the byte at the breakpoint address from (HL) (Register Pair HL = the address) into Register A.
4FCB
LD (DE),A 12
Store Register A (the original byte) to (DE) (Register Pair DE = the entry's saved byte, 4062H or 405FH), so 4E46H-4E47H can put it back.
4FCC
DEC DE 1B
DECrement Register Pair DE by 1, to the high byte of the entry's address (4061H or 405EH).
4FCD
LD A,F7H 3E F7
Load Register A with F7H, the RST 30H instruction: executing it jumps to 0030H, then to 400FH and into DEBUG.
4FCF
LD (HL),A 77
Store Register A (F7H) to (HL) (Register Pair HL = the breakpoint address).
4FD0
CP (HL) BE
Compare Register A (F7H) with the byte at (HL) (Register Pair HL = the breakpoint address): the Z FLAG is set when the memory kept the F7H.
4FD1
If the NZ FLAG is set (the F7H did not stay: ROM or no memory), JUMP to 4E2FH to take out any breakpoint already planted and go back to the command loop. The program does not start.
4FD4
LD A,H 7C
Copy the high byte of the breakpoint address from Register H into Register A.
4FD5
LD (DE),A 12
Store Register A (the high byte) to (DE) (Register Pair DE = 4061H or 405EH).
4FD6
DEC DE 1B
DECrement Register Pair DE by 1, to the low byte of the entry's address (4060H or 405DH).
4FD7
LD A,L 7D
Copy the low byte of the breakpoint address from Register L into Register A.
4FD8
LD (DE),A 12
Store Register A (the low byte) to (DE) (Register Pair DE = 4060H or 405DH).
4FD9
DEC DE 1B
DECrement Register Pair DE by 1, to the saved byte of the next entry (405FH after the first breakpoint).
4FDA
RET C9
RETURN to the caller with the breakpoint planted and recorded.
4FDBH - M: Examine and Change Memory
The M command takes an address (or uses the one at 4060H-4061H from the last M command; it is 0000H after DEBUG is entered, since 4E37H-4E3BH clear it with the breakpoint entry). ENTER after the address only records it, so the byte is marked in the display. A space or comma goes on: the display is drawn with the byte marked, its address is shown at the start of line 13 and its value at the start of line 14 followed by a minus sign, and a new value can be typed. Each space or comma moves to the next address; ENTER ends the command.
4FDB
LD HL,(4060H) 2A 60 40
Fetch the last M address from 4060H into Register Pair HL, kept when no address is typed.
4FDE
GOSUB to 51A3H to read a hexadecimal address into Register Pair HL (Z FLAG: none typed, Register Pair HL unchanged; CARRY FLAG: ended by ENTER).
4FE1
LD (4060H),HL 22 60 40
Address Loop
Store Register Pair HL (the address being examined) into 4060H, where 5165H finds it to mark that byte in the display. 500FH loops back here with the next address.
4FE4
RET C D8
If the CARRY FLAG is set (ENTER), RETURN to the command loop at 4E4BH.
4FE5
PUSH HL E5
Save Register Pair HL (the address being examined) onto the stack.
4FE6
GOSUB to 4ECFH to draw the display, with the byte at the address in 4060H marked by bars on both sides.
4FE9
LD HL,3F40H 21 40 3F
Point Register Pair HL to 3F40H, the first position of line 13, where the memory lines leave the first columns blank.
4FEC
LD (4020H),HL 22 20 40
Store Register Pair HL (3F40H) into 4020H, the cursor position in the ROM's video control block.
4FEF
LD HL,(4060H) 2A 60 40
Fetch the address being examined from 4060H into Register Pair HL.
4FF2
GOSUB to 51D4H to display Register Pair HL (the address) as four hexadecimal digits at the start of line 13.
4FF5
PUSH HL E5
Save Register Pair HL (the address being examined) onto the stack.
4FF6
LD HL,3F80H 21 80 3F
Point Register Pair HL to 3F80H, the first position of line 14.
4FF9
LD (4020H),HL 22 20 40
Store Register Pair HL (3F80H) into 4020H, the cursor position in the ROM's video control block.
4FFC
POP HL E1
Restore Register Pair HL (the address being examined) from the stack.
4FFD
GOSUB to 51D0H to display the byte at (HL) (Register Pair HL = the address) as two hexadecimal digits at the start of line 14.
5000
LD A,2DH 3E 2D
Load Register A with 2DH (ASCII: -), shown before the new value.
5002
GOSUB to ROM routine at 0033H to display the character in Register A (-).
5005
POP DE D1
Restore Register Pair DE from the stack: the address being examined, pushed at 4FE5H.
5006
GOSUB to 51A3H to read a new value into Register Pair HL (Register L is the byte used); the Z FLAG returns set when none was typed, the CARRY FLAG when ENTER ended it.
5009
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the address being examined, Register Pair DE = the value typed (the flags are kept).
500A
If the Z FLAG is set (no new value), JUMP to 500DH and leave the byte as it is.
500C
LD (HL),E 73
Store Register E (the low byte of the value typed) to (HL) (Register Pair HL = the address being examined).
500D
RET C D8
If the CARRY FLAG is set (ENTER), RETURN to the command loop at 4E4BH. 500AH comes here.
500E
INC HL 23
INCrement Register Pair HL by 1, to the next address.
500F
Address Loop End
LOOP BACK to 4FE1H to record and show the next address.
5011H - R: Change a Register
The R command takes a register name as the display shows it (two letters, plus an apostrophe for an alternate register), then a space or comma and a hexadecimal value, which is stored in the saved register in 4065H-407CH. SP and PC can be changed too; the Go command uses the saved values. A wrong name, or ENTER before the value, leaves everything as it was.
5011
GOSUB to 518AH to read and echo the first letter of the name into Register A.
5014
RET Z C8
If the Z FLAG is set (ENTER, space or comma instead of a letter), RETURN to the command loop at 4E4BH.
5015
LD C,A 4F
Copy the first letter from Register A into Register C.
5016
GOSUB to 518AH to read and echo the second letter of the name into Register A.
5019
RET Z C8
If the Z FLAG is set (ENTER, space or comma), RETURN to the command loop at 4E4BH.
501A
LD D,A 57
Copy the second letter from Register A into Register D.
501B
LD E,20H 1E 20
Load Register E with 20H, a space: the third character of a two-letter name in the table at 4F54H.
501D
GOSUB to 518AH to read and echo the next key into Register A.
5020
RET C D8
If the CARRY FLAG is set (ENTER), RETURN to the command loop at 4E4BH without a change.
5021
If the Z FLAG is set (space or comma), JUMP to 5029H with the two-letter name in Register C, Register D and Register E (20H).
5023
LD E,A 5F
Copy the third character from Register A into Register E (an apostrophe for AF', BC', DE' and HL').
5024
GOSUB to 518AH to read and echo the key after the name into Register A.
5027
RET NZ C0
If the NZ FLAG is set (not a space or comma), RETURN to the command loop at 4E4BH.
5028
RET C D8
If the CARRY FLAG is set (ENTER), RETURN to the command loop at 4E4BH.
5029
LD HL,4F54H 21 54 4F
Find the Name
Point Register Pair HL to 4F54H, the table of register names. 5021H comes here.
502C
LD B,0CH 06 0C
Load Register B with 0CH, the number of names (twelve).
502E
LD A,(HL) 7E
Name Loop
Fetch the first character of a name from (HL) (Register Pair HL = the name table) into Register A. 5035H loops back here.
502F
CP C B9
Compare Register A (the name's first character) with Register C (the first letter typed). If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
5030
If the Z FLAG is set, JUMP to 5038H to compare the second character.
5032
INC HL 23
INCrement Register Pair HL by 1 (the first of three steps to the next name).
5033
INC HL 23
INCrement Register Pair HL by 1. 503BH comes here after a match of the first character.
5034
INC HL 23
INCrement Register Pair HL by 1, to the next name. 5040H comes here after a match of two characters.
5035
Name Loop End
DECrement Register B (the names left) and LOOP BACK to 502EH.
5037
RET C9
RETURN to the command loop at 4E4BH: no name matched.
5038
INC HL 23
INCrement Register Pair HL by 1, to the name's second character. 5030H comes here.
5039
LD A,(HL) 7E
Fetch the name's second character from (HL) (Register Pair HL = the name plus 1) into Register A.
503A
CP D BA
Compare Register A with Register D (the second letter typed). If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
503B
If the NZ FLAG is set, JUMP to 5033H to step to the next name.
503D
INC HL 23
INCrement Register Pair HL by 1, to the name's third character.
503E
LD A,(HL) 7E
Fetch the name's third character from (HL) (Register Pair HL = the name plus 2) into Register A.
503F
CP E BB
Compare Register A with Register E (the third character typed, or 20H). If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
5040
If the NZ FLAG is set, JUMP to 5034H to step to the next name.
5042
LD A,18H 3E 18
Load Register A with 18H (24). Register B holds 0CH for the first name (AF) down to 01H for the last (PC).
5044
SUB B 90
SUBtract Register B (the names left when the match was found) from Register A.
5045
SUB B 90
SUBtract Register B from Register A again: Register A = 24 minus twice Register B, the offset of the register in the save area (00H for AF up to 16H for PC).
5046
LD C,A 4F
Copy the offset from Register A into Register C.
5047
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset.
5049
LD HL,4065H 21 65 40
Point Register Pair HL to 4065H, the start of the register save area.
504C
ADD HL,BC 09
ADD Register Pair BC (the offset) to Register Pair HL: Register Pair HL = the saved register (4065H for AF up to 407BH for PC).
504D
PUSH HL E5
Save Register Pair HL (the saved register's address) onto the stack.
504E
LD A,1EH 3E 1E
Load Register A with 1EH, the video control code that erases to the end of the line.
5050
GOSUB to ROM routine at 0033H to send the control code in Register A (1EH), clearing the rest of the bottom line for the value.
5053
POP DE D1
Restore Register Pair DE from the stack: the saved register's address.
5054
GOSUB to 51A3H to read the new value into Register Pair HL; the Z FLAG returns set when none was typed.
5057
RET Z C8
If the Z FLAG is set (no value), RETURN to the command loop at 4E4BH with the register unchanged.
5058
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the saved register's address, Register Pair DE = the new value.
5059
LD (HL),E 73
Store Register E (the low byte of the new value) to (HL) (Register Pair HL = the saved register's low byte).
505A
INC HL 23
INCrement Register Pair HL by 1, to the saved register's high byte.
505B
LD (HL),D 72
Store Register D (the high byte of the new value) to (HL) (Register Pair HL = the saved register's high byte).
505C
RET C9
RETURN to the command loop at 4E4BH, which shows the new value.
505DH - I and C: Execute One Instruction
Entered from 4E82H with Register A = 49H (I) or 43H (C) and the Z FLAG set. SYS5/SYS finds the length and kind of the instruction at the saved program counter from the table at 50E0H, plants a breakpoint on the instruction after it, and for a jump, a return, or (with I) a call, a second breakpoint where it can go. Then it puts back the registers at 4FA4H and lets that one instruction run; the breakpoint brings the program back into DEBUG. C differs from I only on CALL instructions: the subroutine runs at full speed and DEBUG stops after it returns. BREAK is not armed for a step.
505D
PUSH AF F5
Save Register Pair AF (Register A = 49H for I or 43H for C) onto the stack; 50AFH takes it back for a CALL instruction.
505E
LD DE,(407BH) ED 5B 7B 40
Fetch the saved program counter from 407BH into Register Pair DE: the address of the instruction to execute.
5062
LD A,(DE) 1A
Fetch the instruction's first byte from (DE) (Register Pair DE = the program counter) into Register A.
5063
LD HL,5115H 21 15 51
Point Register Pair HL to 5115H, the part of the table for instructions after a DDH or FDH prefix (Index Register IX or IY).
5066
CP DDH FE DD
Compare Register A (the first byte) against DDH, the Index Register IX prefix. If Register A equals DDH, the Z FLAG is set; otherwise the NZ FLAG is set.
5068
If the Z FLAG is set (DDH prefix), JUMP to 5078H to classify the byte after the prefix.
506A
CP FDH FE FD
Compare Register A (the first byte) against FDH, the Index Register IY prefix. If Register A equals FDH, the Z FLAG is set; otherwise the NZ FLAG is set.
506C
If the Z FLAG is set (FDH prefix), JUMP to 5078H to classify the byte after the prefix.
506E
LD HL,50E0H 21 E0 50
Point Register Pair HL to 50E0H, the part of the table for instructions without a prefix.
5071
CP EDH FE ED
Compare Register A (the first byte) against EDH, the extended instruction prefix. If Register A equals EDH, the Z FLAG is set; otherwise the NZ FLAG is set.
5073
If the NZ FLAG is set (no prefix), JUMP to 507BH to classify the first byte itself.
5075
LD HL,510EH 21 0E 51
Point Register Pair HL to 510EH, the part of the table for instructions after an EDH prefix.
5078
INC DE 13
INCrement Register Pair DE by 1, to the byte after the prefix. 5068H and 506CH come here.
5079
LD A,(DE) 1A
Fetch the byte after the prefix from (DE) (Register Pair DE = program counter plus 1) into Register A.
507A
DEC DE 1B
DECrement Register Pair DE by 1, back to the program counter.
507B
LD C,A 4F
Copy the byte to classify from Register A into Register C (the first byte, or the byte after a prefix). 5073H comes here.
507C
LD A,(HL) 7E
Table Loop
Fetch an entry's mask from (HL) (Register Pair HL = the table entry) into Register A. 5087H loops back here.
507D
AND C A1
AND Register A (the mask) with Register C (the byte to classify), keeping the bits that identify the instruction group.
507E
INC HL 23
INCrement Register Pair HL by 1, to the entry's pattern.
507F
CP (HL) BE
Compare Register A (the masked byte) with the pattern at (HL) (Register Pair HL = the entry's second byte). If they are equal, the Z FLAG is set; otherwise the NZ FLAG is set.
5080
INC HL 23
INCrement Register Pair HL by 1, to the entry's type byte (INC does not change the Z FLAG).
5081
If the Z FLAG is set (the instruction belongs to this group), JUMP to 5089H with Register Pair HL at the type byte.
5083
INC HL 23
INCrement Register Pair HL by 1, to the next entry's mask.
5084
LD A,(HL) 7E
Fetch the next entry's first byte from (HL) (Register Pair HL = the next entry) into Register A.
5085
CP 05H FE 05
Compare Register A against 05H. Every mask is 05H or more; the byte that ends each part of the table is below 05H and is itself the type byte for anything not listed. If Register A is less than 05H, the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
5087
Table Loop End
If the NO CARRY FLAG is set (another entry), LOOP BACK to 507CH; otherwise fall through with Register Pair HL at the ending type byte.
5089
LD A,(HL) 7E
Plant the Next Breakpoint
Fetch the type byte from (HL) (Register Pair HL = the entry's type byte, or the ending byte) into Register A: bits 0-3 are the instruction's length, bits 4-7 its kind (0 plain, 1 JP (HL), 2 JP (IX) or JP (IY), 3 JR or DJNZ, 4 JP, 5 RET, 6 CALL). 5081H comes here.
508A
LD B,A 47
Copy the type byte from Register A into Register B, kept for the kind.
508B
AND 0FH E6 0F
AND Register A with 0FH, keeping bits 0-3: the instruction's length in bytes.
508D
LD L,A 6F
Copy the length from Register A into Register L.
508E
LD H,00H 26 00
Load Register H with 00H: Register Pair HL = the length.
5090
ADD HL,DE 19
ADD Register Pair DE (the program counter) to Register Pair HL (the length): Register Pair HL = the address of the next instruction.
5091
PUSH DE D5
Save Register Pair DE (the program counter) onto the stack.
5092
LD DE,4062H 11 62 40
Point Register Pair DE to 4062H, the saved byte of the breakpoint entry at 4060H-4062H.
5095
GOSUB to 4FCAH to plant a breakpoint at the address in Register Pair HL (the next instruction). When the instruction is in ROM the F7H does not stay and 4FD1H goes back to the command loop.
5098
POP HL E1
Restore Register Pair HL from the stack: the program counter, pushed at 5091H.
5099
LD A,B 78
Copy the type byte from Register B into Register A.
509A
AND F0H E6 F0
AND Register A with F0H, keeping bits 4-7: the kind of instruction, times 10H.
509C
If the Z FLAG is set (kind 0: the next instruction always follows), JUMP to 50B4H to start it.
509E
INC HL 23
INCrement Register Pair HL by 1: the program counter plus 1, the first operand byte of an instruction without a prefix.
509F
CP 20H FE 20
Compare Register A (the kind times 10H) against 20H. If Register A is less than 20H, the CARRY FLAG is set; if it equals 20H, the Z FLAG is set.
50A1
If the CARRY FLAG is set (kind 1, JP (HL)), JUMP to 50D8H to take the target from the saved Register Pair HL.
50A3
If the Z FLAG is set (kind 2, JP (IX) or JP (IY)), JUMP to 50CCH to take the target from a saved Index Register.
50A5
CP 40H FE 40
Compare Register A (the kind times 10H) against 40H. If Register A is less than 40H, the CARRY FLAG is set; if it equals 40H, the Z FLAG is set.
50A7
If the CARRY FLAG is set (kind 3, JR or DJNZ), JUMP to 50C0H to add the displacement.
50A9
If the Z FLAG is set (kind 4, JP), JUMP to 50BAH to take the target from the operand at Register Pair HL.
50AB
CP 60H FE 60
Compare Register A (the kind times 10H) against 60H. If Register A is less than 60H, the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
50AD
If the CARRY FLAG is set (kind 5, RET), JUMP to 50B7H to take the target from the program's stack.
50AF
POP AF F1
CALL Instructions
Restore Register Pair AF from the stack: Register A = the command letter pushed at 505DH.
50B0
CP 49H FE 49
Compare Register A against 49H (ASCII: I). If Register A equals 49H, the Z FLAG is set; otherwise the NZ FLAG is set.
50B2
If the Z FLAG is set (I), JUMP to 50BAH to plant a second breakpoint at the subroutine's address, the operand at Register Pair HL. For C there is none, and the subroutine runs at full speed.
50B4
Start the Instruction
JUMP to 4FA4H to put back the registers and resume at the saved program counter. 509CH, 50B2H and 50DEH come here. A word left on the stack (the letter from 505DH) does not matter: 4FC1H loads the program's Stack Pointer.
50B7
LD HL,(4079H) 2A 79 40
RET
Fetch the program's saved Stack Pointer from 4079H into Register Pair HL: the return address is the word at the top of the program's stack. 50ADH comes here.
50BA
LD A,(HL) 7E
JP and CALL
Fetch the low byte of the target from (HL) (Register Pair HL = the operand, or the top of the program's stack) into Register A. 50A9H and 50B2H come here.
50BB
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the target.
50BC
LD H,(HL) 66
Fetch the high byte of the target from (HL) (Register Pair HL = the operand plus 1) into Register H.
50BD
LD L,A 6F
Copy the low byte from Register A into Register L: Register Pair HL = the address the instruction can go to.
50BE
JUMP to 50DBH to plant the second breakpoint there.
50C0
LD C,(HL) 4E
JR and DJNZ
Fetch the displacement from (HL) (Register Pair HL = the program counter plus 1) into Register C. 50A7H comes here.
50C1
XOR A AF
Set Register A to ZERO and clear all flags, the high byte for a forward displacement.
50C2
BIT 7,C CB 79
Test bit 7 of Register C (the displacement): set for a backward jump.
50C4
If the Z FLAG is set (forward), JUMP to 50C7H with Register A = 00H.
50C6
CPL 2F
Complement Register A (00H to FFH), the high byte for a backward displacement.
50C7
LD B,A 47
Copy Register A (00H or FFH) into Register B: Register Pair BC = the displacement extended to 16 bits.
50C8
INC HL 23
INCrement Register Pair HL by 1: the program counter plus 2, the address the displacement counts from.
50C9
ADD HL,BC 09
ADD Register Pair BC (the displacement) to Register Pair HL: Register Pair HL = the jump's target.
50CA
JUMP to 50DBH to plant the second breakpoint there.
50CC
LD HL,(4075H) 2A 75 40
JP (IX) and JP (IY)
Fetch the saved Index Register IX from 4075H into Register Pair HL. 50A3H comes here.
50CF
BIT 5,C CB 69
Test bit 5 of Register C. Bit 5 is the bit that differs between the prefixes DDH (clear) and FDH (set), but Register C holds the byte after the prefix (E9H, set at 507BH), and bit 5 of E9H is set, so the Z FLAG is never set here.
50D1
If the Z FLAG is set, JUMP to 50DBH with the saved Index Register IX. With Register C = E9H this is never taken.
50D3
LD HL,(4077H) 2A 77 40
Fetch the saved Index Register IY from 4077H into Register Pair HL: the second breakpoint goes at the saved Index Register IY for JP (IX) as well as for JP (IY).
50D6
JUMP to 50DBH to plant the second breakpoint there.
50D8
LD HL,(406BH) 2A 6B 40
JP (HL)
Fetch the program's saved Register Pair HL from 406BH into Register Pair HL: the address JP (HL) goes to. 50A1H comes here.
50DB
GOSUB to 4FCAH to plant the second breakpoint at the address in Register Pair HL, recorded in the entry at 405DH-405FH (Register Pair DE = 405FH). 50BEH, 50CAH, 50D1H and 50D6H come here.
50DE
JUMP to 50B4H to start the instruction with both breakpoints planted.
50E0H - Instruction Classification Table (Data)
Data, not code: three-byte entries of a mask, a pattern and a type byte. An instruction belongs to an entry when its byte ANDed with the mask equals the pattern. In the type byte bits 0-3 are the length in bytes and bits 4-7 the kind: 0 plain, 1 JP (HL), 2 JP (IX) or JP (IY), 3 JR or DJNZ, 4 JP, 5 RET, 6 CALL. Each of the three parts ends with a single byte below 05H, the type for any instruction not listed: 50E0H-510DH for instructions without a prefix (length 1), 510EH-5114H for the byte after EDH (length 2), 5115H-5130H for the byte after DDH or FDH (length 2).
50E0-50E2
DEFB C7H, C0H, 51H C7 C0 51
Mask C7H, pattern C0H: RET NZ, RET Z, RET NC, RET C, RET PO, RET PE, RET P and RET M. Type 51H: kind 5 (RET), length 1.
50E3-50E5
DEFB FFH, C9H, 51H FF C9 51
Mask FFH, pattern C9H: RET. Type 51H: kind 5 (RET), length 1.
50E6-50E8
DEFB FFH, E9H, 11H FF E9 11
Mask FFH, pattern E9H: JP (HL). Type 11H: kind 1, length 1.
50E9-50EB
DEFB CFH, 01H, 03H CF 01 03
Mask CFH, pattern 01H: LD BC,nn, LD DE,nn, LD HL,nn and LD SP,nn. Type 03H: kind 0, length 3.
50EC-50EE
DEFB E7H, 22H, 03H E7 22 03
Mask E7H, pattern 22H: LD (nn),HL, LD HL,(nn), LD (nn),A and LD A,(nn). Type 03H: kind 0, length 3.
50EF-50F1
DEFB C7H, C2H, 43H C7 C2 43
Mask C7H, pattern C2H: the eight conditional JP cc,nn. Type 43H: kind 4 (JP), length 3.
50F2-50F4
DEFB FFH, C3H, 43H FF C3 43
Mask FFH, pattern C3H: JP nn. Type 43H: kind 4 (JP), length 3.
50F5-50F7
DEFB C7H, C4H, 63H C7 C4 63
Mask C7H, pattern C4H: the eight conditional CALL cc,nn. Type 63H: kind 6 (CALL), length 3.
50F8-50FA
DEFB FFH, CDH, 63H FF CD 63
Mask FFH, pattern CDH: CALL nn. Type 63H: kind 6 (CALL), length 3.
50FB-50FD
DEFB C7H, 06H, 02H C7 06 02
Mask C7H, pattern 06H: LD r,n for B, C, D, E, H, L, (HL) and A. Type 02H: kind 0, length 2.
50FE-5100
DEFB F7H, D3H, 02H F7 D3 02
Mask F7H, pattern D3H: OUT (n),A and IN A,(n). Type 02H: kind 0, length 2.
5101-5103
DEFB C7H, C6H, 02H C7 C6 02
Mask C7H, pattern C6H: ADD, ADC, SUB, SBC, AND, XOR, OR and CP with an immediate byte. Type 02H: kind 0, length 2.
5104-5106
DEFB FFH, CBH, 02H FF CB 02
Mask FFH, pattern CBH: the CB prefix (shifts, rotates and bit instructions). Type 02H: kind 0, length 2.
5107-5109
DEFB F7H, 10H, 32H F7 10 32
Mask F7H, pattern 10H: DJNZ and JR. Type 32H: kind 3 (relative), length 2.
510A-510C
DEFB E7H, 20H, 32H E7 20 32
Mask E7H, pattern 20H: JR NZ, JR Z, JR NC and JR C. Type 32H: kind 3 (relative), length 2.
510D
DEFB 01H 01
End of the part for instructions without a prefix: type 01H (kind 0, length 1) for every other instruction, the RST instructions included, so a restart's routine runs at full speed.
510E-5110
DEFB C7H, 43H, 04H C7 43 04
After EDH. Mask C7H, pattern 43H: LD (nn),rr and LD rr,(nn). Type 04H: kind 0, length 4.
5111-5113
DEFB F7H, 45H, 52H F7 45 52
After EDH. Mask F7H, pattern 45H: RETN and RETI. Type 52H: kind 5 (RET), length 2.
5114
DEFB 02H 02
End of the part for EDH: type 02H (kind 0, length 2) for every other extended instruction.
5115-5117
DEFB FEH, 34H, 03H FE 34 03
After DDH or FDH. Mask FEH, pattern 34H: INC (IX+d) and DEC (IX+d) (or IY). Type 03H: kind 0, length 3.
5118-511A
DEFB C0H, 40H, 03H C0 40 03
After DDH or FDH. Mask C0H, pattern 40H: the bytes 40H-7FH, the loads between a register and (IX+d) or (IY+d). Type 03H: kind 0, length 3.
511B-511D
DEFB C0H, 80H, 03H C0 80 03
After DDH or FDH. Mask C0H, pattern 80H: the bytes 80H-BFH, ADD, ADC, SUB, SBC, AND, XOR, OR and CP with (IX+d) or (IY+d). Type 03H: kind 0, length 3.
511E-5120
DEFB FFH, 21H, 04H FF 21 04
After DDH or FDH. Mask FFH, pattern 21H: LD IX,nn or LD IY,nn. Type 04H: kind 0, length 4.
5121-5123
DEFB FFH, 22H, 04H FF 22 04
After DDH or FDH. Mask FFH, pattern 22H: LD (nn),IX or LD (nn),IY. Type 04H: kind 0, length 4.
5124-5126
DEFB FFH, 2AH, 04H FF 2A 04
After DDH or FDH. Mask FFH, pattern 2AH: LD IX,(nn) or LD IY,(nn). Type 04H: kind 0, length 4.
5127-5129
DEFB FFH, 36H, 04H FF 36 04
After DDH or FDH. Mask FFH, pattern 36H: LD (IX+d),n or LD (IY+d),n. Type 04H: kind 0, length 4.
512A-512C
DEFB FFH, CBH, 04H FF CB 04
After DDH or FDH. Mask FFH, pattern CBH: the bit instructions on (IX+d) or (IY+d). Type 04H: kind 0, length 4.
512D-512F
DEFB FFH, E9H, 22H FF E9 22
After DDH or FDH. Mask FFH, pattern E9H: JP (IX) or JP (IY). Type 22H: kind 2, length 2.
5130
DEFB 02H 02
End of the part for DDH and FDH: type 02H (kind 0, length 2), for example PUSH IX, POP IX, INC IX, ADD IX,rr and EX (SP),IX.
5131H - Show 16 Bytes of Memory
Called with Register Pair HL = the first address by the register lines (4F27H) and the memory lines (4F3FH). It shows => and a space, then 16 bytes, each after a one-character separator (5165H): two hexadecimal digits, or a space and the byte as a character when 405DH holds 41H (the A command). An extra space separates the eighth byte from the ninth. 52 characters in all. Register Pair HL returns 16 bytes further on; Register Pair BC is kept.
5131
PUSH BC C5
Save Register Pair BC (Register B = the caller's line counter) onto the stack.
5132
LD A,3DH 3E 3D
Load Register A with 3DH (ASCII: =), the first character of the arrow => before the bytes.
5134
GOSUB to ROM routine at 0033H to display the character in Register A (=).
5137
LD A,3EH 3E 3E
Load Register A with 3EH (ASCII: >), the second character of the arrow => before the bytes.
5139
GOSUB to ROM routine at 0033H to display the character in Register A (>).
513C
GOSUB to 51F2H to display a space after the arrow, before the first separator.
513F
LD B,10H 06 10
Load Register B with 10H, the number of bytes on the line (16).
5141
Byte Loop
GOSUB to 5165H to display the separator before the byte at Register Pair HL: a space, or a bar when that byte or the one before it is the M command's address, with the extra space before the ninth byte. 5161H loops back here.
5144
LD A,(405DH) 3A 5D 40
Fetch the display letter from 405DH into Register A (41H after the A command).
5147
CP 41H FE 41
Compare Register A (the display letter) against 41H (ASCII: A). If Register A equals 41H, the Z FLAG is set; otherwise the NZ FLAG is set.
5149
If the NZ FLAG is set (hexadecimal), JUMP to 515EH, where the NZ FLAG makes the CALL show the byte as two digits.
514B
Show as a Character
GOSUB to 51F2H to display a space, so a character takes two columns like two digits.
514E
LD A,(HL) 7E
Fetch the byte from (HL) (Register Pair HL = the address being shown) into Register A.
514F
CP 20H FE 20
Compare Register A (the byte) against 20H. If Register A is less than 20H (a control code), the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
5151
If the CARRY FLAG is set (a control code), JUMP to 5157H to show a period instead.
5153
CP C0H FE C0
Compare Register A (the byte) against C0H. If Register A is less than C0H (a character or a graphics block, 20H-BFH), the CARRY FLAG is set; otherwise the NO CARRY FLAG is set (a space compression code, C0H-FFH).
5155
If the CARRY FLAG is set (20H-BFH), JUMP to 5159H to show the byte as it is.
5157
LD A,2EH 3E 2E
Load Register A with 2EH (ASCII: .), shown for a control code or a space compression code, which the display would act on instead of showing. 5151H comes here.
5159
GOSUB to ROM routine at 0033H to display Register A (the byte or the period). 5155H comes here.
515C
INC HL 23
INCrement Register Pair HL by 1, to the next address.
515D
XOR A AF
Set Register A to ZERO with XOR A, which sets the Z FLAG, so the CALL below is not taken after a character.
515E
If the NZ FLAG is set (hexadecimal, from 5149H), GOSUB to 51D0H to display the byte at (HL) as two hexadecimal digits and move Register Pair HL to the next address.
5161
Byte Loop End
DECrement Register B (the bytes left) and LOOP BACK to 5141H until 16 bytes are shown.
5163
POP BC C1
Restore Register Pair BC (the caller's line counter) from the stack.
5164
RET C9
RETURN to the caller, with Register Pair HL 16 bytes past the first address.
5165H - The Separator Before a Byte
Called by 5131H before each byte, with Register Pair HL = the address about to be shown and Register B = 10H for the first byte down to 01H for the last. The M command's address (4060H-4061H) is marked with Model I graphics bars: AAH (a bar in the right half of the cell) as the separator before it and 95H (a bar in the left half) as the separator after it, so the byte is framed. Any other separator is a space. Before the ninth byte (Register B = 08H) an extra space is shown.
5165
LD DE,(4060H) ED 5B 60 40
Fetch the M command's address from 4060H into Register Pair DE.
5169
INC DE 13
INCrement Register Pair DE by 1: the address just after the marked byte.
516A
PUSH HL E5
Save Register Pair HL (the address about to be shown) onto the stack.
516B
XOR A AF
Set Register A to ZERO with XOR A, which also clears the CARRY FLAG for the SBC below.
516C
SBC HL,DE ED 52
SUBtract Register Pair DE (the M address plus 1) and the CARRY FLAG (clear) from Register Pair HL: the Z FLAG is set when the byte about to be shown is the one after the marked byte.
516E
LD A,95H 3E 95
Load Register A with 95H, the graphics block with the left half lit, the bar after the marked byte (LD does not change the flags).
5170
If the Z FLAG is set (the previous byte was the marked one), JUMP to 5180H to show the bar.
5172
GOSUB to 5184H to show the extra space when Register B = 08H (before the ninth byte).
5175
INC HL 23
INCrement Register Pair HL (the address minus the M address minus 1) by 1: Register Pair HL = 0000H when the byte about to be shown is the marked one.
5176
LD A,L 7D
Copy the low byte of the difference from Register L into Register A.
5177
OR H B4
OR Register A with Register H: the Z FLAG is set when Register Pair HL = 0000H (the marked byte comes next).
5178
POP HL E1
Restore Register Pair HL (the address about to be shown) from the stack.
5179
LD A,AAH 3E AA
Load Register A with AAH, the graphics block with the right half lit, the bar before the marked byte (LD does not change the flags).
517B
If the Z FLAG is set (the marked byte comes next), JUMP to ROM routine at 0033H to display the bar in Register A; its RET returns to 5131H.
517E
JUMP to 5188H, which goes on to 51F2H to show a space as the separator.
5180
GOSUB to ROM routine at 0033H to display the bar in Register A (95H). 5170H comes here.
5183
POP HL E1
Restore Register Pair HL (the address about to be shown) from the stack.
5184
LD A,B 78
Extra Space Before the Ninth Byte
Copy Register B (the bytes left, 10H down to 01H) into Register A. 5172H calls here.
5185
CP 08H FE 08
Compare Register A against 08H. If Register A equals 08H (the ninth byte comes next), the Z FLAG is set; otherwise the NZ FLAG is set.
5187
RET NZ C0
If the NZ FLAG is set, RETURN without showing anything.
5188
JUMP to 51F2H to show a space and return. 517EH comes here for the ordinary separator.
518AH - Read and Echo One Key
Waits for a key through the ROM. ENTER returns at once, not echoed, with Register A = 0DH, the Z FLAG and the CARRY FLAG set. Codes below 20H (the arrows, CLEAR, BREAK) are ignored. Any other key is echoed at the cursor and returned in Register A with the CARRY FLAG clear; the Z FLAG is set for a comma or a space. Register Pair DE is kept.
518A
PUSH DE D5
Save Register Pair DE onto the stack; the ROM routines leave Register Pair DE pointing to a control block.
518B
Key Loop
GOSUB to ROM routine at 0049H to wait for a key; Register A returns its code. 5194H loops back here.
518E
CP 0DH FE 0D
Compare Register A (the key) against 0DH (ENTER). If Register A equals 0DH, the Z FLAG is set; otherwise the NZ FLAG is set.
5190
If the Z FLAG is set (ENTER), JUMP to 51A0H to return with the CARRY FLAG set.
5192
CP 20H FE 20
Compare Register A (the key) against 20H. If Register A is less than 20H (a control key), the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
5194
If the CARRY FLAG is set (a control key), LOOP BACK to 518BH and wait for another key.
5196
GOSUB to ROM routine at 0033H to echo the key in Register A at the cursor (Register A is kept).
5199
POP DE D1
Restore Register Pair DE (the caller's) from the stack.
519A
CP 2CH FE 2C
Compare Register A (the key) against 2CH (ASCII: ,). If Register A equals 2CH, the Z FLAG is set; otherwise the NZ FLAG is set.
519C
RET Z C8
If the Z FLAG is set (a comma), RETURN with the Z FLAG set and the CARRY FLAG clear.
519D
CP 20H FE 20
Compare Register A (the key) against 20H (a space): the Z FLAG is set for a space, and the CARRY FLAG is clear because Register A is 20H or more.
519F
RET C9
RETURN with Register A = the key: the Z FLAG set for a space, the NZ FLAG for anything else.
51A0
POP DE D1
Restore Register Pair DE (the caller's) from the stack. 5190H comes here for ENTER.
51A1
SCF 37
Set the CARRY FLAG, the mark of ENTER (the Z FLAG stays set from the compare at 518EH).
51A2
RET C9
RETURN with Register A = 0DH, the Z FLAG and the CARRY FLAG set.
51A3H - Read a Hexadecimal Number
Reads hexadecimal digits (0-9 and A-F) into Register Pair HL until a space, a comma or ENTER; only the last four digits count. If the first key is a space, a comma or ENTER, it returns at once with the Z FLAG set and Register Pair HL as the caller had it. After digits it returns with the NZ FLAG set. Either way the CARRY FLAG is set when ENTER ended the input. Any other key abandons the command: 51ADH jumps to the command loop at 4E4BH.
51A3
GOSUB to 518AH to read and echo the first key into Register A.
51A6
RET Z C8
If the Z FLAG is set (space, comma or ENTER first), RETURN with Register Pair HL unchanged; the CARRY FLAG tells ENTER from a space or comma.
51A7
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the number so far.
51AA
Digit Loop
GOSUB to 51BFH to turn the character in Register A into a digit value 00H-0FH; the CARRY FLAG returns set when it is not a hexadecimal digit. 51B9H loops back here.
51AD
If the CARRY FLAG is set (not a hexadecimal digit), JUMP to 4E4BH, the command loop, which resets the Stack Pointer and abandons the command.
51B0
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 2.
51B1
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 4.
51B2
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 8.
51B3
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 16, shifted left one digit (the top digit is lost).
51B4
OR L B5
OR Register A (the digit value, 00H-0FH) with Register L (low digit now 0).
51B5
LD L,A 6F
Copy Register A into Register L: the new digit is the lowest digit of Register Pair HL.
51B6
GOSUB to 518AH to read and echo the next key into Register A.
51B9
Digit Loop End
If the NZ FLAG is set (not a space, comma or ENTER), LOOP BACK to 51AAH to take the next digit.
51BB
RRA 1F
Rotate Register A (the ending key: 0DH, 20H or 2CH) right through the CARRY FLAG: bit 0 goes into the CARRY FLAG (set for ENTER, 0DH; clear for 20H or 2CH), and Register A becomes 86H for ENTER or 10H or 16H for a space or comma.
51BC
ADC A,81H CE 81
ADD 81H and the CARRY FLAG to Register A: 86H plus 81H plus 1 carries out and leaves 08H for ENTER; 10H or 16H plus 81H does not carry. The result is never 00H, so the NZ FLAG is set, and the CARRY FLAG is set only for ENTER.
51BE
RET C9
RETURN with Register Pair HL = the number, the NZ FLAG set, and the CARRY FLAG set when ENTER ended it.
51BFH - Hexadecimal Digit Value
Turns the character in Register A into its value: 30H-39H (0-9) give 00H-09H and 41H-46H (A-F) give 0AH-0FH, with the CARRY FLAG clear. Any other character returns with the CARRY FLAG set.
51BF
SUB 30H D6 30
SUBtract 30H (ASCII 0) from Register A (the character).
51C1
RET C D8
If the CARRY FLAG is set (the character is below 30H), RETURN: not a digit.
51C2
ADD A,E9H C6 E9
ADD E9H to Register A (that is, subtract 17H): the CARRY FLAG is set when the character is 47H (G) or above.
51C4
RET C D8
If the CARRY FLAG is set (G or above), RETURN: not a digit.
51C5
ADD A,06H C6 06
ADD 06H to Register A: the CARRY FLAG is set for 41H-46H (A-F), and Register A becomes 00H-05H for them.
51C7
If the CARRY FLAG is set (A-F), JUMP to 51CCH to add ten.
51C9
ADD A,07H C6 07
ADD 07H to Register A: the CARRY FLAG is set for 3AH-40H (the characters between 9 and A).
51CB
RET C D8
If the CARRY FLAG is set (3AH-40H), RETURN: not a digit.
51CC
ADD A,0AH C6 0A
ADD 0AH to Register A: 0AH-0FH for A-F, and 00H-09H (with a carry out) for 0-9. 51C7H comes here.
51CE
OR A B7
OR Register A with itself to clear the CARRY FLAG: a valid digit.
51CF
RET C9
RETURN with the digit value in Register A and the CARRY FLAG clear.
51D0H - Display Hexadecimal Digits and Spaces
Small display routines, all ending in the ROM display routine at 0033H. 51D0H shows the byte at (HL) and advances Register Pair HL; 51D4H shows Register Pair HL as four digits; 51D9H shows Register A as two digits; 51E2H shows the low four bits of Register A as one digit; 51EFH shows Register A as two digits and a space; 51F2H shows a space; 51F6H shows three characters from (HL) and 51FCH one, advancing Register Pair HL.
51D0
LD A,(HL) 7E
Fetch the byte from (HL) (Register Pair HL = the address to show) into Register A.
51D1
INC HL 23
INCrement Register Pair HL by 1, to the next address.
51D2
JUMP to 51D9H to show Register A (the byte) as two hexadecimal digits.
51D4
LD A,H 7C
Show Register Pair HL
Copy the high byte from Register H into Register A.
51D5
GOSUB to 51D9H to show Register A (the high byte) as two hexadecimal digits.
51D8
LD A,L 7D
Copy the low byte from Register L into Register A, then fall into 51D9H to show it.
51D9
PUSH AF F5
Show Register A as Two Digits
Save Register Pair AF (Register A = the byte) onto the stack.
51DA
RRA 1F
Rotate Register A right through the CARRY FLAG (the first of four, bringing the high four bits down).
51DB
RRA 1F
Rotate Register A right through the CARRY FLAG (second).
51DC
RRA 1F
Rotate Register A right through the CARRY FLAG (third).
51DD
RRA 1F
Rotate Register A right through the CARRY FLAG (fourth): the byte's high four bits are now bits 0-3 of Register A.
51DE
GOSUB to 51E2H to show bits 0-3 of Register A (the high digit).
51E1
POP AF F1
Restore Register Pair AF (Register A = the byte) from the stack, then fall into 51E2H to show the low digit.
51E2
AND 0FH E6 0F
Show One Digit
AND Register A with 0FH, keeping bits 0-3, the digit's value.
51E4
ADD A,30H C6 30
ADD 30H to Register A: 30H-39H for 0-9, or 3AH-3FH for 0AH-0FH.
51E6
CP 3AH FE 3A
Compare Register A against 3AH. If Register A is less than 3AH (0-9), the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
51E8
If the CARRY FLAG is set (0-9), JUMP to 51ECH to show it.
51EA
ADD A,07H C6 07
ADD 07H to Register A: 41H-46H, the letters A-F.
51EC
JUMP to ROM routine at 0033H to display the character in Register A; its RET returns to the caller. 51E8H, 51F4H and 51FEH come here.
51EF
Show Register A as Two Digits and a Space
GOSUB to 51D9H to show Register A as two hexadecimal digits, then fall into 51F2H.
51F2
LD A,20H 3E 20
Show a Space
Load Register A with 20H, a space.
51F4
JUMP to 51ECH to display the space in Register A.
51F6
Show Three Characters
GOSUB to 51FCH to display the character at (HL) (Register Pair HL = the text) and advance Register Pair HL.
51F9
GOSUB to 51FCH to display the second character, then fall into 51FCH for the third.
51FC
LD A,(HL) 7E
Show One Character
Fetch the character from (HL) (Register Pair HL = the text) into Register A.
51FD
INC HL 23
INCrement Register Pair HL by 1, to the next character.
51FE
JUMP to 51ECH to display the character in Register A.