LDOS 5.3.1 for the Model III - SYS9/SYS Disassembled

Page Customization

Introduction/Summary

LDOS 5.3.1 SYS9/SYS Disassembly - The Extended DEBUG Commands (Model III)

SYS9/SYS holds the extended commands of DEBUG. DEBUG (EXT) issues request 8BH; the supervisor dispatcher loads SYS9/SYS into the overlay area at 4E00H and calls it, and the code at 4E00H copies the 984 bytes 4E26H-51FDH to the top of memory below the old HIGH$, lowers HIGH$ (4411H) by 03D8H to keep them there, and points the word at 4400H at the copy. DEBUG (SYS5/SYS) jumps to the address at 4400H with every key it does not know, with Register A = the key in lower case and the address of its command loop (4E49H) on the stack; before the extended commands are installed that address is 4876H, an OR A / RET of SYS0/SYS. The manual says SYS9/SYS is of no use without SYS5/SYS: the module reads its keys and numbers and shows its values through SYS5/SYS's routines, and works on DEBUG's cells at 405EH-4064H and 407BH-407CH.

The file is a load module of 1099 bytes: a record of type 1FH with the text Copyright 1991 MISOSYS, Inc., All rights reserved, four load blocks for 4E00H-51FDH, a load block for the two bytes 4BC8H-4BC9H (03FEH, the 1022 bytes that SYS9/SYS takes up in the overlay area) and the transfer address record for 4E00H.

The Module in High Memory

The module starts with a header (4E26H): a JR over it, the link word (the HIGH$ before the module was installed, stored by the installer), the length of the name and the name EXTDBG. It runs at the old HIGH$ less 03D7H: every branch inside it is relative, and every absolute address it uses is outside it, so the addresses on this page are those of the file and at run time each is moved by the same amount. The calls to 5189H, 51A4H, 51D1H, 51D5H, 51DAH and 51F1H go to SYS5/SYS, which is in the overlay area while DEBUG runs, and are linked to that page:

SYS5/SYSWhat the module uses it for
5189HWait for a key and show it: the CARRY FLAG for ENTER, the Z FLAG for a comma or a space; letters come back lower case (the T command changes that, 4FA4H).
51A4HRead a hexadecimal number into Register Pair HL (the last four digits): the NZ FLAG when one was typed, the Z FLAG and Register Pair HL unchanged when the first key was a comma, a space or ENTER; the CARRY FLAG when ENTER ended it. A key that is not a hexadecimal digit gives the command up and goes back to DEBUG's command loop.
51D1H, 51D5H, 51DAHShow in hexadecimal the byte at Register Pair HL (and step past it), Register Pair HL, or Register A.
51F1HShow a space.

Every handler returns to DEBUG's command loop, which puts the Stack Pointer back and draws the screen, so a command's results show on DEBUG's screen: most commands leave their address in DEBUG's M address (4060H), which the screen marks with bars, or in its memory display address (4063H).

The Commands

A number left out by typing only its comma or space takes the value given below, which is then shown; ENTER ends the line. All numbers are hexadecimal.

CommandWhat it does
O ENTERLeave DEBUG for LDOS Ready through @EXIT (402DH) (4E31H).
B aaaa,bbbb,nnnnMove nnnn bytes (0100H when left out, 0000H moves 65536) from aaaa (the memory display address) to bbbb (the M address) with LDIR (4E3CH).
E aaaa SPACEShow the bytes from aaaa (the M address) one after the other and change them: two digits and a space store a value, a space alone goes on, ENTER ends (4E88H).
F aaaa,bbbb,ccFill aaaa to bbbb with the byte cc; nothing is filled when aaaa is not below bbbb (4EBBH).
JStep the program's PC (407BH) past one byte (4EDBH).
L aaaa,ddLocate the byte dd (the last one searched for, 4062H) from aaaa (the byte after the M address) (4EE7H).
N aaaaMove the M address from the record of a load module at aaaa (the M address) to the next record (4F2EH).
Q ii / Q oo,ddRead port ii and show it, or send dd to port oo (4F4FH).
T aaaa SPACEType text into memory from aaaa (the M address), keys stored as typed; a space goes on, ENTER ends (4F73H).
V aaaa,bbbb,nnnnCompare nnnn bytes (0000H: 65536) of aaaa (the memory display address) and bbbb (the M address), stopping on the first pair that differ (4FBBH).
W aaaa,ddddLocate the word dddd (the last one searched for) from aaaa (two bytes after the M address) (5016H).
d,cc,ss,o,aaaa,nnRead (r), write (w) or write with the deleted data mark (the asterisk key) nn sectors of drive d (0-7) from cylinder cc (the directory cylinder) and sector ss (0 and a whole cylinder) to or from memory at aaaa (506CH).
P aaaa,bbbbPrint aaaa to bbbb on the printer, sixteen bytes a line in hexadecimal and as characters (513EH).

The L and W commands search with CPIR and a count of 0000H, over up to 65536 bytes. L keeps its byte at 4062H and W its word at 4062H (low byte) and 405FH (high byte), DEBUG's cells for the byte a breakpoint covers, so a G with breakpoints changes them; the drive commands use the same two cells for the sectors of a cylinder (405FH) and the count of sectors (4062H). When the address is typed and the value is not, L and W show the address where the value kept would be shown, and search for the value kept.

About This Page

Every byte of the file is shown, in address order: the load block at 4BC8H first, then 4E00H-51FDH. The header at 4E28H-4E30H is data. SYS9/SYS changes two bytes of its own, the link word at 4E28H-4E29H, before the copy, and one byte of SYS5/SYS while the T command reads a key (5196H).

Memory Map

Load Blocks in File Order

The five load blocks of the file in the order the overlay loader (4C8CH) reads them, after the copyright record. The transfer address is 4E00H.

AddressContents
4E00H-4EFFH256 bytes
4F00H-4FFFH256 bytes
5000H-50FFH256 bytes
5100H-51FDH254 bytes
4BC8H-4BC9H2 bytes

Sections of the Disassembly

AddressContents
4BC8HThe Overlay Length (Data)
4E00HInstall the Extended Commands in High Memory
4E26HThe Module Header
4E31HThe Key Test and the O Command
4E3CHThe B Command: Move a Block of Memory
4E88HThe E Command: Examine and Change Memory in Hexadecimal
4EBBHThe F Command: Fill Memory
4EDBHThe J Command: Skip a Byte
4EE7HThe L Command: Locate a Byte
4F2EHThe N Command: Go to the Next Record of a Load Module
4F4FHThe Q Command: Port Input and Output
4F73HThe T Command: Type Text into Memory
4FBBHThe V Command: Compare Two Blocks
5016HThe W Command: Locate a Word
506CHThe Drive Commands: Read and Write Sectors
513EHThe P Command: Print a Block of Memory

Memory SYS9/SYS Uses

AddressContents
0033H, 003BHROM: show the character in Register A at the cursor (0033H), print it (003BH, the P command).
402DH@EXIT of SYS0/SYS: the O command leaves DEBUG through it (4E39H).
4411H-4412HHIGH$, lowered by 03D8H to keep the module (4E0AH-4E16H).
405EH-4064HDEBUG's cells the commands use (Variables).
407BH-407CHThe program's saved PC, stepped on by J (4EDFH).
4400H-4401HThe address DEBUG jumps to with a key it does not know: pointed at the module (4E22H).
4763H, 4768H, 4777H, 478FHWRSECT, WRPROT, RDSECT and GETDCT of SYS0/SYS, used by the drive commands (5073H, 510CH-511EH).
4BC8H-4BC9HThe length of the system file in the overlay area: 03FEH for SYS9/SYS.
4E00H-4E25HThe installer, run in the overlay area.
4E26H-51FDHThe module, copied to the top of memory above the new HIGH$.
5189H-51F1H, 5196HSYS5/SYS's key reader, number reader and hexadecimal output, and the byte the T command changes.

Variables

The entry points of SYS9/SYS, then the data of the file, the bytes changed while it runs, and the cells outside the file that it uses, by address.

Entry Points

AddressNameContents
4E00HRequest 8BH: install the module in high memory, unless 4400H is already changed.
4E26HEXTDBGThe module's first byte, where 4400H points: a JR over the header to the key test.
4E31HThe key test, and O: leave DEBUG.
4E3CHB: move a block.
4E88HE: examine and change memory.
4EBBHF: fill memory.
4EDBHJ: step the PC past a byte.
4EE7HL: locate a byte.
4F2EHN: the next record of a load module.
4F4FHQ: port input and output.
4F73HT: type text into memory.
4FBBHV: compare two blocks.
5016HW: locate a word.
506CH0-7: read and write sectors.
513EHP: print a block of memory.

Data in the File

Address
Size
Contents
4BC8H-4BC9H
2 bytes
DEFW 03FEH
4BC8H-4BC9H: 03FEH (1022), the number of bytes from 4E00H that SYS9/SYS takes up (4E00H-51FDH). Loading SYS9/SYS puts it over the length the system file loaded before it left here.
4E28H-4E29H
2 bytes
DEFW 0000H
4E28H-4E29H: the link word, 0000H in the file. 4E0DH stores the old HIGH$ here before the copy: the address of the module installed before this one, or the top of memory.
4E2AH
1 byte
DEFB 06H
4E2AH: 06H, the length of the module's name that follows (six characters).
4E2BH-4E30H
6 bytes
DEFM "EXTDBG"
4E2BH-4E30H: the module's name, EXTDBG, which a search of the modules above HIGH$ matches.

