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

Page Customization

Introduction/Summary

NEWDOS/80 v2.0 SYS11/SYS Disassembly - BASIC RENUM, Second Part (Model I)

SYS11/SYS finishes the BASIC command RENUM, which SYS13 starts. It loads at 4D0CH-51F3H (1,256 bytes in five load records, transfer address 4D0CH), so the twelve bytes 4D00H-4D0BH that SYS13 filled with the RENUM parameters survive the load. SYS13 loads it with RST 28H code 2DH (function 1 of directory slot 0DH, SYS13 51CAH); 51A2H-51F3H are unused zero bytes.

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

How RENUM Works

  1. SYS13 (50FEH) reads up to four numbers (the first new number, the increment, the first and the last old line of the range; defaults 10, 10, 0 and 65529) and the options U and X, walks the program, writes each renumbered line's new number into the line's link field and counts the lines. A line 0 gives CAN'T PROCESS LINE 0, a new number above 65529 SEQ # OVERFLOW.
  2. SYS11 builds a table of 128 line addresses at 64CAH (every C-th line) for fast searches (4D0CH) and checks that the new numbers keep the lines in order (5073H).
  3. First pass (4D28H): every line number referred to after GOTO, GOSUB, THEN, ELSE, RUN, RESUME, ON ... GOTO/GOSUB, ON ERROR GOTO, ERL, LIST, LLIST and after the second comma of GET and PUT is looked up (4EC3H), and the change in the text's length is added up. Problems are listed under ERROR LINES as number/letter: X a number was expected, S a number above 65529 or a line 0, U the line does not exist (with option X only inside the range). With option U, or after any error, RENUM stops here and the program keeps its numbers.
  4. The program is moved up by its maximum growth plus 256 bytes and the stack is moved to the top of memory (4F97H). The second pass copies the program back down with the new numbers in the text.
  5. The renumbered lines are moved to where their new numbers belong, in pieces as large as the free memory allows (4FFDH), the new numbers are copied into the line number fields, DONE is shown and the ROM rebuilds the links (1AE9H).

Variables

Locations inside SYS11 whose contents change while it runs:

Address RangePurpose
4D4CH-4D4DH
2 bytes
The next line table entry the second pass checks (operand of 4D4BH; set to 64CAH at 4FEAH, moved on at 4D65H).
4DE4H
1 byte
The ON flag: 01H after ON, where a list of line numbers may follow GOTO or GOSUB (operand of 4DE3H; written at 4DA8H).
4DEDH-4DEEH
2 bytes
The old number of the line being scanned, shown in error reports (operand of 4DECH; written at 4D78H).
4E81H
1 byte
01H when line 0 is allowed (after RESUME or ON ERROR), else 00H (operand of the OR at 4E80H; written at 4DA4H, 4DD1H).
4EF6H-4EF7H
2 bytes
The output address of the line being copied in the second pass; after it, the program's end (operand of 4EF5H; written at 4D34H, 5007H).
4F01H-4F02H
2 bytes
The input address of the line being copied (operand of 4F00H; written at 4D38H).
4FA6H
1 byte
The errors flag: bit 0 set once an error has been reported, so ERROR LINES is printed once and RENUM stops after the first pass (operand of 4FA5H; set at 4F65H).
5014H-5015H
2 bytes
The start of the block of renumbered lines (operand of 5013H; written at 507BH).
5035H-5036H
2 bytes
The place the block goes (operand of 5034H; written at 50CAH).
50C0H-50C1H
2 bytes
The new number of the line after the block (operand of 50BFH; written at 5087H).
50C8H-50C9H
2 bytes
The new number of the line at the place (operand of 50C7H; written at 50AFH).
50F2H-50F3H
2 bytes
The block's length, 0000H if it stays in place (operand of 50F1H; written at 50CDH).
50F7H-50F8H
2 bytes
What is left of the block to move (operand of 50F6H; written at 5117H).
5121H
1 byte
The pass flag: 00H in the first pass, 01H in the second, when 5120H copies every byte it reads (operand of 5120H; written at 4FDBH).
515AH-515BH
2 bytes
The growth total: how many bytes longer the text is so far in this pass (operand of 5159H; cleared at 4D30H, written at 5163H).
515EH-515FH
2 bytes
The number of digits of the number being replaced (operand of 515DH; written at 4E73H).
5168H-5169H
2 bytes
The highest growth total, the room the second pass needs (operand of 5167H; written at 516CH, read at 4FB7H).

Locations outside SYS11 that it reads or writes:

Address RangePurpose
4020H-4021H
2 bytes
The ROM's cursor address in the video memory: its column decides a new line (4F70H), and error numbers are written straight to it (4F7AH-4F81H).
40A4H-40A5H
2 bytes
The ROM's pointer to the first program line.
40B1H-40B2H
2 bytes
The ROM's top of memory pointer: the program moved up must stay 256 bytes below it, and the stack moves there (4FCCH, 50F9H).
40F9H-40FAH
2 bytes
The ROM's pointer to the end of the program (written at 5003H).
4D00H-4D0BH
12 bytes
SYS13's parameters: 4D00H next new number, 4D02H increment, 4D04H first old line, 4D06H last old line, 4D08H last new number given, 4D0AH option U, 4D0BH option X.
5D51H-5D56H
6 bytes
In BASIC/CMD: the digit buffer of BASIC 5D27H, also the target of 5153H when only the digit count is wanted.
64CAH-65C9H
256 bytes
The table of 128 line addresses, in BASIC/CMD's start-up code (no longer needed).

Disassembly

4D0CH - RENUM, Second Part: the Line Table

SYS13 does the first part of RENUM (SYS13 50FEH): it reads the parameters into 4D00H-4D0BH, checks them, puts each renumbered line's new number into the line's link field (the first two bytes of the line), counts the lines and loads SYS11 with LD A,2DH / RST 28H (SYS13 51CAH). SYS11 loads at 4D0CH, so SYS13's parameter bytes 4D00H-4D0BH stay in memory: 4D00H the next new number, 4D02H the increment, 4D04H-4D07H the first and last old line number of the range, 4D08H the last new number given, 4D0AH option U, 4D0BH option X. The dispatcher enters at 4D0CH (the transfer address) with Register Pair HL = the first program line (40A4H), Register Pair DE = 64CAH, Register B = 80H and Register C = the number of lines per table entry (the line count / 128, rounded up). This part builds a table of 128 line addresses at 64CAH-65C9H (inside BASIC/CMD's start-up code, no longer needed), every C-th line, for the searches at 4EC3H.

TABLE LOOP
Register Pair DE (swapped with HL) = the table entry, Register Pair HL = the line, Register B = the entries left, Register C = the lines per entry.

