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

Page Customization

Introduction/Summary

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

SYS11/SYS carries out the second part of the Disk BASIC command RENUM. It loads 4D0CH-51F3H in five load records (transfer address 4D0CH); the code ends at 51A1H and 51A2H-51F3H are 82 bytes of 00H. SYS13/SYS does the first part: it reads the command's numbers and the options U and X into its own bytes 4D00H-4D0BH, writes each line's new number into the line's link field (lines outside the range get their own number), counts the lines and loads SYS11/SYS with LD A,2DH / RST 28H. Because SYS11/SYS does not load 4D00H-4D0BH, those parameters stay in memory for it.

SYS11/SYS never returns to its caller: it ends by jumping to the ROM at 1AE9H (the links are rebuilt and BASIC goes back to its command level), to BASIC/CMD 5DE2H with an error code, or to SYS0/SYS 4030H after Fatal Error.

The page shows every byte of the file once, in address order.

How RENUM Works

  1. Line table (4D0CH). The address of every Register C-th line goes into the 128 word entries at 64A3H-65A2H (BASIC/CMD's initialization code, used as the input buffer). The line search (4EC3H) does a binary search over the table and then walks the lines, comparing old line numbers; it returns the line's new number from its link field.
  2. Order check (5073H). The renumbered lines (the block) must fit between the lines around the place their new numbers belong, else error 8CH SEQ # OVERFLOW before anything is changed.
  3. First pass (4D28H). Every line number referred to after GOTO, GOSUB, THEN, ELSE, RUN, RESUME, ON ... GOTO/GOSUB lists, ON ERROR GOTO, ERL with a comparison, LIST, LLIST and the item list line of GET and PUT is looked up (token table 4E8AH). Strings, DATA and REM are passed. A reference that cannot be renumbered is listed under Error Lines as number/letter: X a line number was expected, S a number out of range (above 65529, or 0 where only RESUME 0 and ON ERROR GOTO 0 may stand), U a line that does not exist (with option X only inside the range). The change in the number of digits is added up (5153H) and its largest value kept.
  4. Stop or move. With option U, or after any error, RENUM stops: the program is unchanged. Otherwise the program moves up by its largest growth plus 256 bytes (OUT OF MEMORY if it does not fit under the top of memory less 256), the stack moves to the top of memory and the line table moves with the program.
  5. Second pass. The program is copied back down from its moved copy with every reference written as the new number (5120H copies each byte; 4E4CH writes the digits). An error now ends with Fatal Error. Text Now Bad and the DOS.
  6. Placing the block (4FFDH). The block is moved to the end of the program and then inserted at its place, a piece at a time through the free memory (50F1H). The new numbers are copied from the link fields into the line number fields, Done is shown and the ROM rebuilds the links (1AE9H).

Variables

ROM Addresses

Address
Size
Contents
4020H-4021H
2 bytes
Cursor Address
The ROM's cursor in the video memory: read for its column at 4F70H, used as the destination of the digits at 4F7AH and moved past them at 4F81H.
40A4H-40A5H
2 bytes
TXTTAB
The first program line (4D28H, 4FAEH, 5050H, 506CH, 5092H).
40B1H-40B2H
2 bytes
MEMSIZ
The top of memory: the moved program and every piece of the block must stay 256 bytes below it (4FCCH, 50F9H); the stack is moved to it (4FD6H).
40F9H-40FAH
2 bytes
End of Program
The end of the program, the start of the simple variables (4FABH, 5017H, 502FH, 50FDH); set at 5003H after the second pass.

Parameters From SYS13/SYS

Address
Size
Contents
4D00H-4D03H
4 bytes
New Start, Increment
SYS13/SYS's next new number and increment (default 10, 10); not used by SYS11/SYS.
4D04H-4D05H
2 bytes
First Old Number
The first line of the range (default 0): 4F3AH, 5073H.
4D06H-4D07H
2 bytes
Last Old Number
The last line of the range (default 65529): 4F34H, 507FH.
4D08H-4D09H
2 bytes
Last New Number
The new number of the range's last line: 50D1H.
4D0AH
1 byte
Option U
Not 00H: only list the errors (4F9EH).
4D0BH
1 byte
Option X
Not 00H: a missing line is listed only when it lies inside the range (4F2EH).

BASIC/CMD Areas

Address
Size
Contents
5D2AH-5D2EH
5 bytes
Digit Buffer
BASIC/CMD's buffer for the five digits of 5D0BH; 5153H copies the digits onto it so that nothing is written.
64A3H-65A2H
256 bytes
Line Table
128 line addresses (4D0CH), each Register C lines apart; 65A3H is the address after it (4D5CH). Searched at 4EC3H, moved with the program at 4FEDH, updated with the output addresses in the second pass (4D4BH-4D65H).

Operands Changed at Run Time

Address
Size
Contents
4D4CH-4D4DH
2 bytes
Next Table Entry
Operand of 4D4BH: the table entry checked in the second pass (4FEAH, 4D65H).
4DE4H
1 byte
ON Flag
Operand of 4DE3H: 01H after ON (4DC1H), cleared at each statement (4DA8H).
4DEDH-4DEEH
2 bytes
Current Line
Operand of 4DECH: the old number of the line being scanned (4D78H).
4E81H
1 byte
Line 0 Allowed
Operand of 4E80H: 01H after RESUME (4DD1H) or ON ERROR (4DCDH), cleared at each statement (4DA4H).
4EF6H-4EF7H
2 bytes
Output Line
Operand of 4EF5H: the output address of the line being copied (4D34H); the program's new end after the second pass (5007H).
4F01H-4F02H
2 bytes
Input Line
Operand of 4F00H: the input address of the line being copied (4D38H).
4FA6H
1 byte
Errors Flag
Operand of 4FA5H: bit 0 set at 4F65H when the first error is listed.
5014H-5015H
2 bytes
Block Start
Operand of 5013H, stored at 507BH.
5035H-5036H
2 bytes
Place
Operand of 5034H: where the block goes (50CAH).
50C0H-50C1H
2 bytes
Number After the Block
Operand of 50BFH, stored at 5087H.
50C8H-50C9H
2 bytes
Number at the Place
Operand of 50C7H, stored at 50AFH.
50F2H-50F3H
2 bytes
Length to Move
Operand of 50F1H: the block's length or 0000H (50CDH).
50F7H-50F8H
2 bytes
Length Left
Operand of 50F6H: what is left to move after each piece (5117H).
515AH-515BH
2 bytes
Growth Total
Operand of 5159H: the change in the text's length so far (4D30H clears it, 5163H stores it).
515EH-515FH
2 bytes
Old Digits
Operand of 515DH: the number of digits of the number just read (4E73H).
5121H
1 byte
Pass Flag
Operand of 5120H: 00H in the first pass, 01H in the second (4FDBH); read at 4D42H, 4EEFH, 4F44H, 4F57H, 4F97H, 50DCH.
5168H-5169H
2 bytes
Largest Growth
Operand of 5167H: the largest growth total (516CH), read at 4FB7H.

Outside Routines

WhereAddresses
ROM0033H (through BASIC 5D3FH), 132FH (through 5D00H), 1AE9H (rebuild the links, RUN reset, command level); RST 10H, RST 18H.
SYS0/SYS4030H (exit after a displayed error).
BASIC/CMD5CCCH, 5CCEH (step to the next line), 5D00H (number to digits), 5D3DH, 5D3FH, 5D52H (display a space, a character, a carriage return), 5DE2H (relink and give an error).

Disassembly

4D00H - Parameters Left by SYS13/SYS

SYS13/SYS does the first part of RENUM: from its 50FEH it reads the command's numbers and options into its own bytes 4D00H-4D0BH, gives every line in the range its new number by writing that number into the line's link field (the first two bytes of the line), counts the lines and loads SYS11/SYS with LD A,2DH / RST 28H at its 51CAH. SYS11/SYS loads from 4D0CH on, so these twelve bytes stay in memory as SYS13/SYS left them.

4D00-4D0B
DEFS 12
Not in the file: SYS13/SYS's parameter block. 4D00H-4D01H the next new line number (default 10), 4D02H-4D03H the increment (default 10), 4D04H-4D05H the first old line number of the range (default 0), 4D06H-4D07H the last old line number of the range (default 65529), 4D08H-4D09H the new number given to the last line of the range, 4D0AH option U (not 00H = only list the errors), 4D0BH option X (not 00H = list a missing line only when it lies inside the range).

4D0CH - RENUM, Second Part: the Line Table

The SYS0/SYS dispatcher calls the transfer address 4D0CH with the registers SYS13/SYS set: Register Pair HL = the first program line (from 40A4H), Register Pair DE = 64A3H (the line table), Register B = 80H (128 entries) and Register C = the number of lines per entry (the line count divided by 128, rounded up, at least 1). The table at 64A3H-65A2H (BASIC/CMD's initialization code, used as the input buffer) gets the address of every Register C-th line, so that a line can be found by a binary search (4EC3H). Unused entries point at the program's end marker.

TABLE LOOP
Register Pair DE = the table entry to fill (exchanged with Register Pair HL on each pass), 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: Register Pair HL = the table entry to fill (64A3H on the first pass), Register Pair DE = the address of the line it is to hold (the first program line from SYS13/SYS on the first pass).
4D0D
LD (HL),E 73
Store Register E, the low byte of the line's address, at Register Pair HL, the table entry's low byte.
4D0E
INC HL 23
Increment Register Pair HL from the table entry's low byte to its high byte.
4D0F
LD (HL),D 72
Store Register D, the high byte of the line's address, at Register Pair HL, the table entry's high byte.
4D10
INC HL 23
Increment Register Pair HL past the filled entry to the next table entry (2 bytes further).
4D11
PUSH HL E5
Save Register Pair HL (the address of the next table entry) on the stack; 4D22H takes it back into Register Pair DE.
4D12
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the line just put in the table, Register Pair DE = the next table entry.
4D13
LD E,C 59
Load Register E with Register C, the number of lines per entry (from SYS13/SYS): the count of lines to pass before the next entry.
4D14
JUMP to 4D1CH to test the line at Register Pair HL for the program's end marker before passing it.
4D16
GOSUB to BASIC 5CCCH with Register Pair HL at the high byte of the line's link field: it steps past the link and the line number and scans the text to its 00H end, returning Register Pair HL at the next line (the link fields hold new numbers now, so they cannot be followed).
4D19
DEC E 1D
Decrement Register E, the number of lines still to pass before the next table entry (loaded from Register C at 4D13H).
4D1A
If the Z FLAG is set (Register E is 0: Register C lines have been passed), JUMP to 4D22H to fill the next entry with the line at Register Pair HL.
4D1C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field (holding the line's new number, or 00H at the end marker).
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 (the link field's low byte) with the byte at Register Pair HL (its high byte): the Z FLAG is set only for 0000H, the program's end marker.
4D1F
If the NZ FLAG is set (another line), LOOP back to 4D16H to pass it with Register Pair HL at its link field's high byte.
4D21
DEC HL 2B
The end of the program: decrement Register Pair HL back to the end marker's first byte; every entry still to fill gets this address.
4D22
POP DE D1
Restore Register Pair DE from the stack: the address of the next table entry, saved at 4D11H.
4D23
Decrement Register B, the table entries left (80H from SYS13/SYS); if it is not 0, LOOP back to 4D0CH to fill the entry at Register Pair DE with the line at Register Pair HL.
4D25
GOSUB to 5073H, which finds where the renumbered lines will have to go and checks that their new numbers keep the program in order; if not, it gives error 8CH SEQ # OVERFLOW before anything is changed (the first pass flag at 5121H is still 00H).

4D28H - Scan the Program

The main loop, run twice. In the first pass (the operand 5121H = 00H) every line number that the text refers to is looked up (4E4CH), any reference that cannot be renumbered is listed, and the change in the text's length is added up (515AH, with its highest value in 5168H). In the second pass (5121H = 01H) the program has been moved up in memory (4FABH-4FFAH) and is copied back down byte by byte from Register Pair HL (the input) to Register Pair BC (the output), with every reference written as 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 (TXTTAB): the input pointer of the first pass.
4D2B
LD B,H 44
Load Register B with Register H, the high byte of the first program line: the output pointer starts at the same place.
4D2C
LD C,L 4D
Load Register C with Register L, the low byte of the first program line. Register Pair BC = the output pointer (unused in the first pass).
4D2D
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the starting value of the growth total (the second pass enters here from 4FFAH with Register Pair HL and Register Pair BC set for it).
4D30
LD (515AH),DE ED 53 5A 51
Self-Modifying Code
Store Register Pair DE (0000H) at 515AH, the operand of LD HL,nnnn at 5159H: the change in the text's length starts at 0 for this pass.

LINE LOOP
Register Pair HL = the input pointer at the line's link field, Register Pair BC = the output pointer.

4D34
LD (4EF6H),BC ED 43 F6 4E
Self-Modifying Code
Store Register Pair BC (the output address of this line) at 4EF6H, the operand of LD BC,nnnn at 4EF5H, which the line search uses to recognize the line being copied.
4D38
LD (4F01H),HL 22 01 4F
Self-Modifying Code
Store Register Pair HL (the input address of this line) at 4F01H, the operand of LD HL,nnnn at 4F00H: the line search reads this line from its input copy while it is being rewritten.
4D3B
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field (its new number from SYS13/SYS, or 00H at the end marker).
4D3C
INC HL 23
Increment Register Pair HL, the input pointer, to the high byte of the line's link field.
4D3D
OR (HL) B6
OR Register A (the link field's low byte) with the byte at Register Pair HL (its high byte): the Z FLAG is set only for 0000H, the program's end marker.
4D3E
DEC HL 2B
Decrement Register Pair HL, the input pointer, back to the start of the line's link field (DEC HL does not change the flags).
4D3F
If the Z FLAG is set (the end marker at Register Pair HL), JUMP to 4F97H to end the pass.
4D42
LD A,(5121H) 3A 21 51
Load Register A with the byte at 5121H, the pass flag (the operand of LD A,nn at 5120H: 00H in the first pass, 01H in the second).
4D45
OR A B7
OR Register A (the pass flag from 5121H) with itself to set the flags: the Z FLAG is set in the first pass.
4D46
If the Z FLAG is set (the first pass), JUMP to 4D6AH to read the line's header: the table only changes in the second pass.
4D48
PUSH HL E5
Second pass: save Register Pair HL (the input pointer at the line) on the stack for 4D69H.
4D49
PUSH DE D5
Save Register Pair DE (the growth total's start 0000H, or the old number of the line before) on the stack, freeing it for the table check; 4D68H restores it.
4D4A
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the input address of this line, to compare with the table entry.
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; set to 64A3H at 4FEAH and moved on at 4D65H).
4D4E
INC HL 23
Increment Register Pair HL, the table entry's address, to the entry's high byte.
4D4F
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the high byte of the line address in the table entry (moved up at 4FEDH-4FF6H like the program).
4D50
CP D BA
Compare Register A (the entry's high byte) with Register D, the high byte of this line's input address.
4D51
If the NZ FLAG is set (the entry holds another line), JUMP to 4D68H without changing the table.
4D53
DEC HL 2B
Decrement Register Pair HL back to the table entry's low byte.
4D54
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line address in the table entry.
4D55
CP E BB
Compare Register A (the entry's low byte) with Register E, the low byte of this line's input address.
4D56
If the NZ FLAG is set (the entry holds another line), JUMP to 4D68H without changing the table.
4D58
LD (HL),C 71
The table entry at Register Pair HL holds this line: store Register C, the low byte of the line's output address, in the entry instead, since the line will start there.
4D59
INC HL 23
Increment Register Pair HL to the table entry's high byte.
4D5A
LD (HL),B 70
Store Register B, the high byte of the line's output address, at Register Pair HL, the table entry's high byte.
4D5B
INC HL 23
Increment Register Pair HL past the entry to the next table entry.
4D5C
LD DE,65A3H 11 A3 65
Load Register Pair DE with 65A3H, the address after the last of the 128 table entries (64A3H + 256).
4D5F
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,DE at 4D60H (Register A is not changed).
4D60
SBC HL,DE ED 52
Subtract Register Pair DE (65A3H) from Register Pair HL (the next table entry): the Z FLAG is set when the last entry has been passed.
4D62
If the Z FLAG is set (Register Pair HL is 65A3H: no entries left), JUMP to 4D68H, leaving 4D4CH at the last entry.
4D64
ADD HL,DE 19
Add Register Pair DE (65A3H) back to Register Pair HL: Register Pair HL = the next table entry again.
4D65
LD (4D4CH),HL 22 4C 4D
Self-Modifying Code
Store Register Pair HL (the next table entry) at 4D4CH, the operand of LD HL,nnnn at 4D4BH, for the next line.
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 at the line's link field, saved at 4D48H.
4D6A
GOSUB to 5120H, which reads the byte at Register Pair HL (the link field's low byte) into Register A and steps Register Pair HL on; in the second pass it also copies the byte to Register Pair BC.
4D6D
GOSUB to 5120H for the link field's high byte at Register Pair HL (copied to Register Pair BC in the second pass); the ROM rebuilds the links at the end (5070H).
4D70
GOSUB to 5120H for the low byte of the line's old number at Register Pair HL, returned in Register A (and copied in the second pass).
4D73
LD E,A 5F
Load Register E with Register A, the low byte of the line's old number.
4D74
GOSUB to 5120H for the high byte of the line's old number at Register Pair HL, returned in Register A (and copied in the second pass).
4D77
LD D,A 57
Load Register D with Register A, the high byte of the line's old number. Register Pair DE = the line's old number.
4D78
LD (4DEDH),DE ED 53 ED 4D
Self-Modifying Code
Store Register Pair DE (the line's old number) at 4DEDH, the operand of LD DE,nnnn at 4DECH, so that an error report names this line.
4D7C
JUMP to 4DA3H to scan the line's first statement, with Register Pair HL at the first byte of its text.

REM
The REM token (93H): the rest of the line is read (and copied) without a look at it.

4D7E
REM (93H) and the bytes after it: GOSUB to 5120H for the next byte at Register Pair HL, in Register A (copied to Register Pair BC in the second pass); the Z FLAG is set at the line's 00H end.
4D81
If the NZ FLAG is set (Register A is not 00H, the end of the line), LOOP back to 4D7EH for the next byte of the comment.
4D83
JUMP to 4D34H to start the next line, whose link field Register Pair HL (the input pointer) now points at.

STRINGS
A quote (22H): the bytes up to the closing quote are read (and copied) without a look at them.

4D85
LD DE,4DADH 11 AD 4D
A quote (22H) in the statement: load Register Pair DE with 4DADH, the address of the statement loop's next-byte entry.
4D88
PUSH DE D5
Push Register Pair DE (4DADH) on the stack as the return address for the RET Z at 4D8EH.
4D89
LD E,A 5F
Load Register E with Register A, the character that ends the string: the quote 22H (4D97H also calls here with the quote of a DATA item).
4D8A
GOSUB to 5120H for the next byte of the string at Register Pair HL, in Register A (copied to Register Pair BC in the second pass).
4D8D
CP E BB
Compare Register A (the byte of the string) with Register E, the closing quote 22H.
4D8E
RET Z C8
If the Z FLAG is set (the string ends), RETURN to 4DADH (pushed at 4D88H) or, for a DATA item, to 4D9AH after the CALL Z at 4D97H.
4D8F
OR A B7
OR Register A (the byte of the string) with itself to set the flags: the Z FLAG is set for 00H, the end of the line.
4D90
If the NZ FLAG is set (Register A is not 00H: 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 (4DADH, or 4D9AH for a DATA item).
4D93
JUMP to 4D34H to start the next line, whose link field Register Pair HL (the input pointer) now points at.

DATA
DATA (88H): the bytes up to a colon outside quotes, or the end of the line, are read (and copied) without a look at them.

4D95
CP 22H FE 22
Compare Register A (the byte of the DATA statement) against 22H, a quote.
4D97
If the Z FLAG is set (Register A is 22H, a quoted DATA item), GOSUB to 4D89H to pass the string up to its closing quote.
4D9A
DATA (88H), from the table at 4E93H: GOSUB to 5120H for the next byte at Register Pair HL, in Register A (copied in the second pass); the Z FLAG is set at the line's 00H end.
4D9D
If the Z FLAG is set (Register A is 00H, the end of the line), JUMP to 4D34H for the next line.
4D9F
CP 3AH FE 3A
Compare Register A (the byte of the DATA statement) against 3AH, a colon, the end of the statement.
4DA1
If the NZ FLAG is set (Register A is not a colon), LOOP back to 4D95H to test the byte for a quote.

STATEMENT START
A colon (3AH, from the table at 4E90H) or the line's first statement (4D7CH): the flags of 4E81H and 4DE4H are cleared.

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 OR nn at 4E80H: 00H = line 0 is not a valid reference in this statement (4DCDH stores 01H for ON ERROR GOTO 0).
4DA7
XOR A AF
Load Register A with 00H (XOR A with itself), the value for the ON flag.
4DA8
LD (4DE4H),A 32 E4 4D
Self-Modifying Code
Store Register A at 4DE4H, the operand of LD A,nn at 4DE3H: the ON flag, 00H here, 01H after ON (4DC1H), when 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; the two together leave Register Pair HL and the stack unchanged.
4DAC
POP HL E1
Restore Register Pair HL from the stack: the input pointer (a byte not found in the token table comes back here from 4DBAH, with the pointer pushed at 4DB0H).

STATEMENT LOOP
Each byte of the text is looked up in the token table at 4E8AH; a byte with an entry goes to its handler, any other byte is passed.

4DAD
GOSUB to 5120H for the next byte of the text at Register Pair HL, in Register A (copied to Register Pair BC in the second pass).
4DB0
PUSH HL E5
Save Register Pair HL (the input pointer, after the byte in Register A) on the stack while Register Pair HL walks the table.
4DB1
LD HL,4E8AH 21 8A 4E
Load Register Pair HL with 4E8AH, the token table: entries of a handler address (2 bytes) and a byte value, in ascending order of the byte.

TABLE SEARCH
Register Pair HL = the table entry, Register A = the byte of the text.

4DB4
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the table entry's handler address.
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, the high byte of the handler address. Register Pair DE = the entry's handler.
4DB7
INC HL 23
Increment Register Pair HL to the table entry's byte value.
4DB8
CP (HL) BE
Compare Register A (the byte of the text) with the byte at Register Pair HL, the table entry's byte value.
4DB9
INC HL 23
Increment Register Pair HL past the entry to the next table entry (INC HL does not change the flags).
4DBA
If the CARRY FLAG is set (Register A is below the entry's byte, so it has no entry), JUMP to 4DACH to read on with the input pointer from the stack.
4DBC
If the NZ FLAG is set (Register A is above the entry's byte), LOOP back to 4DB4H for the next table entry.
4DBE
POP HL E1
Found: restore Register Pair HL from the stack, the input pointer after the byte, saved at 4DB0H.
4DBF
PUSH DE D5
Push Register Pair DE (the table entry's handler address) on the stack.
4DC0
RET C9
RETURN, which jumps to the handler address in Register Pair DE with Register A = the byte of the text and Register Pair HL = the input pointer after it.
4DC1
LD A,01H 3E 01
ON (A1H): load Register A with 01H, the value of the ON flag.
4DC3
JUMP to 4DA8H to store Register A (01H) at 4DE4H as the ON flag and go on with the statement.
4DC5
LD A,(4DE4H) 3A E4 4D
ERROR (9EH): load Register A with the byte at 4DE4H, the ON flag (01H if ON came before, so this is ON ERROR GOTO).
4DC8
OR A B7
OR Register A (the ON flag from 4DE4H) with itself to set the flags: the Z FLAG is set for a plain ERROR n statement.
4DC9
If the Z FLAG is set (ERROR n: the number is an error code, not a line), JUMP to 4DADH to read on.
4DCB
LD A,01H 3E 01
ON ERROR: load Register A with 01H, the flag value that allows the line number 0 (ON ERROR GOTO 0).
4DCD
JUMP to 4DA4H to store Register A (01H) at 4E81H and clear the ON flag at 4DE4H.
4DCF
LD A,01H 3E 01
RESUME (9FH): load Register A with 01H, the flag value that allows the line number 0 (RESUME 0).
4DD1
LD (4E81H),A 32 81 4E
Self-Modifying Code
Store Register A (01H) at 4E81H, the operand of OR nn at 4E80H: line 0 is a valid reference after RESUME.
4DD4
THEN (CAH), ELSE (95H), RUN (8EH), RESUME and the ends of 4E1FH and 4E3EH: GOSUB to 513BH, which passes blanks and returns Register A = the next byte at Register Pair HL, with the CARRY FLAG set if it is a digit.
4DD7
If the NO CARRY FLAG is set (Register A is not a digit: no line number follows), JUMP to 4DB0H to look the byte in Register A up.
4DD9
GOTO (8DH), GOSUB (91H) and each number after ON: GOSUB to 4E4CH, which reads the line number at Register Pair HL and writes it again as the new number (second pass).
4DDC
GOSUB to 511DH, which passes blanks and reads the next byte at Register Pair HL into Register A (copied in the second pass).
4DDF
CP 2CH FE 2C
Compare Register A (the byte after the line number) against 2CH, a comma.
4DE1
If the NZ FLAG is set (Register A is not a comma), JUMP to 4DB0H to look the byte in Register A up.
4DE3
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the ON flag, the operand 4DE4H (00H in the file; 01H stored at 4DA8H after ON).
4DE5
OR A B7
OR Register A (the ON flag) with itself to set the flags: the NZ FLAG is set after ON.
4DE6
If the NZ FLAG is set (ON ... GOTO or GOSUB), LOOP back to 4DD9H for the next line number of the list.
4DE8
PUSH AF F5
A comma after GOTO or GOSUB without ON: push Register Pair AF, a word for the POP at 4DE9H to take, so that this path joins the one from 4E4FH.
4DE9
POP AF F1
Restore Register Pair AF from the stack, discarding a word: the one pushed at 4DE8H, or (from 4E4FH, where no digit followed) the return address into 4E4CH's caller.
4DEA
LD A,58H 3E 58
Load Register A with 58H, the error letter X: a line number was expected but none follows, or a comma follows GOTO or GOSUB without ON.
4DEC
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the old number of the line being scanned, the operand 4DEDH (0000H in the file; stored at 4D78H for each line).
4DEF
GOSUB to 4F54H, which lists Register Pair DE (the line's old number) with the error letter in Register A (or, in the second pass, stops with FATAL ERROR).
4DF2
DEC BC 0B
Decrement Register Pair BC, the output pointer, back one byte (the byte just read is read again below).
4DF3
DEC HL 2B
Decrement Register Pair HL, the input pointer, back one byte to the byte just read.

SKIP THE STATEMENT
4E40H returns only with bytes inside the statement; at the statement's end it leaves this loop and goes on at 4E10H.

4DF4
GOSUB to 4E40H for the next byte of the statement at Register Pair HL, in Register A (copied in the second pass).
4DF7
LOOP back to 4DF4H for the next byte; 4E40H drops its return address and leaves this loop at the colon or the 00H that ends the statement.
4DF9
POP HL E1
A line number too large (from 4E5FH: the number read so far is above 6552, so another digit would pass 65529): restore Register Pair HL from the stack, the pointer to the digit, pushed at 4E57H.
4DFA
POP BC C1
Restore Register Pair BC from the stack: the output pointer, pushed at 4E51H.
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 (a line number out of range).
4DFE
JUMP to 4DECH to list the error letter in Register A for the line being scanned (Register Pair DE from 4DEDH) and pass the rest of the statement.
4E00
ERL followed by a comparison: GOSUB to 4E4CH, which reads the line number at Register Pair HL and writes it again as the new number (second pass).
4E03
ERL (C2H): GOSUB to 513BH, which passes blanks and returns Register A = the next byte at Register Pair HL, with the CARRY FLAG set if it is a digit.
4E06
If the CARRY FLAG is set (Register A is a digit: a line number), LOOP back to 4E00H to replace it.
4E08
CP D2H FE D2
Compare Register A (the byte after ERL or after the number) against D2H, the AND token: the CARRY FLAG is set for a byte below it.
4E0A
If the CARRY FLAG is set (Register A is below D2H: not an operator), JUMP to 4E10H to look the byte up.
4E0C
CP D7H FE D7
Compare Register A against D7H: the CARRY FLAG is set for the tokens D2H-D6H, AND, OR, >, = and <.
4E0E
If the CARRY FLAG is set (Register A is one of those operators), JUMP to 4E03H: a line number may follow it.
4E10
JUMP to 4DB0H to look the byte in Register A (the colon or 00H from 4E49H, or the byte after a number) up in the table.
4E12
LIST and LLIST (B4H, B5H): GOSUB to 513BH, which passes blanks and returns Register A = the next byte at Register Pair HL, with the CARRY FLAG set if it is a digit.
4E15
If the NO CARRY FLAG is set (Register A is not a digit: no first line number), JUMP to 4E1DH to test for a dash.
4E17
GOSUB to 4E4CH, which reads the first line number at Register Pair HL and writes it again as the new number (second pass).
4E1A
GOSUB to 511DH, which passes blanks and reads the next byte at Register Pair HL into Register A (copied in the second pass).
4E1D
CP CEH FE CE
Compare Register A (the byte after LIST or after its first number) against CEH, the minus token, the dash of a range.
4E1F
If the Z FLAG is set (Register A is CEH, a dash), JUMP to 4DD4H, where a second line number may follow.
4E21
JUMP to 4E10H, which goes on at 4DB0H to look the byte in Register A up.
4E23
LD D,02H 16 02
GET and PUT (A4H, A5H): load Register D with 02H, the number of outer commas before the line number of an item list (the file number, the position, then the line).
4E25
LD E,FFH 1E FF
Load Register E with FFH, the parenthesis level minus 1 (4E27H makes it 00H, the outer level).
4E27
INC E 1C
Increment Register E, the parenthesis level: one level deeper (from FFH to 00H on entry).

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 Register Pair HL, in Register A (at the statement's end 4E40H goes on at 4E10H instead).
4E2B
CP 28H FE 28
Compare Register A (the byte of the statement) against 28H, an opening parenthesis.
4E2D
If the Z FLAG is set (Register A is an opening parenthesis), JUMP to 4E27H to count one level deeper in Register E.
4E2F
DEC E 1D
Decrement Register E, the parenthesis level, provisionally leaving a level.
4E30
CP 29H FE 29
Compare Register A (the byte of the statement) against 29H, a closing parenthesis.
4E32
If the Z FLAG is set (Register A is a closing parenthesis), JUMP to 4E28H with Register E one level lower.
4E34
INC E 1C
Increment Register E back: the Z FLAG is set if Register E, the parenthesis level, is 00H, the outer level.
4E35
If the NZ FLAG is set (Register E is not 0: inside parentheses), LOOP back to 4E28H for the next byte.
4E37
CP 2CH FE 2C
Compare Register A (a byte at the outer level) against 2CH, a comma.
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 outer commas still to pass (02H from 4E23H).
4E3C
If the NZ FLAG is set (Register D is not 0: that was the first comma), LOOP back to 4E28H.
4E3E
After the second outer comma: JUMP to 4DD4H, where a line number may follow (the number of the line holding the GET or PUT item list).

4E40H - Next Byte of the Statement

Reads the next byte at Register Pair HL (copied in the second pass) and returns it in Register A. At the end of the statement (00H or a colon) it does not return: it drops its return address and goes on at 4E10H with the byte in Register A.

4E40
GOSUB to 5120H for the next byte of the text at Register Pair HL, in Register A (copied to Register Pair BC in the second pass).
4E43
OR A B7
OR Register A (the byte read) with itself to set the flags: the Z FLAG is set for 00H, the end of the line.
4E44
If the Z FLAG is set (Register A is 00H, the line's end), JUMP to 4E49H.
4E46
CP 3AH FE 3A
Compare Register A (the byte read) against 3AH, a colon, the end of the statement.
4E48
RET NZ C0
If the NZ FLAG is set (Register A is not a colon: 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 into the caller (4DF7H or 4E2BH).
4E4A
JUMP to 4E10H, which goes on at 4DB0H with Register A = the colon or the 00H.

4E4CH - Replace a Line Number

Called with Register Pair HL at a line number in the text and Register Pair BC = the output pointer. Reads the decimal number (blanks between its digits are passed by RST 10H) and looks the line up. In the second pass the number is written to the output as the line's new number, or unchanged if the line does not exist; in the first pass only the change in the number of digits is counted. Line 0 is accepted only after RESUME or ON ERROR GOTO. Returns with Register Pair HL after the number and Register Pair BC after the output.

4E4C
GOSUB to 513BH, which passes blanks and returns Register A = the next byte at Register Pair HL, with the CARRY FLAG set if it is a digit (the digit is not read yet).
4E4F
If the NO CARRY FLAG is set (Register A is not a digit), JUMP to 4DE9H, which drops this routine's return address and lists error letter X.
4E51
PUSH BC C5
Save Register Pair BC (the output pointer) on the stack while Register Pair BC counts the digits.
4E52
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the line 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 (00H): the low byte. Register Pair BC = 0000H, the count of digits read.

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

4E57
PUSH HL E5
Save Register Pair HL (the address of the first digit) on the stack; 4E70H keeps the address of the latest digit there.
4E58
INC BC 03
Increment Register Pair BC, the count of digits read, for the digit in Register A.
4E59
LD HL,1998H 21 98 19
Load Register Pair HL with 1998H (6552), the largest number that can take another digit and stay at most 65529.
4E5C
OR A B7
OR Register A (the digit character) with itself to clear the CARRY FLAG for the SBC HL,DE at 4E5DH.
4E5D
SBC HL,DE ED 52
Subtract Register Pair DE (the number so far) from Register Pair HL (6552): the CARRY FLAG is set if the number so far is above 6552.
4E5F
If the CARRY FLAG is set (Register Pair DE is above 6552), JUMP to 4DF9H for error letter S, with the digit's address and the output pointer on the stack.
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, the low byte. 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 so far) to Register Pair HL: the number so far 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 character 0) from Register A, the digit character: Register A = the digit's value 0-9.
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, the high byte of the digit count (00H unless 256 or more digits were read). Register Pair DE = the digit's value.
4E6B
ADD HL,DE 19
Add Register Pair DE (the digit's value) to Register Pair HL (the number so far times 10).
4E6C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the number so far with this digit added.
4E6D
POP HL E1
Restore Register Pair HL from the stack: the address of the digit just used.
4E6E
PUSH HL E5
Save Register Pair HL (the address of the digit) on the stack again.
4E6F
RST 10H D7
RST 10H: step Register Pair HL past blanks to the next character and load it into Register A; the CARRY FLAG is set if it is 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 address is kept there and Register Pair HL = the address of the digit just used.
4E71
If the CARRY FLAG is set (Register A, the next character, is a digit), LOOP back to 4E58H to add it.
4E73
LD (515EH),BC ED 43 5E 51
Self-Modifying Code
Store Register Pair BC (the number of digits read) at 515EH, the operand of LD DE,nnnn at 515DH, for the change in the text's length.
4E77
POP BC C1
Restore Register Pair BC from the stack, discarding the address of the character after the number (kept at 4E70H).
4E78
INC HL 23
Increment Register Pair HL past the number's last digit: Register Pair HL = the input pointer after the number.
4E79
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): Register Pair HL = the output pointer saved at 4E51H, and the input pointer is kept on the stack.
4E7A
PUSH HL E5
Push Register Pair HL (the output pointer) on the stack as well, for 4F43H.
4E7B
LD A,D 7A
Load Register A with Register D, the high byte of the line number read.
4E7C
OR E B3
OR Register A with Register E, the low byte: the Z FLAG is set for line 0.
4E7D
If the NZ FLAG is set (Register Pair DE is 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 operand 4E81H (00H in the file, cleared at 4DA4H at each statement; 01H after RESUME, 4DD1H, or ON ERROR, 4DCDH): the NZ FLAG is set if line 0 is allowed.
4E82
If the NZ FLAG is set (line 0 is allowed), JUMP to 4F43H to write it back unchanged with Register Pair DE = 0000H.
4E85
LD A,53H 3E 53
Load Register A with 53H, the error letter S (line 0 where it is not allowed).
4E87
JUMP to 4F56H to list it with Register Pair DE = 0000H, the output pointer and the input pointer already on the stack.

4E8AH - Token Table (Data)

19 entries of three bytes: the handler's address (a word) and the byte of the text it handles, in ascending order of the byte; 4DB1H-4DC0H search it. The last entry (FFH) catches every byte above CAH that has no entry.

4E8A-4E8C
DEFW 4D34H / DEFB 00H 34 4D 00
00H, the end of the line: handler 4D34H, start the next line.
4E8D-4E8F
DEFW 4D85H / DEFB 22H 85 4D 22
22H, a quote: handler 4D85H, pass the string.
4E90-4E92
DEFW 4DA3H / DEFB 3AH A3 4D 3A
3AH, a colon: handler 4DA3H, a new statement (the flags at 4E81H and 4DE4H are cleared).
4E93-4E95
DEFW 4D9AH / DEFB 88H 9A 4D 88
88H, the DATA token: handler 4D9AH, pass the DATA items.
4E96-4E98
DEFW 4DD9H / DEFB 8DH D9 4D 8D
8DH, the GOTO token: handler 4DD9H, a line number must follow.
4E99-4E9B
DEFW 4DD4H / DEFB 8EH D4 4D 8E
8EH, the RUN token: handler 4DD4H, a line number may follow.
4E9C-4E9E
DEFW 4DD9H / DEFB 91H D9 4D 91
91H, the GOSUB token: handler 4DD9H, a line number must follow.
4E9F-4EA1
DEFW 4D7EH / DEFB 93H 7E 4D 93
93H, the REM token: handler 4D7EH, pass the rest of the line.
4EA2-4EA4
DEFW 4DD4H / DEFB 95H D4 4D 95
95H, the ELSE token: handler 4DD4H, a line number may follow.
4EA5-4EA7
DEFW 4DC5H / DEFB 9EH C5 4D 9E
9EH, the ERROR token: handler 4DC5H, ON ERROR GOTO allows line 0.
4EA8-4EAA
DEFW 4DCFH / DEFB 9FH CF 4D 9F
9FH, the RESUME token: handler 4DCFH, a line number (0 allowed) may follow.
4EAB-4EAD
DEFW 4DC1H / DEFB A1H C1 4D A1
A1H, the ON token: handler 4DC1H, sets the ON flag at 4DE4H.
4EAE-4EB0
DEFW 4E23H / DEFB A4H 23 4E A4
A4H, the GET token: handler 4E23H, a line number may follow the second comma.
4EB1-4EB3
DEFW 4E23H / DEFB A5H 23 4E A5
A5H, the PUT token: handler 4E23H, a line number may follow the second comma.
4EB4-4EB6
DEFW 4E12H / DEFB B4H 12 4E B4
B4H, the LIST token: handler 4E12H, a line number or a range may follow.
4EB7-4EB9
DEFW 4E12H / DEFB B5H 12 4E B5
B5H, the LLIST token: handler 4E12H, a line number or a range may follow.
4EBA-4EBC
DEFW 4E03H / DEFB C2H 03 4E C2
C2H, the ERL token: handler 4E03H, a line number may follow a comparison.
4EBD-4EBF
DEFW 4DD4H / DEFB CAH D4 4D CA
CAH, the THEN token: handler 4DD4H, a line number may follow.
4EC0-4EC2
DEFW 4DADH / DEFB FFH AD 4D FF
FFH, the end of the table: handler 4DADH, read on. A byte from CBH to FEH is below FFH, so the search ends here at 4DBAH with the CARRY FLAG and the byte is passed.

4EC3H - Find a Line

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

4EC3
LD HL,64A3H 21 A3 64
Load Register Pair HL with 64A3H, the first entry of the line table built at 4D0CH (it holds the first program line and is the result when every entry tested is above the number wanted).
4EC6
LD BC,0080H 01 80 00
Load Register Pair BC with 0080H, half the table's 256 bytes: the first step of the binary search (64 entries).

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

4EC9
ADD HL,BC 09
Add Register Pair BC (the step in bytes) to Register Pair HL: Register Pair HL = the table entry to test.
4ECA
PUSH HL E5
Save Register Pair HL (the table entry being tested) on the stack.
4ECB
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line address in the table entry.
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 high byte of the line address in the table entry.
4ECE
LD L,A 6F
Load Register L with Register A, the low byte. Register Pair HL = the line the table entry points at.
4ECF
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of that line's link field (its new number, or 00H at the end marker).
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 (the link field's low byte) with the byte at Register Pair HL: the Z FLAG is set for 0000H, the program's end marker.
4ED2
INC HL 23
Increment Register Pair HL to the low byte of the line's number (INC HL does not change the flags).
4ED3
SCF 37
Set the CARRY FLAG: the end marker counts as a line above the number wanted.
4ED4
If the Z FLAG is set (the table entry points at the end marker), JUMP to 4EDEH with the CARRY FLAG set.
4ED6
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
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 high byte of the line's number: the CARRY FLAG is set if the number wanted is lower.
4ED9
DEC HL 2B
Decrement Register Pair HL to the low byte of the line's number (DEC HL does not change the flags).
4EDA
If the NZ FLAG is set (the high bytes differ), JUMP to 4EDEH with the CARRY FLAG from that compare.
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 low byte of the line's number: 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 being tested. POP does not change the flags.
4EDF
If the NO CARRY FLAG is set (the entry's line number is not above the number wanted), JUMP to 4EE4H, keeping this entry.
4EE1
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 4EE2H.
4EE2
SBC HL,BC ED 42
Subtract Register Pair BC (the step) from Register Pair HL: back to the entry tested before, whose line is not above the number wanted.
4EE4
SRL C CB 39
Shift Register C, the step in bytes, right: the step is halved (Register B stays 00H).
4EE6
LD A,C 79
Load Register A with Register C, the step in bytes.
4EE7
CP 02H FE 02
Compare Register A (the step) against 02H: the NO CARRY FLAG is set while the step is at least one entry (2 bytes).
4EE9
If the NO CARRY FLAG is set, LOOP back to 4EC9H to test the entry Register C bytes further on.
4EEB
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line address in the chosen table entry.
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 high byte of the line address.
4EEE
LD L,A 6F
Load Register L with Register A, the low byte. Register Pair HL = the line to start walking from (the first program line, from the entry at 64A3H, when every entry tested was above).

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 LD A,nn at 5120H: 00H in the first pass, 01H in the second).
4EF2
OR A B7
OR Register A (the pass flag) with itself to set the flags: the Z FLAG is set in the first pass.
4EF3
If the Z FLAG is set (the first pass: every line is complete where it is), 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; stored at 4D34H for each line, and at 5007H the program's new end).
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 output address of the line being copied.
4EFA
If the NZ FLAG is set (another line), JUMP to 4F03H to test it where it is.
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 output address of the line being copied.
4EFE
If the NZ FLAG is set (another line), JUMP to 4F03H to test it where it is.
4F00
LD HL,0000H 21 00 00
Self-Modifying Code
It is the line being copied, not yet complete at its output address: load Register Pair HL with its input address instead, the operand 4F01H (0000H in the file; stored at 4D38H for each line).
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 (the link field's low byte) with the byte at Register Pair HL: the Z FLAG is set at the end marker.
4F06
If the Z FLAG is set (the end of the program), JUMP to 4F18H.
4F08
INC HL 23
Increment Register Pair HL to the low byte of the line's number.
4F09
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the low byte of the line's number.
4F0A
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
4F0B
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the high byte of the line's number.
4F0C
CP D BA
Compare Register A (the line number's high byte) 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 the CARRY FLAG from that compare.
4F0F
LD A,C 79
Load Register A with Register C, the low byte of the line's number.
4F10
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, the CARRY FLAG if the line's number is lower.
4F11
If the NO CARRY FLAG is set (the line's number is not below the one wanted), JUMP to 4F1CH with the Z FLAG set if it is the line.
4F13
GOSUB to BASIC 5CCEH with Register Pair HL at the high byte of the line's number: it steps to the text and scans to the 00H end, returning Register Pair HL at the next line.
4F16
LOOP back to 4EEFH to test the next line at Register Pair HL.
4F18
INC HL 23
The end marker: increment Register Pair HL (at the marker's second byte) as if past a line number's low byte.
4F19
INC HL 23
Increment Register Pair HL again, so that 4F1CH-4F1FH step back to the marker's first byte.
4F1A
INC A 3C
Increment Register A (00H from the marker) to 01H: the NZ FLAG, the line was not found.
4F1B
SCF 37
Set the CARRY FLAG: the line wanted lies above every line of the program.
4F1C
DEC HL 2B
Decrement Register Pair HL from the high byte of the line's number towards the link field (DEC HL does not change the flags).
4F1D
DEC HL 2B
Decrement Register Pair HL to the high byte of the line's link field.
4F1E
LD D,(HL) 56
Load Register D with the byte at Register Pair HL, the high byte of the link field: the high byte of the line's new number (00H at the end marker).
4F1F
DEC HL 2B
Decrement Register Pair HL to the low byte of the link field, the start of the line.
4F20
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the link field. Register Pair DE = the line's new number (0000H at the end marker).
4F21
RET C9
RETURN with Register Pair HL = the line, Register Pair DE = its new number, and the Z FLAG set if its old number was the one wanted.

4F22H - Write the New Number

Register Pair DE = the old number read at 4E4CH (not 0), with the output pointer and the input pointer on the stack. A reference to a line that does not exist is error letter U (with option X only if it lies inside the renumbered range) and the old number is kept.

4F22
PUSH DE D5
Save Register Pair DE (the old line number) on the stack.
4F23
GOSUB to 4EC3H, which looks for 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 line number saved at 4F22H.
4F27
If the Z FLAG is set (the line exists), JUMP to 4F43H with Register Pair DE = its new number.
4F29
LD D,B 50
Load Register D with Register B, the high byte of the old line number.
4F2A
LD E,C 59
Load Register E with Register C, the low byte. Register Pair DE = the old line number, to be kept unchanged.
4F2B
LD A,55H 3E 55
Load Register A with 55H, the error letter U (a reference to a line that does not exist).
4F2D
PUSH AF F5
Save Register Pair AF (Register A = U) on the stack, where 4F57H expects the error letter.
4F2E
LD A,(4D0BH) 3A 0B 4D
Load Register A with the byte at 4D0BH, option X (stored by SYS13/SYS): 00H without X.
4F31
OR A B7
OR Register A (option X) 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 listed), JUMP to 4F57H to list it.
4F34
LD HL,(4D06H) 2A 06 4D
Load Register Pair HL with the 16-bit value at 4D06H, the last old line number of the range (stored by SYS13/SYS).
4F37
RST 18H DF
RST 18H: compare Register Pair HL (the range's last line) with Register Pair DE (the missing line). The CARRY FLAG is set if the missing line is above the range.
4F38
If the CARRY FLAG is set (above the range), JUMP to 4F42H: with X it is not listed.
4F3A
LD HL,(4D04H) 2A 04 4D
Load Register Pair HL with the 16-bit value at 4D04H, the first old line number of the range (stored by SYS13/SYS).
4F3D
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the missing line's number, Register Pair DE = the range's first line.
4F3E
RST 18H DF
RST 18H: compare Register Pair HL (the missing line) with Register Pair DE (the range's first line). The NO CARRY FLAG is set if it is not below the range.
4F3F
EX DE,HL EB
Exchange Register Pairs DE and HL back: Register Pair DE = the missing line's number (EX does not change the flags).
4F40
If the NO CARRY FLAG is set (inside the range), JUMP to 4F57H to list it.
4F42
POP AF F1
Restore Register Pair AF from the stack, discarding the error letter U pushed at 4F2DH.
4F43
POP BC C1
Restore Register Pair BC from the stack: the output pointer pushed at 4E7AH.
4F44
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).
4F47
OR A B7
OR Register A (the pass flag) with itself to set the flags: the Z FLAG is set in the first pass.
4F48
If the Z FLAG is set (the first pass), JUMP to 4F4FH to count the digits only.
4F4A
Second pass: GOSUB to 5156H, which writes the digits of Register Pair DE (the new number, or the old one kept) at Register Pair BC, the output, and returns Register Pair BC after them.
4F4D
JUMP to 4F52H to restore Register Pair HL, the input pointer.
4F4F
First pass: GOSUB to 5153H, which converts Register Pair DE into BASIC's digit buffer and adds the change in the number of digits to the growth total.
4F52
POP HL E1
Restore Register Pair HL from the stack: the input pointer after the old number, kept at 4E79H.
4F53
RET C9
RETURN to the caller of 4E4CH with Register Pair HL after the number and Register Pair BC after the output.

4F54H - List an Error

Called from 4DEFH with Register A = the error letter (X or S) and Register Pair DE = the line number to show; 4E87H enters at 4F56H and 4F22H at 4F57H with the input pointer, the output pointer and the error letter already on the stack. The first report shows Error Lines; each report shows the number, a slash and the letter at the cursor. An error in the second pass means the text is already partly rewritten, so it stops with 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 (4E87H enters here with the pointers already pushed).
4F57
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).
4F5A
OR A B7
OR Register A (the pass flag) with itself to set the flags: the NZ FLAG is set in the second pass.
4F5B
If the NZ FLAG is set (the second pass), JUMP to 50E4H to show 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 LD A,nn at 4FA5H (00H until the first error is listed).
4F61
BIT 0,(HL) CB 46
Test bit 0 of the byte at Register Pair HL, the errors flag at 4FA6H: the NZ FLAG is set if an error has been listed before.
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 operand of LD A,nn at 4FA5H becomes 01H, so the heading is shown only once and the first pass ends without renumbering (4FA8H).
4F67
GOSUB to BASIC 5D52H, which displays a carriage return (0DH) through BASIC 5D3FH (also printed when BASIC's printer switch at 5D45H is 24H).
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 displays the message at Register Pair HL and a carriage return.
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 (the cursor address's low byte) against 3FH (0011 1111) to keep the column on the 64-column line (0-63).
4F75
CP 38H FE 38
Compare Register A (the cursor's column) against 38H (column 56): the NO CARRY FLAG is set at column 56 or beyond, too near the end of the line for another report.
4F77
If the NO CARRY FLAG is set (column 56 or beyond), GOSUB to BASIC 5D52H to display a carriage return and 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 through BASIC 5D00H and copies the digits to Register Pair BC: straight into the video memory at the cursor, with Register Pair BC returned after them (it also adds to the growth total, which is not used once an error is listed).
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 that the display goes on after them.
4F85
LD A,2FH 3E 2F
Load Register A with 2FH, a slash, shown between the line number and the error letter.
4F87
GOSUB to BASIC 5D3FH, which displays the character in Register A (the slash) through ROM 0033H.
4F8A
POP AF F1
Restore Register Pair AF from the stack: Register A = the error letter (X, S or U).
4F8B
GOSUB to BASIC 5D3FH, which displays the character in Register A, the error letter.
4F8E
GOSUB to BASIC 5D3DH, which loads Register A with 20H and displays a space.
4F91
GOSUB to BASIC 5D3DH, which displays a second 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: to 4DF2H from 4DEFH, or (from 4E87H and 4F22H) to the caller of 4E4CH, with the number not written.

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: the lines keep their numbers, Done is shown only for U, and the ROM rebuilds the links (5069H). Otherwise the program is moved up in memory by the text's largest growth plus 256 bytes, the stack is moved to the top of memory, the line table is moved with the program, 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 LD A,nn at 5120H: 00H in the first pass, 01H in the second).
4F9A
OR A B7
OR Register A (the pass flag) with itself to set the flags: the NZ FLAG is set at the end of the second pass.
4F9B
If the NZ FLAG is set (the end of the second pass), JUMP to 4FFDH with Register Pair HL at the end marker and Register Pair BC = the output pointer.
4F9E
LD A,(4D0AH) 3A 0A 4D
Load Register A with the byte at 4D0AH, option U (only list the errors; stored by SYS13/SYS): 00H without U.
4FA1
OR A B7
OR Register A (option U) 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 show 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; bit 0 set at 4F65H when the first error is listed).
4FA7
OR A B7
OR Register A (the errors flag) with itself to set the flags: the NZ FLAG is set if an error was listed.
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 SBC HL,DE at 4FB3H.
4FB3
SBC HL,DE ED 52
Subtract Register Pair DE (the program's start from 40A4H) from Register Pair HL (its end from 40F9H): Register Pair HL = the program's length in bytes.
4FB5
LD B,H 44
Load Register B with Register H, the high byte of the program's length.
4FB6
LD C,L 4D
Load Register C with Register L, the low byte. Register Pair BC = the program's length.
4FB7
LD HL,(5168H) 2A 68 51
Load Register Pair HL with the 16-bit value at 5168H, the largest growth total of the first pass (the operand of LD DE,nnnn at 5167H, 0000H in the file, stored at 516CH): how many bytes longer the text becomes at worst while it is rewritten.
4FBA
BIT 7,H CB 7C
Test bit 7 of Register H, the sign of the largest growth total in Register Pair HL: the Z FLAG is set if it is positive.
4FBC
If the Z FLAG is set (Register Pair HL is 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 largest 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: Register Pair HL = the program's end once moved up. The CARRY FLAG is set if this passes FFFFH.
4FC5
If the CARRY FLAG is set (the moved end wraps past FFFFH), JUMP to 4FD1H, whose JP C goes on to 50EDH for OUT OF MEMORY.
4FC7
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the moved end, Register Pair HL = the program's start.
4FC8
ADD HL,BC 09
Add Register Pair BC (the program's length) to Register Pair HL (its start): Register Pair HL = the program's end, the value of 40F9H.
4FC9
PUSH DE D5
Save Register Pair DE (the moved 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 (Register Pair HL = the end, Register Pair DE = the moved end, Register Pair BC = the length) is kept there.
4FCB
POP DE D1
Restore Register Pair DE' from the stack: the moved end, saved at 4FC9H.
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 (MEMSIZ, 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 of memory minus 256) with Register Pair DE' (the moved end). The CARRY FLAG is set if the moved program would pass it.
4FD1
If the CARRY FLAG is set (the moved program does not fit, or it wrapped at 4FC4H), JUMP to 50EDH for OUT OF MEMORY.
4FD4
INC H 24
Increment Register H': Register Pair HL' = the top of memory from 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 top of memory: the stack moves out of the way of the program; nothing on the old stack is used again (RENUM ends by jumping into the ROM).
4FD7
PUSH BC C5
Save Register Pair BC' (the distance) on the new stack.
4FD8
EXX D9
Exchange the alternate set back: Register Pair HL = the program's end, Register Pair DE = the moved end, Register Pair BC = the program's length.
4FD9
LD A,01H 3E 01
Load Register A with 01H, the value of the pass flag in the second pass.
4FDB
LD (5121H),A 32 21 51
Self-Modifying Code
Store Register A (01H) at 5121H, the operand of LD A,nn at 5120H: from now on 5120H copies every byte it reads to the output at Register Pair BC.
4FDE
LDDR ED B8
Move Register Pair BC bytes (the program's length) from Register Pair HL (the end) to Register Pair DE (the moved end), working downward: the bytes from the program's second byte to its end move up by the distance. Afterwards Register Pair HL = the program's start, Register Pair DE = the moved start and Register Pair BC = 0000H.
4FE0
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the program's first byte, which the 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, saved at 4FD7H.
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,64A3H 21 A3 64
Load Register Pair HL with 64A3H, the first entry of the line table built at 4D0CH.
4FEA
LD (4D4CH),HL 22 4C 4D
Self-Modifying Code
Store Register Pair HL (64A3H) at 4D4CH, the operand of LD HL,nnnn at 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 moves by the same distance as the program.

4FED
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line address in the table entry.
4FEE
ADD A,C 81
Add Register C (the low byte of the distance) to Register A.
4FEF
LD (HL),A 77
Store Register A at Register Pair HL, the table entry's new low byte.
4FF0
INC HL 23
Increment Register Pair HL to the table entry's high byte.
4FF1
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the high byte of the line address in the table entry.
4FF2
ADC A,B 88
Add Register B (the high byte of the distance) and the CARRY FLAG from 4FEEH to Register A.
4FF3
LD (HL),A 77
Store Register A at Register Pair HL, the table 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 move (80H from 4FE4H).
4FF6
If the NZ FLAG is set (Register E is not 0), LOOP back to 4FEDH for the next of the 128 entries.
4FF8
POP BC C1
Restore Register Pair BC from the stack: the program's old start, the output pointer of the second pass (saved at 4FE6H).
4FF9
POP HL E1
Restore Register Pair HL from the stack: the moved program's start, the input pointer of the second pass (saved at 4FE3H).
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 first byte (00H).
5000
GOSUB to 5120H to copy the end marker's second byte (00H). Register Pair BC = the byte after the program's new end.
5003
LD (40F9H),BC ED 43 F9 40
Store Register Pair BC (the address after the end marker) 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 (the program's new end) at 4EF6H, the operand of LD BC,nnnn at 4EF5H: no line starts there, so the line searches made by 5073H read every line where it is.
500B
GOSUB to 5073H, which finds the block of renumbered lines and where it goes, now at the program's final addresses, and stores the block's start (5014H), the place (5035H) and the length to move (50F2H).
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 (Register Pair BC is 0: the block is already in place), JUMP to 5050H.

MOVE THE BLOCK TO THE END
Register Pair BC = the length of the piece. Each piece is copied to the end of the program and everything after it 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 Register Pair HL = the byte after the piece, Register Pair DE = the end of the copy, Register Pair BC = 0000H.
501D
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the end of the copy, Register Pair DE = the byte after the piece.
501E
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,DE at 501FH.
501F
SBC HL,DE ED 52
Subtract Register Pair DE (the byte after the piece) from Register Pair HL (the end of the copy): Register Pair HL = the bytes from there to the end of the copy.
5021
LD B,H 44
Load Register B with Register H, the high byte of the count.
5022
LD C,L 4D
Load Register C with Register L, the low byte. Register Pair BC = the bytes to move down.
5023
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the byte after the piece.
5024
POP DE D1
Restore Register Pair DE from the stack: the block's start, saved at 5016H.
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, its copy included, moves down over it, so the piece now ends the program at 40F9H.
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 (the whole length, or as much as the free memory holds), now to be inserted.

INSERT THE BLOCK
Register Pair BC = the length of the piece. Each piece is taken from the end of the program and put into a gap opened at the place, the last part of the block first.

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 of the program) on the stack.
5033
PUSH BC C5
Save Register Pair BC (the length of the piece) 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 of the program) on the stack.
5039
PUSH BC C5
Save Register Pair BC (the length of the piece) on the stack.
503A
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,DE at 503BH.
503B
SBC HL,DE ED 52
Subtract Register Pair DE (the place) from Register Pair HL (the end of the program): Register Pair HL = the bytes from the place to the end.
503D
LD B,H 44
Load Register B with Register H, the high byte of the count.
503E
LD C,L 4D
Load Register C with Register L, the low byte. Register Pair BC = the bytes to move up.
503F
POP HL E1
Restore Register Pair HL from the stack: the length of the piece, saved at 5039H.
5040
POP DE D1
Restore Register Pair DE from the stack: the end of the program, saved at 5038H.
5041
DEC DE 1B
Decrement Register Pair DE: the last byte of the program.
5042
ADD HL,DE 19
Add Register Pair DE (the last byte) to Register Pair HL (the length of the piece): Register Pair HL = where that last byte goes.
5043
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the destination of the last byte, Register Pair 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 length of the piece, opening a gap.
5046
POP DE D1
Restore Register Pair DE from the stack: the place, the start of the gap (saved at 5037H).
5047
POP BC C1
Restore Register Pair BC from the stack: the length of the piece, saved at 5033H.
5048
POP HL E1
Restore Register Pair HL from the stack: the old end of the program (saved at 5032H), where the last piece of the block now starts 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; the program ends at 40F9H again.
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/SYS put there, or 0000H at the end marker).

5053
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the line's link field (the low byte of its new number).
5054
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
5055
LD D,(HL) 56
Load Register D with the byte at Register Pair HL, the high byte. Register Pair DE = the line's new number.
5056
LD A,D 7A
Load Register A with Register D, the high byte of the new number, to test Register Pair DE for 0.
5057
OR E B3
OR Register A with Register E, the low byte: the Z FLAG is set for 0000H, the end marker.
5058
If the Z FLAG is set (the end of the program), JUMP to 5063H to show Done.
505A
INC HL 23
Increment Register Pair HL to the low byte of the line's number.
505B
LD (HL),E 73
Store Register E, the low byte of the new number, at Register Pair HL, the low byte of the line's number.
505C
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
505D
LD (HL),D 72
Store Register D, the high byte of the new number, at Register Pair HL.
505E
GOSUB to BASIC 5CCEH with Register Pair HL at the high byte of the line's number: it steps to the text and scans to the 00H end, returning Register Pair HL at the next line.
5061
LOOP back to 5053H to copy the new number of the 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 displays the message at Register Pair HL and a carriage return.
5069
GOSUB to BASIC 5D52H, which displays a carriage return (4FA8H enters here after errors were listed).
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 rebuilding of the links starts.
5070
JUMP to ROM 1AE9H, which rebuilds every line's link field from Register Pair DE on (CALL 1AFCH), calls the Disk BASIC links 41B5H and 41B8H around the RUN reset at 1B5DH (the variables are cleared) and goes to the BASIC command loop at 1A33H.

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 to move (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 (stored by SYS13/SYS).
5077
GOSUB to 4EC3H, which looks for the line numbered Register Pair DE (or the next one after it): Register Pair HL = the block's first line, Register Pair DE = its new number from the link field.
507A
PUSH DE D5
Save Register Pair DE (the new number of the block's first line) 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 LD HL,nnnn at 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 (stored by SYS13/SYS).
5083
INC DE 13
Increment Register Pair DE, the last old number of the range: the number after the range.
5084
GOSUB to 4EC3H, which looks for that line: Register Pair HL = the first line after the block, Register Pair DE = its new number (0000H at the end marker).
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 LD DE,nnnn at 50BFH.
508B
POP BC C1
Restore Register Pair BC from the stack: the block's start, saved at 507EH.
508C
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 508DH.
508D
SBC HL,BC ED 42
Subtract Register Pair BC (the block's start) from Register Pair HL (the line after it): Register Pair HL = the block's length in bytes.
508F
POP DE D1
Restore Register Pair DE from the stack: the new number of the block's first line, saved at 507AH.
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 new number of the block's first line. The walk stops at the first line whose 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 high byte of the line's link field.
5097
OR (HL) B6
OR Register A (the link field's low byte) with the byte at Register Pair HL: the Z FLAG is set for 0000H, the end marker.
5098
If the Z FLAG is set (the end of the program), JUMP to 50ACH: the place is the end marker.
509A
INC HL 23
Increment Register Pair HL to the low byte of the line's number.
509B
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the low byte of the line's number.
509C
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
509D
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the high byte of the line's number.
509E
CP D BA
Compare Register A (the line number's high byte) with Register D, the high byte of the block's first new number: the CARRY FLAG is set if the line's number is lower.
509F
If the NZ FLAG is set (the high bytes differ), JUMP to 50A3H with the CARRY FLAG from that compare.
50A1
LD A,C 79
Load Register A with Register C, the low byte of the line's number.
50A2
CP E BB
Compare Register A with 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 5CCEH with Register Pair HL at the high byte of the line's number: it returns Register Pair HL at the next line.
50A8
LOOP back to 5095H to test the next line at Register Pair HL.
50AA
DEC HL 2B
Decrement Register Pair HL from the high byte of the line's number to its low byte.
50AB
DEC HL 2B
Decrement Register Pair HL to the high byte of the line's link field.
50AC
LD D,(HL) 56
Load Register D with the byte at Register Pair HL, the high byte of the link field: the high byte of that line's new number (00H at the end marker).
50AD
DEC HL 2B
Decrement Register Pair HL to the low byte of the link field, 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 LD DE,nnnn at 50C7H.
50B3
POP BC C1
Restore Register Pair BC from the stack: the block's length, saved at 5091H.
50B4
POP DE D1
Restore Register Pair DE from the stack: the block's start, saved at 5090H.
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 (the place is 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 (the place) and compares the result with Register Pair DE (the block's start).
50BB
If the CARRY FLAG is set (the place less the block's length is below the block's start: 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's end), JUMP to 50C7H: the block moves up, to the place less its own length. With the Z FLAG the place is the line right after the block, and the block stays.
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, the length to move: nothing.
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, less the block's length when it lies above the block) at 5035H, the operand of LD DE,nnnn at 5034H.
50CD
LD (50F2H),BC ED 43 F2 50
Self-Modifying Code
Store Register Pair BC (the block's length, or 0000H when it stays) at 50F2H, the operand of LD DE,nnnn at 50F1H.
50D1
LD HL,(4D08H) 2A 08 4D
Load Register Pair HL with the 16-bit value at 4D08H, the new number of the block's last line (stored by SYS13/SYS).
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 lower.
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, the high byte of the following line's new number, to test Register Pair DE for 0.
50D7
OR E B3
OR Register A with Register E, the low byte: 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 of the program), 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 (the pass flag) 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
If the Z FLAG is set (the first pass: the text is unchanged), JUMP to BASIC 5DE2H, which rebuilds the links (ROM 1AF8H), clears the variables (ROM 1B59H) and gives the error in Register A.
50E4
LD HL,5170H 21 70 51
The second pass (4F5BH also comes here): load Register Pair HL with 5170H, the address of the message Fatal Error. Text Now Bad (ended by 0DH and 03H).
50E7
GOSUB to 5147H, which displays the message at Register Pair HL and a carriage return.
50EA
JUMP to SYS0/SYS 4030H (LD A,43H / RST 28H), the DOS's exit after 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 give the error (first pass) or show 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 (left by the caller; it is not cleared here, so the result can be 1 byte smaller) from Register Pair HL: Register Pair HL = the free memory in bytes.
5103
LD B,H 44
Load Register B with Register H, the high byte of the free memory.
5104
LD C,L 4D
Load Register C with Register L, the low byte. Register Pair BC = the free memory: the largest piece that fits.
5105
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the length still to move, Register Pair DE = the free memory.
5106
LD A,D 7A
Load Register A with Register D, the high byte of the free memory.
5107
DEC A 3D
Decrement Register A: FFH if less than 256 bytes are free.
5108
CP F0H FE F0
Compare Register A (the high byte of the free memory minus 1) against F0H: the NO CARRY FLAG is set if less than 256 bytes are free, or if the subtraction at 5101H 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 SBC HL,BC at 510EH.
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 with Register Pair HL = what is left after it.
5112
ADD HL,BC 09
Add Register Pair BC back to Register Pair HL: Register Pair HL = the length still to move, smaller than the free memory.
5113
LD B,H 44
Load Register B with Register H, the high byte of the length still to move.
5114
LD C,L 4D
Load Register C with Register L, the low byte. Register Pair BC = the rest of the block: the last piece.
5115
LOOP back to 510DH; the subtraction now leaves 0000H in Register Pair HL.
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 LD DE,nnnn at 50F6H.
511A
LD A,B 78
Load Register A with Register B, the high byte of the piece.
511B
OR C B1
OR Register A with Register C, the low byte: 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 passes blanks (spaces, 09H and 0AH), copying them in the second pass; 513BH also returns the CARRY FLAG if a digit follows, without reading it; 511DH passes blanks and reads the next byte.

511D
GOSUB to 512EH to pass the blanks at Register Pair HL (copied in the second pass), then fall into 5120H to 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 (the pass flag) 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, the input pointer, past the byte read.
5125
If the Z FLAG is set (the first pass: nothing is written), JUMP to 5129H.
5127
LD (BC),A 02
Store Register A (the byte read) at Register Pair BC, the output pointer.
5128
INC BC 03
Increment Register Pair BC, the output pointer, past the byte written.
5129
OR A B7
OR Register A (the byte read) with itself: the Z FLAG is set if it is 00H, the end of the line.
512A
RET C9
RETURN with Register A = the byte read and the Z FLAG set for 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 passed yet).
512F
CP 20H FE 20
Compare Register A (the next byte) against 20H, a space.
5131
If the Z FLAG is set (Register A is a space), JUMP to 512BH to pass it.
5133
CP 0BH FE 0B
Compare Register A (the next byte) against 0BH: the NO CARRY FLAG is set for 0BH and above.
5135
RET NC D0
If the NO CARRY FLAG is set (Register A is not a blank), RETURN with the byte in Register A.
5136
CP 09H FE 09
Compare Register A (the next byte, below 0BH) against 09H: the CARRY FLAG is set below 09H.
5138
RET C D8
If the CARRY FLAG is set (Register A is below 09H: not a blank), RETURN with the byte in Register A.
5139
Register A is 09H or 0AH (a tab or a line feed): JUMP to 512BH to pass it.
513B
GOSUB to 512EH to pass blanks; Register A = the next byte, still at Register Pair HL.
513E
CP 30H FE 30
Compare Register A (the next byte) against 30H, the character 0: the CARRY FLAG is set below it.
5140
If the CARRY FLAG is set (Register A is below 0: not a digit), JUMP to 5145H.
5142
CP 3AH FE 3A
Compare Register A (the next byte) 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 (Register A is a digit 0-9), RETURN with the digit not read yet (Register Pair HL at it).
5145
Not a digit: JUMP to 5120H to read it (copied in the second pass), returning with the CARRY FLAG clear (OR A at 5129H).

5147H - Display a Message

Displays the text at Register Pair HL up to its 03H end byte, then a carriage return. BASIC 5D3FH also prints each character when BASIC's printer switch at 5D45H is 24H.

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 (the character) 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 of the message (INC HL does not change the flags).
514B
If the Z FLAG is set (the end of the message), JUMP to BASIC 5D52H, which displays a carriage return and returns to the caller.
514E
GOSUB to BASIC 5D3FH, which displays the character in Register A through ROM 0033H.
5151
LOOP back to 5147H for the next character at Register Pair HL.

5153H - Count or Write a Number

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

5153
LD BC,5D2AH 01 2A 5D
Load Register Pair BC with 5D2AH, BASIC's digit buffer (where BASIC 5D0BH puts the five digits): the digits are copied onto the buffer itself and nothing in the program is written.
5156
GOSUB to BASIC 5D00H, which stores Register Pair DE at 4121H, converts it with ROM 132FH into 5D2AH-5D2EH, passes the leading zeros and copies the digits to Register Pair BC: afterwards Register Pair BC points past them, Register E = the number of digits and Register D = 00H.
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 number of digits of the number written) to Register Pair HL (the growth total).
515D
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the number of digits of the old number, 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 SBC HL,DE at 5161H.
5161
SBC HL,DE ED 52
Subtract Register Pair DE (the old number of digits) from Register Pair HL: Register Pair 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 LD HL,nnnn at 5159H.
5166
RET M F8
If the SIGN FLAG is set (the growth total is below 0: the text is shorter so far), RETURN.
5167
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the largest 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 largest so far). The CARRY FLAG is set if it is lower.
516B
RET C D8
If the CARRY FLAG is set (not a new largest), RETURN.
516C
LD (5168H),HL 22 68 51
Self-Modifying Code
Store Register Pair HL (the new largest growth total) at 5168H, the operand of LD DE,nnnn at 5167H.
516F
RET C9
RETURN with Register Pair HL = the new largest growth total.

5170H - Messages (Data)

The three texts 5147H displays, each ended by 03H.

5170-518B
DEFM "Fatal Error. Text Now Bad" / DEFB 0DH, 03H 46 61 74 61 6C 20 45 72 72 6F 72 2E 20 20 54 65 78 74 20 4E 6F 77 20 42 61 64 0D 03
The message of 50E4H, shown when an error is found in the second pass, after part of the text has been rewritten; 0DH is a carriage return inside the text and 03H ends it.
518C-5197
DEFM "Error Lines" / DEFB 03H 45 72 72 6F 72 20 4C 69 6E 65 73 03
The heading of 4F6AH, shown before the first error is listed.
5198-519C
DEFM "Done" / DEFB 03H 44 6F 6E 65 03
The message of 5063H, shown when RENUM has finished (also with option U).

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; the CARRY FLAG is clear (from the RST 18H at 50B5H).

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

51A2H - Unused Bytes

The rest of the file.

51A2-51F3
DEFB 00H x 82 00 x 82
82 bytes of 00H to the end of the file (51F3H). Nothing in SYS11/SYS reads or writes them.
51F4-51FF
DEFS 12
Not in the file: the rest of the overlay area. SYS11/SYS neither reads nor writes these bytes.