Bytes Changed While It Runs

Address
Size
Contents
4E28H-4E29H
2 bytes
The module's link word (0000H in the file): the old HIGH$, stored by 4E0DH before the module is copied.
5196H
1 byte
In SYS5/SYS: the second byte of SET 5,A at 5195H (EFH). The T command stores 6FH (BIT 5,A) before it reads a key, so the key keeps its case, and EFH after (4FA7H, 4FACH).

Cells Outside the File That SYS9/SYS Uses

Address
Size
Contents
4411H-4412H
2 bytes
HIGH$: lowered by 03D8H when the module is installed; the old value is the module's link word.
405EH
1 byte
DEBUG's screen layout: set to 73H, the full screen of 256 bytes, after a read with the drive commands (5108H).
405FH
1 byte
DEBUG's cell for the byte breakpoint slot A covers: W keeps the high byte of its word here (5045H); the drive commands keep the sectors of a cylinder (5092H).
4060H-4061H
2 bytes
DEBUG's M address, marked with bars on its screen: the default of E, L, N, T and W and the second block of B and V, and where most commands leave their result.
4062H
1 byte
DEBUG's cell for the byte breakpoint slot B covers: L keeps its byte here (4F0DH), W the low byte of its word (5041H); the drive commands count the sectors down here (50B5H, 50F4H).
4063H-4064H
2 bytes
DEBUG's memory display address: the first block of B and V, and set by L, N and W to the 64 byte boundary below what they find, and by a read to the page read.
407BH-407CH
2 bytes
The program's saved PC: J steps it on by one (4EE3H).
4400H-4401H
2 bytes
The address DEBUG jumps to with a key it does not know: 4876H until the module is installed, then the module's first byte (4E22H).
IY +04H, +07H, +09HThe drive code table of the drive commands' drive (GETDCT): bit 5 of +04H two sides, +07H the heads and sectors of a track, +09H the directory cylinder.

Disassembly

4BC8H - The Overlay Length (Data)

Every system file from SYS1/SYS to SYS12/SYS carries a load block for the two bytes 4BC8H-4BC9H in the resident area of SYS0/SYS. They hold the length of the file's part in the overlay area: for SYS9/SYS 03FEH, the 1022 bytes 4E00H-51FDH. In the file this block is the last load block, after the four blocks of 4E00H-51FDH and before the transfer address record (4E00H). The two bytes are data, not instructions.

4BC8-4BC9
DEFW 03FEH FE 03
4BC8H-4BC9H: 03FEH (1022), the number of bytes from 4E00H that SYS9/SYS takes up (4E00H-51FDH). Loading SYS9/SYS puts it over the length the system file loaded before it left here.

4E00H - Install the Extended Commands in High Memory

DEBUG (EXT) issues request 8BH (SYS7/SYS, its DEBUG member); the supervisor dispatcher loads SYS9/SYS into 4E00H and calls 4E00H. This is the only code of the file that runs where it is loaded. DEBUG (SYS5/SYS) jumps to the address held at 4400H-4401H with any key it does not know; that address is 4876H, an OR A / RET in SYS0/SYS, until the extended commands are installed. When 4400H still holds 4876H, HIGH$ (4411H) is lowered by 03D8H, the 984 bytes 4E26H-51FDH are copied to the space above the new HIGH$, the old HIGH$ goes into the copy's link word, and 4400H is pointed at the copy, so that DEBUG hands its unknown keys to it. When 4400H holds anything else (the commands are already installed) nothing is done.