4D0C
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the table entry to fill, DE = the line's address.
4D0D
LD (HL),E 73
Store Register E (the line's address, low byte) at Register Pair HL, in the table.
4D0E
INC HL 23
Increment Register Pair HL to the entry's high byte.
4D0F
LD (HL),D 72
Store Register D (the line's address, high byte) at Register Pair HL.
4D10
INC HL 23
Increment Register Pair HL to the next table entry.
4D11
PUSH HL E5
Save Register Pair HL (the next table entry) on the stack.
4D12
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the line.
4D13
LD E,C 59
Load Register E with Register C, the lines to pass before the next entry.
4D14
JUMP to 4D1CH to test for the end of the program first.
4D16
GOSUB to BASIC 5CF3H, which steps Register Pair HL to the next line by scanning to the 00H end (the link fields hold new numbers now, not addresses).
4D19
DEC E 1D
Decrement Register E, the lines left to pass.
4D1A
If the Z FLAG is set (Register C lines passed), JUMP to 4D22H.
4D1C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field.
4D1D
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
4D1E
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set for 0000H, the end of the program.
4D1F
If the NZ FLAG is set (another line), LOOP back to 4D16H.
4D21
DEC HL 2B
At the end: decrement Register Pair HL back to the end marker; every remaining entry gets this address.
4D22
POP DE D1
Restore Register Pair DE from the stack: the next table entry.
4D23
Decrement Register B (the entries left) and LOOP back to 4D0CH for all 128 entries.
4D25
GOSUB to 5073H, which finds where the renumbered lines have to go; if their new numbers would run into the line that follows them, it raises error 8CH SEQ # OVERFLOW.

4D28H - Scan the Program

The main loop, used twice. In the first pass (5121H = 00H) every line number referred to in the text is looked up and the growth of the text is added up (515AH, the highest value in 5168H); errors are listed. In the second pass (5121H = 01H) the program has been moved up in memory (4FABH) and is copied back down byte by byte from Register Pair HL (input) to Register Pair BC (output), with every reference replaced by the new number (5120H copies each byte it reads).

4D28
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: the input pointer.
4D2B
LD B,H 44
Load Register B with Register H: the output pointer starts at the same place.
4D2C
LD C,L 4D
Load Register C with Register L. Register Pair BC = the output pointer.
4D2D
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H (the second pass enters here from 4FFAH).
4D30
LD (515AH),DE ED 53 5A 51
Self-Modifying Code
Store Register Pair DE (0000H) at 515AH, the operand of 5159H: the text's growth total starts at 0.

LINE LOOP
Register Pair HL = the input pointer at the line, Register Pair BC = the output pointer.

4D34
LD (4EF6H),BC ED 43 F6 4E
Self-Modifying Code
Store Register Pair BC (this line's output address) at 4EF6H, the operand of 4EF5H.
4D38
LD (4F01H),HL 22 01 4F
Self-Modifying Code
Store Register Pair HL (this line's input address) at 4F01H, the operand of 4F00H.
4D3B
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the link field.
4D3C
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
4D3D
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set for 0000H, the end of the program.
4D3E
DEC HL 2B
Decrement Register Pair HL back to the line's start (the flags are not changed).
4D3F
If the Z FLAG is set (the end), JUMP to 4F97H.
4D42
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (the operand of 5120H).
4D45
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set in the first pass.
4D46
If the Z FLAG is set (first pass), JUMP to 4D6AH.
4D48
PUSH HL E5
Second pass: save Register Pair HL (the input pointer) on the stack.
4D49
PUSH DE D5
Save Register Pair DE on the stack, freeing it for the table check at 4D4AH-4D65H; it is restored at 4D68H.
4D4A
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = this line's input address.
4D4B
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the next table entry to check; the operand 4D4CH (0000H in the file) is set to 64CAH at 4FEAH and moved on at 4D65H.
4D4E
INC HL 23
Increment Register Pair HL to the entry's high byte.
4D4F
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's high byte.
4D50
CP D BA
Compare Register A with Register D, the high byte of this line's input address.
4D51
If the NZ FLAG is set (another line), JUMP to 4D68H.
4D53
DEC HL 2B
Decrement Register Pair HL to the entry's low byte.
4D54
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's low byte.
4D55
CP E BB
Compare Register A with Register E, the low byte of this line's input address.
4D56
If the NZ FLAG is set (the entry's low byte differs: another line), JUMP to 4D68H.
4D58
LD (HL),C 71
The table entry at Register Pair HL points at this line: store Register C (the line's output address, low byte) in the entry instead, since the line now starts there.
4D59
INC HL 23
Increment Register Pair HL to the entry's high byte.
4D5A
LD (HL),B 70
Store Register B (the output address, high byte) at Register Pair HL.
4D5B
INC HL 23
Increment Register Pair HL to the next entry.
4D5C
LD DE,65CAH 11 CA 65
Load Register Pair DE with 65CAH, the end of the table.
4D5F
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
4D60
SBC HL,DE ED 52
Subtract Register Pair DE from Register Pair HL: the Z FLAG is set past the last entry.
4D62
If the Z FLAG is set (the table is done), JUMP to 4D68H without moving on.
4D64
ADD HL,DE 19
Add Register Pair DE back: HL = the next entry.
4D65
LD (4D4CH),HL 22 4C 4D
Self-Modifying Code
Store Register Pair HL (the next entry) at 4D4CH, the operand of 4D4BH.
4D68
POP DE D1
Restore Register Pair DE from the stack, the value saved at 4D49H.
4D69
POP HL E1
Restore Register Pair HL from the stack: the input pointer.
4D6A
GOSUB to 5120H, which reads the next byte at Register Pair HL (the link field's low byte), copying it to Register Pair BC in the second pass.
4D6D
GOSUB to 5120H, which reads (and in the second pass copies) the link field's high byte at Register Pair HL.
4D70
GOSUB to 5120H: the old line number's low byte, in Register A.
4D73
LD E,A 5F
Load Register E with Register A, the old line number's low byte.
4D74
GOSUB to 5120H: the old line number's high byte, in Register A.
4D77
LD D,A 57
Load Register D with Register A. Register Pair DE = the line's old number.
4D78
LD (4DEDH),DE ED 53 ED 4D
Self-Modifying Code
Store Register Pair DE (the old number) at 4DEDH, the operand of 4DECH, for error reports.
4D7C
JUMP to 4DA3H to scan the line's first statement.
4D7E
REM (93H): GOSUB to 5120H for the next byte, in Register A; the Z FLAG is set at the line's 00H end.
4D81
If the NZ FLAG is set (not the end), LOOP back to 4D7EH.
4D83
JUMP to 4D34H to start the next line, whose link field Register Pair HL now points at.
4D85
LD DE,4DADH 11 AD 4D
A quote (22H): load Register Pair DE with 4DADH, the next-byte entry of the statement loop.
4D88
PUSH DE D5
Push Register Pair DE (4DADH) as the return address after the string.
4D89
LD E,A 5F
Load Register E with Register A, the quote character that ends the string.

SKIP A STRING
Register E = the closing quote.

4D8A
GOSUB to 5120H for the next byte of the string, in Register A.
4D8D
CP E BB
Compare Register A with Register E, the closing quote.
4D8E
RET Z C8
If the Z FLAG is set (the string ends), RETURN (to 4DADH, or to 4D9AH when called from DATA).
4D8F
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the line's end.
4D90
If the NZ FLAG is set (more of the string), LOOP back to 4D8AH.
4D92
POP AF F1
The line ended inside the string: restore Register Pair AF from the stack, discarding the return address.
4D93
JUMP to 4D34H to start the next line, whose link field Register Pair HL now points at.

SKIP DATA
DATA (88H): the bytes up to a colon or the line's end are skipped (copied in the second pass).

4D95
CP 22H FE 22
Compare Register A (the byte) against 22H, a quote.
4D97
If the Z FLAG is set (a quoted DATA item), GOSUB to 4D89H to skip the string.
4D9A
GOSUB to 5120H for the next byte, in Register A; the Z FLAG is set at the line's end.
4D9D
If the Z FLAG is set, JUMP to 4D34H for the next line.
4D9F
CP 3AH FE 3A
Compare Register A against 3AH, a colon, the end of the statement.
4DA1
If the NZ FLAG is set (not a colon), LOOP back to 4D95H.
4DA3
XOR A AF
The start of a statement: load Register A with 00H (XOR A with itself).
4DA4
LD (4E81H),A 32 81 4E
Self-Modifying Code
Store Register A at 4E81H, the operand of the OR at 4E80H: 00H = line 0 not allowed (01H after RESUME or ON ERROR).
4DA7
XOR A AF
Load Register A with 00H (XOR A with itself).
4DA8
LD (4DE4H),A 32 E4 4D
Self-Modifying Code
Store Register A at 4DE4H, the operand of 4DE3H: the ON flag (01H after ON, where a list of line numbers may follow GOTO or GOSUB).
4DAB
PUSH HL E5
Save Register Pair HL (the input pointer) on the stack, for the POP at 4DACH.
4DAC
POP HL E1
Restore Register Pair HL from the stack (a byte not in the token table enters here).

STATEMENT LOOP
Each byte is looked up in the token table at 4E8AH; the table's handler deals with the line numbers that may follow.

4DAD
GOSUB to 5120H for the next byte of the text, in Register A.
4DB0
PUSH HL E5
Save Register Pair HL (the input pointer) on the stack.
4DB1
LD HL,4E8AH 21 8A 4E
Load Register Pair HL with 4E8AH, the token table.

TABLE SEARCH
Register Pair HL walks the table: handler address, byte value; the table is in ascending order of the byte.

4DB4
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the handler address's low byte.
4DB5
INC HL 23
Increment Register Pair HL to the high byte of the table entry's handler address.
4DB6
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the handler.
4DB7
INC HL 23
Increment Register Pair HL to the entry's byte value.
4DB8
CP (HL) BE
Compare Register A (the text byte) with the byte at Register Pair HL, the entry's byte.
4DB9
INC HL 23
Increment Register Pair HL to the next entry (the flags are not changed).
4DBA
If the CARRY FLAG is set (the text byte is below it, so not in the table), JUMP to 4DACH to read on.
4DBC
If the NZ FLAG is set (above it), LOOP back to 4DB4H for the next entry.
4DBE
POP HL E1
Found: restore Register Pair HL from the stack, the input pointer.
4DBF
PUSH DE D5
Push Register Pair DE (the handler's address) on the stack.
4DC0
RET C9
RETURN, which jumps to the handler with Register A = the byte.
4DC1
LD A,01H 3E 01
ON (A1H): load Register A with 01H, the ON flag.
4DC3
JUMP to 4DA8H to store Register A (01H) at 4DE4H as the ON flag.
4DC5
LD A,(4DE4H) 3A E4 4D
ERROR (9EH): load Register A with the byte at 4DE4H, the ON flag.
4DC8
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set for a plain ERROR n.
4DC9
If the Z FLAG is set (ERROR n, where n is no line number), JUMP to 4DADH.
4DCB
LD A,01H 3E 01
ON ERROR: load Register A with 01H, the flag value that allows line 0.
4DCD
JUMP to 4DA4H, which allows line 0 (GOTO 0) and clears the ON flag.
4DCF
LD A,01H 3E 01
RESUME (9FH): load Register A with 01H, the flag value that allows line 0 (RESUME 0).
4DD1
LD (4E81H),A 32 81 4E
Self-Modifying Code
Store Register A (01H) at 4E81H: line 0 is allowed (RESUME 0).
4DD4
THEN, ELSE, RUN and RESUME: GOSUB to 513BH, which skips blanks; the CARRY FLAG is set if a digit follows.
4DD7
If the NO CARRY FLAG is set (no number), JUMP to 4DB0H to handle the byte in Register A.
4DD9
GOTO and GOSUB: GOSUB to 4E4CH, which reads the line number at Register Pair HL and replaces it.
4DDC
GOSUB to 511DH, which skips blanks and reads the next byte, in Register A.
4DDF
CP 2CH FE 2C
Compare Register A (the byte after the number) against 2CH, a comma.
4DE1
If the NZ FLAG is set (no comma), JUMP to 4DB0H to handle the byte.
4DE3
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the ON flag; the operand 4DE4H (00H in the file) is stored at 4DA8H.
4DE5
OR A B7
OR Register A with itself to set the flags: the NZ FLAG is set after ON.
4DE6
If the NZ FLAG is set (ON ... GOTO/GOSUB), LOOP back to 4DD9H for the next number of the list.
4DE8
PUSH AF F5
Push Register Pair AF, a word for the POP at 4DE9H to take.
4DE9
POP AF F1
Restore Register Pair AF from the stack, discarding a word (from 4E4FH this is its return address).
4DEA
LD A,58H 3E 58
Load Register A with 58H, the error letter X: a line number was expected, or a comma follows GOTO/GOSUB without ON.
4DEC
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the old number of the current line; the operand 4DEDH (0000H in the file) is stored at 4D78H.
4DEF
GOSUB to 4F54H, which reports Register Pair DE with the error letter in Register A.
4DF2
DEC BC 0B
Decrement Register Pair BC, stepping the output pointer back.
4DF3
DEC HL 2B
Decrement Register Pair HL, stepping the input pointer back.

SKIP THE STATEMENT
4E40H returns only for bytes inside the statement; at its end it goes on at 4E10H.

4DF4
GOSUB to 4E40H for the next byte of the statement.
4DF7
LOOP back to 4DF4H for the next byte; 4E40H leaves this loop at the statement's end.
4DF9
POP HL E1
A number too large for a line number (more digits would pass 65535, from 4E5FH): restore Register Pair HL from the stack, the input pointer.
4DFA
POP BC C1
Restore Register Pair BC from the stack: the output pointer.
4DFB
POP AF F1
Restore Register Pair AF from the stack, discarding the return address into 4E4CH's caller.
4DFC
LD A,53H 3E 53
Load Register A with 53H, the error letter S.
4DFE
JUMP to 4DECH to report it for the current line.
4E00
ERL: GOSUB to 4E4CH, which reads the number and replaces it.
4E03
ERL (C2H): GOSUB to 513BH, which skips blanks; the CARRY FLAG is set if a digit follows.
4E06
If the CARRY FLAG is set (a number), LOOP back to 4E00H.
4E08
CP D2H FE D2
Compare Register A against D2H, the AND token: the CARRY FLAG is set below it.
4E0A
If the CARRY FLAG is set (Register A is below D2H, not an operator), JUMP to 4E10H.
4E0C
CP D7H FE D7
Compare Register A against D7H: the CARRY FLAG is set for AND, OR, >, = or < (D2H-D6H).
4E0E
If the CARRY FLAG is set (an operator), JUMP to 4E03H: a number may follow.
4E10
JUMP to 4DB0H to handle the byte in Register A.
4E12
LIST and LLIST (B4H, B5H): GOSUB to 513BH, which skips blanks; the CARRY FLAG is set if a digit follows.
4E15
If the NO CARRY FLAG is set (no number), JUMP to 4E1DH.
4E17
GOSUB to 4E4CH, which reads the number and replaces it.
4E1A
GOSUB to 511DH, which skips blanks and reads the next byte, in Register A.
4E1D
CP CEH FE CE
Compare Register A against CEH, the - token of a range.
4E1F
If the Z FLAG is set (a dash), JUMP to 4DD4H: a second number may follow.
4E21
JUMP to 4E10H to handle the byte in Register A.
4E23
LD D,02H 16 02
GET and PUT (A4H, A5H): load Register D with 02H, the commas before the item list's line number.
4E25
LD E,FFH 1E FF
Load Register E with FFH, the parenthesis level minus 1.
4E27
INC E 1C
Increment Register E, one parenthesis level deeper.

FIND THE SECOND COMMA
Register E = the parenthesis level, Register D = the outer commas still to pass.

4E28
GOSUB to 4E40H for the next byte of the statement (at its end the byte is handled at 4DB0H).
4E2B
CP 28H FE 28
Compare Register A against 28H, an opening parenthesis.
4E2D
If the Z FLAG is set (an opening parenthesis), JUMP to 4E27H to count one level deeper in Register E.
4E2F
DEC E 1D
Decrement Register E, provisionally leaving a level.
4E30
CP 29H FE 29
Compare Register A against 29H, a closing parenthesis.
4E32
If the Z FLAG is set, JUMP to 4E28H with the level decremented.
4E34
INC E 1C
Increment Register E back: the Z FLAG is set at the outer level (Register E = 0).
4E35
If the NZ FLAG is set (inside parentheses), LOOP back to 4E28H.
4E37
CP 2CH FE 2C
Compare Register A against 2CH, a comma at the outer level.
4E39
If the NZ FLAG is set (Register A is not a comma), LOOP back to 4E28H for the next byte.
4E3B
DEC D 15
Decrement Register D, the commas still to pass.
4E3C
If the NZ FLAG is set (the first comma), LOOP back to 4E28H.
4E3E
After the second comma: JUMP to 4DD4H, where a line number may follow (the item list's line; see SYS10).
4E40
GOSUB to 5120H for the next byte of the text, in Register A.
4E43
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set at the line's end.
4E44
If the Z FLAG is set (Register A = 00H, the line's end), JUMP to 4E49H.
4E46
CP 3AH FE 3A
Compare Register A (the byte read) against 3AH, a colon.
4E48
RET NZ C0
If the NZ FLAG is set (inside the statement), RETURN with the byte in Register A.
4E49
POP DE D1
The statement ends: restore Register Pair DE from the stack, discarding the return address.
4E4A
JUMP to 4E10H, which handles the colon or 00H in Register A.

4E4CH - Replace a Line Number

Reads the decimal number at Register Pair HL (blanks between the digits are allowed, as RST 10H skips them) and looks it up. The number is written again (second pass) as the new line number, or unchanged if the line does not exist. Line 0 is only accepted after RESUME or ON ERROR GOTO. Entered with Register Pair BC = the output pointer; returns with Register Pair HL after the number.

4E4C
GOSUB to 513BH, which skips blanks; the CARRY FLAG is set if a digit follows.
4E4F
If the NO CARRY FLAG is set (no digit), JUMP to 4DE9H for error letter X.
4E51
PUSH BC C5
Save Register Pair BC (the output pointer) on the stack.
4E52
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the number being built.
4E55
LD B,D 42
Load Register B with Register D (00H), the high byte of the digit count.
4E56
LD C,E 4B
Load Register C with Register E. Register Pair BC = 0, the count of digits.

DIGIT LOOP
Register Pair DE = the number so far, Register Pair BC = the digits counted, Register A = the digit character.

4E57
PUSH HL E5
Save Register Pair HL (the pointer to this digit) on the stack.
4E58
INC BC 03
Increment Register Pair BC, counting the digit.
4E59
LD HL,1998H 21 98 19
Load Register Pair HL with 1998H (6552), the largest number that can take another digit without passing 65535.
4E5C
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
4E5D
SBC HL,DE ED 52
Subtract Register Pair DE (the number so far) from Register Pair HL: the CARRY FLAG is set if it is above 6552.
4E5F
If the CARRY FLAG is set (too large), JUMP to 4DF9H for error letter S.
4E61
LD H,D 62
Load Register H with Register D, the high byte of the number so far.
4E62
LD L,E 6B
Load Register L with Register E. Register Pair HL = the number so far.
4E63
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = the number so far times 2.
4E64
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = the number so far times 4.
4E65
ADD HL,DE 19
Add Register Pair DE (the number) to Register Pair HL: times 5.
4E66
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = the number so far times 10.
4E67
SUB 30H D6 30
Subtract 30H (the digit 0) from Register A: the digit's value.
4E69
LD E,A 5F
Load Register E with Register A, the digit's value.
4E6A
LD D,B 50
Load Register D with Register B (00H while fewer than 256 digits). Register Pair DE = the digit.
4E6B
ADD HL,DE 19
Add Register Pair DE (the digit) to Register Pair HL.
4E6C
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the number so far.
4E6D
POP HL E1
Restore Register Pair HL from the stack: the pointer to this digit.
4E6E
PUSH HL E5
Save Register Pair HL (the pointer to this digit) on the stack again.
4E6F
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.
4E70
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): the next character's pointer is kept, and HL = the last digit's pointer.
4E71
If the CARRY FLAG is set (another digit), LOOP back to 4E58H.
4E73
LD (515EH),BC ED 43 5E 51
Self-Modifying Code
Store Register Pair BC (the number of digits) at 515EH, the operand of 515DH, for the growth count.
4E77
POP BC C1
Restore Register Pair BC from the stack, discarding the next character's pointer.
4E78
INC HL 23
Increment Register Pair HL: HL = the byte after the last digit.
4E79
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): HL = the saved output pointer, and the input pointer is saved.
4E7A
PUSH HL E5
Push Register Pair HL (the output pointer) on the stack too.
4E7B
LD A,D 7A
Load Register A with Register D, the high byte of the number.
4E7C
OR E B3
OR Register A with Register E: the Z FLAG is set for line 0.
4E7D
If the NZ FLAG is set (not 0), JUMP to 4F22H to look the line up.
4E80
OR 00H F6 00
Self-Modifying Code
Line 0: OR Register A (00H) with the flag in the operand 4E81H (00H in the file; 01H after RESUME or ON ERROR, stored at 4DA4H and 4DD1H).
4E82
If the NZ FLAG is set (line 0 allowed), JUMP to 4F43H to write it back unchanged.
4E85
LD A,53H 3E 53
Load Register A with 53H, the error letter S.
4E87
JUMP to 4F56H to report it with Register Pair DE = 0000H.

4E8AH - Token Table

Data, not code: three bytes per entry, the handler's address and the byte (token) it handles, in ascending order of the byte. A byte that is not in the table is read past. The FFH entry ends the table.

4E8A-4E8B
DEFW 4D34H 34 4D
DEFW 4D34H, the handler for the byte 00H: the end of the line, go on with the next one.
4E8C
DEFB 00H 00
00H, the end of a line, handled at 4D34H (the next line).
4E8D-4E8E
DEFW 4D85H 85 4D
DEFW 4D85H, the handler for a quote: skip the string.
4E8F
DEFB 22H 22
22H, a quote ("), handled at 4D85H: skip the string.
4E90-4E91
DEFW 4DA3H A3 4D
DEFW 4DA3H, the handler for a colon: the next statement starts.
4E92
DEFB 3AH 3A
3AH, a colon (:), handled at 4DA3H: the next statement.
4E93-4E94
DEFW 4D9AH 9A 4D
DEFW 4D9AH, the handler for DATA: skip the statement.
4E95
DEFB 88H 88
88H, the DATA token, handled at 4D9AH: skip the statement.
4E96-4E97
DEFW 4DD9H D9 4D
DEFW 4DD9H, the handler for GOTO: a line number (a list after ON).
4E98
DEFB 8DH 8D
8DH, the GOTO token, handled at 4DD9H: a line number follows.
4E99-4E9A
DEFW 4DD4H D4 4D
DEFW 4DD4H, the handler for RUN: an optional line number.
4E9B
DEFB 8EH 8E
8EH, the RUN token, handled at 4DD4H: an optional line number.
4E9C-4E9D
DEFW 4DD9H D9 4D
DEFW 4DD9H, the handler for GOSUB: a line number (a list after ON).
4E9E
DEFB 91H 91
91H, the GOSUB token, handled at 4DD9H: a line number follows.
4E9F-4EA0
DEFW 4D7EH 7E 4D
DEFW 4D7EH, the handler for REM: skip the rest of the line.
4EA1
DEFB 93H 93
93H, the REM token, handled at 4D7EH: skip the rest of the line.
4EA2-4EA3
DEFW 4DD4H D4 4D
DEFW 4DD4H, the handler for ELSE: an optional line number.
4EA4
DEFB 95H 95
95H, the ELSE token, handled at 4DD4H: an optional line number.
4EA5-4EA6
DEFW 4DC5H C5 4D
DEFW 4DC5H, the handler for ERROR: ON ERROR allows GOTO 0.
4EA7
DEFB 9EH 9E
9EH, the ERROR token, handled at 4DC5H (ON ERROR GOTO).
4EA8-4EA9
DEFW 4DCFH CF 4D
DEFW 4DCFH, the handler for RESUME: an optional line number, 0 allowed.
4EAA
DEFB 9FH 9F
9FH, the RESUME token, handled at 4DCFH: an optional line number.
4EAB-4EAC
DEFW 4DC1H C1 4D
DEFW 4DC1H, the handler for ON: set the ON flag.
4EAD
DEFB A1H A1
A1H, the ON token, handled at 4DC1H: sets the ON flag at 4DE4H.
4EAE-4EAF
DEFW 4E23H 23 4E
DEFW 4E23H, the handler for GET: the item list's line number.
4EB0
DEFB A4H A4
A4H, the GET token, handled at 4E23H: a line number after two commas.
4EB1-4EB2
DEFW 4E23H 23 4E
DEFW 4E23H, the handler for PUT: the item list's line number.
4EB3
DEFB A5H A5
A5H, the PUT token, handled at 4E23H: a line number after two commas.
4EB4-4EB5
DEFW 4E12H 12 4E
DEFW 4E12H, the handler for LIST: a line number range.
4EB6
DEFB B4H B4
B4H, the LIST token, handled at 4E12H: a line number range follows.
4EB7-4EB8
DEFW 4E12H 12 4E
DEFW 4E12H, the handler for LLIST: a line number range.
4EB9
DEFB B5H B5
B5H, the LLIST token, handled at 4E12H: a line number range follows.
4EBA-4EBB
DEFW 4E03H 03 4E
DEFW 4E03H, the handler for ERL: comparisons with line numbers.
4EBC
DEFB C2H C2
C2H, the ERL token, handled at 4E03H: compared with line numbers.
4EBD-4EBE
DEFW 4DD4H D4 4D
DEFW 4DD4H, the handler for THEN: an optional line number.
4EBF
DEFB CAH CA
CAH, the THEN token, handled at 4DD4H: an optional line number.
4EC0-4EC1
DEFW 4DADH AD 4D
DEFW 4DADH, the handler of the end entry: 4DADH reads the next byte (a text byte below FFH is passed at 4DBAH before this entry is reached).
4EC2
DEFB FFH FF
FFH, the end of the token table: every text byte below FFH stops the search before here, and FFH itself goes to 4DADH to read on.

4EC3H - Find a Line

Looks for the line with the old number in Register Pair DE. A binary search over the 128 table entries finds the last one whose line number is not above DE; from there the lines are walked. Returns Register Pair HL = the line, and Register Pair DE = the contents of its link field (the new number), with the Z FLAG set if the line exists. Otherwise NZ, with HL and DE for the next higher line (DE = 0000H at the end of the program).

4EC3
LD HL,64CAH 21 CA 64
Load Register Pair HL with 64CAH, the start of the line table.
4EC6
LD BC,0080H 01 80 00
Load Register Pair BC with 0080H, half the table in bytes, the first step.

BINARY SEARCH
Register Pair HL = the table entry, Register Pair BC = the step (halved each time), Register Pair DE = the number wanted.

4EC9
ADD HL,BC 09
Add Register Pair BC (the step) to Register Pair HL: the entry to test.
4ECA
PUSH HL E5
Save Register Pair HL (the entry) on the stack.
4ECB
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's low byte.
4ECC
INC HL 23
Increment Register Pair HL to the high byte of the table entry.
4ECD
LD H,(HL) 66
Load Register H with the byte at Register Pair HL, the entry's high byte.
4ECE
LD L,A 6F
Load Register L with Register A. Register Pair HL = the line the entry points at.
4ECF
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field.
4ED0
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
4ED1
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set at the end of the program.
4ED2
INC HL 23
Increment Register Pair HL to the line number's low byte (the flags are not changed).
4ED3
SCF 37
Set the CARRY FLAG: the end of the program counts as above the number wanted.
4ED4
If the Z FLAG is set (the end), JUMP to 4EDEH with the CARRY FLAG set.
4ED6
INC HL 23
Increment Register Pair HL to the line number's high byte.
4ED7
LD A,D 7A
Load Register A with Register D, the high byte of the number wanted.
4ED8
CP (HL) BE
Compare Register A with the byte at Register Pair HL: the CARRY FLAG is set if the number wanted is lower.
4ED9
DEC HL 2B
Decrement Register Pair HL to the line number's low byte (the flags are not changed).
4EDA
If the NZ FLAG is set (the high bytes differ), JUMP to 4EDEH with that result.
4EDC
LD A,E 7B
Load Register A with Register E, the low byte of the number wanted.
4EDD
CP (HL) BE
Compare Register A with the byte at Register Pair HL: the CARRY FLAG is set if the number wanted is lower.
4EDE
POP HL E1
Restore Register Pair HL from the stack: the table entry. POP does not change the flags.
4EDF
If the NO CARRY FLAG is set (the entry's line is not above), JUMP to 4EE4H, keeping this entry.
4EE1
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
4EE2
SBC HL,BC ED 42
Subtract Register Pair BC (the step) from Register Pair HL: go back to the entry before.
4EE4
SRL C CB 39
Shift Register C (the step) right: the step through the table is halved.
4EE6
LD A,C 79
Load Register A with Register C, the step through the table.
4EE7
CP 02H FE 02
Compare Register A against 02H: the NO CARRY FLAG is set while the step is at least one entry.
4EE9
If the NO CARRY FLAG is set, LOOP back to 4EC9H.
4EEB
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the chosen entry's low byte.
4EEC
INC HL 23
Increment Register Pair HL to the high byte of the chosen table entry.
4EED
LD H,(HL) 66
Load Register H with the byte at Register Pair HL, the entry's high byte.
4EEE
LD L,A 6F
Load Register L with Register A. Register Pair HL = the line to start walking from.

LINE WALK
Register Pair HL = the line, Register Pair DE = the number wanted.

4EEF
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (the operand of 5120H).
4EF2
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set in the first pass.
4EF3
If the Z FLAG is set (first pass), JUMP to 4F03H.
4EF5
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the output address of the line being copied; the operand 4EF6H (0000H in the file) is stored at 4D34H and 5007H.
4EF8
LD A,H 7C
Load Register A with Register H, the high byte of the line to test.
4EF9
CP B B8
Compare Register A with Register B, the high byte of the line being copied.
4EFA
If the NZ FLAG is set (another line), JUMP to 4F03H.
4EFC
LD A,L 7D
Load Register A with Register L, the low byte of the line to test.
4EFD
CP C B9
Compare Register A with Register C, the low byte of the line being copied.
4EFE
If the NZ FLAG is set (another line), JUMP to 4F03H.
4F00
LD HL,0000H 21 00 00
Self-Modifying Code
It is the line being copied, not complete at its output address yet: load Register Pair HL with its input address instead; the operand 4F01H (0000H in the file) is stored at 4D38H.
4F03
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field.
4F04
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
4F05
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set at the end of the program.
4F06
If the Z FLAG is set (the end), JUMP to 4F18H.
4F08
INC HL 23
Increment Register Pair HL to the line number's low byte.
4F09
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the line number's low byte.
4F0A
INC HL 23
Increment Register Pair HL to the high byte of the line number.
4F0B
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the line number's high byte.
4F0C
CP D BA
Compare Register A with Register D, the high byte of the number wanted: the CARRY FLAG is set if the line's number is lower.
4F0D
If the NZ FLAG is set (the high bytes differ), JUMP to 4F11H with that result.
4F0F
LD A,C 79
Load Register A with Register C, the line number's low byte.
4F10
CP E BB
Compare Register A with Register E: the Z FLAG is set on an exact match.
4F11
If the NO CARRY FLAG is set (the line's number is not below the one wanted), JUMP to 4F1CH.
4F13
GOSUB to BASIC 5CF5H, which steps Register Pair HL through the line to the next one.
4F16
LOOP back to 4EEFH to test the next line at Register Pair HL.
4F18
INC HL 23
The end of the program: increment Register Pair HL, stepping as if past a line number.
4F19
INC HL 23
Increment Register Pair HL again, to the line number's high byte position.
4F1A
INC A 3C
Increment Register A (00H) to 01H: the NZ FLAG, not found.
4F1B
SCF 37
Set the CARRY FLAG: the line wanted lies below the end of the program.
4F1C
DEC HL 2B
Decrement Register Pair HL back towards the link field.
4F1D
DEC HL 2B
Decrement Register Pair HL to the link field's high byte.
4F1E
LD D,(HL) 56
Load Register D with the byte at Register Pair HL, the link field's high byte (the new number).
4F1F
DEC HL 2B
Decrement Register Pair HL to the link field's low byte, the start of the line.
4F20
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL. Register Pair DE = the line's new number (0000H at the end).
4F21
RET C9
RETURN with Register Pair HL = the line and the Z FLAG set if it was found.

4F22H - Write the New Number

Register Pair DE = the old number. A reference to a line that does not exist gives error letter U (with option X only if it lies inside the renumbered range); the old number is then written back unchanged.

4F22
PUSH DE D5
Save Register Pair DE (the old number) on the stack.
4F23
GOSUB to 4EC3H, which finds the line numbered Register Pair DE: the Z FLAG is set if it exists, with Register Pair DE = its new number.
4F26
POP BC C1
Restore Register Pair BC from the stack: the old number.
4F27
If the Z FLAG is set (the line exists), JUMP to 4F43H with Register Pair DE = the new number.
4F29
LD D,B 50
Load Register D with Register B, the old number's high byte.
4F2A
LD E,C 59
Load Register E with Register C. Register Pair DE = the old number again, to be written back unchanged.
4F2B
LD A,55H 3E 55
Load Register A with 55H, the error letter U.
4F2D
PUSH AF F5
Save Register Pair AF (Register A = U) on the stack.
4F2E
LD A,(4D0BH) 3A 0B 4D
Load Register A with the byte at 4D0BH, option X (set by SYS13).
4F31
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set without X.
4F32
If the Z FLAG is set (no X: every missing line is reported), JUMP to 4F57H.
4F34
LD HL,(4D06H) 2A 06 4D
Load Register Pair HL with the 16-bit value at 4D06H, the last old number of the range.
4F37
RST 18H DF
RST 18H: compare Register Pair HL (the range's end) with Register Pair DE (the reference). The CARRY FLAG is set if the reference lies above the range.
4F38
If the CARRY FLAG is set, JUMP to 4F42H: not reported.
4F3A
LD HL,(4D04H) 2A 04 4D
Load Register Pair HL with the 16-bit value at 4D04H, the first old number of the range.
4F3D
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the reference, DE = the range's start.
4F3E
RST 18H DF
RST 18H: compare Register Pair HL (the reference) with Register Pair DE. The NO CARRY FLAG is set if it lies inside the range.
4F3F
EX DE,HL EB
Exchange Register Pairs DE and HL back: DE = the reference. EX does not change the flags.
4F40
If the NO CARRY FLAG is set (inside the range), JUMP to 4F57H to report it.
4F42
POP AF F1
Restore Register Pair AF from the stack, discarding the error letter.
4F43
POP BC C1
Restore Register Pair BC from the stack: the output pointer.
4F44
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag.
4F47
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set in the first pass.
4F48
If the Z FLAG is set (first pass), JUMP to 4F4FH.
4F4A
Second pass: GOSUB to 5156H, which writes the digits of Register Pair DE at Register Pair BC (the output).
4F4D
JUMP to 4F52H to restore Register Pair HL, the input pointer.
4F4F
First pass: GOSUB to 5153H, which only counts the digits for the growth total.
4F52
POP HL E1
Restore Register Pair HL from the stack: the input pointer after the old number.
4F53
RET C9
RETURN with Register Pair HL after the number and Register Pair BC after the output.

4F54H - Report an Error

Called from 4DEFH with Register A = the error letter (X, S or U) and Register Pair DE = the line number to show; 4F22H enters at 4F57H with Register Pair AF, the output pointer and the input pointer already on the stack. The first report prints ERROR LINES; each report then shows the number, a slash and the letter. An error in the second pass means the text is already partly rewritten, so it goes to FATAL ERROR at 50E4H instead.

4F54
PUSH HL E5
Save Register Pair HL (the input pointer) on the stack.
4F55
PUSH BC C5
Save Register Pair BC (the output pointer) on the stack.
4F56
PUSH AF F5
Save Register Pair AF (Register A = the error letter) on the stack.
4F57
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (the operand of 5120H: 00H in the first pass, 01H in the second).
4F5A
OR A B7
OR Register A with itself to set the flags: the NZ FLAG is set in the second pass.
4F5B
If the NZ FLAG is set (second pass), JUMP to 50E4H to print FATAL ERROR. TEXT NOW BAD and go back to the DOS.
4F5E
LD HL,4FA6H 21 A6 4F
Load Register Pair HL with 4FA6H, the address of the errors flag (the operand of the LD A,00H at 4FA5H: 00H until the first error is reported).
4F61
BIT 0,(HL) CB 46
Test bit 0 of the byte at Register Pair HL (the errors flag): the NZ FLAG is set if an error has already been reported.
4F63
If the NZ FLAG is set (the heading is already shown), JUMP to 4F70H.
4F65
SET 0,(HL) CB C6
Self-Modifying Code
Set bit 0 of the byte at Register Pair HL (4FA6H, the errors flag) so 4FA5H loads 01H and the heading is printed only once.
4F67
GOSUB to BASIC 5D79H, which prints a carriage return (0DH) through BASIC 5D66H to start a new output line.
4F6A
LD HL,518CH 21 8C 51
Load Register Pair HL with 518CH, the address of the message ERROR LINES (ended by 03H).
4F6D
GOSUB to 5147H, which prints the message at Register Pair HL and starts a new line.
4F70
LD A,(4020H) 3A 20 40
Load Register A with the byte at 4020H, the low byte of the ROM's cursor address in the video memory (3C00H-3FFFH).
4F73
AND 3FH E6 3F
Mask Register A against 3FH (0011 1111) to keep the column on the 64-column line (0-63).
4F75
CP 38H FE 38
Compare Register A against 38H (column 56): the NO CARRY FLAG is set if the cursor is at column 56 or beyond, too close to the end of the line for another report.
4F77
If the NO CARRY FLAG is set, GOSUB to BASIC 5D79H, which prints a carriage return to start a new line.
4F7A
LD BC,(4020H) ED 4B 20 40
Load Register Pair BC with the 16-bit value at 4020H, the ROM's cursor address in the video memory.
4F7E
GOSUB to 5156H, which converts Register Pair DE (the line number) to decimal with BASIC 5D27H and copies the digits to Register Pair BC: they go straight into the video memory at the cursor, and Register Pair BC comes back just past them. 5156H also adds the digit count minus the old number's count (515EH) to the growth total; since Register Pair DE is the old number itself, the two counts match unless the text wrote it with leading zeros.
4F81
LD (4020H),BC ED 43 20 40
Store Register Pair BC (the video address after the digits) at 4020H, the ROM's cursor address, so the printing goes on from there.
4F85
LD A,2FH 3E 2F
Load Register A with 2FH, a slash (/), printed between the number and the letter.
4F87
GOSUB to BASIC 5D66H, which prints the character in Register A (a slash) through ROM 0033H.
4F8A
POP AF F1
Restore Register Pair AF from the stack: Register A = the error letter.
4F8B
GOSUB to BASIC 5D66H, which prints the character in Register A: the error letter.
4F8E
GOSUB to BASIC 5D64H, which loads Register A with 20H and prints a space.
4F91
GOSUB to BASIC 5D64H, which prints another space between the reports.
4F94
POP BC C1
Restore Register Pair BC from the stack: the output pointer.
4F95
POP HL E1
Restore Register Pair HL from the stack: the input pointer.
4F96
RET C9
RETURN with Register Pair HL = the input pointer and Register Pair BC = the output pointer. From 4F22H (via 4F57H) this returns to 4E4CH's caller, so the missing line's number is left as it was.

4F97H - End of the First Pass

4D3FH jumps here when the scan reaches the program's end marker. With option U, or after an error was listed, RENUM stops here: the lines keep their numbers and BASIC rebuilds the links. Otherwise the program is moved up in memory by the text's maximum growth plus 256 bytes, the stack is moved to the top of memory, and the second pass copies the program back down with the new numbers.

4F97
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (the operand of 5120H: 00H in the first pass, 01H in the second).
4F9A
OR A B7
OR Register A with itself to set the flags: the NZ FLAG is set in the second pass.
4F9B
If the NZ FLAG is set (the end of the second pass), JUMP to 4FFDH.
4F9E
LD A,(4D0AH) 3A 0A 4D
Load Register A with the byte at 4D0AH, option U (only report the errors; set by SYS13): 00H without U.
4FA1
OR A B7
OR Register A with itself to set the flags: the NZ FLAG is set with option U.
4FA2
If the NZ FLAG is set (option U), JUMP to 5063H to print DONE and give the program back to BASIC unchanged.
4FA5
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the errors flag, the operand 4FA6H (00H in the file, set to 01H at 4F65H when the first error is reported).
4FA7
OR A B7
OR Register A with itself to set the flags: the NZ FLAG is set if an error was reported.
4FA8
If the NZ FLAG is set (errors were listed), JUMP to 5069H to stop without renumbering.
4FAB
LD HL,(40F9H) 2A F9 40
Load Register Pair HL with the 16-bit value at 40F9H, the ROM's pointer to the end of the program (the start of the simple variables).
4FAE
LD DE,(40A4H) ED 5B A4 40
Load Register Pair DE with the 16-bit value at 40A4H, the ROM's pointer to the first program line.
4FB2
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
4FB3
SBC HL,DE ED 52
Subtract Register Pair DE (the start) from Register Pair HL (the end): HL = the program's length in bytes.
4FB5
LD B,H 44
Load Register B with Register H, the length's high byte.
4FB6
LD C,L 4D
Load Register C with Register L. Register Pair BC = the program's length.
4FB7
LD HL,(5168H) 2A 68 51
Self-Modifying Code
Load Register Pair HL with the highest growth total of the text, the operand 5168H (0000H in the file, stored at 516CH): how many bytes longer the text gets at worst while it is rewritten.
4FBA
BIT 7,H CB 7C
Test bit 7 of Register H, the sign of the growth total in Register Pair HL: the Z FLAG is set if it is positive.
4FBC
If the Z FLAG is set (positive), JUMP to 4FC1H to keep it.
4FBE
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H: a negative growth counts as none.
4FC1
INC H 24
Increment Register H: Register Pair HL = the growth plus 256 bytes, the distance the program is moved up.
4FC2
PUSH HL E5
Save Register Pair HL (the distance) on the stack.
4FC3
ADD HL,DE 19
Add Register Pair DE (the program's start) to Register Pair HL (the distance).
4FC4
ADD HL,BC 09
Add Register Pair BC (the program's length) to Register Pair HL: HL = the program's new end once moved up. The CARRY FLAG is set if this passes FFFFH.
4FC5
If the CARRY FLAG is set (it wraps past FFFFH), JUMP to 4FD1H, whose JP C goes to 50EDH for OUT OF MEMORY.
4FC7
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the new end, HL = the program's start.
4FC8
ADD HL,BC 09
Add Register Pair BC (the length) to Register Pair HL (the start): HL = the program's old end.
4FC9
PUSH DE D5
Save Register Pair DE (the new end) on the stack.
4FCA
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set BC', DE' and HL'; the main set (HL = the old end, DE = the new end, BC = the length) is kept there.
4FCB
POP DE D1
Restore Register Pair DE' from the stack: the new end.
4FCC
LD HL,(40B1H) 2A B1 40
Load Register Pair HL' with the 16-bit value at 40B1H, the ROM's top of memory pointer (the highest address BASIC may use).
4FCF
DEC H 25
Decrement Register H': Register Pair HL' = the top of memory minus 256, room kept for the stack.
4FD0
RST 18H DF
RST 18H: compare Register Pair HL' (the top minus 256) with Register Pair DE' (the new end). The CARRY FLAG is set if the moved program would pass it.
4FD1
If the CARRY FLAG is set (the program would not fit), JUMP to 50EDH for OUT OF MEMORY.
4FD4
INC H 24
Increment Register H': Register Pair HL' = the top of memory (40B1H) again.
4FD5
POP BC C1
Restore Register Pair BC' from the stack: the distance (the growth plus 256) saved at 4FC2H.
4FD6
LD SP,HL F9
Load the Stack Pointer SP with Register Pair HL': the stack moves to the top of memory, out of the way of the program (the old stack's contents are no longer needed).
4FD7
PUSH BC C5
Save Register Pair BC' (the distance) on the new stack.
4FD8
EXX D9
Exchange the alternate set back: HL = the old end, DE = the new end, BC = the length.
4FD9
LD A,01H 3E 01
Load Register A with 01H, the pass flag value of the second pass.
4FDB
LD (5121H),A 32 21 51
Self-Modifying Code
Store Register A (01H) at 5121H, the operand of 5120H: from now on 5120H copies every byte it reads to the output.
4FDE
LDDR ED B8
Move Register Pair BC bytes (the length) from Register Pair HL (the old end) to Register Pair DE (the new end), working downward to the program's second byte: the program moves up in memory. Afterwards HL = the program's start, DE = its new start and BC = 0000H.
4FE0
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the program's first byte, which LDDR did not move.
4FE1
LD (DE),A 12
Store Register A at Register Pair DE, the first byte of the moved program.
4FE2
POP BC C1
Restore Register Pair BC from the stack: the distance the program was moved.
4FE3
PUSH DE D5
Save Register Pair DE (the moved program's start: the input pointer of the second pass) on the stack.
4FE4
LD E,80H 1E 80
Load Register E with 80H, the count of the line table's 128 entries.
4FE6
PUSH HL E5
Save Register Pair HL (the program's old start: the output pointer of the second pass) on the stack.
4FE7
LD HL,64CAH 21 CA 64
Load Register Pair HL with 64CAH, the start of the line table (128 line addresses built at 4D0CH).
4FEA
LD (4D4CH),HL 22 4C 4D
Self-Modifying Code
Store Register Pair HL (64CAH) at 4D4CH, the operand of 4D4BH: the second pass checks the table entries from the first one.

TABLE LOOP
Register Pair HL = the table entry, Register Pair BC = the distance, Register E = the entries left. Every line address in the table is moved by the same distance as the program.

4FED
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's low byte.
4FEE
ADD A,C 81
Add Register C (the distance's low byte) to Register A.
4FEF
LD (HL),A 77
Store Register A at Register Pair HL, the entry's new low byte.
4FF0
INC HL 23
Increment Register Pair HL to the entry's high byte.
4FF1
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the entry's high byte.
4FF2
ADC A,B 88
Add Register B (the distance's high byte) and the CARRY FLAG from the low byte to Register A.
4FF3
LD (HL),A 77
Store Register A at Register Pair HL, the entry's new high byte.
4FF4
INC HL 23
Increment Register Pair HL to the next table entry.
4FF5
DEC E 1D
Decrement Register E, the table entries left to adjust.
4FF6
If the NZ FLAG is set (entries remain), LOOP back to 4FEDH for all 128.
4FF8
POP BC C1
Restore Register Pair BC from the stack: the program's old start, the output pointer.
4FF9
POP HL E1
Restore Register Pair HL from the stack: the moved program's start, the input pointer.
4FFA
JUMP to 4D2DH to run the scan again as the second pass, copying the program from Register Pair HL down to Register Pair BC.

4FFDH - End of the Second Pass

4F9BH jumps here when the second pass reaches the end marker, with Register Pair HL = the marker in the moved copy and Register Pair BC = the output pointer. The text is rewritten. The renumbered lines (the block) are moved to where their new numbers belong, the new numbers are copied from the link fields into the line number fields, DONE is shown and the ROM rebuilds the links.

4FFD
GOSUB to 5120H, which reads the byte at Register Pair HL and, in the second pass, copies it to Register Pair BC: the end marker's low byte.
5000
GOSUB to 5120H to copy the end marker's high byte. Register Pair BC = the byte after the program's new end.
5003
LD (40F9H),BC ED 43 F9 40
Store Register Pair BC at 40F9H, the ROM's pointer to the end of the program (the start of the simple variables).
5007
LD (4EF6H),BC ED 43 F6 4E
Self-Modifying Code
Store Register Pair BC at 4EF6H, the operand of 4EF5H, so the line searches made by 5073H compare against the program's end rather than a line being copied.
500B
GOSUB to 5073H, which finds the block of renumbered lines and where it goes, now at the program's final addresses.
500E
GOSUB to 50F1H, which returns Register Pair BC = the first piece of the block to move (as much as the free memory holds), with the Z FLAG set if nothing has to move.
5011
If the Z FLAG is set (the block is already in place), JUMP to 5050H.

MOVE THE BLOCK TO THE END
Register Pair BC = the piece's length. Each piece is copied to the end of the program and the rest of the program is moved down over it, until the whole block sits at the end.

5013
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the start of the block, the operand 5014H (0000H in the file, stored at 507BH).
5016
PUSH HL E5
Save Register Pair HL (the block's start) on the stack.
5017
LD DE,(40F9H) ED 5B F9 40
Load Register Pair DE with the 16-bit value at 40F9H, the end of the program: the free memory above it.
501B
LDIR ED B0
Copy Register Pair BC bytes (the piece) from Register Pair HL (the block's start) to Register Pair DE (the end of the program). Afterwards HL = the byte after the piece, DE = the end of the copy, BC = 0000H.
501D
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the end of the copy, DE = the byte after the piece.
501E
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
501F
SBC HL,DE ED 52
Subtract Register Pair DE (the byte after the piece) from Register Pair HL (the end of the copy): HL = the bytes from there up to the end of the copy.
5021
LD B,H 44
Load Register B with Register H, the count's high byte.
5022
LD C,L 4D
Load Register C with Register L. Register Pair BC = the bytes to move down.
5023
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the byte after the piece.
5024
POP DE D1
Restore Register Pair DE from the stack: the block's start.
5025
LDIR ED B0
Copy Register Pair BC bytes from Register Pair HL (the byte after the piece) down to Register Pair DE (the block's start): everything after the piece, including its copy, moves down over it, so the piece now ends the program.
5027
GOSUB to 50F6H, which returns Register Pair BC = the next piece of the block, with the Z FLAG set when none is left.
502A
If the NZ FLAG is set (more of the block remains), LOOP back to 5013H.
502C
GOSUB to 50F1H, which returns Register Pair BC = the first piece of the block again, now to be inserted.

INSERT THE BLOCK
Register Pair BC = the piece's length. Each piece is taken from the end of the program and put into a gap opened at the place the block goes.

502F
LD HL,(40F9H) 2A F9 40
Load Register Pair HL with the 16-bit value at 40F9H, the end of the program.
5032
PUSH HL E5
Save Register Pair HL (the end) on the stack.
5033
PUSH BC C5
Save Register Pair BC (the piece's length) on the stack.
5034
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the place the block goes, the operand 5035H (0000H in the file, stored at 50CAH).
5037
PUSH DE D5
Save Register Pair DE (the place) on the stack.
5038
PUSH HL E5
Save Register Pair HL (the end) on the stack.
5039
PUSH BC C5
Save Register Pair BC (the piece's length) on the stack.
503A
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
503B
SBC HL,DE ED 52
Subtract Register Pair DE (the place) from Register Pair HL (the end): HL = the bytes from the place up to the end of the program.
503D
LD B,H 44
Load Register B with Register H, the count's high byte.
503E
LD C,L 4D
Load Register C with Register L. Register Pair BC = the bytes to move up.
503F
POP HL E1
Restore Register Pair HL from the stack: the piece's length.
5040
POP DE D1
Restore Register Pair DE from the stack: the end of the program.
5041
DEC DE 1B
Decrement Register Pair DE: the last byte before the end.
5042
ADD HL,DE 19
Add Register Pair DE (the last byte) to Register Pair HL (the piece's length): HL = where that last byte goes.
5043
EX DE,HL EB
Exchange Register Pairs DE and HL: DE = the destination, HL = the last byte.
5044
LDDR ED B8
Move Register Pair BC bytes from Register Pair HL (the last byte) to Register Pair DE, working downward to the place: everything from the place on moves up by the piece's length, opening a gap.
5046
POP DE D1
Restore Register Pair DE from the stack: the place, the start of the gap.
5047
POP BC C1
Restore Register Pair BC from the stack: the piece's length.
5048
POP HL E1
Restore Register Pair HL from the stack: the old end of the program, where the piece now is after the move.
5049
LDIR ED B0
Copy Register Pair BC bytes (the piece) from Register Pair HL into the gap at Register Pair DE.
504B
GOSUB to 50F6H, which returns Register Pair BC = the next piece, with the Z FLAG set when none is left.
504E
If the NZ FLAG is set (more of the block remains), LOOP back to 502FH.
5050
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.

COPY THE NEW NUMBERS
Register Pair HL = the line, Register Pair DE = its link field (the new number SYS13 put there, or 0000H at the end).

5053
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the link field's low byte (the new number's low byte).
5054
INC HL 23
Increment Register Pair HL to the link field's high byte.
5055
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the new line number.
5056
LD A,D 7A
Load Register A with Register D, the high byte, to test Register Pair DE for zero.
5057
OR E B3
OR Register A with Register E: the Z FLAG is set for 0000H, the end of the program.
5058
If the Z FLAG is set (the end), JUMP to 5063H.
505A
INC HL 23
Increment Register Pair HL to the line number field.
505B
LD (HL),E 73
Store Register E (the new number's low byte) at Register Pair HL.
505C
INC HL 23
Increment Register Pair HL to the line number's high byte.
505D
LD (HL),D 72
Store Register D (the new number's high byte) at Register Pair HL.
505E
GOSUB to BASIC 5CF5H, which steps Register Pair HL through the line to the next one.
5061
LOOP back to 5053H for the next line at Register Pair HL.
5063
LD HL,5198H 21 98 51
Load Register Pair HL with 5198H, the address of the message DONE (ended by 03H).
5066
GOSUB to 5147H, which prints the message at Register Pair HL and starts a new line.
5069
GOSUB to BASIC 5D79H, which prints a carriage return to start a new line.
506C
LD DE,(40A4H) ED 5B A4 40
Load Register Pair DE with the 16-bit value at 40A4H, the ROM's pointer to the first program line, where the link rebuild starts.
5070
JUMP to ROM 1AE9H, the ROM's Fix Line Pointers entry, which rebuilds every line's link field from Register Pair DE on (the link fields held new numbers until now).

5073H - Where the Block Goes

Called from 4D25H (before the first pass) and 500BH (after the second). Finds the lines of the renumbered range (the block, from the first old number in 4D04H to the last in 4D06H) and the line their new numbers must go before: the first line whose number is not below the block's first new number. If the block's last new number (4D08H) is not below that line's new number, the renumbering would put the lines out of order: error 8CH SEQ # OVERFLOW (FATAL ERROR in the second pass). Stores the block's start (5014H), the place (5035H) and the length (50F2H, 0000H if the block stays where it is).

5073
LD DE,(4D04H) ED 5B 04 4D
Load Register Pair DE with the 16-bit value at 4D04H, the first old line number of the range (set by SYS13).
5077
GOSUB to 4EC3H, which finds the line numbered Register Pair DE (or the next one after it): HL = the first line of the block, DE = its new number from the link field.
507A
PUSH DE D5
Save Register Pair DE (the block's first new number) on the stack.
507B
LD (5014H),HL 22 14 50
Self-Modifying Code
Store Register Pair HL (the block's first line) at 5014H, the operand of 5013H.
507E
PUSH HL E5
Save Register Pair HL (the block's start) on the stack.
507F
LD DE,(4D06H) ED 5B 06 4D
Load Register Pair DE with the 16-bit value at 4D06H, the last old line number of the range.
5083
INC DE 13
Increment Register Pair DE: the number after the range.
5084
GOSUB to 4EC3H, which finds that line: HL = the first line after the block, DE = its new number (0000H at the end of the program).
5087
LD (50C0H),DE ED 53 C0 50
Self-Modifying Code
Store Register Pair DE (the new number of the line after the block) at 50C0H, the operand of 50BFH.
508B
POP BC C1
Restore Register Pair BC from the stack: the block's start.
508C
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
508D
SBC HL,BC ED 42
Subtract Register Pair BC (the block's start) from Register Pair HL (the line after it): HL = the block's length in bytes.
508F
POP DE D1
Restore Register Pair DE from the stack: the block's first new number.
5090
PUSH BC C5
Save Register Pair BC (the block's start) on the stack.
5091
PUSH HL E5
Save Register Pair HL (the block's length) on the stack.
5092
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.

FIND THE PLACE
Register Pair HL = the line, Register Pair DE = the block's first new number. The walk stops at the first line whose (old) number is not below it.

5095
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field.
5096
INC HL 23
Increment Register Pair HL to the link field's high byte.
5097
OR (HL) B6
OR Register A with the byte at Register Pair HL: the Z FLAG is set for 0000H, the end of the program.
5098
If the Z FLAG is set (the end), JUMP to 50ACH: the place is the end marker.
509A
INC HL 23
Increment Register Pair HL to the line number field.
509B
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the line number's low byte.
509C
INC HL 23
Increment Register Pair HL to the line number's high byte.
509D
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the line number's high byte.
509E
CP D BA
Compare Register A against Register D, the high byte of the block's first new number.
509F
If the NZ FLAG is set (the high bytes differ, and the CARRY FLAG gives the order), JUMP to 50A3H.
50A1
LD A,C 79
Load Register A with Register C, the line number's low byte.
50A2
CP E BB
Compare Register A against Register E, the low byte of the block's first new number: the CARRY FLAG is set if the line's number is below it.
50A3
If the NO CARRY FLAG is set (the line's number is not below it), JUMP to 50AAH: the place is found.
50A5
GOSUB to BASIC 5CF5H, which steps Register Pair HL through the line to the next one.
50A8
LOOP back to 5095H to test the next line at Register Pair HL.
50AA
DEC HL 2B
Decrement Register Pair HL back to the line number's low byte.
50AB
DEC HL 2B
Decrement Register Pair HL to the link field's high byte.
50AC
LD D,(HL) 56
Load Register D with the byte at Register Pair HL, the link field's high byte (the line's new number).
50AD
DEC HL 2B
Decrement Register Pair HL to the link field's low byte, the start of the line.
50AE
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL. Register Pair DE = that line's new number (0000H at the end marker); Register Pair HL = the place.
50AF
LD (50C8H),DE ED 53 C8 50
Self-Modifying Code
Store Register Pair DE (the new number of the line at the place) at 50C8H, the operand of 50C7H.
50B3
POP BC C1
Restore Register Pair BC from the stack: the block's length.
50B4
POP DE D1
Restore Register Pair DE from the stack: the block's start.
50B5
RST 18H DF
RST 18H: compare Register Pair HL (the place) with Register Pair DE (the block's start). The CARRY FLAG is set if the place lies below the block.
50B6
If the CARRY FLAG is set (below the block), JUMP to 50C7H: the block moves down to the place.
50B8
GOSUB to 519DH, which subtracts Register Pair BC (the block's length) from Register Pair HL: HL = where the place will be once the block is taken out, compared with Register Pair DE (the block's start).
50BB
If the CARRY FLAG is set (the place lies inside the block), JUMP to 50BFH: the block stays.
50BD
If the NZ FLAG is set (the place lies above the block), JUMP to 50C7H: the block moves up to the place.
50BF
LD DE,0000H 11 00 00
Self-Modifying Code
The block stays where it is: load Register Pair DE with the new number of the line after the block, the operand 50C0H (0000H in the file, stored at 5087H).
50C2
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H: nothing to move.
50C5
JUMP to 50CAH to store Register Pair HL and Register Pair BC.
50C7
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the new number of the line at the place, the operand 50C8H (0000H in the file, stored at 50AFH).
50CA
LD (5035H),HL 22 35 50
Self-Modifying Code
Store Register Pair HL (the place, adjusted for the block's removal when it lies above) at 5035H, the operand of 5034H.
50CD
LD (50F2H),BC ED 43 F2 50
Self-Modifying Code
Store Register Pair BC (the block's length, or 0000H) at 50F2H, the operand of 50F1H.
50D1
LD HL,(4D08H) 2A 08 4D
Load Register Pair HL with the 16-bit value at 4D08H, the block's last new number (stored by SYS13).
50D4
RST 18H DF
RST 18H: compare Register Pair HL (the block's last new number) with Register Pair DE (the new number of the line that will follow the block). The CARRY FLAG is set if it is below.
50D5
RET C D8
If the CARRY FLAG is set (the order is kept), RETURN.
50D6
LD A,D 7A
Load Register A with Register D, to test Register Pair DE for zero.
50D7
OR E B3
OR Register A with Register E: the Z FLAG is set if no line follows the block (the end marker).
50D8
RET Z C8
If the Z FLAG is set (the block goes at the end), RETURN.
50D9
LD A,8CH 3E 8C
Load Register A with 8CH, BASIC's error code for SEQ # OVERFLOW.
50DB
LD B,A 47
Load Register B with Register A, keeping the error code (50EFH enters here with 0CH, OUT OF MEMORY).
50DC
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (00H in the first pass, 01H in the second).
50DF
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set in the first pass.
50E0
LD A,B 78
Load Register A with Register B, the error code. LD does not change the flags.
50E1
JP Z,5E09H CA 09 5E
If the Z FLAG is set (first pass: the text is unchanged), JUMP to BASIC 5E09H, which rebuilds the links (ROM 1AF8H), clears the variables (ROM 1B59H) and raises the error in Register A.
50E4
LD HL,5170H 21 70 51
Second pass (4F5BH also comes here): load Register Pair HL with 5170H, the address of the message FATAL ERROR. TEXT NOW BAD.
50E7
GOSUB to 5147H, which prints the message at Register Pair HL and starts a new line.
50EA
JUMP to SYS0 4030H, the DOS's return for an error already displayed: the program cannot be given back to BASIC.
50ED
LD A,0CH 3E 0C
Load Register A with 0CH, BASIC's error code for OUT OF MEMORY.
50EF
JUMP to 50DBH to raise it (first pass) or print FATAL ERROR (second pass).

50F1H - The Next Piece to Move

The block is moved through the free memory between the end of the program (40F9H) and 256 bytes below the top of memory (40B1H). 50F1H starts with the block's whole length, 50F6H goes on with what is left. Returns Register Pair BC = the piece to move, with the Z FLAG set if none; less than 256 free bytes is OUT OF MEMORY.

50F1
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the block's length, the operand 50F2H (0000H in the file, stored at 50CDH).
50F4
JUMP to 50F9H with Register Pair DE = the block's whole length.
50F6
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with what is left of the block, the operand 50F7H (0000H in the file, stored at 5117H).
50F9
LD HL,(40B1H) 2A B1 40
Load Register Pair HL with the 16-bit value at 40B1H, the ROM's top of memory pointer.
50FC
DEC H 25
Decrement Register H: Register Pair HL = the top of memory minus 256, room kept for the stack.
50FD
LD BC,(40F9H) ED 4B F9 40
Load Register Pair BC with the 16-bit value at 40F9H, the end of the program.
5101
SBC HL,BC ED 42
Subtract Register Pair BC (the end of the program) and the CARRY FLAG (not cleared here) from Register Pair HL: HL = the free memory in bytes.
5103
LD B,H 44
Load Register B with Register H, the free memory's high byte.
5104
LD C,L 4D
Load Register C with Register L. Register Pair BC = the free memory: the largest piece that fits.
5105
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the length still to move, DE = the free memory.
5106
LD A,D 7A
Load Register A with Register D, the free memory's high byte.
5107
DEC A 3D
Decrement Register A: FFH if less than 256 bytes are free.
5108
CP F0H FE F0
Compare Register A against F0H: the NO CARRY FLAG is set if less than 256 bytes are free, or if the value is so large that the subtraction wrapped (the program passes the limit).
510A
If the NO CARRY FLAG is set, JUMP to 50EDH for OUT OF MEMORY.
510D
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
510E
SBC HL,BC ED 42
Subtract Register Pair BC (the piece) from Register Pair HL (the length still to move). The CARRY FLAG is set if less than a whole piece is left.
5110
If the NO CARRY FLAG is set (a whole piece of Register Pair BC bytes), JUMP to 5117H.
5112
ADD HL,BC 09
Add Register Pair BC back to Register Pair HL: HL = the length still to move, smaller than the free memory.
5113
LD B,H 44
Load Register B with Register H, the remaining length's high byte.
5114
LD C,L 4D
Load Register C with Register L. Register Pair BC = the rest of the block: the last piece.
5115
LOOP back to 510DH; the subtraction now leaves 0000H.
5117
LD (50F7H),HL 22 F7 50
Self-Modifying Code
Store Register Pair HL (what is left after this piece) at 50F7H, the operand of 50F6H.
511A
LD A,B 78
Load Register A with Register B, the piece's high byte.
511B
OR C B1
OR Register A with Register C: the Z FLAG is set if the piece in Register Pair BC is empty.
511C
RET C9
RETURN with Register Pair BC = the piece to move and the Z FLAG set if nothing is left.

511DH - Reading the Text

5120H reads the next byte of the program at Register Pair HL and, in the second pass, also copies it to the output at Register Pair BC. 512EH skips blanks (spaces, 09H and 0AH), copying them in the second pass; 513BH also returns the CARRY FLAG if a digit follows, without reading it.

511D
GOSUB to 512EH to skip blanks, then read the next byte.
5120
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the pass flag, the operand 5121H (00H in the file for the first pass; set to 01H at 4FDBH for the second).
5122
OR A B7
OR Register A with itself to set the flags: the Z FLAG is set in the first pass.
5123
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next byte of the program. LD does not change the flags.
5124
INC HL 23
Increment Register Pair HL past the byte read, the input pointer.
5125
If the Z FLAG is set (first pass: nothing is written), JUMP to 5129H.
5127
LD (BC),A 02
Store Register A (the byte) at Register Pair BC, the output.
5128
INC BC 03
Increment Register Pair BC, the output pointer.
5129
OR A B7
OR Register A with itself: the Z FLAG is set if the byte is 00H, the end of the line.
512A
RET C9
RETURN with Register A = the byte read and the Z FLAG set at 00H.
512B
GOSUB to 5120H to read (and in the second pass copy) the blank at Register Pair HL.
512E
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next byte of the program (not stepped past).
512F
CP 20H FE 20
Compare Register A (the next byte) against 20H, a space.
5131
If the Z FLAG is set (a space), JUMP to 512BH to pass it.
5133
CP 0BH FE 0B
Compare Register A against 0BH: the NO CARRY FLAG is set for 0BH and above.
5135
RET NC D0
If the NO CARRY FLAG is set (not a blank), RETURN with Register A = the byte.
5136
CP 09H FE 09
Compare Register A against 09H: the CARRY FLAG is set below 09H.
5138
RET C D8
If the CARRY FLAG is set (not a blank), RETURN with Register A = the byte.
5139
Register A is 09H or 0AH (a tab or a line feed): JUMP to 512BH to pass it.
513B
GOSUB to 512EH to skip blanks; Register A = the next byte, still at Register Pair HL.
513E
CP 30H FE 30
Compare Register A against 30H (the character 0): the CARRY FLAG is set below it.
5140
If the CARRY FLAG is set (not a digit), JUMP to 5145H.
5142
CP 3AH FE 3A
Compare Register A against 3AH, one above the character 9: the CARRY FLAG is set for a digit.
5144
RET C D8
If the CARRY FLAG is set (a digit 0-9), RETURN with the digit not read yet.
5145
Not a digit: JUMP to 5120H to read it, returning with the CARRY FLAG clear.

5147H - Print a Message

Prints the text at Register Pair HL up to its 03H end byte and starts a new line.

5147
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next character of the message.
5148
CP 03H FE 03
Compare Register A against 03H, the end byte of the message: the Z FLAG is set at the end.
514A
INC HL 23
Increment Register Pair HL to the next character. INC HL does not change the flags.
514B
If the Z FLAG is set (the end), JUMP to BASIC 5D79H, which prints a carriage return and returns to the caller.
514E
GOSUB to BASIC 5D66H, which prints the character in Register A through ROM 0033H.
5151
LOOP back to 5147H for the next character at Register Pair HL.

5153H - Put Out a Number

Converts Register Pair DE to decimal (BASIC 5D27H, leading zeros dropped) and copies the digits to Register Pair BC; 5153H points Register Pair BC at BASIC's own digit buffer 5D51H, so only the count matters. The difference between the new and the old number of digits is added to the growth total (515AH), whose highest value is kept in 5168H.

5153
LD BC,5D51H 01 51 5D
Load Register Pair BC with 5D51H, BASIC's digit buffer (where BASIC 5D32H builds the digits anyway): nothing is written to the program.
5156
CALL 5D27H CD 27 5D
GOSUB to BASIC 5D27H, which stores Register Pair DE at 4121H, converts it with ROM 132FH into 5D51H, drops the leading zeros and copies the digits to Register Pair BC: afterwards BC points past them, E = the number of digits and D = 0.
5159
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the growth total, the operand 515AH (0000H in the file, cleared at 4D30H at the start of each pass).
515C
ADD HL,DE 19
Add Register Pair DE (the new number's digit count) to Register Pair HL (the growth total).
515D
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the old number's digit count, the operand 515EH (0000H in the file, stored at 4E73H).
5160
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5161
SBC HL,DE ED 52
Subtract Register Pair DE (the old digit count) from Register Pair HL: HL = the new growth total.
5163
LD (515AH),HL 22 5A 51
Self-Modifying Code
Store Register Pair HL (the growth total) at 515AH, the operand of 5159H.
5166
RET M F8
If the SIGN FLAG is set (the text is shorter so far), RETURN.
5167
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the highest growth total so far, the operand 5168H (0000H in the file, read at 4FB7H).
516A
RST 18H DF
RST 18H: compare Register Pair HL (the growth total) with Register Pair DE (the highest so far). The CARRY FLAG is set if it is lower.
516B
RET C D8
If the CARRY FLAG is set (not a new highest), RETURN.
516C
LD (5168H),HL 22 68 51
Self-Modifying Code
Store Register Pair HL (the new highest growth total) at 5168H, the operand of 5167H.
516F
RET C9
RETURN with Register Pair HL = the new highest growth total.

5170H - Messages

5170-518B
DEFM "FATAL ERROR. TEXT NOW BAD", 0DH, 03H 46 41 54 41 4C 20 45 52 52 4F 52 2E 20 20 54 45 58 54 20 4E 4F 57 20 42 41 44 0D 03
The message FATAL ERROR. TEXT NOW BAD, a carriage return (0DH) and the 03H end byte, printed at 50E4H when an error hits the second pass.
518C-5197
DEFM "ERROR LINES", 03H 45 52 52 4F 52 20 4C 49 4E 45 53 03
The message ERROR LINES and the 03H end byte, printed at 4F6AH before the first error report.
5198-519C
DEFM "DONE", 03H 44 4F 4E 45 03
The message DONE and the 03H end byte, printed at 5063H when RENUM is finished.

519DH - Compare After Taking the Block Out

Called from 50B8H with Register Pair HL = the place, Register Pair BC = the block's length and Register Pair DE = the block's start.

519D
SBC HL,BC ED 42
Subtract Register Pair BC (the block's length) and the CARRY FLAG (clear after 50B6H) from Register Pair HL (the place): HL = where the place will be once the block is taken out.
519F
RET C D8
If the CARRY FLAG is set (it went below 0000H), RETURN.
51A0
RST 18H DF
RST 18H: compare Register Pair HL with Register Pair DE (the block's start): the CARRY FLAG is set if below, the Z FLAG if equal.
51A1
RET C9
RETURN with the flags of the comparison of Register Pair HL with Register Pair DE.

51A2H - Unused Bytes

51A2-51F3
NOP x 82 00 x 82
82 zero bytes to the end of the file (51F3H). Nothing in SYS11 reads or writes them.