TRS-80 DOS - NEWDOS/80 v2.0 for the Model I - SYS18/SYS Disassembled

Page Customization

Introduction/Summary

NEWDOS/80 v2.0 SYS18/SYS Disassembly - BASIC Direct Mode Input and Commands (Model I)

SYS18/SYS works on BASIC's command line: it reads the line (with single keys that list lines at once), recognizes NEWDOS/80's extra commands in it and runs RENEW, RENUM and REF. It is one of the three BASIC overlays that load at 5200H (SYS18-SYS20), here 5200H-56E7H (1,256 bytes in five load records, transfer address 5200H); 555EH-56E7H are unused zero bytes. BASIC loads it with RST 28H code 34H (function 1 of directory slot 14H) through its overlay loader at 576CH.

The page shows every byte of the file once, in address order. Calls into BASIC/CMD are linked only where the BASIC page has a row with the right bytes at that address.

Entry Points

AddressFromPurpose
5202HROM link 41AFH (BASIC 575DH/5767H)The command line input (5202H); the ROM's INLIN calls the link at 0368H, and BASIC only sends it here for the command line (called from 1A7EH).
54FFHROM link 41B2H (BASIC 5756H)After the ROM has tokenized the line (1AA1H) (54FFH).

Variables

Locations inside SYS18 whose contents change while it runs (operands written by the code itself or by BASIC):

Address RangePurpose
5205H-5206H
2 bytes
Address of the display routine that shows the cursor-on code (operand of the CALL at 5204H): 0033H in the file, set by BASIC during its start-up (6583H, 658DH).
5227H
1 byte
First key of the previous line (operand of 5226H; written at 522FH), so a second : goes further back.
5272H-5273H
2 bytes
Number of the first line of the last : or @ listing (operand of 5271H; written at 536EH).
5373H-5374H
2 bytes
Number of the last line that fits in the listing (operand of 5372H; written at 5354H).
54A6H
1 byte
Attribute of DI (A1H) or DU (A0H) (operand of 54A5H; written at 5458H).

Locations outside SYS18 that it reads or writes:

Address RangePurpose
4020H-4021H
2 bytes
The ROM's cursor address on the screen (5394H).
40A4H-40A5H
2 bytes
The ROM's pointer to the first program line.
40A7H-40A8H
2 bytes
The ROM's pointer to the input buffer, where lines are typed, expanded and copied.
40ECH-40EDH
2 bytes
The ROM's current line for LIST and EDIT (the start of @, the arrows, . and , and of DI./DU.).
4369H
1 byte
SYS0's system state; bit 5 set while a chain file supplies the keys (5207H).
436CH
1 byte
SYS0's SYSTEM options; bit 0 = AS, upper case inside quotes (54FFH).
57B6H-57B7H
2 bytes
In BASIC/CMD: the code (57B6H) and flag (57B7H) of the command marked at 540AH, read and cleared at 5523H-5528H.
6421H
1 byte
BASIC's RUN ONLY flag: not 0 forbids direct statements (521EH).

Keys and Commands (from the code)

InputEffect
@ (or shift-@) as the first keyList from the current line as many lines as fit in 15 screen rows (at most 64 lines).
:List the lines ending at the current line, from up to 13 lines before it, as fit in 15 rows; another : goes further back.
up arrow / down arrowList the line before / after the current line.
. / (or shift-down arrow)List the current / the last line (/ and shift-down go to the last).
; or shift-up arrowList the first line.
,EDIT the current line.
A, D, E, L followed by a number or a periodExpanded to AUTO, DELETE, EDIT, LIST (not when the line holds an =).
DU n,m / DI n,mCopy line n (n may be a period for the current line) as line m / move it (the old line is deleted).
RENEWGet the program back after NEW.
RENUM, REFRun through RST 28H: SYS13 (code 4FH) and SYS12 (code 2EH).

With SYSTEM option AB (RUN ONLY) the command line gives ILLEGAL DIRECT. With option AS the letters inside quotes of every typed line are made upper case. A direct statement met while a file area is in use (loading an ASCII program) is error 84H DIRECT STATEMENT IN FILE. While a chain file runs, the line is read without the special keys.

Disassembly

5200H - Load Entry

BASIC/CMD loads SYS18 through its overlay loader at 576CH with RST 28H code 34H (function 1 of directory slot 14H) into 5200H-56E7H. After loading, the SYS0 dispatcher calls 5200H, which must return with the Z FLAG set (no error); BASIC/CMD then jumps to the entry address it put in Register Pair BC: 5202H or 54FFH.

5200
CP A BF
Compare Register A with itself. The result is always equal, so the Z FLAG is set: the load succeeded with no error.
5201
RET C9
RETURN to the SYS0 dispatcher with the Z FLAG set, which tells BASIC/CMD's loader the overlay is in place.

5202H - Direct Mode Line Input

Entered from BASIC 5767H through the ROM's link at 41AFH, which INLIN (0361H) calls at 0368H before it reads a line, and only when that line is the BASIC command line (INLIN called from 1A7EH). Register Pair BC holds the ROM's line counts. As the first key of a line, some keys list program lines at once: @ lists from the current line (40ECH) as many lines as fit in 15 screen rows; : lists the lines up to 13 before it (a second : goes back further); the up and down arrows list the line before or after the current one; . and / list the current or the last line; ; and shift-up arrow list the first line; a comma edits the current line. Any other key starts an ordinary input line, which is then checked for SYS18's own commands (53CBH).