4E00
LD HL,(4400H) 2A 00 44
Fetch the word at 4400H-4401H into Register Pair HL: the address DEBUG jumps to with a key it does not know (4876H when no extended commands are installed).
4E03
XOR A AF
Set Register A to 00H (XOR A), which clears the CARRY FLAG for the ADC below.
4E04
LD DE,B78AH 11 8A B7
Load Register Pair DE with B78AH, which is 10000H less 4876H: adding it to 4876H gives 0000H.
4E07
ADC HL,DE ED 5A
ADD Register Pair DE and the CARRY FLAG (clear) to Register Pair HL (the word from 4400H): the Z FLAG is set only when that word is 4876H.
4E09
RET NZ C0
RETurn if the NZ FLAG is set (4400H no longer holds 4876H: the extended commands, or another program's, are already there), with nothing installed.
4E0A
LD HL,(4411H) 2A 11 44
Fetch HIGH$, the highest address free for programs, from 4411H-4412H into Register Pair HL.
4E0D
LD (4E28H),HL 22 28 4E
Store Register Pair HL (the old HIGH$) at 4E28H-4E29H, the link word of the module header, before the header is copied.
4E10
LD BC,03D8H 01 D8 03
Load Register Pair BC with 03D8H (984), the length of the module 4E26H-51FDH.
4E13
XOR A AF
Set Register A to 00H (XOR A), which clears the CARRY FLAG for the SBC below.
4E14
SBC HL,BC ED 42
SUBtract Register Pair BC (03D8H) from Register Pair HL (the old HIGH$): the new HIGH$, 984 bytes lower.
4E16
LD (4411H),HL 22 11 44
Store Register Pair HL (the new HIGH$) at 4411H-4412H: the 984 bytes above it are now kept from other programs.
4E19
INC HL 23
INCrement Register Pair HL to the first byte above the new HIGH$, where the module is copied and runs.
4E1A
PUSH HL E5
Save Register Pair HL (the module's run address) to the stack, for 4400H.
4E1B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the module's run address, the destination of the copy.
4E1C
LD HL,4E26H 21 26 4E
Load Register Pair HL with 4E26H, the first byte of the module in the overlay area, the source of the copy.
4E1F
LDIR ED B0
Copy (DE) = (HL) for Register Pair BC (03D8H) bytes, HL and DE counting up (LDIR): 4E26H-51FDH go to the space above the new HIGH$.
4E21
POP HL E1
Restore Register Pair HL (the module's run address) from the stack.
4E22
LD (4400H),HL 22 00 44
Store Register Pair HL (the module's run address) at 4400H-4401H: DEBUG now jumps to the copy of 4E26H with every key it does not know.
4E25
RET C9
RETurn to the caller of the RST 28H (SYS7/SYS's DEBUG member) with the module installed.

4E26H - The Module Header

The 984 bytes 4E26H-51FDH are the module that runs in high memory, at the old HIGH$ less 03D7H. They start with the header that a module installed above HIGH$ carries: a JR over the header, the link word (the HIGH$ before the module was installed), the length of the name and the name EXTDBG. Every branch of the module is relative or goes outside it (the ROM, SYS0/SYS, or SYS5/SYS's routines at 5189H-51F1H), so it runs wherever it is copied. The addresses on this page from here on are those of the file; at run time each is (old HIGH$ less 03D7H) + (address less 4E26H). An address 5189H, 51A4H, 51D1H, 51D5H, 51DAH or 51F1H in an instruction of the module is a routine of SYS5/SYS, which is in the overlay area while DEBUG runs, not a byte of this page.

4E26
JUMP over the header to 4E31H, the test of the key: DEBUG enters the module here with Register A = the key (lower case) and its command loop's address, 4E49H of SYS5/SYS, on the stack.
4E28-4E29
DEFW 0000H 00 00
4E28H-4E29H: the link word, 0000H in the file. 4E0DH stores the old HIGH$ here before the copy: the address of the module installed before this one, or the top of memory.
4E2A
DEFB 06H 06
4E2AH: 06H, the length of the module's name that follows (six characters).
4E2B-4E30
DEFM "EXTDBG" 45 58 54 44 42 47
4E2BH-4E30H: the module's name, EXTDBG, which a search of the modules above HIGH$ matches.

4E31H - The Key Test and the O Command

Register A = the key DEBUG did not know, made lower case by its key reader (5189H of SYS5/SYS). The commands are tested one after the other: o, b, e, f, j, l, n, q, t, v, w, the drives 0-7 (506CH) and p (513EH). A handler returns to DEBUG's command loop (4E49H of SYS5/SYS), which puts the Stack Pointer back and draws the screen again; a key that is none of them returns there at once. O ENTER leaves DEBUG for LDOS Ready through @EXIT.

4E31
CP 6FH FE 6F
Compare Register A (the key) against 6FH, the letter o.
4E33
If the NZ FLAG is set (not o), JUMP to 4E3CH to test for b.
4E35
GOSUB to 5189H, SYS5/SYS's key reader, to wait for the next key: the CARRY FLAG is set for ENTER.
4E38
RET NC D0
RETurn to DEBUG's command loop if the NO CARRY FLAG is set (any key but ENTER): the command is given up.
4E39
JUMP to 402DH, @EXIT of SYS0/SYS: DEBUG is left and LDOS Ready is shown.

4E3CH - The B Command: Move a Block of Memory

B aaaa,bbbb,nnnn ENTER copies nnnn bytes from aaaa to bbbb with LDIR. Each number may be left out by typing only the comma or space: aaaa is then the memory display address (4063H), bbbb the M address (4060H) and nnnn 0100H, and the value taken is shown. ENTER after aaaa ends the command; ENTER after bbbb moves 0100H bytes. A count of 0000H moves 65536 bytes. aaaa is left in 4063H, and 4060H ends at the byte after the copy.

4E3C
CP 62H FE 62
Compare Register A (the key) against 62H, the letter b.
4E3E
If the NZ FLAG is set (not b), JUMP to 4E88H to test for e.
4E40
LD HL,(4063H) 2A 63 40
Fetch the memory display address from 4063H-4064H into Register Pair HL: the source when none is typed.
4E43
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the number typed with the NZ FLAG, or unchanged with the Z FLAG when only a comma, a space or ENTER was typed; the CARRY FLAG is set when ENTER ended it.
4E46
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): no block is moved.
4E47
LD (4063H),HL 22 63 40
Store Register Pair HL (the source) at 4063H-4064H, the memory display address.
4E4A
If the NZ FLAG is set (the source was typed, and shown as it was typed), JUMP to 4E54H for the destination.
4E4C
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the source taken) as four hexadecimal digits.
4E4F
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
4E51
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
4E54
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL: the destination when none is typed.
4E57
GOSUB to 51A4H, SYS5/SYS's number reader, for the destination: Register Pair HL = the number typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4E5A
LD (4060H),HL 22 60 40
Store Register Pair HL (the destination) at 4060H-4061H, the M address. LD does not change the flags.
4E5D
If the NZ FLAG is set (the destination was typed), JUMP to 4E69H for the count.
4E5F
PUSH AF F5
Save Register Pair AF to the stack: the CARRY FLAG (ENTER or not) is needed after the display.
4E60
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the destination taken) as four hexadecimal digits.
4E63
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
4E65
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
4E68
POP AF F1
Restore Register Pair AF from the stack: the CARRY FLAG again says whether ENTER ended the destination.
4E69
LD HL,0100H 21 00 01
Load Register Pair HL with 0100H (256), the count when none is typed. LD does not change the flags.
4E6C
If the CARRY FLAG is set (ENTER after the destination), JUMP to 4E73H to show the count of 0100H and move.
4E6E
GOSUB to 51A4H, SYS5/SYS's number reader, for the count: Register Pair HL = the number typed (NZ FLAG) or 0100H (Z FLAG).
4E71
If the NZ FLAG is set (the count was typed), JUMP to 4E78H to move the block.
4E73
PUSH HL E5
Save Register Pair HL (the count) to the stack, since 51D5H does not keep it.
4E74
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the count taken) as four hexadecimal digits.
4E77
POP HL E1
Restore Register Pair HL (the count) from the stack.
4E78
LD B,H 44
Copy Register H (the high byte of the count) into Register B.
4E79
LD C,L 4D
Copy Register L (the low byte of the count) into Register C: Register Pair BC = the number of bytes to move (0000H moves 65536).
4E7A
LD HL,(4063H) 2A 63 40
Fetch the source from 4063H-4064H into Register Pair HL.
4E7D
LD DE,(4060H) ED 5B 60 40
Fetch the destination from 4060H-4061H into Register Pair DE.
4E81
LDIR ED B0
Copy (DE) = (HL) for Register Pair BC bytes, HL and DE counting up (LDIR): the block is moved, first byte first.
4E83
LD (4060H),DE ED 53 60 40
Store Register Pair DE (the byte after the copy) at 4060H-4061H, the M address.
4E87
RET C9
RETurn to DEBUG's command loop, which draws the screen again.

4E88H - The E Command: Examine and Change Memory in Hexadecimal

E aaaa SPACE shows the byte at aaaa and a minus sign and waits for a value: two hexadecimal digits and a space or comma store it and go on to the next byte, a space or comma alone goes on without changing it, ENTER (after a value, which it stores, or alone) ends. Without aaaa the M address (4060H) is used and shown. The M address follows the bytes as they are passed.

4E88
CP 65H FE 65
Compare Register A (the key) against 65H, the letter e.
4E8A
If the NZ FLAG is set (not e), JUMP to 4EBBH to test for f.
4E8C
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL: the address when none is typed.
4E8F
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the address typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4E92
LD (4060H),HL 22 60 40
Store Register Pair HL (the address) at 4060H-4061H, the M address. LD does not change the flags.
4E95
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): the M address is set and nothing more is done.
4E96
If the NZ FLAG is set (the address was typed), JUMP to 4E9EH to show the first byte.
4E98
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the M address taken) as four hexadecimal digits.
4E9B
GOSUB to 51F1H in SYS5/SYS to show a space between the address and the byte.
4E9E
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
4EA0
GOSUB to the ROM at 0033H to show Register A (1EH): the rest of the bottom line is erased.
4EA3
GOSUB to 51D1H in SYS5/SYS to show the byte at Register Pair HL as two hexadecimal digits; Register Pair HL steps past it. 4EB9H loops back here for each byte.
4EA6
DEC HL 2B
DECrement Register Pair HL back to the byte just shown.
4EA7
LD A,2DH 3E 2D
Load Register A with 2DH, a minus sign, the prompt for the new value.
4EA9
GOSUB to the ROM at 0033H to show Register A (the minus sign) at the cursor.
4EAC
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the byte, while Register Pair HL takes the value.
4EAD
GOSUB to 51A4H, SYS5/SYS's number reader, for the new value: Register Pair HL = the value typed (NZ FLAG), or unchanged with the Z FLAG for a comma, a space or ENTER alone; the CARRY FLAG for ENTER.
4EB0
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the address of the byte, Register E = the low byte of the value. EX does not change the flags.
4EB1
If the Z FLAG is set (no value typed), JUMP to 4EB4H: the byte stays as it is.
4EB3
LD (HL),E 73
Store Register E (the new value, the last two digits typed) at Register Pair HL, the byte.
4EB4
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER ended the value).
4EB5
INC HL 23
INCrement Register Pair HL (the address of the byte) to the next byte of memory.
4EB6
LD (4060H),HL 22 60 40
Store Register Pair HL (the next byte) at 4060H-4061H, the M address.
4EB9
LOOP BACK to 4EA3H to show the next byte and wait for its value.

4EBBH - The F Command: Fill Memory

F aaaa,bbbb,cc ENTER stores the byte cc from aaaa to bbbb. All three numbers must be typed; one left out ends the command. The first test is made with the CARRY FLAG clear (HL less BC: aaaa below bbbb), every later one with the CARRY FLAG still set from the test before (HL less BC less 1), so the fill runs from aaaa up to and including bbbb; when aaaa is not below bbbb nothing is stored, so aaaa equal to bbbb fills no byte.

4EBB
CP 66H FE 66
Compare Register A (the key) against 66H, the letter f.
4EBD
If the NZ FLAG is set (not f), JUMP to 4EDBH to test for j.
4EBF
GOSUB to 51A4H, SYS5/SYS's number reader, for the first address: Register Pair HL = the number, the Z FLAG when none was typed.
4EC2
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no first address): nothing is filled.
4EC3
PUSH HL E5
Save Register Pair HL (the first address) to the stack.
4EC4
GOSUB to 51A4H, SYS5/SYS's number reader, for the last address into Register Pair HL, the Z FLAG when none was typed.
4EC7
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, the Stack Pointer unchanged: Register Pair HL = the first address, and the last address goes on the stack.
4EC8
POP BC C1
Restore Register Pair BC from the stack: the last address. POP does not change the flags.
4EC9
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no last address).
4ECA
PUSH HL E5
Save Register Pair HL (the first address) to the stack while Register Pair HL takes the byte.
4ECB
GOSUB to 51A4H, SYS5/SYS's number reader, for the byte into Register Pair HL, the Z FLAG when none was typed.
4ECE
LD E,L 5D
Copy Register L (the byte to fill with, the last two digits typed) into Register E.
4ECF
POP HL E1
Restore Register Pair HL (the first address) from the stack. POP does not change the flags.
4ED0
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no byte typed).
4ED1
XOR A AF
Set Register A to 00H (XOR A), which clears the CARRY FLAG for the first SBC.
4ED2
PUSH HL E5
Save Register Pair HL (the address to fill) to the stack, since the SBC changes it. 4ED9H loops back here.
4ED3
SBC HL,BC ED 42
SUBtract Register Pair BC (the last address) and the CARRY FLAG from Register Pair HL: the NO CARRY FLAG when Register Pair HL is past the end.
4ED5
POP HL E1
Restore Register Pair HL (the address to fill) from the stack. POP does not change the flags.
4ED6
RET NC D0
RETurn to DEBUG's command loop if the NO CARRY FLAG is set: the fill is done.
4ED7
LD (HL),E 73
Store Register E (the byte to fill with) at Register Pair HL.
4ED8
INC HL 23
INCrement Register Pair HL to the next address. INC of a pair does not change the CARRY FLAG, which stays set for the next SBC.
4ED9
LOOP BACK to 4ED2H to test and fill the next address.

4EDBH - The J Command: Skip a Byte

J steps the program's saved PC (407BH-407CH, which DEBUG keeps) on by one byte, so that the program goes on after it.

