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

Page Customization

Introduction/Summary

NEWDOS/80 v2.0 SYS12/SYS Disassembly - REF (Model III)

SYS12/SYS carries out the Disk BASIC direct command REF, which lists where line numbers, variable names or a piece of text are used in the program. It loads 4D00H-51D2H in five load records (transfer address 4D00H); the code ends at 51B1H, 51B2H-51BEH are data and 51BFH-51D2H are 20 bytes of 00H. Its variables 51D3H-51FFH lie after the file. SYS18/SYS runs it from its command table (REF, code 2EH): at its 5531H it pushes BASIC/CMD's 641EH (the end of the statement) and does RST 28H. When REF is done SYS12/SYS returns through the SYS0/SYS dispatcher (4BC5H) to 641EH and then to the ROM's READY at 1A25H; a plain REF that finds a line jumps into the ROM's LIST at 2B33H instead, a bad parameter goes to the ROM's SYNTAX ERROR at 1997H, and 4F2BH is described below.

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

The Forms of REF

FormWhat it does
REF name, REF numberMode 2: every line that uses the variable (the item must have one or two characters; in the text only the first two characters of a name count) or refers to the line number (up to 5 digits). The item is shown right-aligned in 5 columns, then each line number; for a name the line number is followed by the form: /$ /% /! /# for a type character, an opening parenthesis for an array, and the count when it is used more than once in the line.
REF "text, REF =textMode 2 with a text search: every line holding the bytes after the quote or the = token (up to 16, a closing quote included) is shown. Strings and remarks are searched too.
REF followed by the multiplication sign, or by $The full report: every line number referred to and then every name, in order (mode 0 finds the next item and keeps up to 32 of its lines at 4300H, mode 1 reports them and scans on if the list was full). With $ the output is printed as well (BASIC/CMD's printer switch 5D45H). Holding BREAK pauses between items, ENTER goes on, the up arrow stops.
the same, followed by a name or numberThe full report from that item on.
REF, REF @nMode 3: lists (through the ROM's LIST) the next line after the last one shown, or from line n on, that holds the remembered item or text; Text End when there is none. The last line shown (4E76H) is reset to FFFFH at the end of every other report, so a plain REF then starts at the first line.

The scan (4F46H) passes strings, REM and ' remarks, DATA statements, numbers with a fraction and constants after &H and &O; the AS of a FIELD statement in the same line is not taken as a name. A line with a match changes the JP Z,4DFCH at 4F6DH into JP 4DFCH, so the line is reported when the scan reaches the next one.

At 4F2BH a plain REF that walks past the last line of the program (no line after the last one shown) jumps to the Text End message with a line address still on the stack, so the RET at the end of BASIC 5D70H goes to that address, the program's end marker, and not back through the dispatcher.

Variables

ROM Addresses

Address
Size
Contents
3840H
1 byte
Keyboard Row
Bit 0 ENTER, bit 2 BREAK, bit 3 the up arrow (4DB6H-4DC9H).
4020H-4021H
2 bytes
Cursor Address
The ROM's cursor in the video memory; its column decides the line breaks of the report (51A1H).
40A4H-40A5H
2 bytes
TXTTAB
The first program line (4DCCH, 4F1DH).

DOS Addresses

Address
Size
Contents
4300H-433FH
64 bytes
Line List
SYS0/SYS's sector buffer, used for up to 32 line addresses of the item found in mode 0 (5101H); 4340H marks a full list.

BASIC/CMD Addresses

Address
Size
Contents
5D45H
1 byte
Printer Switch
The operand of BASIC/CMD's 5D44H: 4D04H stores the first character after REF there; 24H ($) makes 5D3FH print as well.

Operands and Opcodes Changed at Run Time

Address
Size
Contents
4E0CH
1 byte
Mode
Operand of 4E0BH: 0 find the next item, 1 report it (full report), 2 one item, 3 list one line (4DD1H).
4E76H-4E77H
2 bytes
Last Line Shown
Operand of 4E75H: the number of the line found (50E7H); n - 1 after REF @n (4D1DH); FFFFH after a report (4E17H).
4E7AH-4E7BH
2 bytes
Line Address
Operand of 4E79H: the line being scanned (4F70H).
4ED9H-4EDAH
2 bytes
Count
Operand of 4ED8H: the count shown with a form (4E9CH).
4EEFH-4EF0H
2 bytes
List End
Operand of 4EEEH (512AH, 5182H).
4EF2H-4EF3H
2 bytes
List Next
Operand of 4EF1H (4E6DH, 5185H).
4F6DH
1 byte
Line Matched
Opcode: CAH, JP Z (4DF0H), or C3H, JP (50DDH) after a match.
4F7CH
1 byte
Text Search
Opcode: 21H, LD HL (4D4DH), or C3H, JP 512FH (4D44H).
4FBEH
1 byte
Numbers Looked At
Opcode: 30H, JR NC (numbers compared), or 18H, JR (numbers passed) (4DEBH).
4FFCH, 50A9H
2 bytes
Compare Condition
Opcodes: DAH, JP C (mode 0), or C2H, JP NZ (modes 1 to 3) (4DDAH, 4DDDH).
5021H
1 byte
Best Test
Opcode: 38H, JR C (the best is a number), or 18H, JR (a name or none) (517CH).
5085H-5086H
2 bytes
FIELD Position
Operand of 5084H: the last FIELD token (4FB4H), cleared at 4DF6H.

Variables After the File

Address
Size
Contents
51D3H-51D8H
6 bytes
Item Compared
Length byte and characters.
51D9H-51DEH
6 bytes
Best or Reported Item
Length byte and characters; FFH FFH for none.
51DFH-51E4H
6 bytes
Number Found
The digits of a number in the text.
51E5H-51EEH
10 bytes
Counters
Plain, $, %, !, # and the same as arrays.
51EFH-51FFH
17 bytes
Search Text
Up to 16 bytes and a 00H.

Outside Routines

WhereAddresses
ROM002BH (read a key), 1997H (SYNTAX ERROR), 1E5BH (LINGET), 2B33H (LIST4); the READY entry 1A25H is pushed by SYS18/SYS.
BASIC/CMD5D30H (spaces), 5D3DH (a space), 5D3FH (a character), 5D4FH (a space and a carriage return), 5D52H (a carriage return), 5D67H (a number in decimal), 5D70H (Register B characters); 641EH (the end of the statement) is pushed by SYS18/SYS.
SYS0/SYSThe dispatcher's return 4BC5H.

Disassembly

4D00H - REF: Read the Parameter

SYS18/SYS runs REF from its command table (the entry REF, code 2EH) at its 5531H: it pushes BASIC/CMD's 641EH (the end of the statement) above the ROM's READY entry 1A25H (pushed at its 5518H) and does RST 28H with Register A = 2EH (slot 0EH, function 1). The SYS0/SYS dispatcher calls 4D00H with Register Pair HL = the command line after REF; SYS12/SYS's RET goes back through the dispatcher (4BC5H) to 641EH. Forms, from the code: REF alone (list the next line that holds the remembered item), REF @n (the same from line n on), REF name or REF number (every line that uses it), REF "text or REF =text (every line holding the text), REF followed by the multiplication sign or $ (every line number and name in the program, in order; $ also prints), and either of those followed by a name or number (the full report from that item on).

4D00
GOSUB to BASIC 5D4FH, which displays a space and then a carriage return (0DH) through BASIC 5D3FH, so the report starts on a new line.
4D03
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the first character of the command line after REF (00H if nothing follows).
4D04
LD (5D45H),A 32 45 5D
Store Register A (the first character) at 5D45H, BASIC/CMD's printer switch (the operand of its LD A,nn at 5D44H): when it is 24H ($), BASIC 5D3FH prints every character as well as displaying it; BASIC 6430H clears it at the end of the statement.
4D07
OR A B7
OR Register A (the first character after REF) with itself to set the flags: the Z FLAG is set if nothing follows REF.
4D08
If the Z FLAG is set (Register A is 00H: a plain REF), JUMP to 4D21H to list the next line holding the remembered item.
4D0A
CP 40H FE 40
Compare Register A (the first character after REF) against 40H, the character @.
4D0C
If the Z FLAG is set (Register A is @), JUMP to 4D12H to read the line number after it.
4D0E
CP 60H FE 60
Compare Register A (the first character after REF) against 60H, the character the shifted @ key gives, which counts as @ too.
4D10
If the NZ FLAG is set (Register A is neither 40H nor 60H), JUMP to 4D24H to test for a text search.
4D12
GOSUB to ROM 1E5BH, inside LINGET (1E5AH) after its DEC HL: it steps Register Pair HL past the @ and reads the decimal line number into Register Pair DE; Register A returns the character after it.
4D15
OR A B7
OR Register A (the character after the line number) with itself to set the flags: the Z FLAG is set for 00H, the end of the command line.
4D16
If the NZ FLAG is set (something follows the number), JUMP to 4D7FH for SYNTAX ERROR.
4D18
LD A,D 7A
Load Register A with Register D, the high byte of the line number n read by LINGET.
4D19
OR E B3
OR Register A with Register E, the low byte: the Z FLAG is set for line 0.
4D1A
If the Z FLAG is set (Register Pair DE is 0000H), JUMP to 4D1DH without decrementing.
4D1C
DEC DE 1B
Decrement Register Pair DE: n - 1, so that the line search at 4F07H starts at line n itself.
4D1D
LD (4E76H),DE ED 53 76 4E
Self-Modifying Code
Store Register Pair DE (n - 1, or 0) at 4E76H, the operand of LD HL,nnnn at 4E75H: the number of the last line shown, after which the search starts.
4D21
JUMP to 4F07H to find and list the next line holding the remembered item (mode 3).
4D24
CP 22H FE 22
Compare Register A (the first character after REF) against 22H, a quote: a text search.
4D26
If the Z FLAG is set (Register A is a quote), JUMP to 4D2CH to copy the search text.
4D28
CP D5H FE D5
Compare Register A (the first character after REF) against D5H, the token BASIC stores for =: a text search with the rest of the line as typed in token form.
4D2A
If the NZ FLAG is set (Register A is neither a quote nor D5H), JUMP to 4D49H for a name or a number.
4D2C
EX DE,HL EB
Text search: exchange Register Pairs DE and HL, so that Register Pair DE = the command line at the quote or the = token.
4D2D
LD HL,51EFH 21 EF 51
Load Register Pair HL with 51EFH, the search text buffer after the end of the file (51EFH-51FFH).
4D30
LD B,10H 06 10
Load Register B with 10H (16), the number of bytes of the command line to copy.

COPY THE SEARCH TEXT
Register Pair DE = the command line, Register Pair HL = the buffer, Register B = the bytes left. The search text ends at its first 00H; a closing quote, if typed, is part of it.

4D32
INC DE 13
Increment Register Pair DE, the command line pointer, to the next byte after the quote or the = token.
4D33
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a byte of the search text (or the command line's 00H end).
4D34
LD (HL),A 77
Store Register A (the byte of the search text) at Register Pair HL in the buffer.
4D35
INC HL 23
Increment Register Pair HL to the next byte of the buffer.
4D36
Decrement Register B, the bytes left to copy, and LOOP back to 4D32H until 16 bytes are copied.
4D38
LD (HL),B 70
Store Register B (00H after the loop) at Register Pair HL, 51FFH, after the 16 bytes: the search text always ends with a 00H.
4D39
LD HL,3000H 21 00 30
Load Register Pair HL with 3000H: Register L = 00H, a length byte of 0, Register H = 30H, the character 0.
4D3C
LD (51D3H),HL 22 D3 51
Store Register Pair HL at 51D3H: the item compared becomes the one-character number 0 (length byte 51D3H = 00H, character 51D4H = 30H).
4D3F
LD (51D9H),HL 22 D9 51
Store Register Pair HL at 51D9H: the item reported is the same, so 4E89H reports the text with one counter, like a line number.
4D42
LD A,C3H 3E C3
Load Register A with C3H, the opcode of JP nnnn, to turn 4F7CH into a jump.
4D44
LD (4F7CH),A 32 7C 4F
Self-Modifying Code
Store Register A (C3H) at 4F7CH: the LD HL,512FH there becomes JP 512FH, so every byte of the program is compared with the search text instead of being parsed.
4D47
JUMP to 4D9AH to report every line holding the text (mode 2).
4D49
LD B,06H 06 06
A name or a number: load Register B with 06H, one more than the longest item of 5 characters.
4D4B
LD A,21H 3E 21
Load Register A with 21H, the opcode of LD HL,nnnn.
4D4D
LD (4F7CH),A 32 7C 4F
Self-Modifying Code
Store Register A (21H) at 4F7CH, putting back the LD HL,512FH there: no text search.
4D50
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the command line at the first character after REF.
4D51
LD HL,51DAH 21 DA 51
Load Register Pair HL with 51DAH, the characters of the item to report (after its length byte at 51D9H).
4D54
LD C,00H 0E 00
Load Register C with 00H: the item is not preceded by $ or the multiplication sign.
4D56
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the first character after REF.
4D57
CP 24H FE 24
Compare Register A (the first character after REF) against 24H, the character $.
4D59
If the Z FLAG is set (Register A is $: also printed, from 4D04H), JUMP to 4D5FH for a full report.
4D5B
CP CFH FE CF
Compare Register A (the first character after REF) against CFH, the token BASIC stores for the multiplication sign.
4D5D
If the NZ FLAG is set (neither $ nor the multiplication sign), JUMP to 4D68H with Register Pair HL = 51DAH: one item.
4D5F
INC DE 13
Increment Register Pair DE, the command line pointer, past the $ or the multiplication sign token.
4D60
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the character after the $ or the multiplication sign.
4D61
OR A B7
OR Register A (that character) with itself to set the flags: the Z FLAG is set for 00H, the end of the command line.
4D62
If the Z FLAG is set (nothing follows), JUMP to 4DAAH to report every item from the start.
4D64
INC C 0C
Increment Register C to 01H: a full report starting from the item that follows.
4D65
LD HL,51D4H 21 D4 51
Load Register Pair HL with 51D4H, the characters of the item compared (after its length byte at 51D3H): the report starts after it.
4D68
PUSH HL E5
Save Register Pair HL (51DAH, or 51D4H for a full report from an item) on the stack, the buffer for the item's characters.
4D69
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the item's first character.
4D6A
SUB 30H D6 30
Subtract 30H (the character 0) from Register A, the item's first character.
4D6C
CP 0AH FE 0A
Compare Register A (the first character minus 30H) against 0AH: the CARRY FLAG is set for a digit.
4D6E
If the CARRY FLAG is set (the item is a line number), JUMP to 4D76H to copy it.
4D70
SUB 11H D6 11
Subtract 11H more from Register A: the letters A-Z become 00H-19H.
4D72
CP 1AH FE 1A
Compare Register A (the first character minus 41H) against 1AH: the NO CARRY FLAG is set if it is not a letter.
4D74
If the NO CARRY FLAG is set (neither a digit nor a letter), JUMP to 4D7FH for SYNTAX ERROR.

COPY THE ITEM
Register Pair DE = the command line, Register Pair HL = the buffer, Register B counts down from 6.

4D76
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a character of the item (or the command line's 00H end).
4D77
OR A B7
OR Register A (the character) with itself to set the flags: the Z FLAG is set for 00H, the end of the command line.
4D78
INC DE 13
Increment Register Pair DE, the command line pointer (INC DE does not change the flags).
4D79
If the Z FLAG is set (the end of the item), JUMP to 4D82H with Register B = 6 minus the characters copied.
4D7B
LD (HL),A 77
Store Register A (the character) at Register Pair HL in the item buffer.
4D7C
INC HL 23
Increment Register Pair HL to the next place in the item buffer.
4D7D
Decrement Register B, the room left; if it is not 0, LOOP back to 4D76H for the next character.
4D7F
JUMP to ROM 1997H (SNERR, error code 02H) for SYNTAX ERROR: an item of 6 characters or more, a character that is neither a digit nor a letter, something after REF @n, or nothing to look for (4F16H).
4D82
LD A,05H 3E 05
Load Register A with 05H, to work out the item's length byte.
4D84
SUB B 90
Subtract Register B (6 minus the characters copied) from Register A: Register A = the number of characters minus 1, the item's length byte.
4D85
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the byte after the item's characters in the buffer.
4D86
POP HL E1
Restore Register Pair HL from the stack: the item buffer's first character (51DAH or 51D4H), saved at 4D68H.
4D87
BIT 6,(HL) CB 76
Test bit 6 of the byte at Register Pair HL, the item's first character: set for a letter (a name), clear for a digit.
4D89
If the Z FLAG is set (a line number), JUMP to 4D94H to store its length byte.
4D8B
CP 02H FE 02
Compare Register A (the name's length byte) against 02H: a variable name has 1 or 2 characters (length byte 0 or 1).
4D8D
If the NO CARRY FLAG is set (3 or more characters), JUMP to 4D7FH for SYNTAX ERROR.
4D8F
LD A,20H 3E 20
Load Register A with 20H, a space, to pad a one-letter name.
4D91
LD (DE),A 12
Store Register A (a space) at Register Pair DE, after the name's characters: a one-letter name gets a space as its second character, as 5094H gives the names in the text.
4D92
LD A,01H 3E 01
Load Register A with 01H: every name has the length byte 01H (two characters).
4D94
DEC HL 2B
Decrement Register Pair HL to the length byte before the item's characters (51D9H or 51D3H).
4D95
LD (HL),A 77
Store Register A (the item's length byte) at Register Pair HL.
4D96
BIT 0,C CB 41
Test bit 0 of Register C, set at 4D64H for a full report that starts from an item.
4D98
If the NZ FLAG is set (the full report from an item), JUMP to 4DA2H.
4D9A
One item (4D47H enters here for a text search): GOSUB to 5171H, which sets the opcode at 5021H for the kind of item at 51DAH and empties the line list at 4300H.
4D9D
LD A,02H 3E 02
Load Register A with 02H: mode 2, report every line that uses one item.
4D9F
JUMP to 4E2FH to show the item and scan the program in mode 2.
4DA2
LD B,00H 06 00
Load Register B with 00H, the high byte of the count in Register Pair BC.
4DA4
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the length byte at 51D3H. Register Pair BC = the characters minus 1.
4DA5
INC C 0C
Increment Register C: Register Pair BC = the number of characters of the item.
4DA6
ADD HL,BC 09
Add Register Pair BC (the number of characters) to Register Pair HL (51D3H): Register Pair HL = the item's last character.
4DA7
DEC (HL) 35
Decrement the byte at Register Pair HL, the item's last character, so that the item itself is the first one found above it.
4DA8
JUMP to 4DB0H to start the full report after the item at 51D3H.
4DAA
LD HL,0000H 21 00 00
The whole program: load Register Pair HL with 0000H.
4DAD
LD (51D3H),HL 22 D3 51
Store Register Pair HL (0000H) at 51D3H: the item to start after has the length byte 00H and the character 00H, below every line number and name.

4DB0H - The Full Report: the Next Item

Each round of the full report first scans the whole program in mode 0 for the smallest line number or name above the last one reported (51D3H), keeping the addresses of up to 32 lines that use it in the DOS sector buffer at 4300H; then it reports that item in mode 1. Line numbers come before names. Holding BREAK pauses between items (ENTER goes on), the up arrow stops the report.

4DB0
LD BC,FFFFH 01 FF FF
Load Register Pair BC with FFFFH: no item found yet (two FFH characters are above every name).
4DB3
GOSUB to 5168H, which stores Register Pair BC (FFFFH) at 51DAH as the best item's characters, sets its length byte 51D9H to 01H, sets the opcode at 5021H and empties the line list.
4DB6
LD HL,3840H 21 40 38
Load Register Pair HL with 3840H, the keyboard row with ENTER (bit 0), BREAK (bit 2) and the up arrow (bit 3).
4DB9
BIT 3,(HL) CB 5E
Test bit 3 of the byte at Register Pair HL (3840H): the up arrow key; the NZ FLAG is set while it is held.
4DBB
If the NZ FLAG is set (the up arrow is held), JUMP to ROM 002BH, which reads a key through the keyboard control block 4015H and RETURNs to the address on the stack: the dispatcher's 4BC5H and then BASIC 641EH, so REF ends.
4DBE
BIT 2,(HL) CB 56
Test bit 2 of the byte at Register Pair HL (3840H): the BREAK key.
4DC0
If the Z FLAG is set (BREAK is not held), JUMP to 4DCBH to look for the next item.

PAUSE
Register Pair HL = 3840H; the loop waits for ENTER (go on) or the up arrow (stop).

4DC2
BIT 3,(HL) CB 5E
Test bit 3 of the byte at Register Pair HL (3840H): the up arrow key.
4DC4
If the NZ FLAG is set (the up arrow is pressed), JUMP to 4DBBH to stop the report.
4DC7
BIT 0,(HL) CB 46
Test bit 0 of the byte at Register Pair HL (3840H): the ENTER key.
4DC9
If the Z FLAG is set (ENTER is not pressed), LOOP back to 4DC2H.
4DCB
XOR A AF
Load Register A with 00H (XOR A with itself): mode 0, find the next item.
4DCC
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 (4E63H enters here in mode 2).
4DD0
OR A B7
OR Register A (the mode, 0 to 3) with itself to set the flags: the Z FLAG is set for mode 0 (4E70H, 4EEBH, 4F01H and 4F43H enter here with Register Pair DE = the line to start from).
4DD1
LD (4E0CH),A 32 0C 4E
Self-Modifying Code
Store Register A (the mode) at 4E0CH, the operand of LD A,nn at 4E0BH, read at 4E80H, 5013H and 50B2H.
4DD4
LD A,DAH 3E DA
Load Register A with DAH, the opcode of JP C,nnnn. LD does not change the flags.
4DD6
If the Z FLAG is set (mode 0), JUMP to 4DDAH with Register A = DAH.
4DD8
LD A,C2H 3E C2
Modes 1 to 3: load Register A with C2H, the opcode of JP NZ,nnnn.
4DDA
LD (4FFCH),A 32 FC 4F
Self-Modifying Code
Store Register A at 4FFCH, the opcode of the number test: JP C (mode 0) skips the numbers below the last item, JP NZ (modes 1 to 3) skips every number that is not the item.
4DDD
LD (50A9H),A 32 A9 50
Self-Modifying Code
Store Register A at 50A9H, the opcode of the same test for names.
4DE0
LD A,(51D4H) 3A D4 51
Load Register A with the byte at 51D4H, the first character of the item compared (00H at the start of a full report).
4DE3
CP 3AH FE 3A
Compare Register A (that character) against 3AH: the CARRY FLAG is set for a digit or a lower byte, so line numbers are looked at.
4DE5
LD A,30H 3E 30
Load Register A with 30H, the opcode of JR NC, which is never taken at 4FBEH. LD does not change the flags.
4DE7
If the CARRY FLAG is set (the item compared is a number), JUMP to 4DEBH: numbers in the text are compared.
4DE9
LD A,18H 3E 18
Load Register A with 18H, the opcode of JR: numbers in the text are passed (names come after every number).
4DEB
LD (4FBEH),A 32 BE 4F
Self-Modifying Code
Store Register A (30H or 18H) at 4FBEH, the opcode of the number test there.
4DEE
LD A,CAH 3E CA
Load Register A with CAH, the opcode of JP Z,nnnn.
4DF0
LD (4F6DH),A 32 6D 4F
Self-Modifying Code
Store Register A (CAH) at 4F6DH, putting back the JP Z,4DFCH there: no match in the line yet.
4DF3
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H: no FIELD token seen yet.
4DF6
LD (5085H),HL 22 85 50
Self-Modifying Code
Store Register Pair HL (0000H) at 5085H, the operand of LD DE,nnnn at 5084H, the position of the last FIELD token.
4DF9
JUMP to 4F6BH to scan the program from the line whose link field Register Pair DE points at.

4DFCH - At the Next Line

Reached through the JP at 4F6DH with Register Pair DE at the link field of the next line: always when the line just scanned had a match (4F6DH was made JP), otherwise only when the link's low byte is 00H. A line with a match is reported (4E80H); the end marker ends the scan.

4DFC
LD A,(4F6DH) 3A 6D 4F
Load Register A with the byte at 4F6DH, the opcode of the jump that brought the scan here (CAH, or C3H after a match).
4DFF
CP C3H FE C3
Compare Register A (that opcode) against C3H: the Z FLAG is set if a match in the line just scanned made it JP.
4E01
If the Z FLAG is set (the line had a match), JUMP to 4E80H to report it.
4E04
INC DE 13
Increment Register Pair DE to the high byte of the next line's link field.
4E05
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the high byte of the link.
4E06
OR A B7
OR Register A (the link's high byte) with itself: the Z FLAG is set for 00H, which with the low byte 00H is the end marker.
4E07
DEC DE 1B
Decrement Register Pair DE back to the link's low byte (DEC DE does not change the flags).
4E08
If the NZ FLAG is set (another line), JUMP to 4F70H to scan it.
4E0B
LD A,00H 3E 00
Self-Modifying Code
The end of the program: load Register A with the mode, the operand 4E0CH (00H in the file; stored at 4DD1H).
4E0D
OR A B7
OR Register A (the mode) with itself to set the flags: the Z FLAG is set for mode 0.
4E0E
If the Z FLAG is set (mode 0, the search for the next item is done), JUMP to 4E28H.
4E10
PUSH AF F5
Save Register Pair AF (Register A = the mode, 1 to 3) on the stack.
4E11
GOSUB to BASIC 5D52H, which displays a carriage return (0DH) to end the output line.
4E14
LD HL,FFFFH 21 FF FF
Load Register Pair HL with FFFFH, the value that makes a later plain REF start at the first line.
4E17
LD (4E76H),HL 22 76 4E
Self-Modifying Code
Store Register Pair HL (FFFFH) at 4E76H, the operand of LD HL,nnnn at 4E75H: the number of the last line shown.
4E1A
POP AF F1
Restore Register Pair AF from the stack: Register A = the mode.
4E1B
DEC A 3D
Decrement Register A, the mode: the Z FLAG is set for mode 1.
4E1C
If the Z FLAG is set (mode 1, the full report), LOOP back to 4DB0H for the next item.
4E1E
DEC A 3D
Decrement Register A again: the Z FLAG is set for mode 2.
4E1F
RET Z C8
If the Z FLAG is set (mode 2, one item), RETURN through the dispatcher's 4BC5H to BASIC 641EH: REF is done.
4E20
LD B,09H 06 09
Mode 3 with no further line (4F2BH also jumps here): load Register B with 09H, the length of the message Text End and its carriage return.
4E22
LD HL,51B6H 21 B6 51
Load Register Pair HL with 51B6H, the message Text End.
4E25
JUMP to BASIC 5D70H, which displays Register B characters from Register Pair HL through 5D3FH; its RET ends REF.
4E28
LD A,(51DAH) 3A DA 51
The end of a mode 0 scan: load Register A with the byte at 51DAH, the best item's first character (FFH if none was found).
4E2B
INC A 3C
Increment Register A: the Z FLAG is set if it was FFH.
4E2C
RET Z C8
If the Z FLAG is set (no item is left above the last one), RETURN through 4BC5H to BASIC 641EH: the full report is complete.
4E2D
LD A,01H 3E 01
Load Register A with 01H: mode 1, report the item found.
4E2F
PUSH AF F5
Save Register Pair AF (Register A = the mode, 1 or 2; 4D9FH enters here) on the stack.
4E30
LD HL,51D9H 21 D9 51
Load Register Pair HL with 51D9H, the length byte of the item to report.
4E33
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the item's length byte (its characters minus 1).
4E34
INC C 0C
Increment Register C: the number of characters of the item.
4E35
LD A,(4F7CH) 3A 7C 4F
Load Register A with the byte at 4F7CH, the opcode there (C3H during a text search, else 21H).
4E38
CP C3H FE C3
Compare Register A (that opcode) against C3H: the Z FLAG is set for a text search.
4E3A
LD A,06H 3E 06
Load Register A with 06H, the spaces shown in place of a name. LD does not change the flags.
4E3C
If the Z FLAG is set (a text search), JUMP to 4E53H: no item is shown.
4E3E
PUSH HL E5
Save Register Pair HL (51D9H, the length byte) on the stack.
4E3F
INC HL 23
Increment Register Pair HL to 51DAH, the item's first character.
4E40
LD A,05H 3E 05
Load Register A with 05H, the width of the item's column.
4E42
SUB C 91
Subtract Register C (the item's characters) from Register A: the spaces needed to right-align the item; the Z FLAG is set for none.
4E43
If the NZ FLAG is set (spaces are needed), GOSUB to BASIC 5D30H, which displays Register A spaces.
4E46
LD B,C 41
Load Register B with Register C, the item's number of characters.
4E47
GOSUB to BASIC 5D70H, which displays Register B characters from Register Pair HL (51DAH): the item; Register B returns 00H.
4E4A
POP HL E1
Restore Register Pair HL from the stack: 51D9H, the reported item's length byte.
4E4B
LD DE,51D3H 11 D3 51
Load Register Pair DE with 51D3H, the item compared.
4E4E
INC C 0C
Increment Register C: the item's characters plus its length byte.
4E4F
LDIR ED B0
Copy Register Pair BC bytes (Register B is 00H after 5D70H) from Register Pair HL (51D9H) to Register Pair DE (51D3H): the reported item becomes the item compared, so the next round looks above it and the scan matches it.
4E51
LD A,01H 3E 01
Load Register A with 01H, one space after the item.
4E53
GOSUB to BASIC 5D30H, which displays Register A spaces (1 after the item, or 6 for a text search).
4E56
LD HL,51E5H 21 E5 51
Load Register Pair HL with 51E5H, the ten counters of uses in a line.
4E59
LD B,0AH 06 0A
Load Register B with 0AH (10), the number of counters to clear.
4E5B
LD (HL),00H 36 00
Store 00H at Register Pair HL, clearing a counter.
4E5D
INC HL 23
Increment Register Pair HL to the next counter.
4E5E
Decrement Register B, the counters left, and LOOP back to 4E5BH until all ten are cleared.
4E60
POP AF F1
Restore Register Pair AF from the stack: Register A = the mode, 1 or 2.
4E61
CP 01H FE 01
Compare Register A (the mode) against 01H: the Z FLAG is set for mode 1.
4E63
If the NZ FLAG is set (mode 2), JUMP to 4DCCH to scan the whole program from the first line.
4E66
LD HL,4300H 21 00 43
Mode 1: load Register Pair HL with 4300H, the list of the line addresses found in mode 0.
4E69
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of a listed line's address (4EF8H loops back here).
4E6A
INC HL 23
Increment Register Pair HL to the high byte of the listed line's address.
4E6B
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the line to scan.
4E6C
INC HL 23
Increment Register Pair HL to the next entry of the list.
4E6D
LD (4EF2H),HL 22 F2 4E
Self-Modifying Code
Store Register Pair HL (the next entry) at 4EF2H, the operand of LD HL,nnnn at 4EF1H.
4E70
JUMP to 4DD0H to scan from the line at Register Pair DE with Register A = 01H, mode 1.
4E73
POP AF F1
Mode 3, a line found (from 4E85H): restore Register Pair AF from the stack, discarding the dispatcher's return address 4BC5H.
4E74
POP AF F1
Restore Register Pair AF from the stack, discarding BASIC's 641EH as well, so that the two words pushed next are the ones LIST4 takes.
4E75
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the number of the line found, the operand 4E76H (0000H in the file; stored at 50E7H, and at 4D1DH and 4E17H).
4E78
PUSH HL E5
Push Register Pair HL (the line's number) on the stack: the last line to list, taken by LIST4's POP DE.
4E79
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the address of the line found, the operand 4E7AH (0000H in the file; stored at 4F70H for each line).
4E7C
PUSH HL E5
Push Register Pair HL (the line's address) on the stack: the first line to list, taken by LIST4's POP HL.
4E7D
JUMP to ROM 2B33H (LIST4, inside LIST), which sets 40A2H to FFFFH, takes the line's address and number from the stack and lists that one line, then goes to the ROM's command level.

4E80H - Report a Line

Reached from 4E01H with Register Pair DE at the next line's link field, after a line with a match. In mode 3 the line is listed. Otherwise the line's number (4E76H) is shown once for every form of use counted in it (51E5H-51EEH): the name alone, with $ % ! # (the type characters at 51B2H-51B5H), and each of these as an array (followed by an opening parenthesis), with the count when it is more than one. A line number or a text search has only the first counter.

4E80
LD A,(4E0CH) 3A 0C 4E
Load Register A with the byte at 4E0CH, the mode (the operand of LD A,nn at 4E0BH).
4E83
CP 03H FE 03
Compare Register A (the mode) against 03H: the Z FLAG is set for mode 3, a plain REF or REF @n.
4E85
If the Z FLAG is set (mode 3), JUMP to 4E73H to list the line.
4E87
PUSH AF F5
Save Register Pair AF (Register A = the mode, 1 or 2) on the stack.
4E88
PUSH DE D5
Save Register Pair DE (the next line's link field, where the scan goes on) on the stack.
4E89
LD A,(51DAH) 3A DA 51
Load Register A with the byte at 51DAH, the first character of the reported item.
4E8C
LD BC,0100H 01 00 01
Load Register Pair BC with 0100H: Register B = 1, the number of counters to show, Register C = 0, the first counter's number.
4E8F
CP 41H FE 41
Compare Register A (the item's first character) against 41H: the NO CARRY FLAG is set for a letter (a name).
4E91
If the CARRY FLAG is set (a line number, or the 30H of a text search), JUMP to 4E95H with one counter.
4E93
LD B,0AH 06 0A
Load Register B with 0AH (10): a name has ten counters.
4E95
LD HL,51E5H 21 E5 51
Load Register Pair HL with 51E5H, the first counter.

COUNTER LOOP
Register Pair HL = the counter, Register C = its number (0-9), Register B = the counters left.

4E98
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the counter: how often the item was used in this form in the line.
4E99
OR A B7
OR Register A (the count) with itself to set the flags: the Z FLAG is set if the item was not used in this form.
4E9A
If the Z FLAG is set (a count of 0), JUMP to 4EE3H for the next counter.
4E9C
LD (4ED9H),A 32 D9 4E
Self-Modifying Code
Store Register A (the count) at 4ED9H, the low byte of the operand of LD DE,nnnn at 4ED8H.
4E9F
LD (HL),00H 36 00
Store 00H at Register Pair HL, clearing the counter for the next line.
4EA1
PUSH HL E5
Save Register Pair HL (the counter's address) on the stack.
4EA2
PUSH BC C5
Save Register Pair BC (Register B = the counters left, Register C = the counter's number) on the stack.
4EA3
GOSUB to 519EH, which displays a space and, near the right edge, starts a new line indented to column 7.
4EA6
LD DE,(4E76H) ED 5B 76 4E
Load Register Pair DE with the 16-bit value at 4E76H, the line's number (the operand of LD HL,nnnn at 4E75H, stored at 50E7H).
4EAA
GOSUB to BASIC 5D67H, which displays Register Pair DE (the line's number) in decimal through 5D3FH.
4EAD
POP BC C1
Restore Register Pair BC from the stack: Register C = the counter's number, Register B = the counters left.
4EAE
LD A,C 79
Load Register A with Register C, the counter's number.
4EAF
OR A B7
OR Register A (the counter's number) with itself to set the flags: the Z FLAG is set for counter 0, the plain use.
4EB0
PUSH BC C5
Save Register Pair BC on the stack again for 4EE1H (PUSH does not change the flags).
4EB1
If the NZ FLAG is set (counters 1 to 9), JUMP to 4EBBH to show the form.
4EB3
LD A,(4ED9H) 3A D9 4E
Counter 0: load Register A with the byte at 4ED9H, the count stored at 4E9CH.
4EB6
CP 02H FE 02
Compare Register A (the count) against 02H: the CARRY FLAG is set if the item was used once.
4EB8
If the CARRY FLAG is set (used once), JUMP to 4EE1H: the line number alone says it.
4EBA
LD A,C 79
Load Register A with Register C (00H), the counter's number.
4EBB
CP 05H FE 05
Compare Register A (the counter's number) against 05H: the NO CARRY FLAG is set for the array counters 5 to 9.
4EBD
LD A,2FH 3E 2F
Load Register A with 2FH, a slash, the mark of a use that is not an array. LD does not change the flags.
4EBF
If the CARRY FLAG is set (counters 0 to 4), JUMP to 4EC7H with the slash in Register A and the type number in Register C.
4EC1
LD A,C 79
Load Register A with Register C, the counter's number (5 to 9).
4EC2
SUB 05H D6 05
Subtract 05H from Register A: the type number (0 none, 1 $, 2 %, 3 !, 4 #).
4EC4
LD C,A 4F
Load Register C with Register A, the type number.
4EC5
LD A,28H 3E 28
Load Register A with 28H, an opening parenthesis, the mark of an array use.
4EC7
GOSUB to BASIC 5D3FH, which displays the character in Register A (the slash or the parenthesis).
4ECA
LD A,C 79
Load Register A with Register C, the type number (0 to 4).
4ECB
OR A B7
OR Register A (the type number) with itself to set the flags: the Z FLAG is set when there is no type character.
4ECC
If the Z FLAG is set (no type character), JUMP to 4ED8H.
4ECE
LD B,00H 06 00
Load Register B with 00H, so that Register Pair BC = the type number.
4ED0
LD HL,51B1H 21 B1 51
Load Register Pair HL with 51B1H, one byte before the type characters $ % ! # at 51B2H-51B5H.
4ED3
ADD HL,BC 09
Add Register Pair BC (the type number 1 to 4) to Register Pair HL: Register Pair HL = the address of the type character.
4ED4
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the type character.
4ED5
GOSUB to BASIC 5D3FH, which displays the type character in Register A.
4ED8
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the count, the operand 4ED9H (0000H in the file; its low byte stored at 4E9CH, its high byte stays 00H).
4EDB
LD A,E 7B
Load Register A with Register E, the count of uses in this form.
4EDC
CP 02H FE 02
Compare Register A (the count) against 02H: the NO CARRY FLAG is set for 2 or more.
4EDE
If the NO CARRY FLAG is set (used more than once), GOSUB to BASIC 5D67H, which displays the count in Register Pair DE in decimal.
4EE1
POP BC C1
Restore Register Pair BC from the stack: Register B = the counters left, Register C = the counter's number.
4EE2
POP HL E1
Restore Register Pair HL from the stack: the counter's address.
4EE3
INC HL 23
Increment Register Pair HL to the next counter.
4EE4
INC C 0C
Increment Register C, the next counter's number.
4EE5
Decrement Register B, the counters left, and LOOP back to 4E98H until they are all shown.
4EE7
POP DE D1
Restore Register Pair DE from the stack: the next line's link field, saved at 4E88H.
4EE8
POP AF F1
Restore Register Pair AF from the stack: Register A = the mode, saved at 4E87H.
4EE9
CP 01H FE 01
Compare Register A (the mode) against 01H: the Z FLAG is set for mode 1.
4EEB
If the NZ FLAG is set (mode 2), JUMP to 4DD0H to go on with the line at Register Pair DE.
4EEE
LD BC,0000H 01 00 00
Self-Modifying Code
Mode 1: load Register Pair BC with the end of the line list, the operand 4EEFH (0000H in the file; stored at 512AH and 5182H).
4EF1
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the next entry of the line list, the operand 4EF2H (0000H in the file; stored at 4E6DH and 5185H).
4EF4
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 4EF5H.
4EF5
SBC HL,BC ED 42
Subtract Register Pair BC (the list's end) from Register Pair HL (the next entry): the Z FLAG is set when the list is used up.
4EF7
ADD HL,BC 09
Add Register Pair BC back: Register Pair HL = the next entry again (ADD HL,BC does not change the Z FLAG).
4EF8
If the NZ FLAG is set (lines left in the list), JUMP to 4E69H to scan the next one.
4EFB
LD BC,4340H 01 40 43
Load Register Pair BC with 4340H, the end of a full list (32 line addresses from 4300H).
4EFE
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 4EFFH.
4EFF
SBC HL,BC ED 42
Subtract Register Pair BC (4340H) from Register Pair HL (the list's end): the Z FLAG is set if the list was full, so more lines may follow.
4F01
If the Z FLAG is set (the list was full), JUMP to 4DD0H with Register A = 01H to scan the rest of the program from the line at Register Pair DE.
4F04
JUMP to 4E0BH: every line of this item is reported, and the mode in 4E0CH decides what follows.

4F07H - Plain REF and REF @n

Finds the first line after the last one shown (4E76H; FFFFH = from the first line, n - 1 after REF @n) and scans from there in mode 3 for the remembered item (or the search text), listing the first line that holds it.

4F07
LD A,(4F7CH) 3A 7C 4F
Load Register A with the byte at 4F7CH, the opcode there (C3H after a text search, else 21H).
4F0A
CP C3H FE C3
Compare Register A (that opcode) against C3H: the Z FLAG is set for a text search.
4F0C
LD A,(51DAH) 3A DA 51
Load Register A with the byte at 51DAH, the remembered item's first character (FFH after a full report). LD does not change the flags.
4F0F
If the NZ FLAG is set (not a text search), JUMP to 4F15H to test Register A.
4F11
LD A,(51EFH) 3A EF 51
A text search: load Register A with the byte at 51EFH, the first byte of the search text.
4F14
DEC A 3D
Decrement Register A, so that the INC at 4F15H gives the Z FLAG for a search text that starts with 00H.
4F15
INC A 3C
Increment Register A: the Z FLAG is set if the remembered item's first character is FFH, or if the search text is empty.
4F16
If the Z FLAG is set (nothing to look for), JUMP to ROM 1997H for SYNTAX ERROR.
4F19
LD BC,(4E76H) ED 4B 76 4E
Load Register Pair BC with the 16-bit value at 4E76H, the number of the last line shown (the operand of LD HL,nnnn at 4E75H).
4F1D
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.
4F21
LD A,B 78
Load Register A with Register B, the high byte of the last line shown.
4F22
AND C A1
AND Register A with Register C, the low byte: FFH only for FFFFH.
4F23
INC A 3C
Increment Register A: the Z FLAG is set for FFFFH, start at the first line.
4F24
If the Z FLAG is set, JUMP to 4F41H with Register Pair DE = the first line.
4F26
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the line to test (the first line).

FIND THE LINE AFTER THE LAST ONE SHOWN
Register Pair HL = the line, Register Pair BC = the number of the last line shown.

4F27
PUSH HL E5
Save Register Pair HL (the line's address) on the stack.
4F28
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the low byte of the line's link field.
4F29
INC HL 23
Increment Register Pair HL to the high byte of the line's link field.
4F2A
OR (HL) B6
OR Register A (the link's low byte) with the byte at Register Pair HL: the Z FLAG is set at the end marker.
4F2B
If the Z FLAG is set (no line after the last one shown), JUMP to 4E20H for the message Text End. The line's address pushed at 4F27H is still on the stack, so the RET of BASIC 5D70H goes to that address (the program's end marker) instead of to the dispatcher's 4BC5H.
4F2E
INC HL 23
Increment Register Pair HL to the low byte of the line's number.
4F2F
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the low byte of the line's number.
4F30
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
4F31
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the line's number.
4F32
INC HL 23
Increment Register Pair HL to the line's text.
4F33
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a byte of the line's text.
4F34
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set for the line's 00H end; the CARRY FLAG is cleared.
4F35
INC HL 23
Increment Register Pair HL (INC HL does not change the flags).
4F36
If the NZ FLAG is set (not the end), LOOP back to 4F33H: Register Pair HL ends at the next line.
4F38
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the line's number, Register Pair DE = the next line.
4F39
SBC HL,BC ED 42
Subtract Register Pair BC (the last line shown) and the CARRY FLAG (clear from 4F34H) from Register Pair HL (this line's number): the Z FLAG is set if equal, the CARRY FLAG if this line comes before.
4F3B
POP HL E1
Restore Register Pair HL from the stack: this line's address. POP does not change the flags.
4F3C
If the Z FLAG is set (this is the last line shown), JUMP to 4F41H with Register Pair DE = the line after it.
4F3E
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = this line, Register Pair HL = the next line (EX does not change the flags).
4F3F
If the CARRY FLAG is set (this line comes before the last one shown), LOOP back to 4F27H with Register Pair HL = the next line.
4F41
LD A,03H 3E 03
Load Register A with 03H: mode 3, find and list one line (Register Pair DE = the line to start at).
4F43
JUMP to 4DD0H to scan from the line at Register Pair DE in mode 3.

4F46H - Scan the Text

Register Pair DE walks through the program's text. Strings, REM and ' remarks, DATA, constants after & and decimal fractions are passed; line numbers (strings of digits) and variable names are collected and compared with the item. A match counts in the counters 51E5H-51EEH and turns the JP Z,4DFCH at 4F6DH into JP 4DFCH, so that the line is reported when the scan reaches the next line. During a text search the JP 512FH at 4F7CH compares every byte with the search text instead.

4F46
LD BC,4F77H 01 77 4F
A quote: load Register Pair BC with 4F77H, the scan's next-byte entry.
4F49
PUSH BC C5
Push Register Pair BC (4F77H) on the stack as the return address for the RET Z at 4F4EH.
4F4A
LD B,A 47
Load Register B with Register A, the quote 22H that ends the string (4F60H also calls here for a quoted DATA item).

PASS A STRING
Register Pair DE steps through the string; Register B = the closing quote.

4F4B
INC DE 13
Increment Register Pair DE to the next byte of the line.
4F4C
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a byte of the string.
4F4D
CP B B8
Compare Register A (the byte) with Register B, the closing quote.
4F4E
RET Z C8
If the Z FLAG is set (the string ends), RETURN to 4F77H (pushed at 4F49H) or, for a DATA item, to 4F63H after the CALL Z at 4F60H.
4F4F
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set for the line's 00H end.
4F50
If the NZ FLAG is set (Register A is not 00H: more of the string), LOOP back to 4F4BH.
4F52
POP AF F1
The line ended inside the string: restore Register Pair AF from the stack, discarding the return address (4F77H or 4F63H).
4F53
JUMP to 4F6AH with Register Pair DE at the line's 00H end, to go on with the next line.

PASS DATA
DATA (88H): Register Pair DE steps through the statement to its colon or the line's end.

4F55
INC DE 13
Increment Register Pair DE to the next byte of the DATA statement.
4F56
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a byte of the DATA statement.
4F57
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set for the line's 00H end.
4F58
If the Z FLAG is set (the line ends), JUMP to 4F6AH for the next line.
4F5A
CP 3AH FE 3A
Compare Register A (the byte) against 3AH, a colon, the end of the statement.
4F5C
If the Z FLAG is set (a colon), JUMP to 4F77H to go on with the next statement.
4F5E
CP 22H FE 22
Compare Register A (the byte of the DATA statement) against 22H, a quote.
4F60
If the Z FLAG is set (a quoted DATA item), GOSUB to 4F4AH to pass the string up to its closing quote.
4F63
LOOP back to 4F55H for the next byte of the DATA statement.

PASS A REMARK
REM (93H) or ' (FBH): Register Pair DE steps to the line's 00H end.

4F65
INC DE 13
Increment Register Pair DE to the next byte of the remark.
4F66
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a byte of the remark.
4F67
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set for the line's 00H end.
4F68
If the NZ FLAG is set (not the end), LOOP back to 4F65H.
4F6A
INC DE 13
Increment Register Pair DE past the line's 00H end to the low byte of the next line's link field.
4F6B
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the low byte of the next line's link field (4DF9H enters here with Register Pair DE at the line to start from).
4F6C
OR A B7
OR Register A (the link's low byte) with itself to set the flags: the Z FLAG is set if it is 00H.
4F6D
Self-Modifying Code
If the Z FLAG is set (the link's low byte is 00H, which may be the end marker), JUMP to 4DFCH. The opcode at 4F6DH is CAH (JP Z, stored at 4DF0H) or, after a match in the line just scanned, C3H (JP, stored at 50DDH): then every next line goes to 4DFCH, which reports the line.
4F70
LD (4E7AH),DE ED 53 7A 4E
Self-Modifying Code
Store Register Pair DE (the address of the line about to be scanned; 4E08H enters here) at 4E7AH, the operand of LD HL,nnnn at 4E79H, read at 5087H, 50DFH and 5114H.
4F74
INC DE 13
Increment Register Pair DE, 1 of 3, from the link's low byte towards the line's text.
4F75
INC DE 13
Increment Register Pair DE, 2 of 3, to the low byte of the line's number.
4F76
INC DE 13
Increment Register Pair DE, 3 of 3, to the high byte of the line's number; 4F77H steps to the first byte of the text.

BYTE LOOP
Register Pair DE = the byte of the line being looked at, in Register A.

4F77
INC DE 13
Increment Register Pair DE to the next byte of the line.
4F78
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the byte to look at (several routines come back here with Register A and Register Pair DE already set).
4F79
OR A B7
OR Register A (the byte) with itself to set the flags: the Z FLAG is set for the line's 00H end.
4F7A
If the Z FLAG is set (the line ends), JUMP to 4F6AH for the next line.
4F7C
LD HL,512FH 21 2F 51
Self-Modifying Code
Load Register Pair HL with 512FH, which nothing here uses; the opcode at 4F7CH is 21H (LD HL, stored at 4D4DH) or, during a text search, C3H (stored at 4D44H): JP 512FH, which compares the byte with the search text.
4F7F
CP 41H FE 41
Compare Register A (the byte) against 41H: the NO CARRY FLAG is set for a letter or a token.
4F81
If the NO CARRY FLAG is set (41H or above), JUMP to 4F9BH.
4F83
CP 30H FE 30
Compare Register A (the byte) against 30H: the NO CARRY FLAG is set for a digit or 3AH-40H.
4F85
If the NO CARRY FLAG is set (30H-40H), JUMP to 4FBAH.
4F87
CP 20H FE 20
Compare Register A (the byte, below 30H) against 20H, a space.
4F89
If the Z FLAG is set (a space), JUMP to 4F77H for the next byte.
4F8B
CP 22H FE 22
Compare Register A (the byte) against 22H, a quote.
4F8D
If the Z FLAG is set (a quote), JUMP to 4F46H to pass the string.
4F8F
CP 26H FE 26
Compare Register A (the byte) against 26H, the character & that starts a hexadecimal or octal constant.
4F91
If the Z FLAG is set (&), JUMP to 504BH to pass the constant.
4F94
CP 2EH FE 2E
Compare Register A (the byte) against 2EH, a period: a number such as .5 is no line number.
4F96
If the Z FLAG is set (a period), JUMP to 4FE1H to pass its digits.
4F99
Any other byte below 30H: JUMP to 4F77H for the next byte.
4F9B
LD C,A 4F
Load Register C with Register A, the letter or token, as a name's first character. LD does not change the flags (the Z FLAG is from CP 41H).
4F9C
If the Z FLAG is set (the letter A), JUMP to 5073H: it may be the AS of a FIELD statement.
4F9F
CP 5BH FE 5B
Compare Register A (the letter or token) against 5BH: the CARRY FLAG is set for a letter B-Z.
4FA1
If the CARRY FLAG is set (a letter B-Z), JUMP to 5091H: a name.
4FA4
CP 93H FE 93
Compare Register A (the token) against 93H, the REM token.
4FA6
If the Z FLAG is set (REM), JUMP to 4F65H to pass the remark.
4FA8
CP FBH FE FB
Compare Register A (the token) against FBH, the token BASIC stores for the ' remark.
4FAA
If the Z FLAG is set (a ' remark), JUMP to 4F65H to pass the remark.
4FAC
CP 88H FE 88
Compare Register A (the token) against 88H, the DATA token.
4FAE
If the Z FLAG is set (DATA), JUMP to 4F55H to pass the DATA statement.
4FB0
CP A3H FE A3
Compare Register A (the token) against A3H, the FIELD token.
4FB2
If the NZ FLAG is set (another token or a byte above 5AH), JUMP to 4F77H for the next byte.
4FB4
LD (5085H),DE ED 53 85 50
Self-Modifying Code
Store Register Pair DE (the address of the FIELD token) at 5085H, the operand of LD DE,nnnn at 5084H, so that FIELD ... AS name counts the name and not AS.
4FB8
JUMP to 4F77H for the next byte after the FIELD token.
4FBA
CP 3AH FE 3A
Compare Register A (the byte, 30H-40H) against 3AH: the NO CARRY FLAG is set for 3AH-40H (not a digit).
4FBC
If the NO CARRY FLAG is set (not a digit), JUMP to 4F77H for the next byte.
4FBE
Self-Modifying Code
A digit (the CARRY FLAG is set from 4FBAH): JR NC,4FE1H is never taken. The opcode at 4FBEH is 30H (JR NC, stored at 4DEBH when the item compared is a number) or 18H (JR, when it is a name): then every number is passed at 4FE1H.
4FC0
LD HL,51DFH 21 DF 51
Load Register Pair HL with 51DFH, the buffer for the number found in the text (51DFH-51E4H).
4FC3
LD B,06H 06 06
Load Register B with 06H, one more than the most digits a line number has.
4FC5
CP 30H FE 30
Compare Register A (the first digit) against 30H, the digit 0.
4FC7
If the NZ FLAG is set (not a leading 0), JUMP to 4FD9H to store the digit.
4FC9
LD (HL),A 77
Store Register A (30H, the digit 0) at Register Pair HL (51DFH), the buffer's first digit; Register Pair HL is not moved, so a digit that follows replaces it.
4FCA
GOSUB to 514BH, which steps Register Pair DE to the next byte that is not a space, 09H or 0AH and returns it in Register A.
4FCD
CP 30H FE 30
Compare Register A (the next byte) against 30H, another 0.
4FCF
If the Z FLAG is set (another 0), LOOP back to 4FCAH: leading zeros are dropped, a lone 0 stays.

COLLECT THE DIGITS
Register Pair HL = the buffer, Register B counts down the room left, Register A = the byte.

4FD1
CP 30H FE 30
Compare Register A (the byte) against 30H: the CARRY FLAG is set below the digit 0.
4FD3
If the CARRY FLAG is set (the number ends), JUMP to 4FEEH to test for a period.
4FD5
CP 3AH FE 3A
Compare Register A (the byte) against 3AH: the NO CARRY FLAG is set above the digit 9.
4FD7
If the NO CARRY FLAG is set (the number ends), JUMP to 4FF2H.
4FD9
LD (HL),A 77
Store Register A (the digit) at Register Pair HL in the number buffer.
4FDA
INC HL 23
Increment Register Pair HL to the next place in the number buffer.
4FDB
GOSUB to 514BH for the next byte that is not a blank, in Register A, with Register Pair DE at it.
4FDE
Decrement Register B, the room left; if it is not 0, LOOP back to 4FD1H.
4FE0
DEC DE 1B
Six digits stored, too many for a line number: decrement Register Pair DE so that 4FE1H reads the byte after the sixth digit again, and pass the rest of the number.

PASS DIGITS
Register Pair DE steps over the digits that follow.

4FE1
GOSUB to 514BH for the next byte that is not a blank, in Register A, with Register Pair DE at it.
4FE4
CP 3AH FE 3A
Compare Register A (the byte) against 3AH: the NO CARRY FLAG is set above the digit 9.
4FE6
If the NO CARRY FLAG is set (above 9), JUMP to 4FECH.
4FE8
CP 30H FE 30
Compare Register A (the byte) against 30H: the NO CARRY FLAG is set for a digit.
4FEA
If the NO CARRY FLAG is set (a digit), LOOP back to 4FE1H.
4FEC
JUMP to 4F78H to look at the byte in Register A (Register Pair DE at it).
4FEE
CP 2EH FE 2E
Compare Register A (the byte after the digits) against 2EH, a period: the number has a fraction, so it is no line number.
4FF0
If the Z FLAG is set (a period), JUMP to 4FE1H to pass the fraction's digits.
4FF2
LD A,05H 3E 05
Load Register A with 05H, to work out the number's length byte.
4FF4
SUB B 90
Subtract Register B (the room left: 6 minus the digits stored) from Register A: the digits minus 1; for a lone 0 Register B is still 6 and the result is FFH with the CARRY FLAG.
4FF5
ADC A,00H CE 00
Add 00H and the CARRY FLAG to Register A: the length byte of the number found (00H for a lone 0).
4FF7
LD C,A 4F
Load Register C with Register A, the length byte of the number found.
4FF8
LD HL,(51D3H) 2A D3 51
Load Register Pair HL with the 16-bit value at 51D3H: Register L = the length byte of the item compared, Register H = its first character.
4FFB
CP L BD
Compare Register A (the length byte of the number found) with Register L: the CARRY FLAG is set if the number found is shorter, the Z FLAG if they have the same length.
4FFC
Self-Modifying Code
JUMP to 4F78H (pass this number) under the condition stored at 4DDAH: JP C (DAH, mode 0: a shorter number is smaller than the item compared) or JP NZ (C2H, modes 1 to 3: a number of another length is another number). 5005H and 500EH come back here with new flags.
4FFF
If the NZ FLAG is set (mode 0 and the number is larger), JUMP to 501CH to compare it with the best so far.
5001
LD A,(51DFH) 3A DF 51
The same length: load Register A with the byte at 51DFH, the first digit of the number found.
5004
CP H BC
Compare Register A (the first digit found) with Register H, the first digit of the item compared (from 51D4H).
5005
If the NZ FLAG is set (they differ), JUMP to 4FFCH to decide with the flags of this compare.
5007
LD IY,51D5H FD 21 D5 51
Load Index Register IY with 51D5H, the rest of the item compared's digits.
500B
GOSUB to 5189H, which compares Register C digits from 51E0H (the rest of the number found) with those at Index Register IY: the Z FLAG is set if they are all equal.
500E
If the NZ FLAG is set (they differ), JUMP to 4FFCH to decide with the flags of the compare.
5010
LD HL,51E5H 21 E5 51
The same number: load Register Pair HL with 51E5H, the first counter.
5013
LD A,(4E0CH) 3A 0C 4E
Load Register A with the byte at 4E0CH, the mode (the operand of LD A,nn at 4E0BH).
5016
OR A B7
OR Register A (the mode) with itself to set the flags: the Z FLAG is set for mode 0.
5017
If the NZ FLAG is set (modes 1 to 3), JUMP to 50D9H to count the use in the counter at Register Pair HL.
501A
Mode 0: JUMP to 4FECH, passing the number; only numbers above the last item matter.
501C
LD HL,(51D9H) 2A D9 51
Mode 0, a number above the last item: load Register Pair HL with the 16-bit value at 51D9H: Register L = the best item's length byte, Register H = its first character.
501F
LD A,C 79
Load Register A with Register C, the length byte of the number found.
5020
CP L BD
Compare Register A (the length byte found) with Register L (the best's): the CARRY FLAG is set if the number found is shorter, the Z FLAG if equal.
5021
Self-Modifying Code
The opcode at 5021H (stored at 517CH) is 38H, JR C,5037H, when the best item so far is a number (a smaller number becomes the new best), or 18H, JR 5037H, when the best is a name or none (FFFFH): any number comes before every name. 502AH and 5033H come back here with new flags.
5023
If the NZ FLAG is set (the number found is longer, so larger than the best), JUMP to 4F78H to pass it.
5026
LD A,(51DFH) 3A DF 51
The same length: load Register A with the byte at 51DFH, the first digit of the number found.
5029
CP H BC
Compare Register A (the first digit found) with Register H, the best item's first digit (from 51DAH).
502A
If the NZ FLAG is set (they differ), JUMP to 5021H to decide with the flags of this compare.
502C
LD IY,51DBH FD 21 DB 51
Load Index Register IY with 51DBH, the rest of the best item's digits.
5030
GOSUB to 5189H, which compares Register C digits from 51E0H with those at Index Register IY: the Z FLAG is set if equal.
5033
If the NZ FLAG is set (they differ), JUMP to 5021H to decide with the flags of the compare.
5035
The same number as the best: JUMP to 5048H to add this line to the list.
5037
LD A,C 79
A new best number: load Register A with Register C, its length byte.
5038
INC C 0C
Increment Register C: the number of digits to copy.
5039
PUSH DE D5
Save Register Pair DE (the text pointer) on the stack.
503A
LD HL,51DFH 21 DF 51
Load Register Pair HL with 51DFH, the digits found.
503D
LD DE,51DAH 11 DA 51
Load Register Pair DE with 51DAH, the best item's characters.
5040
LD B,00H 06 00
Load Register B with 00H, so that Register Pair BC = the number of digits.
5042
LDIR ED B0
Copy Register Pair BC bytes (the digits) from Register Pair HL (51DFH) to Register Pair DE (51DAH): the number found becomes the best.
5044
POP DE D1
Restore Register Pair DE from the stack: the text pointer.
5045
GOSUB to 516EH, which stores Register A (the length byte) at 51D9H, sets the opcode at 5021H for a number and empties the line list.
5048
JUMP to 5101H to add this line to the list at 4300H.
504B
An &: GOSUB to 514BH, which steps Register Pair DE to the next byte that is not a blank and returns it in Register A.
504E
CP 44H FE 44
Compare Register A (the byte after the &) against 44H, the letter D.
5050
If the Z FLAG is set (&D), JUMP to 4F6AH, the code that starts the next line: Register Pair DE (at the D) is taken as a line's 00H end, so the bytes after the D are read as a link field and a line number (4F6BH-4F76H) and 4E7AH gets the address after the D.
5053
CP 4FH FE 4F
Compare Register A (the byte after the &) against 4FH, the letter O (an octal constant).
5055
If the Z FLAG is set (&O), JUMP to 4FE1H to pass the digits.
5058
CP 48H FE 48
Compare Register A (the byte after the &) against 48H, the letter H (a hexadecimal constant).
505A
If the NZ FLAG is set (none of D, O and H), JUMP to 5070H to look at the byte in Register A.

PASS HEXADECIMAL DIGITS
Register Pair DE steps over 0-9 and A-F.

505C
GOSUB to 514BH for the next byte that is not a blank, in Register A, with Register Pair DE at it.
505F
CP 47H FE 47
Compare Register A (the byte) against 47H: the NO CARRY FLAG is set above the letter F.
5061
If the NO CARRY FLAG is set (above F), JUMP to 5070H: the constant ends.
5063
CP 41H FE 41
Compare Register A (the byte) against 41H: the NO CARRY FLAG is set for A-F.
5065
If the NO CARRY FLAG is set (A-F), LOOP back to 505CH.
5067
CP 3AH FE 3A
Compare Register A (the byte) against 3AH: the NO CARRY FLAG is set for 3AH-40H.
5069
If the NO CARRY FLAG is set (3AH-40H), JUMP to 5070H: the constant ends.
506C
CP 30H FE 30
Compare Register A (the byte) against 30H: the NO CARRY FLAG is set for a digit.
506E
If the NO CARRY FLAG is set (a digit), LOOP back to 505CH.
5070
JUMP to 4F78H to look at the byte in Register A (Register Pair DE at it).
5073
The letter A (Register C = 41H): GOSUB to 514BH for the next byte that is not a blank, in Register A.
5076
CP 53H FE 53
Compare Register A (the byte after the A) against 53H, the letter S (the word AS).
5078
If the NZ FLAG is set (not S), JUMP to 5094H: a name starting with A, Register A = its second character.
507A
LD B,A 47
Load Register B with Register A (53H, S), the second character if this is the name AS.
507B
GOSUB to 514BH for the next byte that is not a blank, in Register A.
507E
GOSUB to 5161H: the CARRY FLAG is set if Register A is not a letter.
5081
If the CARRY FLAG is set (no letter after AS), JUMP to 509FH: the name AS itself.
5083
PUSH DE D5
Save Register Pair DE (the text pointer at the letter after AS) on the stack.
5084
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the address of the last FIELD token, the operand 5085H (0000H in the file; stored at 4FB4H, cleared at 4DF6H).
5087
LD HL,(4E7AH) 2A 7A 4E
Load Register Pair HL with the 16-bit value at 4E7AH, the address of the line being scanned (the operand of LD HL,nnnn at 4E79H).
508A
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,DE at 508BH.
508B
SBC HL,DE ED 52
Subtract Register Pair DE (the last FIELD token's address) from Register Pair HL (the line's start): the CARRY FLAG is set if the FIELD token lies after the line's start, in this line.
508D
POP DE D1
Restore Register Pair DE from the stack: the text pointer at the letter after AS. POP does not change the flags.
508E
If the NO CARRY FLAG is set (no FIELD in this line), JUMP to 509FH: the name AS, with the letter in Register A starting the rest of it.
5090
LD C,A 4F
FIELD ... AS name: load Register C with Register A, the letter after AS, the name's first character.
5091
A name with its first character in Register C (4FA1H enters here): GOSUB to 514BH for the next byte that is not a blank, in Register A.
5094
LD B,20H 06 20
Load Register B with 20H, a space, the second character of a one-letter name.
5096
GOSUB to 515AH: the CARRY FLAG is set if Register A is not a letter or a digit.
5099
If the CARRY FLAG is set (a one-letter name), JUMP to 50A4H with Register B = 20H.
509B
LD B,A 47
Load Register B with Register A, the name's second character.

PASS THE REST OF THE NAME
Only the first two characters count.

509C
GOSUB to 514BH for the next byte that is not a blank, in Register A, with Register Pair DE at it.
509F
GOSUB to 515AH: the CARRY FLAG is set if Register A is not a letter or a digit.
50A2
If the NO CARRY FLAG is set (the name goes on), LOOP back to 509CH.
50A4
LD HL,(51D4H) 2A D4 51
Load Register Pair HL with the 16-bit value at 51D4H: Register L = the item compared's first character, Register H = its second (51D5H).
50A7
LD A,C 79
Load Register A with Register C, the name's first character.
50A8
CP L BD
Compare Register A (the name's first character) with Register L: the CARRY FLAG is set if the name is smaller, the Z FLAG if the first characters match.
50A9
Self-Modifying Code
JUMP to 4F78H (pass this name) under the condition stored at 4DDDH: JP C (mode 0: names below the item compared are passed) or JP NZ (modes 1 to 3: other names are passed). 50B0H comes back here with new flags.
50AC
If the NZ FLAG is set (mode 0 and the name is larger), JUMP to 50EEH to compare it with the best so far.
50AE
LD A,B 78
Load Register A with Register B, the name's second character.
50AF
CP H BC
Compare Register A (the second character) with Register H, the item compared's second character.
50B0
If the NZ FLAG is set (they differ), JUMP to 50A9H to decide with the flags of this compare.
50B2
LD A,(4E0CH) 3A 0C 4E
The same name: load Register A with the byte at 4E0CH, the mode.
50B5
OR A B7
OR Register A (the mode) with itself to set the flags: the Z FLAG is set for mode 0.
50B6
If the Z FLAG is set (mode 0), JUMP to 50EBH: only names above the last item matter.
50B8
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the character after the name (a type character or not).
50B9
LD HL,51E9H 21 E9 51
Load Register Pair HL with 51E9H, the counter of the # form.
50BC
LD IY,51B5H FD 21 B5 51
Load Index Register IY with 51B5H, the # among the type characters.
50C0
LD B,04H 06 04
Load Register B with 04H, the four type characters.

FIND THE TYPE
Index Register IY steps back through # ! % $ (51B5H-51B2H), Register Pair HL through their counters (51E9H-51E6H).

50C2
CP (IY+00H) FD BE 00
Compare Register A (the character after the name) with the byte at Index Register IY+00H, a type character.
50C5
If the Z FLAG is set (this type), JUMP to 50CDH with Register Pair HL = its counter.
50C7
DEC HL 2B
Decrement Register Pair HL to the counter before.
50C8
DEC IY FD 2B
Decrement Index Register IY to the type character before.
50CA
Decrement Register B, the types left, and LOOP back to 50C2H.
50CC
DEC DE 1B
No type character: Register Pair HL = 51E5H, the plain counter; decrement Register Pair DE so that 50CDH reads the character after the name again.
50CD
GOSUB to 514BH for the next byte that is not a blank, in Register A, with Register Pair DE at it.
50D0
CP 28H FE 28
Compare Register A (the byte after the name and its type) against 28H, an opening parenthesis: an array.
50D2
If the NZ FLAG is set (not an array), JUMP to 50D9H to count it with Register Pair DE at that byte.
50D4
LD BC,0005H 01 05 00
Load Register Pair BC with 0005H, the distance from a counter to the same form's array counter.
50D7
ADD HL,BC 09
Add Register Pair BC (5) to Register Pair HL: Register Pair HL = the same form's array counter.
50D8
INC DE 13
Increment Register Pair DE past the opening parenthesis.
50D9
INC (HL) 34
Increment the byte at Register Pair HL: one more use counted in this form in this line (5017H and 5140H enter here).
50DA
LD HL,4F6DH 21 6D 4F
Load Register Pair HL with 4F6DH, the opcode of the jump at the start of the next line.
50DD
LD (HL),C3H 36 C3
Self-Modifying Code
Store C3H (JP) at Register Pair HL, 4F6DH: the line is reported when the scan reaches the next line.
50DF
LD HL,(4E7AH) 2A 7A 4E
Load Register Pair HL with the 16-bit value at 4E7AH, the address of the line being scanned.
50E2
INC HL 23
Increment Register Pair HL, 1 of 2, to the high byte of the line's link field.
50E3
INC HL 23
Increment Register Pair HL, 2 of 2, to the low byte of the line's number.
50E4
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the low byte of the line's number.
50E5
INC HL 23
Increment Register Pair HL to the high byte of the line's number.
50E6
LD B,(HL) 46
Load Register B with the byte at Register Pair HL. Register Pair BC = the line's number.
50E7
LD (4E76H),BC ED 43 76 4E
Self-Modifying Code
Store Register Pair BC (the line's number) at 4E76H, the operand of LD HL,nnnn at 4E75H: the number shown in the report, and the last line shown for a plain REF.
50EB
JUMP to 4F78H to look at the byte in Register A, with Register Pair DE at it.
50EE
LD HL,(51DAH) 2A DA 51
Mode 0, a name above the last item: load Register Pair HL with the 16-bit value at 51DAH: Register L = the best item's first character, Register H = its second.
50F1
LD A,C 79
Load Register A with Register C, the name's first character.
50F2
CP L BD
Compare Register A (the name's first character) with Register L: the CARRY FLAG is set if the name is smaller than the best.
50F3
If the CARRY FLAG is set (smaller), JUMP to 50FEH: a new best (50FAH comes back here with new flags).
50F5
If the NZ FLAG is set (larger than the best), JUMP to 4F78H to pass it.
50F8
LD A,B 78
Load Register A with Register B, the name's second character.
50F9
CP H BC
Compare Register A (the second character) with Register H, the best item's second character.
50FA
If the NZ FLAG is set (they differ), JUMP to 50F3H to decide with the flags of this compare.
50FC
The same name as the best: JUMP to 5101H to add this line to the list.
50FE
GOSUB to 5168H, which stores Register Pair BC (Register C = the first character, Register B = the second) at 51DAH as the best item, sets its length byte and empties the line list.

5101H - Remember the Line

Adds the address of the line being scanned (4E7AH) to the list at 4300H-433FH (32 lines) unless the list is full or the line is already its last entry.

5101
LD HL,(4EEFH) 2A EF 4E
Load Register Pair HL with the 16-bit value at 4EEFH, the end of the line list (the operand of LD BC,nnnn at 4EEEH).
5104
LD BC,4340H 01 40 43
Load Register Pair BC with 4340H, the end of a full list.
5107
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 5108H.
5108
SBC HL,BC ED 42
Subtract Register Pair BC (4340H) from Register Pair HL (the list's end): the Z FLAG is set if the list is full.
510A
ADD HL,BC 09
Add Register Pair BC back: Register Pair HL = the list's end again (ADD HL,BC does not change the Z FLAG).
510B
If the Z FLAG is set (the list is full), JUMP to 50EBH.
510D
LD BC,4300H 01 00 43
Load Register Pair BC with 4300H, the start of the list.
5110
OR A B7
OR Register A with itself to clear the CARRY FLAG for the SBC HL,BC at 5111H.
5111
SBC HL,BC ED 42
Subtract Register Pair BC (4300H) from Register Pair HL (the list's end): the Z FLAG is set if the list is empty.
5113
ADD HL,BC 09
Add Register Pair BC back: Register Pair HL = the list's end (the Z FLAG is kept).
5114
LD BC,(4E7AH) ED 4B 7A 4E
Load Register Pair BC with the 16-bit value at 4E7AH, the address of the line being scanned. LD does not change the flags.
5118
If the Z FLAG is set (the list is empty), JUMP to 5126H to add the line.
511A
DEC HL 2B
Decrement Register Pair HL to the high byte of the last entry.
511B
LD A,B 78
Load Register A with Register B, the high byte of the line's address.
511C
CP (HL) BE
Compare Register A with the byte at Register Pair HL, the high byte of the last entry.
511D
If the NZ FLAG is set (another line), JUMP to 5125H to add the line.
511F
DEC HL 2B
Decrement Register Pair HL to the low byte of the last entry.
5120
LD A,C 79
Load Register A with Register C, the low byte of the line's address.
5121
CP (HL) BE
Compare Register A with the byte at Register Pair HL, the low byte of the last entry.
5122
INC HL 23
Increment Register Pair HL back to the last entry's high byte (INC HL does not change the flags).
5123
If the Z FLAG is set (the line is already the last entry), JUMP to 50EBH.
5125
INC HL 23
Increment Register Pair HL to the list's end.
5126
LD (HL),C 71
Store Register C, the low byte of the line's address, at Register Pair HL, the list's end.
5127
INC HL 23
Increment Register Pair HL to the high byte of the new entry.
5128
LD (HL),B 70
Store Register B, the high byte of the line's address, at Register Pair HL.
5129
INC HL 23
Increment Register Pair HL past the new entry: the new end of the list.
512A
LD (4EEFH),HL 22 EF 4E
Self-Modifying Code
Store Register Pair HL (the new end of the list) at 4EEFH, the operand of LD BC,nnnn at 4EEEH.
512D
JUMP to 50EBH to go on scanning with Register A and Register Pair DE.

512FH - Text Search

Reached through JP 512FH at 4F7CH with Register A = the byte of the line at Register Pair DE. Compares the bytes from there with the search text at 51EFH up to its 00H end; a match counts in 51E5H, the scan goes on after it.

512F
LD HL,51EFH 21 EF 51
Load Register Pair HL with 51EFH, the search text.
5132
CP (HL) BE
Compare Register A (the byte of the line) with the byte at Register Pair HL, the first byte of the search text.
5133
If the NZ FLAG is set (no match here), JUMP to 5148H.
5135
PUSH DE D5
Save Register Pair DE (the position in the line) on the stack.

COMPARE LOOP
Register Pair DE steps through the line, Register Pair HL through the search text.

5136
INC DE 13
Increment Register Pair DE to the next byte of the line.
5137
INC HL 23
Increment Register Pair HL to the next byte of the search text.
5138
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next byte of the search text.
5139
OR A B7
OR Register A (that byte) with itself to set the flags: the Z FLAG is set at the search text's 00H end.
513A
If the NZ FLAG is set (more to compare), JUMP to 5143H.
513C
POP HL E1
A match: restore Register Pair HL from the stack, discarding the saved position (Register Pair DE is past the match).
513D
LD HL,51E5H 21 E5 51
Load Register Pair HL with 51E5H, the first counter.
5140
JUMP to 50D9H to count the match and mark the line.
5143
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, the next byte of the line.
5144
CP (HL) BE
Compare Register A (the line's byte) with the byte at Register Pair HL, the search text's byte.
5145
If the Z FLAG is set (they match), LOOP back to 5136H.
5147
POP DE D1
Restore Register Pair DE from the stack: the position where the compare began.
5148
JUMP to 4F77H for the next byte of the line after Register Pair DE.

514BH - Small Helpers

514BH: the next byte of the line in Register A, passing spaces, 09H and 0AH. 515AH: the CARRY FLAG if Register A is not a letter or digit; 5161H: the CARRY FLAG if it is not a letter. 5168H and 516EH: store the best item's characters (Register Pair BC) and length byte, set 5021H and empty the line list; 5171H: only the last two.

514B
INC DE 13
Increment Register Pair DE to the next byte of the line.
514C
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE.
514D
CP 20H FE 20
Compare Register A (the byte) against 20H, a space.
514F
If the Z FLAG is set (a space), LOOP back to 514BH.
5151
RET NC D0
If the NO CARRY FLAG is set (above 20H), RETURN with the byte in Register A.
5152
CP 0BH FE 0B
Compare Register A (the byte, below 20H) against 0BH: the NO CARRY FLAG is set for 0BH-1FH.
5154
RET NC D0
If the NO CARRY FLAG is set (0BH-1FH), RETURN with the byte in Register A.
5155
CP 09H FE 09
Compare Register A (the byte) against 09H: the CARRY FLAG is set below 09H (such as the line's 00H end).
5157
RET C D8
If the CARRY FLAG is set (below 09H), RETURN with the byte in Register A.
5158
Register A is 09H or 0AH: LOOP back to 514BH to pass it.
515A
CP 30H FE 30
Compare Register A (the byte) against 30H: the CARRY FLAG is set below the digit 0.
515C
RET C D8
If the CARRY FLAG is set, RETURN with the CARRY FLAG: not a letter or digit.
515D
CP 3AH FE 3A
Compare Register A (the byte) against 3AH: the CARRY FLAG is set for a digit.
515F
CCF 3F
Complement the CARRY FLAG: the NO CARRY FLAG now marks a digit.
5160
RET NC D0
If the NO CARRY FLAG is set (a digit), RETURN with the NO CARRY FLAG.
5161
CP 41H FE 41
Compare Register A (the byte) against 41H: the CARRY FLAG is set below the letter A.
5163
RET C D8
If the CARRY FLAG is set, RETURN with the CARRY FLAG: not a letter.
5164
CP 5BH FE 5B
Compare Register A (the byte) against 5BH: the CARRY FLAG is set for A-Z.
5166
CCF 3F
Complement the CARRY FLAG: the NO CARRY FLAG now marks a letter.
5167
RET C9
RETURN with the CARRY FLAG set if Register A is not a letter (nor a digit, from 515AH).
5168
LD (51DAH),BC ED 43 DA 51
Store Register Pair BC (two characters: FFFFH for none, or a name's first character in Register C and second in Register B) at 51DAH, the best item's characters.
516C
LD A,01H 3E 01
Load Register A with 01H, the length byte of a name (two characters).
516E
LD (51D9H),A 32 D9 51
Store Register A (the length byte) at 51D9H, the best item's length byte (5045H enters here with a number's length byte).
5171
LD A,(51DAH) 3A DA 51
Load Register A with the byte at 51DAH, the best item's first character (4D9AH enters here).
5174
CP 41H FE 41
Compare Register A (that character) against 41H: the NO CARRY FLAG is set for a letter or FFH (a name, or none).
5176
LD A,18H 3E 18
Load Register A with 18H, the opcode of JR. LD does not change the flags.
5178
If the NO CARRY FLAG is set (a name or none), JUMP to 517CH with Register A = 18H.
517A
LD A,38H 3E 38
A number: load Register A with 38H, the opcode of JR C.
517C
LD (5021H),A 32 21 50
Self-Modifying Code
Store Register A (18H or 38H) at 5021H, the opcode of the test of a number found against the best.
517F
LD HL,4300H 21 00 43
Load Register Pair HL with 4300H, the start of the line list.
5182
LD (4EEFH),HL 22 EF 4E
Self-Modifying Code
Store Register Pair HL (4300H) at 4EEFH, the operand of LD BC,nnnn at 4EEEH: the list's end is its start, the list is empty.
5185
LD (4EF2H),HL 22 F2 4E
Self-Modifying Code
Store Register Pair HL (4300H) at 4EF2H, the operand of LD HL,nnnn at 4EF1H: the list's next entry is its first.
5188
RET C9
RETURN with the line list at 4300H empty and the opcode at 5021H set for the item.

5189H - Compare Characters

Compares Register C characters from 51E0H with those at Index Register IY. The Z FLAG is set if they are all equal (or Register C is 0); otherwise the flags of the first difference.

5189
LD A,C 79
Load Register A with Register C, the number of characters to compare (the length byte, the characters after the first).
518A
OR A B7
OR Register A (the count) with itself to set the flags: the Z FLAG is set for none.
518B
LD B,A 47
Load Register B with Register A, the count. LD does not change the flags.
518C
RET Z C8
If the Z FLAG is set (nothing to compare), RETURN with the Z FLAG.
518D
LD HL,51E0H 21 E0 51
Load Register Pair HL with 51E0H, the second digit of the number found.

COMPARE LOOP
Register Pair HL and Index Register IY step through the two strings; Register B counts.

5190
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a digit of the number found.
5191
CP (IY+00H) FD BE 00
Compare Register A (the digit found) with the byte at Index Register IY+00H, the other number's digit.
5194
INC HL 23
Increment Register Pair HL to the next digit (INC HL does not change the flags).
5195
RET NZ C0
If the NZ FLAG is set (they differ), RETURN with the NZ FLAG and the CARRY FLAG of the compare.
5196
INC IY FD 23
Increment Index Register IY to the other number's next digit.
5198
Decrement Register B, the digits left, and LOOP back to 5190H.
519A
RET C9
RETURN with the Z FLAG set: all digits are equal.

519BH - Position the Output

519EH displays a space; at column 53 or beyond it starts a new line, and near the start of a line it indents to column 7, past the item's column.

519B
GOSUB to BASIC 5D52H, which displays a carriage return (0DH) to start a new line.
519E
GOSUB to BASIC 5D3DH, which displays a space (4EA3H calls here).
51A1
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.
51A4
AND 3FH E6 3F
Mask Register A (the cursor's low byte) against 3FH (0011 1111): the cursor's column (0-63).
51A6
CP 35H FE 35
Compare Register A (the column) against 35H (53): the NO CARRY FLAG is set for column 53 or more.
51A8
If the NO CARRY FLAG is set (near the right edge), JUMP to 519BH for a new line.
51AA
SUB 07H D6 07
Subtract 07H from Register A, the column: the column minus 7.
51AC
RET NC D0
If the NO CARRY FLAG is set (column 7 or more), RETURN.
51AD
NEG ED 44
Negate Register A (the column minus 7): the number of spaces up to column 7.
51AF
JUMP to BASIC 5D30H, which displays Register A spaces and returns.

51B2H - Data

The type characters and the message of 4E20H.

51B2-51B5
DEFM "$%!#" 24 25 21 23
The type characters, read through 4ED0H-4ED4H (type numbers 1-4) and 50BCH-50C8H (Index Register IY from 51B5H down): $ string, % integer, ! single precision, # double precision.
51B6-51BE
DEFM "Text End" / DEFB 0DH 54 65 78 74 20 45 6E 64 0D
The message of 4E20H (9 bytes with its carriage return), shown when a plain REF finds no further line.
51BF-51D2
DEFB 00H x 20 00 x 20
20 bytes of 00H to the end of the file (51D2H). Nothing in SYS12/SYS reads or writes them.

51D3H - Variables After the File

Not loaded by SYS12/SYS (the file ends at 51D2H); they keep their contents while no other overlay overwrites them.

51D3-51D8
DEFS 6
The item compared: 51D3H its length byte (the characters minus 1), 51D4H-51D8H its characters. Set at 4D39H, 4DADH, 4D94H and 4E4FH; read at 4DE0H, 4FF8H, 5007H and 50A4H.
51D9-51DE
DEFS 6
The best or reported item: 51D9H its length byte, 51DAH-51DEH its characters (FFH FFH for none). Set at 4D3FH, 4D95H, 5042H, 5168H and 516EH; read at 4E28H, 4E30H, 4E89H, 4F0CH, 501CH, 50EEH and 5171H.
51DF-51E4
DEFS 6
The digits of the number found in the text (4FC9H, 4FD9H); 51DFH is read at 5001H and 5026H, 51E0H on by 5189H.
51E5-51EE
DEFS 10
The counters of uses in the line: 51E5H plain, 51E6H $, 51E7H %, 51E8H !, 51E9H #, and 51EAH-51EEH the same forms as arrays. Increased at 50D9H, cleared at 4E5BH and 4E9FH.
51EF-51FF
DEFS 17
The search text, copied at 4D32H-4D38H (16 bytes and a 00H at 51FFH); read at 4F11H and 512FH-5144H.