5202
LD A,0EH 3E 0E
Load Register A with 0EH, the display code that switches the cursor on.
5204
Self-Modifying Code
GOSUB to the display routine whose address is the operand 5205H: 0033H (the ROM's display routine) in the file; BASIC stores other addresses there during its start-up (6583H and 658DH). It shows the character in Register A.
5207
LD A,(4369H) 3A 69 43
Load Register A with the byte at 4369H, SYS0's system state byte.
520A
BIT 5,A CB 6F
Test bit 5 of Register A: set while a chain file is supplying the keys.
520C
If the Z FLAG is set (no chain file), JUMP to 521AH to handle the first key.
520E
PUSH BC C5
Save Register Pair BC (the ROM's line counts) on the stack.
520F
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the 16-bit value at 40A7H, the ROM's pointer to the input buffer.
5212
LD B,F0H 06 F0
Load Register B with F0H (240), the most characters in a line.
5214
GOSUB to the ROM's KEYIN at 05D9H, which reads a line of up to Register B characters into the buffer at Register Pair HL (here from the chain file), without SYS18's special first keys.
5217
JUMP to 53CBH to check the line for SYS18's commands.
521A
GOSUB to the ROM's $KEY at 0049H, which waits for a key and returns it in Register A.
521D
PUSH AF F5
Save Register Pair AF (Register A = the first key) on the stack.
521E
LD A,(6421H) 3A 21 64
Load Register A with the byte at 6421H, BASIC/CMD's RUN ONLY flag (not 0 when direct statements are not allowed).
5221
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set if direct statements are allowed.
5222
If the NZ FLAG is set (RUN ONLY), JUMP to the ROM's IDERR at 2831H, which reports ILLEGAL DIRECT.
5225
POP AF F1
Restore Register Pair AF from the stack: Register A = the first key.
5226
LD L,00H 2E 00
Self-Modifying Code
Load Register L with the first key of the previous line; the operand 5227H (00H in the file) is stored at 522FH.
5228
CP 60H FE 60
Compare Register A (the key) against 60H, shift-@.
522A
If the NZ FLAG is set (not shift-@), JUMP to 522EH.
522C
LD A,40H 3E 40
Load Register A with 40H: shift-@ is treated as @.
522E
PUSH AF F5
Save Register Pair AF (Register A = the key) on the stack.
522F
LD (5227H),A 32 27 52
Self-Modifying Code
Store Register A (the key) at 5227H, the operand of 5226H, as the previous key for the next line.
5232
CP 3AH FE 3A
Compare Register A (the key) against 3AH, a colon.
5234
If the Z FLAG is set (a colon), JUMP to 5271H.
5236
CP 0AH FE 0A
Compare Register A against 0AH, the down arrow.
5238
If the Z FLAG is set (the down arrow), JUMP to 527CH to start from the current line.
523A
CP 5BH FE 5B
Compare Register A against 5BH, the up arrow.
523C
If the Z FLAG is set (the up arrow), JUMP to 527CH.
523E
CP 2EH FE 2E
Compare Register A (the first key) against 2EH, a period.
5240
If the Z FLAG is set (a period), JUMP to 527CH.
5242
CP 2CH FE 2C
Compare Register A (the first key) against 2CH, a comma.
5244
If the Z FLAG is set (a comma), JUMP to 527CH.
5246
LD HL,(40A4H) 2A A4 40
Load Register Pair HL with the 16-bit value at 40A4H, the ROM's pointer to the first program line.
5249
CP 3BH FE 3B
Compare Register A (the key) against 3BH, a semicolon.
524B
If the Z FLAG is set (a semicolon), JUMP to 524FH with the Z FLAG set.
524D
CP 1BH FE 1B
Compare Register A against 1BH, shift-up arrow.
524F
If the Z FLAG is set (a semicolon or shift-up arrow), JUMP to 537AH to list the first line (Register Pair HL).
5252
LD DE,FFFFH 11 FF FF
Load Register Pair DE with FFFFH (65535), a line number past every line, to find the last line.
5255
CP 1AH FE 1A
Compare Register A against 1AH, shift-down arrow.
5257
If the Z FLAG is set (shift-down arrow), JUMP to 5280H to find the last line.
5259
CP 2FH FE 2F
Compare Register A (the first key) against 2FH, a slash.
525B
If the Z FLAG is set (a slash), JUMP to 5280H to find the last line.
525D
CP 40H FE 40
Compare Register A (the first key) against 40H, the character @.
525F
If the Z FLAG is set (@), JUMP to 527CH to start from the current line.
5261
POP AF F1
Any other key: restore Register Pair AF from the stack, Register A = the key.
5262
PUSH BC C5
Save Register Pair BC (the ROM's line counts) on the stack.
5263
LD HL,53CBH 21 CB 53
Load Register Pair HL with 53CBH, SYS18's check of the typed line.
5266
PUSH HL E5
Push Register Pair HL (53CBH): KEYIN returns there when the line is complete.
5267
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the 16-bit value at 40A7H, the ROM's pointer to the input buffer.
526A
LD B,F0H 06 F0
Load Register B with F0H (240), the most characters in a line.
526C
LD C,B 48
Load Register C with Register B (240), the buffer size KEYIN keeps in Register C.
526D
PUSH HL E5
Push Register Pair HL (the input buffer), as KEYIN's own entry does.
526E
JUMP into the ROM's KEYIN at 05E3H, which takes the key already in Register A as the line's first character and reads the rest.
5271
LD DE,0000H 11 00 00
Self-Modifying Code
A colon: load Register Pair DE with the number of the first line of the last colon listing; the operand 5272H (0000H in the file) is stored at 536EH.
5274
CP L BD
Compare Register A (the colon) with Register L, the previous line's first key.
5275
If the Z FLAG is set (a colon again), JUMP to 5280H to go back from that line.
5277
LD A,L 7D
Load Register A with Register L, the previous key.
5278
CP 40H FE 40
Compare Register A (the previous line's first key) against 40H, the character @.
527A
If the Z FLAG is set (after an @ listing), JUMP to 5280H to go back from its first line.
527C
LD DE,(40ECH) ED 5B EC 40
Load Register Pair DE with the 16-bit value at 40ECH, the ROM's current line for LIST and EDIT.
5280
LD HL,(40A4H) 2A A4 40
Load Register Pair HL with the 16-bit value at 40A4H, the ROM's pointer to the first program line.
5283
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the count of lines passed.
5286
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the first line's link.
5287
INC HL 23
Increment Register Pair HL to the high byte of the first line's link.
5288
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set if the link is 0000H, no program.
5289
DEC HL 2B
Decrement Register Pair HL back to the line's start.
528A
If the Z FLAG is set (no program), JUMP to 537AH, which lists nothing.

FIND THE LINE LOOP
Register Pair HL = the line being tested, Register Pair DE = the line number wanted, Register Pair BC = the lines passed.

528D
INC HL 23
Increment Register Pair HL: 1 of 2 to the line number.
528E
INC HL 23
Increment Register Pair HL to the low byte of the line number.
528F
INC HL 23
Increment Register Pair HL to the high byte of the line number.
5290
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the high byte of this line's number.
5291
CP D BA
Compare Register A with Register D, the high byte of the number wanted.
5292
DEC HL 2B
Decrement Register Pair HL to the low byte (the flags are not changed).
5293
If the NZ FLAG is set (the high bytes differ), JUMP to 5297H with their compare.
5295
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of this line's number.
5296
CP E BB
Compare Register A with Register E, the low byte of the number wanted: the Z FLAG is set on an exact match.
5297
DEC HL 2B
Decrement Register Pair HL back towards the line's start.
5298
DEC HL 2B
Decrement Register Pair HL: HL = the line's start (the link).
5299
If the NO CARRY FLAG is set (this line's number is not below the one wanted), JUMP to 52ADH: found.
529B
PUSH HL E5
Save Register Pair HL (this line) on the stack.
529C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the link.
529D
INC HL 23
Increment Register Pair HL to the high byte of this line's link.
529E
LD H,(HL) 66
Load Register H with the byte at Register Pair HL, the high byte of the link.
529F
LD L,A 6F
Load Register L with Register A. Register Pair HL now points at the next line.
52A0
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the next line's link.
52A1
INC HL 23
Increment Register Pair HL to the high byte of the next line's link.
52A2
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set if the next line is the program's end marker.
52A3
If the Z FLAG is set (this was the last line), JUMP to 52A9H.
52A5
INC BC 03
Increment Register Pair BC, the lines passed.
52A6
POP AF F1
Restore Register Pair AF from the stack, discarding the saved line.
52A7
LOOP back to 528EH with Register Pair HL one byte into the next line.
52A9
POP HL E1
The last line: restore Register Pair HL from the stack, the last line's start.
52AA
POP AF F1
Restore Register Pair AF from the stack: Register A = the key.
52AB
JUMP to 52BFH with Register A = the key and Register Pair HL = the last line.
52AD
POP DE D1
Found: restore Register Pair DE from the stack; Register D = the key (pushed as Register A at 522EH).
52AE
LD A,D 7A
Load Register A with Register D, the key. LD does not change the flags.
52AF
If the NZ FLAG is set (the line found has a higher number, the current line does not exist), JUMP to 52B8H.
52B1
LD DE,0001H 11 01 00
Load Register Pair DE with 0001H: one line on.
52B4
CP 0AH FE 0A
Compare Register A (the key) against 0AH, the down arrow.
52B6
If the Z FLAG is set (the down arrow), JUMP to 52CEH with Register Pair DE = +1.
52B8
LD DE,FFFFH 11 FF FF
Load Register Pair DE with FFFFH: one line back (-1).
52BB
CP 5BH FE 5B
Compare Register A (the key) against 5BH, the up arrow.
52BD
If the Z FLAG is set (the up arrow), JUMP to 52CEH with Register Pair DE = -1.
52BF
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: no step, the listing starts at this line.
52C2
CP 40H FE 40
Compare Register A (the key) against 40H, the character @.
52C4
If the Z FLAG is set (@), JUMP to 52CEH with Register Pair DE = 0.
52C6
LD DE,FFF3H 11 F3 FF
Load Register Pair DE with FFF3H: 13 lines back (-13).
52C9
CP 3AH FE 3A
Compare Register A (the key) against 3AH, a colon.
52CB
If the NZ FLAG is set (a period, comma, slash, or an arrow at a line that does not exist), JUMP to 5379H to list or edit the line at Register Pair HL.
52CE
PUSH AF F5
Save Register Pair AF (Register A = the key) on the stack.
52CF
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the step (+1, -1, 0 or -13), DE = the line found.
52D0
ADD HL,BC 09
Add Register Pair BC (the lines before the found one) to Register Pair HL: HL = the index of the target line from the first line.
52D1
LD A,H 7C
Load Register A with Register H, the high byte of the target index.
52D2
CP FFH FE FF
Compare Register A against FFH: the Z FLAG is set if the index is negative (before the first line).
52D4
If the NZ FLAG is set (0 or more), JUMP to 52D9H.
52D6
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H: start at the first line instead.
52D9
PUSH BC C5
Save Register Pair BC (the found line's index) on the stack.
52DA
LD B,H 44
Load Register B with Register H, the high byte of the target index.
52DB
LD C,L 4D
Load Register C with Register L. Register Pair BC now holds the target index.
52DC
POP HL E1
Restore Register Pair HL from the stack: the found line's index.
52DD
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
52DE
SBC HL,BC ED 42
Subtract Register Pair BC (the target index) from Register Pair HL (the found index): HL = the lines from the target to the found line.
52E0
PUSH HL E5
Save Register Pair HL (that number of lines) on the stack.
52E1
LD HL,(40A4H) 2A A4 40
Load Register Pair HL with the 16-bit value at 40A4H, the first program line.

STEP TO THE TARGET LINE
Register Pair BC counts down the lines to pass; Register Pair HL = the current line, Register Pair DE = the next.

52E4
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of this line's link.
52E5
INC HL 23
Increment Register Pair HL to the high byte of this line's link.
52E6
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE now points at the next line.
52E7
DEC HL 2B
Decrement Register Pair HL back to this line's start.
52E8
LD A,B 78
Load Register A with Register B, the high byte of the lines left to pass.
52E9
OR C B1
OR Register A with Register C, the low byte: the Z FLAG is set when none are left.
52EA
DEC BC 0B
Decrement Register Pair BC, the lines left (the flags are not changed).
52EB
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the next line, DE = this one.
52EC
If the NZ FLAG is set (lines left to pass), LOOP back to 52E4H.
52EE
POP BC C1
Restore Register Pair BC from the stack: the lines from the target to the found line.
52EF
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the target line.
52F0
INC BC 03
Increment Register Pair BC: the number of lines to list (up to and including the found line).
52F1
POP AF F1
Restore Register Pair AF from the stack: Register A = the key.
52F2
CP 3AH FE 3A
Compare Register A (the key) against 3AH, a colon.
52F4
LD B,A 47
Load Register B with Register A (the key). LD does not change the flags.
52F5
If the Z FLAG is set (a colon; Register C holds the lines to list), JUMP to 52FCH.
52F7
CP 40H FE 40
Compare Register A (the key) against 40H, the character @.
52F9
If the NZ FLAG is set (an arrow), JUMP to 5379H to list the target line at Register Pair HL.
52FB
LD C,A 4F
Load Register C with Register A (40H): @ lists up to 64 lines, as many as fit.
52FC
POP AF F1
Restore Register Pair AF from the stack, discarding the next word there (the key pushed at 522EH was already taken at 52AAH or 52ADH); the listing never returns through it, because LIST4 ends at READY.
52FD
LD A,1CH 3E 1C
Load Register A with 1CH, the display code for cursor home.
52FF
GOSUB to BASIC 5D66H, which shows the character in Register A.
5302
LD A,1FH 3E 1F
Load Register A with 1FH, the display code that erases to the end of the screen.
5304
GOSUB to BASIC 5D66H to show it: the screen is cleared.

COUNT THE ROWS
Each line is expanded (BUFLIN) and its screen rows counted; lines are added while the total stays below 15 rows. Register D = rows so far, Register E = lines counted, Register C = the most lines wanted, Register B = the key.

5307
PUSH HL E5
Save Register Pair HL (the first line to list) on the stack.
5308
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: Register D = the screen rows used, Register E = the lines counted.
530B
PUSH HL E5
Save Register Pair HL (the line being counted) on the stack.
530C
PUSH DE D5
Save Register Pair DE (the counts) on the stack.
530D
PUSH BC C5
Save Register Pair BC (the key and the line limit) on the stack.
530E
INC HL 23
Increment Register Pair HL: 1 of 2 to the line number.
530F
INC HL 23
Increment Register Pair HL to the low byte of the line number.
5310
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the line number.
5311
INC HL 23
Increment Register Pair HL to the high byte of the line number.
5312
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE now holds the line number.
5313
PUSH DE D5
Save Register Pair DE (the line number) on the stack.
5314
INC HL 23
Increment Register Pair HL to the line's text.
5315
GOSUB to the ROM's BUFLIN at 2B7EH, which expands the tokenized text at Register Pair HL into readable text in the input buffer; Register Pair BC returns at its end.
5318
POP DE D1
Restore Register Pair DE from the stack: the line number.
5319
PUSH DE D5
Save Register Pair DE (the line number) on the stack again, for 533DH.
531A
GOSUB to BASIC 5D32H, which works out the digits of the line number in Register Pair DE: Register E returns how many there are.
531D
XOR A AF
Load Register A with 00H (XOR A with itself).
531E
LD D,01H 16 01
Load Register D with 01H: the line takes at least one row.
5320
INC E 1C
Increment Register E: the column after the number and its space.
5321
LD (BC),A 02
Store Register A (00H) at Register Pair BC, ending the expanded text.
5322
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the 16-bit value at 40A7H, the input buffer holding the expanded text.
5325
JUMP to 5337H to start counting at the first character in Register Pair HL.
5327
CP 0DH FE 0D
Compare Register A (the character) against 0DH, a carriage return.
5329
If the Z FLAG is set (a carriage return, a new row), JUMP to 5334H.
532B
CP 0AH FE 0A
Compare Register A (the character) against 0AH, a line feed.
532D
If the Z FLAG is set (a line feed, a new row), JUMP to 5334H.
532F
INC E 1C
Increment Register E, the column in the current screen row.
5330
BIT 6,E CB 73
Test bit 6 of Register E: set when the column reaches 64, the end of a row.
5332
If the Z FLAG is set (still in the row), JUMP to 5337H.
5334
INC D 14
Increment Register D, the rows this line takes.
5335
LD E,00H 1E 00
Load Register E with 00H, column 0 of the new row.
5337
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a character of the expanded text.
5338
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the 00H end.
5339
INC HL 23
Increment Register Pair HL to the next character (the flags are not changed).
533A
If the NZ FLAG is set (not the end), LOOP back to 5327H.
533C
LD A,D 7A
Load Register A with Register D, the rows this line takes.
533D
POP HL E1
Restore Register Pair HL from the stack: this line's number.
533E
POP BC C1
Restore Register Pair BC from the stack: the key and the line limit.
533F
POP DE D1
Restore Register Pair DE from the stack: the rows and lines counted so far.
5340
ADD A,D 82
Add Register D (the rows so far) to Register A (this line's rows).
5341
LD D,A 57
Load Register D with Register A, the rows including this line.
5342
CP 0FH FE 0F
Compare Register A against 0FH (15): the CARRY FLAG is set if fewer than 15 rows are used.
5344
If the CARRY FLAG is set (the line fits), JUMP to 5354H.
5346
POP HL E1
Too many rows: restore Register Pair HL from the stack, discarding the line pushed at 530BH.
5347
LD A,B 78
Load Register A with Register B, the key (a colon or @).
5348
CP 40H FE 40
Compare Register A (the key) against 40H, the character @.
534A
If the Z FLAG is set (@), JUMP to 5367H to list the lines that fit.
534C
POP HL E1
A colon: restore Register Pair HL from the stack, the first line of the listing.
534D
DEC C 0D
Decrement Register C, the lines to list: one fewer, starting a line later.
534E
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the first line's link.
534F
INC HL 23
Increment Register Pair HL to the high byte of the first line's link.
5350
LD H,(HL) 66
Load Register H with the byte at Register Pair HL, the high byte of the link.
5351
LD L,A 6F
Load Register L with Register A. Register Pair HL now points at the next line, the new first line.
5352
JUMP to 5307H to count the rows again from there.
5354
LD (5373H),HL 22 73 53
Self-Modifying Code
Store Register Pair HL (this line's number) at 5373H, the operand of the LD HL,0000H at 5372H: the last line to list so far.
5357
POP HL E1
Restore Register Pair HL from the stack: this line's start.
5358
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of its link.
5359
INC HL 23
Increment Register Pair HL to the high byte of this line's link.
535A
LD H,(HL) 66
Load Register H with the byte at Register Pair HL, the high byte of the link.
535B
LD L,A 6F
Load Register L with Register A. Register Pair HL now points at the next line.
535C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the next line's link.
535D
INC HL 23
Increment Register Pair HL to the high byte of the next line's link.
535E
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set at the program's end marker.
535F
DEC HL 2B
Decrement Register Pair HL back to the next line's start.
5360
If the Z FLAG is set (no more lines), JUMP to 5367H to list what was counted.
5362
INC E 1C
Increment Register E, the number of lines counted for the listing.
5363
LD A,E 7B
Load Register A with Register E, the lines counted.
5364
CP C B9
Compare Register A with Register C, the most lines wanted: the CARRY FLAG is set if more may follow.
5365
If the CARRY FLAG is set, LOOP back to 530BH for the next line.
5367
POP HL E1
Restore Register Pair HL from the stack: the first line of the listing.
5368
PUSH HL E5
Save Register Pair HL (the first line of the listing) on the stack again.
5369
INC HL 23
Increment Register Pair HL: 1 of 2 to the line number.
536A
INC HL 23
Increment Register Pair HL to the low byte of the line number.
536B
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the first line's number.
536C
INC HL 23
Increment Register Pair HL to the high byte of the first line's number.
536D
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE now holds the first line's number.
536E
LD (5272H),DE ED 53 72 52
Self-Modifying Code
Store Register Pair DE (the first listed line's number) at 5272H, the operand of 5271H, where the next colon starts.
5372
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the number of the last line to list; the operand 5373H (0000H in the file) was stored at 5354H.
5375
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): the last line's number is saved, and HL = the first line.
5376
PUSH HL E5
Push Register Pair HL (the first line) on the stack, as the ROM's LIST4 wants it.
5377
JUMP to 53BEH to list the lines whose range is now on the stack.
5379
PUSH AF F5
One line: save Register Pair AF (Register A = the key) on the stack.
537A
LD A,1DH 3E 1D
Load Register A with 1DH, the display code that moves the cursor to the start of the line.
537C
GOSUB to the ROM's display routine at 0033H, which shows the character in Register A.
537F
POP AF F1
Restore Register Pair AF from the stack: Register A = the key.
5380
POP BC C1
Restore Register Pair BC from the stack, discarding the word on top: the key pushed at 522EH on the paths from 524FH and 528AH, otherwise the next word below it. The listing and EDIT do not return through it.
5381
LD B,H 44
Load Register B with Register H, the high byte of the line's address.
5382
LD C,L 4D
Load Register C with Register L. Register Pair BC now holds the line's address.
5383
INC HL 23
Increment Register Pair HL: 1 of 2 to the line number.
5384
INC HL 23
Increment Register Pair HL to the low byte of the line number.
5385
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the line number.
5386
INC HL 23
Increment Register Pair HL to the high byte of the line number.
5387
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE now holds the line number.
5388
CP 2CH FE 2C
Compare Register A (the key) against 2CH, a comma.
538A
If the Z FLAG is set (a comma), JUMP to 2E65H in the ROM's EDIT routine, which edits the line at Register Pair BC.
538D
PUSH DE D5
Push Register Pair DE (the line number): the last line to list.
538E
PUSH BC C5
Push Register Pair BC (the line's address): the first line to list.
538F
LD A,0FH 3E 0F
Load Register A with 0FH, the display code that switches the cursor off.
5391
GOSUB to the ROM's display routine at 0033H to show it.
5394
LD HL,(4020H) 2A 20 40
Load Register Pair HL with the 16-bit value at 4020H, the ROM's cursor address on the screen.
5397
LD DE,FFC0H 11 C0 FF
Load Register Pair DE with FFC0H, which is -64 (one screen row).
539A
ADD HL,DE 19
Add Register Pair DE to Register Pair HL: HL = the same place in the row above.
539B
LD A,H 7C
Load Register A with Register H, the high byte of that address.
539C
CP 3CH FE 3C
Compare Register A against 3CH: the CARRY FLAG is set if the address lies above the screen (below 3C00H).
539E
If the CARRY FLAG is set (no row above), JUMP to 53B9H.
53A0
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the address in the row above.
53A1
LD B,0AH 06 0A
Load Register B with 0AH (10), the characters to compare.
53A3
LD HL,53C1H 21 C1 53
Load Register Pair HL with 53C1H, the text READY and five spaces as they appear on the screen.

IS THE ROW ABOVE THE READY LINE?
Register Pair DE = the screen, Register Pair HL = the text at 53C1H, Register B = the characters left.

53A6
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a character on the screen.
53A7
INC DE 13
Increment Register Pair DE to the next screen position.
53A8
CP 20H FE 20
Compare Register A against 20H: the CARRY FLAG is set for a byte below 20H.
53AA
If the NO CARRY FLAG is set (20H or above), JUMP to 53AEH to compare Register A as it is.
53AC
OR 40H F6 40
OR Register A with 40H: a byte below 20H is shown as 40H-5FH on the screen, so it is compared in that form.
53AE
CP (HL) BE
Compare Register A with the byte at Register Pair HL, the character expected.
53AF
INC HL 23
Increment Register Pair HL to the next expected character (the flags are not changed).
53B0
If the NZ FLAG is set (it differs), JUMP to 53B9H.
53B2
Decrement Register B and LOOP back to 53A6H until all 10 characters match.
53B4
LD A,1BH 3E 1B
The row above is the READY line: load Register A with 1BH, the display code that moves the cursor up a row.
53B6
GOSUB to the ROM's display routine at 0033H: the listing is written over the READY line.
53B9
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases to the end of the line.
53BB
GOSUB to the ROM's display routine at 0033H to show it.
53BE
JUMP to LIST4 at 2B33H in the ROM's LIST routine, which lists from the first line on the stack to the last line number on the stack, then returns to READY.
53C1-53CA
DEFM "READY " 52 45 41 44 59 20 20 20 20 20
The text READY and five spaces as the screen shows it, compared with the row above the cursor at 53AEH.

53CBH - Check the Typed Line

KEYIN returns here with the typed line in the input buffer (Register Pair HL = the buffer, Register B = the characters typed, Register C = the buffer size, the CARRY FLAG set if BREAK was pressed). A line starting with a digit goes on as usual. Otherwise its first word is looked up in the table at 54B7H: RENEW, RENUM and REF are replaced by an FFH byte and spaces, so that the tokenized line is recognized at 54FFH; DI and DU (move and duplicate a line) are carried out at once; the one-letter abbreviations A, D, E and L (followed by a number or a period) are expanded into AUTO, DELETE, EDIT and LIST. The line then goes back to the ROM's INLIN at 0375H.

53CB
PUSH AF F5
Save Register Pair AF (the CARRY FLAG = BREAK) on the stack; INLIN at 0375H gets it back.
53CC
If the CARRY FLAG is set (BREAK was pressed), JUMP to 5455H to hand the line straight back.
53CF
PUSH DE D5
Save Register Pair DE on the stack; 5454H restores it.
53D0
PUSH BC C5
Save Register Pair BC (Register B = the characters typed, Register C = the buffer size) on the stack.
53D1
PUSH HL E5
Save Register Pair HL (the start of the input buffer) on the stack.
53D2
DEC HL 2B
Decrement Register Pair HL so the RST 10H that follows fetches the first character.
53D3
RST 10H D7
RST 10H: move Register Pair HL to the first non-blank character and load it into Register A; the CARRY FLAG is set for a digit.
53D4
If the NO CARRY FLAG is set (the line does not start with a digit), JUMP to 53E0H to look for a command.
53D6
GOSUB to the ROM's LINGET at 1E5AH, which reads the line number at Register Pair HL into Register Pair DE; Register A returns the character after it.
53D9
CP 0DH FE 0D
Compare Register A (the character after the number) against 0DH, the carriage return that ends the typed line.
53DB
If the NZ FLAG is set (text follows the number), JUMP to 5452H: an ordinary program line.
53DD
JUMP to the ROM's SNERR at 1997H to report SYNTAX ERROR: a line number alone ends here, as does an expanded abbreviation that would not fit (5438H).
53E0
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the first character of the line.
53E1
LD HL,54B7H 21 B7 54
Load Register Pair HL with 54B7H, the start of SYS18's command table.

TABLE SEARCH LOOP
Register Pair HL = the table entry, Register Pair DE = the typed text; the text's start is saved on the stack.

53E4
PUSH DE D5
Save Register Pair DE (the start of the typed word) on the stack.
53E5
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a character of the typed word.
53E6
INC DE 13
Increment Register Pair DE to the next typed character.
53E7
GOSUB to BASIC 57BAH, which makes the character in Register A upper case.
53EA
CP (HL) BE
Compare Register A with the byte at Register Pair HL, the table entry's character.
53EB
If the Z FLAG is set (it matches), JUMP to 53FBH.
53ED
BIT 7,(HL) CB 7E
Test bit 7 of the byte at Register Pair HL: set for the attribute byte after the entry's name.
53EF
INC HL 23
Increment Register Pair HL (the flags are not changed).
53F0
If the Z FLAG is set (still in the name), LOOP back to 53EDH until Register Pair HL is past the attribute byte.
53F2
INC HL 23
Increment Register Pair HL over the first value byte.
53F3
INC HL 23
Increment Register Pair HL over the second: HL = the next entry.
53F4
POP DE D1
Restore Register Pair DE from the stack: the start of the typed word.
53F5
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next entry's first byte.
53F6
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the 00H that ends the table.
53F7
If the NZ FLAG is set (another entry), LOOP back to 53E4H.
53F9
JUMP to 5452H: not one of SYS18's commands, the line goes on as typed.
53FB
INC HL 23
Increment Register Pair HL to the entry's next byte.
53FC
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's next character or its attribute byte.
53FD
BIT 7,A CB 7F
Test bit 7 of Register A: set for the attribute byte, the whole name matched.
53FF
If the Z FLAG is set (more of the name), LOOP back to 53E5H to compare the next typed character.
5401
INC HL 23
Increment Register Pair HL to the first value byte.
5402
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the first value byte.
5403
INC HL 23
Increment Register Pair HL to the entry's second value byte.
5404
LD B,(HL) 46
Load Register B with the byte at Register Pair HL. Register Pair BC now holds the entry's value.
5405
POP HL E1
Restore Register Pair HL from the stack: the start of the command word in the buffer.
5406
BIT 6,A CB 77
Test bit 6 of Register A (the attribute): set for RENEW, RENUM and REF.
5408
If the Z FLAG is set (not one of them), JUMP to 5419H.
540A
LD (57B6H),BC ED 43 B6 57
Store Register Pair BC at 57B6H-57B7H in BASIC/CMD: Register C (the RST 28H code, or 01H for RENEW) at 57B6H and Register B (the flag 01H) at 57B7H, for 54FFH after tokenizing.
540E
LD (HL),FFH 36 FF
Store FFH at Register Pair HL, over the command's first letter: the mark 54FFH looks for.
5410
INC HL 23
Increment Register Pair HL to the next letter.
5411
RST 18H DF
RST 18H: compare Register Pair HL with Register Pair DE (just past the command word). The NO CARRY FLAG is set at the end of the word.
5412
If the NO CARRY FLAG is set (the word is done), JUMP to 5452H.
5414
LD (HL),20H 36 20
Store 20H (a space) at Register Pair HL, over a letter of the command word, so the ROM's tokenizer does not make a keyword of it.
5416
INC HL 23
Increment Register Pair HL to the next letter.
5417
JUMP to 5411H to test the next letter at Register Pair HL.
5419
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the text after the command word.
541A
DEC HL 2B
Decrement Register Pair HL so the RST 10H that follows fetches that character.
541B
BIT 5,A CB 6F
Test bit 5 of Register A (the attribute): set for DI and DU.
541D
If the NZ FLAG is set (DI or DU), JUMP to 5458H.
541F
RST 10H D7
An abbreviation: RST 10H moves Register Pair HL to the next non-blank character, in Register A; the CARRY FLAG is set for a digit.
5420
If the CARRY FLAG is set (a line number follows), JUMP to 5426H.
5422
CP 2EH FE 2E
Compare Register A against 2EH, a period (the current line).
5424
If the NZ FLAG is set (neither a number nor a period), JUMP to 5452H: not an abbreviation.

LOOK FOR AN = SIGN
A line such as L=5 is an assignment, not LIST 5. Register Pair HL steps through the rest of the line.

5426
CALL 65CFH CD CF 65
GOSUB to BASIC 65CFH, which fetches the next character at Register Pair HL into Register A and sets the Z FLAG if it is =.
5429
If the Z FLAG is set (an =, an assignment), JUMP to 5452H.
542B
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line.
542D
If the NZ FLAG is set (more of the line), LOOP back to 5426H.
542F
POP HL E1
Restore Register Pair HL from the stack: the start of the input buffer.
5430
POP DE D1
Restore Register Pair DE from the stack: the Register Pair BC pushed at 53D0H, so Register D = the characters typed and Register E = the buffer size.
5431
LD A,D 7A
Load Register A with Register D, the line's length.
5432
EX AF,AF' 08
Exchange Register Pair AF with the alternate AF': the line's length is kept in the alternate Register A.
5433
LD A,(BC) 0A
Load Register A with the byte at Register Pair BC, the length of the full keyword (Register Pair BC = the entry's value, the address of a length byte and the letters).
5434
DEC A 3D
Decrement Register A: the keyword's length minus the one letter typed, the characters to add.
5435
ADD A,D 82
Add Register D (the line's length) to Register A: the new length.
5436
LD D,A 57
Load Register D with Register A, the new length.
5437
CP E BB
Compare Register A with Register E (the buffer size): the NO CARRY FLAG is set if the line would not fit.
5438
If the NO CARRY FLAG is set (too long), JUMP to 53DDH to report SYNTAX ERROR.
543A
PUSH DE D5
Save Register Pair DE (Register D = the new length, Register E = the buffer size) on the stack: the counts INLIN gets back.
543B
PUSH HL E5
Save Register Pair HL (the start of the buffer) on the stack.
543C
LD A,(BC) 0A
Load Register A with the byte at Register Pair BC, the keyword's length.
543D
EX AF,AF' 08
Exchange Register Pair AF with the alternate AF': Register A = the line's old length, and the keyword's length goes to the alternate Register A.
543E
INC BC 03
Increment Register Pair BC to the keyword's first letter.
543F
PUSH BC C5
Save Register Pair BC (the keyword's letters) on the stack.
5440
LD C,A 4F
Load Register C with Register A, the line's old length.
5441
LD B,00H 06 00
Load Register B with 00H, so Register Pair BC = the old length.
5443
ADD HL,BC 09
Add Register Pair BC to Register Pair HL: HL = the buffer plus the old length, the end of the line.
5444
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the end of the line.
5445
EX AF,AF' 08
Exchange Register Pair AF with the alternate AF': Register A = the keyword's length.
5446
LD H,B 60
Load Register H with Register B (00H), the high byte of the count.
5447
LD L,A 6F
Load Register L with Register A. Register Pair HL = the keyword's length.
5448
DEC L 2D
Decrement Register L: HL = the characters to add.
5449
ADD HL,DE 19
Add Register Pair DE (the end of the line) to Register Pair HL: HL = the new end of the line.
544A
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the new end, HL = the old end.
544B
LDDR ED B8
LDDR: copy Register Pair BC bytes (the old length) from Register Pair HL downwards to Register Pair DE, moving the line up to make room for the keyword; afterwards HL points at the typed letter.
544D
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = where the typed letter was, the start of the room made.
544E
POP HL E1
Restore Register Pair HL from the stack: the keyword's letters.
544F
LD C,A 4F
Load Register C with Register A, the keyword's length (Register B is 00H after LDDR).
5450
LDIR ED B0
LDIR: copy Register Pair BC bytes (the keyword) from Register Pair HL to Register Pair DE, over the letter and the room made.
5452
POP HL E1
Restore Register Pair HL from the stack: the start of the input buffer.
5453
POP BC C1
Restore Register Pair BC from the stack: the counts for INLIN (Register B = the line's length, Register C = the buffer size).
5454
POP DE D1
Restore Register Pair DE from the stack: the Register Pair DE saved at 53CFH.
5455
JUMP to 0375H in the ROM's INLIN routine, which pops Register Pair AF (the BREAK flag pushed at 53CBH) and finishes the line.
5458
LD (54A6H),A 32 A6 54
DI or DU: Self-Modifying Code
Store Register A (the attribute: A1H for DI, A0H for DU) at 54A6H, the operand of the LD A,00H at 54A5H.
545B
RST 10H D7
RST 10H: move Register Pair HL to the next non-blank character, in Register A; the CARRY FLAG is set for a digit.
545C
If the CARRY FLAG is set (a line number), JUMP to 5469H.
545E
CP 2EH FE 2E
Compare Register A against 2EH, a period (the current line).
5460
If the NZ FLAG is set (neither), JUMP to 5452H: the line goes on as typed.
5462
LD BC,(40ECH) ED 4B EC 40
Load Register Pair BC with the 16-bit value at 40ECH, the ROM's current line for LIST and EDIT: the line to move or copy.
5466
RST 10H D7
RST 10H: move Register Pair HL past the period; Register A holds the next character.
5467
JUMP to 546EH with Register Pair BC = the current line's number.
5469
GOSUB to the ROM's LINGET at 1E5AH, which reads the line number at Register Pair HL into Register Pair DE; Register A returns the character after it.
546C
LD B,D 42
Load Register B with Register D, the high byte of the line number.
546D
LD C,E 4B
Load Register C with Register E. Register Pair BC now holds the number of the line to move or copy.
546E
CP 2CH FE 2C
Compare Register A (the character after the first line number) against 2CH, a comma.
5470
If the NZ FLAG is set (no comma), JUMP to 5452H: the line goes on as typed.
5472
RST 10H D7
RST 10H: move Register Pair HL past the comma; Register A holds the next character, the CARRY FLAG set for a digit.
5473
If the NO CARRY FLAG is set (no new line number), JUMP to 5452H.
5475
GOSUB to the ROM's LINGET at 1E5AH: Register Pair DE = the new line number; Register A = the character after it.
5478
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line.
547A
If the NZ FLAG is set (more follows), JUMP to 5452H.
547C
POP AF F1
Restore Register Pair AF from the stack, discarding 1 of 6 words: the HL pushed at 53D1H. DI and DU store the line themselves and never return to INLIN.
547D
POP AF F1
Restore Register Pair AF from the stack, discarding 2 of 6: the BC pushed at 53D0H.
547E
POP AF F1
Restore Register Pair AF from the stack, discarding 3 of 6: the DE pushed at 53CFH.
547F
POP AF F1
Restore Register Pair AF from the stack, discarding 4 of 6: the AF pushed at 53CBH.
5480
POP AF F1
Restore Register Pair AF from the stack, discarding 5 of 6: the BC pushed at 5262H (or 520EH).
5481
POP AF F1
Restore Register Pair AF from the stack, discarding 6 of 6: the return address into the ROM's INLIN.
5482
PUSH DE D5
Save Register Pair DE (the new line number) on the stack.
5483
LD D,B 50
Load Register D with Register B, the high byte of the old line number.
5484
LD E,C 59
Load Register E with Register C. Register Pair DE now holds the old line number.
5485
GOSUB to the ROM's FNDLIN at 1B2CH, which looks for the line numbered Register Pair DE: Register Pair BC returns its address and the CARRY FLAG is set if it exists.
5488
If the NO CARRY FLAG is set (no such line), JUMP to the ROM's USERR at 1ED9H, which reports UNDEFINED LINE NUMBER.
548B
LD DE,(40A7H) ED 5B A7 40
Load Register Pair DE with the 16-bit value at 40A7H, the ROM's pointer to the input buffer.
548F
LD H,B 60
Load Register H with Register B, the high byte of the old line's address.
5490
LD L,C 69
Load Register L with Register C. Register Pair HL now points at the old line.
5491
DEC DE 1B
Decrement Register Pair DE: 1 of 2 below the input buffer.
5492
DEC DE 1B
Decrement Register Pair DE: DE = two bytes before the input buffer, where the line's text is copied.
5493
PUSH DE D5
Save Register Pair DE (that address) on the stack.
5494
PUSH BC C5
Save Register Pair BC (the old line's address) on the stack.
5495
LD BC,0004H 01 04 00
Load Register Pair BC with 0004H: the count starts at 4 for the line's link and number.
5498
ADD HL,BC 09
Add Register Pair BC (4) to Register Pair HL: HL = the old line's text.

COPY THE TEXT
Register Pair HL = the old line's text, Register Pair DE = the copy, Register Pair BC = the length counted.

5499
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a byte of the old line's text.
549A
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the 00H that ends the line.
549B
LD (DE),A 12
Store Register A at Register Pair DE, in the copy.
549C
INC HL 23
Increment Register Pair HL to the next byte of the line.
549D
INC DE 13
Increment Register Pair DE to the next byte of the copy.
549E
INC BC 03
Increment Register Pair BC, counting the byte (the flags are not changed).
549F
If the NZ FLAG is set (not the end), LOOP back to 5499H.
54A1
LD D,B 50
Load Register D with Register B, the high byte of the line's length (4 plus its text and the 00H).
54A2
LD E,C 59
Load Register E with Register C. Register Pair DE now holds the line's length.
54A3
POP BC C1
Restore Register Pair BC from the stack: the old line's address.
54A4
PUSH DE D5
Save Register Pair DE (the line's length) on the stack.
54A5
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the attribute (A1H for DI, A0H for DU); the operand 54A6H (00H in the file) was stored at 5458H.
54A7
RRCA 0F
Rotate Register A right: bit 0 goes into the CARRY FLAG, set for DI.
54A8
If the NO CARRY FLAG is set (DU, duplicate), JUMP to 54B0H: the old line stays.
54AA
DI: GOSUB to 2BE4H in the ROM's DELETE routine, which takes the line at Register Pair BC out of the program.
54AD
GOSUB to the ROM's LINKER at 1AF8H, which rebuilds the line links.
54B0
POP BC C1
Restore Register Pair BC from the stack: the line's length.
54B1
POP HL E1
Restore Register Pair HL from the stack: the copy of the text, two bytes before the input buffer.
54B2
POP DE D1
Restore Register Pair DE from the stack: the new line number.
54B3
DEC HL 2B
Decrement Register Pair HL, one byte before the copy, as the ROM's code at 1AA7H wants it.
54B4
JUMP to 1AA7H in the ROM, which stores the text at Register Pair HL as line number Register Pair DE, as if it had been typed, and returns to READY.

54B7H - The Command Table

Data, not code. Each entry is the name (upper case), an attribute byte with bit 7 set, and two value bytes. Bit 6: the command is carried out after tokenizing (54FFH); the values are the RST 28H code (01H for RENEW) and a flag. Bit 5: DI (bit 0 set) or DU. Otherwise a one-letter abbreviation; the value is the address of the full keyword (a length byte and the letters). The table ends with a 00H byte.

54B7-54BB
DEFM "RENEW" 52 45 4E 45 57
DEFM "RENEW", the name of the command that gets a program back after NEW.
54BC
DEFB C0H C0
Attribute byte C0H for RENEW: bit 7 (attribute), bit 6 (carried out at 54FFH after tokenizing).
54BD-54BE
DEFB 01H, 01H 01 01
Value bytes for RENEW: code 01H (RENEW itself, carried out at 554AH) and flag 01H.
54BF-54C3
DEFM "RENUM" 52 45 4E 55 4D
DEFM "RENUM", the name of the renumber command.
54C4
DEFB C0H C0
Attribute byte C0H for RENUM: bit 7 (attribute), bit 6 (carried out at 54FFH).
54C5-54C6
DEFB 4FH, 01H 4F 01
Value bytes for RENUM: RST 28H code 4FH (SYS13 function 2) and flag 01H.
54C7-54C9
DEFM "REF" 52 45 46
DEFM "REF", the name of the cross-reference command.
54CA
DEFB C0H C0
Attribute byte C0H for REF: bit 7 (attribute), bit 6 (carried out at 54FFH).
54CB-54CC
DEFB 2EH, 01H 2E 01
Value bytes for REF: RST 28H code 2EH (SYS12 function 1) and flag 01H.
54CD-54CE
DEFM "DI" 44 49
DEFM "DI", the name of the command that moves a line to a new number.
54CF
DEFB A1H A1
Attribute byte A1H for DI: bit 7 (attribute), bit 5 (DI or DU), bit 0 (move, delete the old line).
54D0-54D1
DEFB 00H, 00H 00 00
Two value bytes for DI (00H, 00H); DI and DU never read them.
54D2-54D3
DEFM "DU" 44 55
DEFM "DU", the name of the command that duplicates a line under a new number.
54D4
DEFB A0H A0
Attribute byte A0H for DU: bit 7 (attribute), bit 5 (DI or DU), bit 0 clear (keep the old line).
54D5-54D6
DEFB 00H, 00H 00 00
Two value bytes for DU (00H, 00H); DI and DU never read them.
54D7
DEFM "A" 41
DEFM "A", the one-letter abbreviation that expands to AUTO.
54D8
DEFB 80H 80
Attribute byte 80H for A: bit 7 only, a one-letter abbreviation.
54D9-54DA
DEFW 54FAH FA 54
DEFW 54FAH, the address of the length byte and letters of AUTO.
54DB
DEFM "D" 44
DEFM "D", the one-letter abbreviation that expands to DELETE.
54DC
DEFB 80H 80
Attribute byte 80H for D: bit 7 only, a one-letter abbreviation.
54DD-54DE
DEFW 54F3H F3 54
DEFW 54F3H, the address of the length byte and letters of DELETE.
54DF
DEFM "E" 45
DEFM "E", the one-letter abbreviation that expands to EDIT.
54E0
DEFB 80H 80
Attribute byte 80H for E: bit 7 only, a one-letter abbreviation.
54E1-54E2
DEFW 54EEH EE 54
DEFW 54EEH, the address of the length byte and letters of EDIT.
54E3
DEFM "L" 4C
DEFM "L", the one-letter abbreviation that expands to LIST.
54E4
DEFB 80H 80
Attribute byte 80H for L: bit 7 only, a one-letter abbreviation.
54E5-54E6
DEFW 54E8H E8 54
DEFW 54E8H, the address of the length byte and letters of LIST.
54E7
DEFB 00H 00
00H: the end of the command table, tested at 53F6H.
54E8-54EC
DEFM 04H, "LIST" 04 4C 49 53 54
Length byte 04H and "LIST", copied in place of L at 5450H.
54ED
DEFB 0DH 0D
A 0DH byte between LIST and EDIT that no code reads.
54EE-54F2
DEFM 04H, "EDIT" 04 45 44 49 54
Length byte 04H and "EDIT", copied in place of E.
54F3-54F9
DEFM 06H, "DELETE" 06 44 45 4C 45 54 45
Length byte 06H and "DELETE", copied in place of D.
54FA-54FE
DEFM 04H, "AUTO" 04 41 55 54 4F
Length byte 04H and "AUTO", copied in place of A.

54FFH - After Tokenizing

Entered from BASIC 5758H through the ROM's link at 41B2H, which the ROM calls at 1AA1H after tokenizing a typed line. BASIC has pushed Register Pairs AF and BC (the CARRY FLAG set if the line has a line number); Register Pair HL points just before the tokenized line. With the SYSTEM option AS, letters inside quotes are made upper case. A line marked by 53CBH (first byte FFH) is RENEW, RENUM or REF: RENEW (code 01H) gets the program back after NEW; RENUM and REF are run with RST 28H. A direct statement (no line number) while a file area is in use (BASIC 63A9H) is error 84H DIRECT STATEMENT IN FILE.

54FF
LD A,(436CH) 3A 6C 43
Load Register A with the byte at 436CH, SYS0's SYSTEM option byte.
5502
BIT 0,A CB 47
Test bit 0 of Register A, the SYSTEM option AS (make letters in quotes upper case).
5504
If the Z FLAG is set (option AS is off), JUMP to 5522H.
5506
PUSH HL E5
Save Register Pair HL (the text pointer, just before the tokenized line) on the stack.

UPPER CASE IN QUOTES
Register Pair HL steps through the tokenized line; the text after a REM is left alone.

5507
INC HL 23
Increment Register Pair HL to the next byte of the tokenized line.
5508
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL.
5509
CP 22H FE 22
Compare Register A (the byte of the tokenized line) against 22H, a quote.
550B
If the NZ FLAG is set (not a quote), JUMP to 551AH.
550D
INC HL 23
Inside quotes: increment Register Pair HL to the next character.
550E
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL.
550F
CP 22H FE 22
Compare Register A against 22H, the closing quote.
5511
If the Z FLAG is set (the closing quote), JUMP to 5507H.
5513
GOSUB to BASIC 57BAH, which makes the character in Register A upper case.
5516
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the 00H that ends the line.
5517
LD (HL),A 77
Store Register A (the character, now upper case) back at Register Pair HL.
5518
If the NZ FLAG is set (not the end), LOOP back to 550DH.
551A
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set at the end of the line.
551B
If the Z FLAG is set (the end), JUMP to 5521H.
551D
CP 93H FE 93
Compare Register A against 93H, the REM token.
551F
If the NZ FLAG is set (not REM), LOOP back to 5507H; after a REM the rest is left as typed.
5521
POP HL E1
Restore Register Pair HL from the stack: the text pointer.
5522
PUSH HL E5
Save Register Pair HL (the text pointer) on the stack.
5523
LD BC,(57B6H) ED 4B B6 57
Load Register Pair BC with the 16-bit value at 57B6H: Register C = the code stored at 540AH, Register B = its flag (01H if 53CBH marked the line).
5527
XOR A AF
Load Register A with 00H (XOR A with itself).
5528
LD (57B7H),A 32 B7 57
Store Register A (00H) at 57B7H, clearing the flag: the mark counts only for this line.
552B
RST 10H D7
RST 10H: move Register Pair HL to the first non-blank byte of the tokenized line, in Register A.
552C
INC A 3C
Increment Register A: the Z FLAG is set if the byte was FFH, the mark from 540EH.
552D
If the Z FLAG is set (the marked line), JUMP to 5539H.
552F
POP HL E1
Restore Register Pair HL from the stack: the text pointer.
5530
POP BC C1
Restore Register Pair BC from the stack: BASIC's Register Pair BC.
5531
POP AF F1
Restore Register Pair AF from the stack: BASIC's Register Pair AF, the CARRY FLAG set if the line has a line number.
5532
RET C D8
If the CARRY FLAG is set (a program line), RETURN to the ROM, which stores it.
5533
CALL 63A9H CD A9 63
GOSUB to BASIC 63A9H, which returns straight to the ROM (the direct statement is run) unless a file area is in use.
5536
JP 5DDFH C3 DF 5D
A file area is in use: JUMP to BASIC 5DDFH, which raises error 84H DIRECT STATEMENT IN FILE.
5539
The FFH mark: decrement Register B (the flag) and, if it is not 0 (the flag was not set, so the FFH was typed), JUMP to 552FH.
553B
POP AF F1
Restore Register Pair AF from the stack, discarding 1 of 4: the text pointer pushed at 5522H.
553C
POP AF F1
Restore Register Pair AF from the stack, discarding 2 of 4: BASIC's Register Pair BC.
553D
POP AF F1
Restore Register Pair AF from the stack, discarding 3 of 4: BASIC's Register Pair AF.
553E
POP AF F1
Restore Register Pair AF from the stack, discarding 4 of 4: the ROM's return address; the command is carried out here instead.
553F
RST 10H D7
RST 10H: move Register Pair HL past the spaces that replaced the command word, to its parameters; Register A holds the first.
5540
LD DE,1A25H 11 25 1A
Load Register Pair DE with 1A25H, the ROM's READY.
5543
PUSH DE D5
Push Register Pair DE (1A25H): the command returns to READY.
5544
LD A,C 79
Load Register A with Register C, the code from the command table.
5545
CP 20H FE 20
Compare Register A against 20H: the NO CARRY FLAG is set for an RST 28H code (RENUM 4FH, REF 2EH).
5547
If the NO CARRY FLAG is set, JUMP to 5559H to call the overlay.
554A
DEC A 3D
Decrement Register A: the Z FLAG is set for code 01H, RENEW.
554B
If the NZ FLAG is set (an unknown code), JUMP to the ROM's SNERR at 1997H to report SYNTAX ERROR.
554E
LD HL,(40A4H) 2A A4 40
RENEW: load Register Pair HL with the 16-bit value at 40A4H, the first program line.
5551
LD (HL),FFH 36 FF
Store FFH at Register Pair HL, the low byte of the first line's link: NEW cleared the link to 0000H; any non-zero value brings the program back.
5553
GOSUB to the ROM's LINKER at 1AF8H, which rebuilds every line's link and so finds the program's end again.
5556
JUMP to 1B59H in the ROM's NEW routine, which sets the variable pointers after the program and returns to READY.
5559
LD DE,6445H 11 45 64
Load Register Pair DE with 6445H, BASIC/CMD's statement-end clean-up.
555C
PUSH DE D5
Push Register Pair DE (6445H): the overlay returns there, and from there to READY.
555D
RST 28H EF
RST 28H with Register A = the code (4FH RENUM in SYS13, 2EH REF in SYS12) and Register Pair HL = the parameters after the command word.

555EH - Unused Bytes

555EH-56E7H fill the last load record; nothing reads or executes them.

555E-56E7
NOP x 394 00 x 394
394 zero bytes that fill the end of the file (up to 56E7H). No code jumps, calls or reads here.