4EDB
CP 6AH FE 6A
Compare Register A (the key) against 6AH, the letter j.
4EDD
If the NZ FLAG is set (not j), JUMP to 4EE7H to test for l.
4EDF
LD HL,(407BH) 2A 7B 40
Fetch the program's saved PC from 407BH-407CH into Register Pair HL.
4EE2
INC HL 23
INCrement Register Pair HL (the PC) by one: past the byte it points at.
4EE3
LD (407BH),HL 22 7B 40
Store Register Pair HL (the new PC) at 407BH-407CH, where DEBUG's G command goes on.
4EE6
RET C9
RETurn to DEBUG's command loop, which shows the new PC.

4EE7H - The L Command: Locate a Byte

L aaaa,dd ENTER searches memory from aaaa for the byte dd. Without aaaa the search starts at the byte after the M address (4060H), which is shown; without dd the byte of the last search (4062H) is used and shown, and a byte typed is kept there for the next search. The search runs over up to 65536 bytes (CPIR with Register Pair BC = 0000H); since the byte at 4062H holds the value searched for, it always finds one. The M address is set on the byte found and the memory display (4063H) on the 64 byte boundary below it. When aaaa is typed and dd is not, the byte shown is the low byte of aaaa, though the search is for the byte at 4062H.

4EE7
CP 6CH FE 6C
Compare Register A (the key) against 6CH, the letter l.
4EE9
If the NZ FLAG is set (not l), JUMP to 4F2EH to test for n.
4EEB
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL.
4EEE
INC HL 23
INCrement Register Pair HL: the start when none is typed, the byte after the M address, so that a second L finds the next byte.
4EEF
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the start typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4EF2
LD (4060H),HL 22 60 40
Store Register Pair HL (the start) at 4060H-4061H, the M address. LD does not change the flags.
4EF5
If the NZ FLAG is set (the start was typed), JUMP to 4F05H for the byte.
4EF7
PUSH AF F5
Save Register Pair AF to the stack: the CARRY FLAG (ENTER or not) is needed after the display.
4EF8
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the start taken) as four hexadecimal digits.
4EFB
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
4EFD
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
4F00
POP AF F1
Restore Register Pair AF from the stack: the CARRY FLAG again says whether ENTER ended the start.
4F01
LD A,(4062H) 3A 62 40
Fetch the byte of the last search from 4062H into Register A. LD does not change the flags.
4F04
LD L,A 6F
Copy Register A (the last byte searched for) into Register L, the byte to show when none is typed.
4F05
If the CARRY FLAG is set (ENTER: no byte follows), JUMP to 4F12H to show Register L and search.
4F07
GOSUB to 51A4H, SYS5/SYS's number reader, for the byte: Register Pair HL = the number typed (NZ FLAG) or unchanged (Z FLAG).
4F0A
If the Z FLAG is set (no byte typed), JUMP to 4F12H to show Register L and search for the byte at 4062H.
4F0C
LD A,L 7D
Copy Register L (the byte typed, its last two digits) into Register A.
4F0D
LD (4062H),A 32 62 40
Store Register A (the byte typed) at 4062H, the byte to search for, kept for the next L.
4F10
JUMP to 4F16H to search for the byte now held at 4062H.
4F12
LD A,L 7D
Copy Register L (the byte at 4062H when no start was typed, else the low byte of the start) into Register A.
4F13
GOSUB to 51DAH in SYS5/SYS to show Register A as two hexadecimal digits.
4F16
LD HL,(4060H) 2A 60 40
Fetch the start from 4060H-4061H into Register Pair HL.
4F19
LD A,(4062H) 3A 62 40
Fetch the byte to search for from 4062H into Register A.
4F1C
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H: the CPIR below compares up to 65536 bytes.
4F1F
CPIR ED B1
Compare Register A with the byte at Register Pair HL, step Register Pair HL up and count Register Pair BC down, until a match (the Z FLAG) or Register Pair BC reaches 0000H (CPIR).
4F21
RET NZ C0
RETurn to DEBUG's command loop if the NZ FLAG is set: no byte matched in 65536 bytes.
4F22
DEC HL 2B
DECrement Register Pair HL back to the byte that matched (CPIR leaves it one past).
4F23
LD (4060H),HL 22 60 40
Store Register Pair HL (the byte found) at 4060H-4061H, the M address, which the display marks with bars.
4F26
LD A,L 7D
Copy Register L (the low byte of the address found) into Register A.
4F27
AND C0H E6 C0
Keep bits 7-6 of Register A (AND C0H): the 64 byte boundary at or below the byte found.
4F29
LD L,A 6F
Copy Register A into Register L: Register Pair HL = that boundary.
4F2A
LD (4063H),HL 22 63 40
Store Register Pair HL (the boundary) at 4063H-4064H, the memory display address: the four lines of memory DEBUG shows hold the byte found.
4F2D
RET C9
RETurn to DEBUG's command loop, which draws the screen with the byte found.

4F2EH - The N Command: Go to the Next Record of a Load Module

N aaaa ENTER, or N ENTER for the M address (4060H): the byte there is taken as the type byte of a record of a load module, and the next byte as its length; the M address is moved to the type byte of the next record (the address + 2 + the length). A length of 00H, 01H or 02H counts 256 more, as for a load block, whose length byte counts its two address bytes too and is 00H-02H for blocks of 254-256 bytes of data. The memory display (4063H) is set on the 64 byte boundary below. With the M address on the opcode of a JR that jumps forward, the M address moves to the JR's destination.

4F2E
CP 6EH FE 6E
Compare Register A (the key) against 6EH, the letter n.
4F30
If the NZ FLAG is set (not n), JUMP to 4F4FH to test for q.
4F32
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL: the record's type byte when no address is typed.
4F35
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the address typed, or unchanged. The flags are not tested.
4F38
INC HL 23
INCrement Register Pair HL to the record's length byte, after the type byte.
4F39
LD D,00H 16 00
Load Register D with 00H, the high byte of the length.
4F3B
LD E,(HL) 5E
Fetch the length byte at Register Pair HL into Register E: Register Pair DE = the length.
4F3C
LD A,E 7B
Copy Register E (the length byte) into Register A.
4F3D
CP 03H FE 03
Compare Register A (the length byte) against 03H: the CARRY FLAG for 00H, 01H and 02H.
4F3F
If the NO CARRY FLAG is set (03H or more), JUMP to 4F42H.
4F41
INC D 14
INCrement Register D: a length byte of 00H-02H stands for 256 more, Register Pair DE = 0100H-0102H.
4F42
INC DE 13
INCrement Register Pair DE: one more for the length byte itself.
4F43
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL (the length byte): Register Pair HL = the type byte of the next record.
4F44
LD (4060H),HL 22 60 40
Store Register Pair HL (the next record) at 4060H-4061H, the M address.
4F47
LD A,L 7D
Copy Register L (the low byte of the next record) into Register A.
4F48
AND C0H E6 C0
Keep bits 7-6 of Register A (AND C0H): the 64 byte boundary at or below the next record.
4F4A
LD L,A 6F
Copy Register A into Register L: Register Pair HL = that boundary.
4F4B
LD (4063H),HL 22 63 40
Store Register Pair HL (the boundary) at 4063H-4064H, the memory display address.
4F4E
RET C9
RETurn to DEBUG's command loop, which draws the screen with the next record marked.

4F4FH - The Q Command: Port Input and Output

Q ii ENTER reads port ii and shows =dd, then waits for a key so that the value can be read before the screen is drawn again. Q oo,dd ENTER sends the byte dd to port oo. A port or byte left out ends the command.

4F4F
CP 71H FE 71
Compare Register A (the key) against 71H, the letter q.
4F51
If the NZ FLAG is set (not q), JUMP to 4F73H to test for t.
4F53
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
4F55
GOSUB to the ROM at 0033H to show Register A (1EH): the rest of the bottom line is erased.
4F58
GOSUB to 51A4H, SYS5/SYS's number reader, for the port: Register Pair HL = the number, the Z FLAG when none was typed, the CARRY FLAG for ENTER.
4F5B
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no port typed).
4F5C
LD C,L 4D
Copy Register L (the port, the last two digits typed) into Register C, the port for IN A,(C) and OUT (C),L. LD does not change the flags.
4F5D
If the CARRY FLAG is set (ENTER after the port: no byte to send), JUMP to 4F66H to read the port.
4F5F
GOSUB to 51A4H, SYS5/SYS's number reader, for the byte to send into Register Pair HL, the Z FLAG when none was typed.
4F62
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no byte typed): nothing is sent.
4F63
OUT (C),L ED 69
Send Register L (the byte typed) to port Register C.
4F65
RET C9
RETurn to DEBUG's command loop, the byte having been sent to the port.
4F66
LD A,3DH 3E 3D
Load Register A with 3DH, an equals sign, to show before the value read.
4F68
GOSUB to the ROM at 0033H to show Register A (the equals sign) at the cursor.
4F6B
IN A,(C) ED 78
Read port Register C (the port typed) into Register A: the byte at the port.
4F6D
GOSUB to 51DAH in SYS5/SYS to show Register A (the byte read) as two hexadecimal digits.
4F70
JUMP to 5189H, SYS5/SYS's key reader, to wait for a key; its RET goes back to DEBUG's command loop.

4F73H - The T Command: Type Text into Memory

T aaaa SPACE shows the byte at aaaa as a character and a minus sign and waits for a key: the key is stored there as typed, upper or lower case, and the next byte is shown; a space goes on without changing the byte; ENTER ends. Without aaaa the M address (4060H) is used and shown. To keep the case of the keys, the SET 5,A of SYS5/SYS's key reader (5195H) is made BIT 5,A while a key is read, by writing 6FH over its second byte at 5196H, and put back to SET 5,A (EFH) afterwards. A byte is shown with bit 7 cleared, and as a period when that is a control code (below 20H); the second test, against C0H, can never be met after bit 7 is cleared.

4F73
CP 74H FE 74
Compare Register A (the key) against 74H, the letter t.
4F75
If the NZ FLAG is set (not t), JUMP to 4FBBH to test for v.
4F77
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL: the address when none is typed.
4F7A
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the address typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4F7D
LD (4060H),HL 22 60 40
Store Register Pair HL (the address) at 4060H-4061H, the M address. LD does not change the flags.
4F80
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): the M address is set and nothing more is done.
4F81
If the NZ FLAG is set (the address was typed), JUMP to 4F86H.
4F83
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the M address taken) as four hexadecimal digits.
4F86
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
4F88
GOSUB to the ROM at 0033H to show Register A (1EH): the rest of the bottom line is erased.
4F8B
GOSUB to 51F1H in SYS5/SYS to show a space before the byte. 4FB9H loops back here for each byte.
4F8E
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A.
4F8F
AND 7FH E6 7F
Clear bit 7 of Register A (AND 7FH): the byte as a character 00H-7FH.
4F91
CP 20H FE 20
Compare Register A against 20H, a space: the CARRY FLAG for a control code.
4F93
If the CARRY FLAG is set (a control code), JUMP to 4F99H to show a period instead.
4F95
CP C0H FE C0
Compare Register A against C0H. After the AND 7FH Register A is below 80H, so the CARRY FLAG is always set.
4F97
If the CARRY FLAG is set (always), JUMP to 4F9BH to show the character.
4F99
LD A,2EH 3E 2E
Load Register A with 2EH, a period, shown for a byte that is not a printable character.
4F9B
GOSUB to the ROM at 0033H to show Register A (the character, or the period) at the cursor.
4F9E
LD A,2DH 3E 2D
Load Register A with 2DH, a minus sign, the prompt for the key.
4FA0
GOSUB to the ROM at 0033H to show Register A (the minus sign) at the cursor.
4FA3
PUSH HL E5
Save Register Pair HL (the address of the byte) to the stack while Register Pair HL points into SYS5/SYS.
4FA4
LD HL,5196H 21 96 51
Load Register Pair HL with 5196H, the second byte of SET 5,A at 5195H in SYS5/SYS's key reader.
4FA7
LD (HL),6FH 36 6F
Store 6FH at 5196H (Register Pair HL): the instruction becomes BIT 5,A, so the key keeps its case.
4FA9
GOSUB to 5189H, SYS5/SYS's key reader, to wait for a key and show it: Register A = the key as typed, the Z FLAG for a comma or a space, the CARRY FLAG for ENTER.
4FAC
LD (HL),EFH 36 EF
Store EFH at 5196H (Register Pair HL): the instruction is SET 5,A again. LD does not change the flags.
4FAE
POP HL E1
Restore Register Pair HL (the address of the byte) from the stack.
4FAF
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): the text ends.
4FB0
CP 20H FE 20
Compare Register A (the key) against 20H, a space.
4FB2
If the Z FLAG is set (a space), JUMP to 4FB5H: the byte stays as it is.
4FB4
LD (HL),A 77
Store Register A (the key, as typed) at Register Pair HL, the byte.
4FB5
INC HL 23
INCrement Register Pair HL to the next byte of memory, the one the next key goes to.
4FB6
LD (4060H),HL 22 60 40
Store Register Pair HL (the next byte) at 4060H-4061H, the M address.
4FB9
LOOP BACK to 4F8BH to show the next byte and wait for its key.

4FBBH - The V Command: Compare Two Blocks

V aaaa,bbbb,nnnn ENTER compares nnnn bytes from aaaa with those from bbbb and stops at the first pair that differ: the memory display address (4063H) is left on the byte of the first block and the M address (4060H) on the byte of the second, so the screen shows both. When all nnnn pairs are the same they are left one past the blocks. Left out, aaaa is the memory display address, bbbb the M address and nnnn 0000H (65536 bytes), and the values taken are shown; ENTER after a number takes the defaults for the numbers after it.

4FBB
CP 76H FE 76
Compare Register A (the key) against 76H, the letter v.
4FBD
If the NZ FLAG is set (not v), JUMP to 5016H to test for w.
4FBF
LD HL,(4063H) 2A 63 40
Fetch the memory display address from 4063H-4064H into Register Pair HL: the first block when none is typed.
4FC2
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the address typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4FC5
LD (4063H),HL 22 63 40
Store Register Pair HL (the first block) at 4063H-4064H, the memory display address. LD does not change the flags.
4FC8
If the NZ FLAG is set (the address was typed), JUMP to 4FD4H.
4FCA
PUSH AF F5
Save Register Pair AF to the stack: the CARRY FLAG (ENTER or not) is needed after the display.
4FCB
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the first block taken) as four hexadecimal digits.
4FCE
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
4FD0
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
4FD3
POP AF F1
Restore Register Pair AF from the stack: the CARRY FLAG again says whether ENTER ended the first address.
4FD4
If the CARRY FLAG is set (ENTER), JUMP to 4FEBH: the second block stays the M address and the count is 0000H.
4FD6
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL: the second block when none is typed.
4FD9
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the address typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
4FDC
LD (4060H),HL 22 60 40
Store Register Pair HL (the second block) at 4060H-4061H, the M address. LD does not change the flags.
4FDF
If the NZ FLAG is set (the address was typed), JUMP to 4FEBH for the count.
4FE1
PUSH AF F5
Save Register Pair AF to the stack: the CARRY FLAG (ENTER or not) is needed after the display.
4FE2
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the second block taken) as four hexadecimal digits.
4FE5
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
4FE7
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
4FEA
POP AF F1
Restore Register Pair AF from the stack: the CARRY FLAG again says whether ENTER ended the second address.
4FEB
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the count when none is typed (65536 bytes). LD does not change the flags.
4FEE
If the CARRY FLAG is set (ENTER), JUMP to 4FFAH to compare with the count of 0000H.
4FF0
GOSUB to 51A4H, SYS5/SYS's number reader, for the count: Register Pair HL = the number typed (NZ FLAG) or 0000H (Z FLAG).
4FF3
If the NZ FLAG is set (the count was typed), JUMP to 4FFAH to compare.
4FF5
PUSH HL E5
Save Register Pair HL (the count) to the stack, since 51D5H does not keep it.
4FF6
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the count taken, 0000H) as four hexadecimal digits.
4FF9
POP HL E1
Restore Register Pair HL (the count) from the stack.
4FFA
LD B,H 44
Copy Register H (the high byte of the count) into Register B.
4FFB
LD C,L 4D
Copy Register L (the low byte of the count) into Register C: Register Pair BC = the pairs to compare.
4FFC
LD HL,(4063H) 2A 63 40
Fetch the first block's address from 4063H-4064H into Register Pair HL.
4FFF
LD DE,(4060H) ED 5B 60 40
Fetch the second block's address from 4060H-4061H into Register Pair DE.
5003
LD A,(DE) 1A
Fetch the byte of the second block at Register Pair DE into Register A. 500CH loops back here.
5004
CP (HL) BE
Compare Register A against the byte of the first block at Register Pair HL.
5005
If the NZ FLAG is set (the bytes differ), JUMP to 500EH to stop on them.
5007
INC DE 13
INCrement Register Pair DE to the next byte of the second block.
5008
INC HL 23
INCrement Register Pair HL to the next byte of the first block.
5009
DEC BC 0B
DECrement Register Pair BC, the pairs still to compare.
500A
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
500B
OR C B1
OR Register C (the low byte) into Register A: the Z FLAG when the count is 0000H.
500C
If the NZ FLAG is set (more pairs to compare), LOOP BACK to 5003H.
500E
LD (4060H),DE ED 53 60 40
Store Register Pair DE (the differing byte of the second block, or the byte after it) at 4060H-4061H, the M address.
5012
LD (4063H),HL 22 63 40
Store Register Pair HL (the differing byte of the first block, or the byte after it) at 4063H-4064H, the memory display address.
5015
RET C9
RETurn to DEBUG's command loop, which shows the first block from that byte, with the M address of the second marked when it lies in the lines shown.

5016H - The W Command: Locate a Word

W aaaa,dddd ENTER searches memory from aaaa for the word dddd, low byte first. Without aaaa the search starts two bytes after the M address (4060H), which is shown; without dddd the word of the last search is used and shown. The word is kept in two cells of DEBUG that are not next to each other: the low byte at 4062H, the high byte at 405FH. CPIR finds the low byte and the byte after it is compared with the high byte; when it differs the CPIR goes on from there with the count it had. The count of 65536 runs over the whole search, so a word that is not in memory ends the command when it runs out (RET PO). The M address is set on the low byte of the word found and the memory display (4063H) on the 64 byte boundary below it. When aaaa is typed and dddd is not, the word shown is aaaa itself, though the search is for the word kept.

5016
CP 77H FE 77
Compare Register A (the key) against 77H, the letter w.
5018
If the NZ FLAG is set (not w), JUMP to 506CH to test for a drive number.
501A
LD HL,(4060H) 2A 60 40
Fetch the M address from 4060H-4061H into Register Pair HL.
501D
INC HL 23
INCrement Register Pair HL: one byte past the M address.
501E
INC HL 23
INCrement Register Pair HL again: the start when none is typed, past the word a W found before.
501F
GOSUB to 51A4H, SYS5/SYS's number reader: Register Pair HL = the start typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
5022
LD (4060H),HL 22 60 40
Store Register Pair HL (the start) at 4060H-4061H, the M address. LD does not change the flags.
5025
If the NZ FLAG is set (the start was typed), JUMP to 5039H for the word.
5027
PUSH AF F5
Save Register Pair AF to the stack: the CARRY FLAG (ENTER or not) is needed after the display.
5028
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the start taken) as four hexadecimal digits.
502B
LD A,2CH 3E 2C
Load Register A with 2CH, a comma, to show after the number.
502D
GOSUB to the ROM at 0033H to show Register A (the comma) at the cursor.
5030
POP AF F1
Restore Register Pair AF from the stack: the CARRY FLAG again says whether ENTER ended the start.
5031
LD A,(4062H) 3A 62 40
Fetch the low byte of the last word searched for from 4062H into Register A.
5034
LD L,A 6F
Copy Register A (the low byte) into Register L.
5035
LD A,(405FH) 3A 5F 40
Fetch the high byte of the last word searched for from 405FH into Register A.
5038
LD H,A 67
Copy Register A (the high byte) into Register H: Register Pair HL = the last word, to show when none is typed.
5039
If the CARRY FLAG is set (ENTER: no word follows), JUMP to 504AH to show Register Pair HL and search.
503B
GOSUB to 51A4H, SYS5/SYS's number reader, for the word: Register Pair HL = the number typed (NZ FLAG) or unchanged (Z FLAG).
503E
If the Z FLAG is set (no word typed), JUMP to 504AH to show Register Pair HL and search for the word kept.
5040
LD A,L 7D
Copy Register L (the low byte of the word typed) into Register A.
5041
LD (4062H),A 32 62 40
Store Register A (the low byte) at 4062H, kept for the next W.
5044
LD A,H 7C
Copy Register H (the high byte of the word typed) into Register A.
5045
LD (405FH),A 32 5F 40
Store Register A (the high byte) at 405FH, kept for the next W.
5048
JUMP to 504DH to search for the word now held at 4062H and 405FH.
504A
GOSUB to 51D5H in SYS5/SYS to show Register Pair HL (the last word, or the start when it was typed) as four hexadecimal digits.
504D
LD HL,(4060H) 2A 60 40
Fetch the start from 4060H-4061H into Register Pair HL.
5050
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H: the CPIRs below compare up to 65536 bytes in all.
5053
LD A,(4062H) 3A 62 40
Fetch the low byte of the word from 4062H into Register A. 505DH loops back here.
5056
CPIR ED B1
Compare Register A with the byte at Register Pair HL, step Register Pair HL up and count Register Pair BC down, until a match (the Z FLAG) or Register Pair BC reaches 0000H (CPIR).
5058
RET PO E0
RETurn to DEBUG's command loop if the PARITY ODD FLAG is set: Register Pair BC ran out, the whole of memory was searched.
5059
LD A,(405FH) 3A 5F 40
Fetch the high byte of the word from 405FH into Register A.
505C
CP (HL) BE
Compare Register A against the byte at Register Pair HL, the byte after the low byte found.
505D
If the NZ FLAG is set (not the word), LOOP BACK to 5053H to go on searching from that byte.
505F
DEC HL 2B
DECrement Register Pair HL back to the high byte of the word found.
5060
DEC HL 2B
DECrement Register Pair HL to its low byte, the start of the word.
5061
LD (4060H),HL 22 60 40
Store Register Pair HL (the word found) at 4060H-4061H, the M address, which the display marks with bars.
5064
LD A,L 7D
Copy Register L (the low byte of the address found) into Register A.
5065
AND C0H E6 C0
Keep bits 7-6 of Register A (AND C0H): the 64 byte boundary at or below the word found.
5067
LD L,A 6F
Copy Register A into Register L: Register Pair HL = that boundary.
5068
LD (4063H),HL 22 63 40
Store Register Pair HL (the boundary) at 4063H-4064H, the memory display address.
506B
RET C9
RETurn to DEBUG's command loop, which draws the screen with the word found.

506CH - The Drive Commands: Read and Write Sectors

d,cc,ss,o,aaaa,nn ENTER, the command key d being the drive 0-7: cylinder cc (left out: the directory cylinder, byte +09H of the drive code table), first sector ss, operation o (r read, w write, or the asterisk key: write with the deleted data mark used for directory sectors), memory address aaaa, and nn sectors. With ss typed the count is 1, else the transfer starts at sector 0 and the count is the sectors of a cylinder (the heads times the sectors of a track, doubled for two sides, kept at 405FH). ENTER before the operation ends the command. Each sector goes to or from the next 256 bytes of memory, and the sector after the cylinder's last starts the next cylinder. An error shows the error number in hexadecimal between two asterisk characters and waits for a key: ENTER stops, any other key goes on with the next sector. A read with r ends with the memory display (4063H) and the M address (4060H) on the first page read and DEBUG's screen layout (405EH) set to 73H, the full screen of 256 bytes. When aaaa is left out, the memory address is the last number read before it (the sector, or the cylinder).

506C
SUB 30H D6 30
SUBtract 30H from Register A (the key): the digits 0-7 become the drive numbers 00H-07H.
506E
CP 08H FE 08
Compare Register A against 08H: the CARRY FLAG for a drive number 00H-07H.
5070
If the NO CARRY FLAG is set (not a digit 0-7), JUMP to 50D5H, which goes on to 513EH to test for p, with Register A = the key less 30H.
5072
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for GETDCT and the sector routines.
5073
GOSUB to 478FH (GETDCT) in SYS0/SYS to point Index Register IY at the drive code table of drive Register C.
5076
LD A,(IY+07H) FD 7E 07
Fetch byte +07H of the drive code table at Index Register IY into Register A: bits 7-5 the heads less one, bits 4-0 the highest sector on a track.
5079
AND E0H E6 E0
Keep bits 7-5 of Register A (AND E0H): the heads less one.
507B
RLCA 07
Rotate Register A left one bit (RLCA): first of three rotations that bring bits 7-5 to bits 2-0.
507C
RLCA 07
Rotate Register A left one bit (RLCA): second of the three rotations.
507D
RLCA 07
Rotate Register A left one bit (RLCA): bits 2-0 now hold the heads less one.
507E
INC A 3C
INCrement Register A (the heads less one): Register A = the number of heads of the drive.
507F
LD B,A 47
Copy Register A (the number of heads) into Register B, the count of the DJNZ below.
5080
LD A,(IY+07H) FD 7E 07
Fetch byte +07H of the drive code table at Index Register IY into Register A again.
5083
AND 1FH E6 1F
Keep bits 4-0 of Register A (AND 1FH): the highest sector on a track.
5085
INC A 3C
INCrement Register A: the number of sectors on a track.
5086
LD H,A 67
Copy Register A (the sectors on a track) into Register H, the number to add.
5087
XOR A AF
Set Register A to 00H (XOR A), the sum to build.
5088
ADD A,H 84
ADD Register H (the sectors on a track) to Register A, once for each head.
5089
DECrement Register B (the heads left) and LOOP BACK to 5088H until Register A = the heads times the sectors on a track.
508B
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of byte +04H of the drive code table at Index Register IY: set when the drive has two sides.
508F
If the Z FLAG is set (one side), JUMP to 5092H.
5091
ADD A,A 87
ADD Register A to itself: the sectors of a cylinder on two sides.
5092
LD (405FH),A 32 5F 40
Store Register A (the sectors of a cylinder) at 405FH, a cell DEBUG keeps (the high byte of W's word); it is used below as the count of a whole cylinder and the last sector plus one.
5095
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
5097
GOSUB to the ROM at 0033H to show Register A (1EH): the rest of the bottom line is erased.
509A
GOSUB to 5189H, SYS5/SYS's key reader, for the key after the drive number (the comma): the CARRY FLAG for ENTER.
509D
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): nothing is done.
509E
GOSUB to 51A4H, SYS5/SYS's number reader, for the cylinder: Register Pair HL = the number typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
50A1
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): nothing is done.
50A2
LD D,L 55
Copy Register L (the cylinder typed, its last two digits) into Register D, the cylinder for the sector routines. LD does not change the flags.
50A3
If the NZ FLAG is set (the cylinder was typed), JUMP to 50A8H for the sector.
50A5
LD D,(IY+09H) FD 56 09
Fetch byte +09H of the drive code table at Index Register IY into Register D: the directory cylinder, when none is typed.
50A8
GOSUB to 51A4H, SYS5/SYS's number reader, for the first sector: Register Pair HL = the number typed (NZ FLAG) or unchanged (Z FLAG), the CARRY FLAG for ENTER.
50AB
LD E,L 5D
Copy Register L (the sector typed) into Register E, the sector for the sector routines. LD does not change the flags.
50AC
LD A,01H 3E 01
Load Register A with 01H, the count of one sector when a sector is typed. LD does not change the flags.
50AE
If the NZ FLAG is set (the sector was typed), JUMP to 50B5H to keep the count of 1.
50B0
LD E,00H 1E 00
Load Register E with 00H: without a sector the transfer starts at sector 0.
50B2
LD A,(405FH) 3A 5F 40
Fetch the sectors of a cylinder from 405FH into Register A: the count of a whole cylinder.
50B5
LD (4062H),A 32 62 40
Store Register A (the count of sectors) at 4062H, a cell DEBUG keeps (the byte L and the low byte of W's word), counted down by the transfer.
50B8
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER after the sector): no operation was given.
50B9
GOSUB to 5189H, SYS5/SYS's key reader, for the operation: Register A = the letter r (72H), the letter w (77H) or the asterisk (2AH), the CARRY FLAG for ENTER.
50BC
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): nothing is done.
50BD
LD B,A 47
Copy Register A (the operation key) into Register B, tested for each sector.
50BE
GOSUB to 5189H, SYS5/SYS's key reader, for the key after the operation (the comma): the CARRY FLAG for ENTER.
50C1
RET C D8
RETurn to DEBUG's command loop if the CARRY FLAG is set (ENTER): nothing is done.
50C2
GOSUB to 51A4H, SYS5/SYS's number reader, for the memory address: Register Pair HL = the number typed, or unchanged (the last number read) when none is typed; the CARRY FLAG for ENTER.
50C5
PUSH HL E5
Save Register Pair HL (the memory address) to the stack: 50F9H takes it back for the display after a read.
50C6
If the CARRY FLAG is set (ENTER: no count follows), JUMP to 50D7H to start the transfer.
50C8
PUSH HL E5
Save Register Pair HL (the memory address) to the stack while Register Pair HL takes the count.
50C9
GOSUB to 51A4H, SYS5/SYS's number reader, for the count of sectors into Register Pair HL, the Z FLAG when none was typed.
50CC
LD A,L 7D
Copy Register L (the count typed, its last two digits) into Register A. LD does not change the flags.
50CD
POP HL E1
Restore Register Pair HL (the memory address) from the stack. POP does not change the flags.
50CE
If the Z FLAG is set (no count typed), JUMP to 50D7H with the count already at 4062H.
50D0
LD (4062H),A 32 62 40
Store Register A (the count typed) at 4062H, the count of sectors.
50D3
JUMP to 50D7H to start the transfer with the count typed.
50D5
JUMP to 513EH to test for p: a key that is not a drive number comes here from 5070H.
50D7
LD A,B 78
Copy Register B (the operation key) into Register A. 50F7H loops back here for each sector.
50D8
CP 72H FE 72
Compare Register A (the operation) against 72H, the letter r.
50DA
If the Z FLAG is set (r), JUMP to 510CH to read the sector.
50DC
CP 77H FE 77
Compare Register A (the operation) against 77H, the letter w.
50DE
If the Z FLAG is set (w), JUMP to 5117H to write the sector.
50E0
CP 2AH FE 2A
Compare Register A (the operation) against 2AH, the asterisk key, for a write with the deleted data mark.
50E2
If the Z FLAG is set (the key 2AH), JUMP to 511EH to write the sector with the deleted data mark. Any other key moves on without a transfer.
50E4
INC H 24
INCrement Register H: Register Pair HL = the next 256 bytes of memory. The sector routines come back here after each sector.
50E5
INC E 1C
INCrement Register E (the sector just done) to the next sector.
50E6
LD A,(405FH) 3A 5F 40
Fetch the sectors of a cylinder from 405FH into Register A.
50E9
DEC A 3D
DECrement Register A: the last sector of a cylinder.
50EA
CP E BB
Compare Register A (the last sector) against Register E (the next sector): the NO CARRY FLAG while Register E is on the cylinder.
50EB
If the NO CARRY FLAG is set (the next sector is on this cylinder), JUMP to 50F0H.
50ED
LD E,00H 1E 00
Load Register E with 00H, the first sector of the next cylinder.
50EF
INC D 14
INCrement Register D (the cylinder) to the next cylinder.
50F0
LD A,(4062H) 3A 62 40
Fetch the count of sectors still to do from 4062H into Register A.
50F3
DEC A 3D
DECrement Register A (the sectors still to do): one sector is done.
50F4
LD (4062H),A 32 62 40
Store Register A (the sectors still to do) at 4062H.
50F7
If the NZ FLAG is set (sectors left), LOOP BACK to 50D7H for the next sector.
50F9
POP HL E1
Restore Register Pair HL (the memory address the transfer started at) from the stack. 513CH comes here when ENTER stops after an error.
50FA
LD A,B 78
Copy Register B (the operation) into Register A.
50FB
CP 72H FE 72
Compare Register A (the operation) against 72H, the letter r.
50FD
RET NZ C0
RETurn to DEBUG's command loop if the NZ FLAG is set (a write): the screen is drawn as it was.
50FE
LD L,00H 2E 00
Load Register L with 00H: Register Pair HL = the start of the 256 byte page where the read began.
5100
LD (4063H),HL 22 63 40
Store Register Pair HL (that page) at 4063H-4064H, the memory display address.
5103
LD (4060H),HL 22 60 40
Store Register Pair HL (that page) at 4060H-4061H, the M address.
5106
LD A,73H 3E 73
Load Register A with 73H, the value of DEBUG's screen layout cell for the full screen of 256 bytes.
5108
LD (405EH),A 32 5E 40
Store Register A (73H) at 405EH, DEBUG's screen layout: the sector read is shown on the full screen.
510B
RET C9
RETurn to DEBUG's command loop, which draws the full screen.
510C
GOSUB to 4777H (RDSECT) in SYS0/SYS to read cylinder Register D, sector Register E of drive Register C into the 256 bytes at Register Pair HL: the Z FLAG on success, else the error number in Register A.
510F
If the Z FLAG is set (read), JUMP to 50E4H for the next sector.
5111
CP 06H FE 06
Compare Register A (the error number) against 06H, the result for a sector with the deleted data mark (a directory sector), which was read all the same.
5113
If the Z FLAG is set (06H), JUMP to 50E4H: the sector was read.
5115
JUMP to 5123H to show the error number in Register A.
5117
GOSUB to 4763H (WRSECT) in SYS0/SYS to write the 256 bytes at Register Pair HL to cylinder Register D, sector Register E of drive Register C: the Z FLAG on success, else the error number in Register A.
511A
If the Z FLAG is set (written), JUMP to 50E4H for the next sector.
511C
JUMP to 5123H to show the error number in Register A.
511E
GOSUB to 4768H (WRPROT) in SYS0/SYS to write the 256 bytes at Register Pair HL to cylinder Register D, sector Register E of drive Register C with the deleted data mark: the Z FLAG on success, else the error number in Register A.
5121
If the Z FLAG is set (written), JUMP to 50E4H for the next sector.
5123
PUSH DE D5
Save Register Pair DE (the cylinder and sector) to the stack while the error is shown through the ROM, which may change it.
5124
PUSH AF F5
Save Register Pair AF (Register A = the error number) to the stack.
5125
GOSUB to 51F1H in SYS5/SYS to show a space before the error.
5128
LD A,2AH 3E 2A
Load Register A with 2AH, an asterisk, shown before the error number.
512A
GOSUB to the ROM at 0033H to show Register A (the asterisk) at the cursor.
512D
POP AF F1
Restore Register Pair AF (Register A = the error number) from the stack.
512E
GOSUB to 51DAH in SYS5/SYS to show Register A (the error number) as two hexadecimal digits.
5131
LD A,2AH 3E 2A
Load Register A with 2AH, an asterisk, shown after the error number.
5133
GOSUB to the ROM at 0033H to show Register A (the asterisk) at the cursor.
5136
GOSUB to 5189H, SYS5/SYS's key reader, to wait for a key: the CARRY FLAG for ENTER.
5139
POP DE D1
Restore Register Pair DE (the cylinder and sector) from the stack. POP does not change the flags.
513A
If the NO CARRY FLAG is set (any key but ENTER), JUMP to 50E4H to go on with the next sector.
513C
JUMP to 50F9H to end the transfer, since ENTER was pressed after the error.

513EH - The P Command: Print a Block of Memory

Register A = the key less 30H (from 506CH), so the test against 40H is met by the key p (70H). P aaaa,bbbb ENTER prints memory through the ROM's printer routine (003BH), sixteen bytes a line from the 16 byte boundary at or below aaaa: two carriage returns first; then for each line the address in four hexadecimal digits, two spaces, the sixteen bytes in hexadecimal each followed by a space with one more space after every fourth byte, a space, the sixteen bytes as characters (a period for a byte below 20H or from 80H up) and a carriage return. Lines are printed while the next line starts below bbbb; three more carriage returns end the listing. Both numbers must be typed. Each hexadecimal digit is made by ADD 90H / DAA / ADC 40H / DAA. The ROM routine at 003BH gives Register A back, which the double spaces and returns rely on. A key that is not p comes to the RET NZ and goes back to DEBUG's command loop.

513E
CP 40H FE 40
Compare Register A (the key less 30H) against 40H: the Z FLAG for the key p (70H).
5140
RET NZ C0
RETurn to DEBUG's command loop if the NZ FLAG is set: the key is none of the extended commands and nothing is done.
5141
GOSUB to 51A4H, SYS5/SYS's number reader, for the first address: Register Pair HL = the number, the Z FLAG when none was typed.
5144
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no first address): nothing is printed.
5145
PUSH HL E5
Save Register Pair HL (the first address) to the stack.
5146
GOSUB to 51A4H, SYS5/SYS's number reader, for the last address into Register Pair HL, the Z FLAG when none was typed.
5149
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, the Stack Pointer unchanged: Register Pair HL = the first address, and the last address goes on the stack.
514A
POP BC C1
Restore Register Pair BC from the stack: the last address, the end test of each line. POP does not change the flags.
514B
RET Z C8
RETurn to DEBUG's command loop if the Z FLAG is set (no last address).
514C
LD A,L 7D
Copy Register L (the low byte of the first address) into Register A.
514D
AND F0H E6 F0
Keep bits 7-4 of Register A (AND F0H): the 16 byte boundary at or below the first address.
514F
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the start of the first line.
5150
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to print before the listing.
5152
GOSUB to the ROM at 003BH to print Register A (the carriage return).
5155
GOSUB to the ROM at 003BH to print Register A (0DH again, given back by the ROM): a second carriage return.
5158
PUSH HL E5
Save Register Pair HL (the start of the line) to the stack, for the characters at 51D2H. 519BH loops back here for each line.
5159
LD A,H 7C
Copy Register H (the high byte of the line's address) into Register A.
515A
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): first of four rotations that bring bits 7-4 to bits 3-0.
515B
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): second of the four rotations.
515C
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): third of the four rotations.
515D
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): bits 7-4 of Register H are now in bits 3-0.
515E
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the first digit of the address, 00H-0FH.
5160
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
5162
DAA 27
Decimal adjust Register A (DAA): 90H-99H stay with no carry; 9AH-9FH become 00H-05H with the CARRY FLAG set.
5163
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
5165
DAA 27
Decimal adjust Register A (DAA): D0H-D9H become 30H-39H, the characters 0-9; 41H-46H stay, the characters A-F.
5166
GOSUB to the ROM at 003BH to print Register A, the first digit of the address.
5169
LD A,H 7C
Copy Register H (the high byte of the line's address) into Register A.
516A
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the second digit of the address.
516C
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
516E
DAA 27
Decimal adjust Register A (DAA): 9AH-9FH become 00H-05H with the CARRY FLAG set.
516F
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
5171
DAA 27
Decimal adjust Register A (DAA): Register A = the character 0-9 or A-F.
5172
GOSUB to the ROM at 003BH to print Register A, the second digit of the address.
5175
LD A,L 7D
Copy Register L (the low byte of the line's address) into Register A.
5176
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): first of four rotations that bring bits 7-4 to bits 3-0.
5177
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): second of the four rotations.
5178
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): third of the four rotations.
5179
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): bits 7-4 of Register L are now in bits 3-0.
517A
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the third digit of the address.
517C
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
517E
DAA 27
Decimal adjust Register A (DAA): 9AH-9FH become 00H-05H with the CARRY FLAG set.
517F
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
5181
DAA 27
Decimal adjust Register A (DAA): Register A = the character 0-9 or A-F.
5182
GOSUB to the ROM at 003BH to print Register A, the third digit of the address.
5185
LD A,L 7D
Copy Register L (the low byte of the line's address) into Register A.
5186
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the fourth digit of the address (0, since the line starts on a 16 byte boundary).
5188
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
518A
DAA 27
Decimal adjust Register A (DAA): 9AH-9FH become 00H-05H with the CARRY FLAG set.
518B
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
518D
DAA 27
Decimal adjust Register A (DAA): Register A = the character 0-9 or A-F.
518E
GOSUB to the ROM at 003BH to print Register A, the fourth digit of the address.
5191
LD A,20H 3E 20
Load Register A with 20H, a space, to print after the address.
5193
GOSUB to the ROM at 003BH to print Register A (the space).
5196
GOSUB to the ROM at 003BH to print Register A (20H again, given back by the ROM): a second space.
5199
JUMP to 519DH to print the bytes of the line.
519B
LOOP BACK to 5158H to print the next line. 51F1H comes here while the next line starts below the last address.
519D
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A. 51CBH loops back here for each byte of the line.
519E
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): first of four rotations that bring bits 7-4 to bits 3-0.
519F
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): second of the four rotations.
51A0
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): third of the four rotations.
51A1
RRA 1F
Rotate Register A right through the CARRY FLAG (RRA): bits 7-4 of the byte are now in bits 3-0.
51A2
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the byte's first digit.
51A4
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
51A6
DAA 27
Decimal adjust Register A (DAA): 9AH-9FH become 00H-05H with the CARRY FLAG set.
51A7
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
51A9
DAA 27
Decimal adjust Register A (DAA): Register A = the character 0-9 or A-F.
51AA
GOSUB to the ROM at 003BH to print Register A, the byte's first digit.
51AD
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A again.
51AE
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): the byte's second digit.
51B0
ADD A,90H C6 90
ADD 90H to Register A: 90H-99H for 0-9, 9AH-9FH for 0AH-0FH.
51B2
DAA 27
Decimal adjust Register A (DAA): 9AH-9FH become 00H-05H with the CARRY FLAG set.
51B3
ADC A,40H CE 40
ADD 40H and the CARRY FLAG to Register A: D0H-D9H for 0-9, 41H-46H for 0AH-0FH.
51B5
DAA 27
Decimal adjust Register A (DAA): Register A = the character 0-9 or A-F.
51B6
GOSUB to the ROM at 003BH to print Register A, the byte's second digit.
51B9
LD A,20H 3E 20
Load Register A with 20H, a space, printed after each byte.
51BB
GOSUB to the ROM at 003BH to print Register A (the space).
51BE
INC HL 23
INCrement Register Pair HL to the next byte of memory.
51BF
LD A,L 7D
Copy Register L (the low byte of the next address) into Register A.
51C0
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): 00H with the Z FLAG when the sixteen bytes of the line are printed.
51C2
If the Z FLAG is set (the end of the line), JUMP to 51CDH to print the characters.
51C4
AND 03H E6 03
Keep bits 1-0 of Register A (AND 03H): 00H with the Z FLAG after every fourth byte.
51C6
LD A,20H 3E 20
Load Register A with 20H, a space. LD does not change the flags.
51C8
If the Z FLAG is set (after a fourth byte), GOSUB to the ROM at 003BH to print Register A (one more space).
51CB
LOOP BACK to 519DH to print the next byte of the line.
51CD
LD A,20H 3E 20
Load Register A with 20H, a space, between the bytes and the characters.
51CF
GOSUB to the ROM at 003BH to print Register A (the space).
51D2
POP HL E1
Restore Register Pair HL from the stack: the start of the line, saved at 5158H.
51D3
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A. 51E5H loops back here for each character.
51D4
CP 20H FE 20
Compare Register A against 20H: the CARRY FLAG for a control code.
51D6
If the CARRY FLAG is set (below 20H), JUMP to 51DCH to print a period instead.
51D8
CP 80H FE 80
Compare Register A against 80H: the CARRY FLAG for a character below 80H.
51DA
If the CARRY FLAG is set (20H-7FH, a printable character), JUMP to 51DEH to print it.
51DC
LD A,2EH 3E 2E
Load Register A with 2EH, a period, printed for a byte that is not a printable character.
51DE
GOSUB to the ROM at 003BH to print Register A (the character, or the period).
51E1
INC HL 23
INCrement Register Pair HL to the next byte of the line.
51E2
LD A,L 7D
Copy Register L (the low byte of the next address) into Register A.
51E3
AND 0FH E6 0F
Keep bits 3-0 of Register A (AND 0FH): 00H with the Z FLAG after the sixteenth character.
51E5
If the NZ FLAG is set (characters left in the line), LOOP BACK to 51D3H.
51E7
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the line.
51E9
GOSUB to the ROM at 003BH to print Register A (the carriage return).
51EC
PUSH HL E5
Save Register Pair HL (the start of the next line) to the stack, since the SBC changes it.
51ED
XOR A AF
Set Register A to 00H (XOR A), which clears the CARRY FLAG for the SBC.
51EE
SBC HL,BC ED 42
SUBtract Register Pair BC (the last address) from Register Pair HL (the next line): the CARRY FLAG while the next line starts below it.
51F0
POP HL E1
Restore Register Pair HL (the start of the next line) from the stack. POP does not change the flags.
51F1
If the CARRY FLAG is set (the next line starts below the last address), JUMP to 519BH, which goes back to 5158H to print it.
51F3
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the listing.
51F5
GOSUB to the ROM at 003BH to print Register A (the carriage return).
51F8
GOSUB to the ROM at 003BH to print Register A (0DH again, given back by the ROM).
51FB
JUMP to the ROM at 003BH to print Register A (0DH) a third time; its RET goes back to DEBUG's command loop.