TRS-80 DOS - LDOS 5.3.1 for the Model I - BASIC/OV2 Disassembled

Page Customization

Summary:

LDOS 5.3.1 BASIC/OV2 Disassembly - The LBASIC Cross Reference Overlay (Model I)

BASIC/OV2 is the overlay behind LBASIC's CMD"X" statement, the DOS version 5 cross reference facility. It reads the tokenised BASIC program that is sitting in memory and produces a listing of every variable and every line number reference, each followed by the numbers of the lines in which it appears. The banner it prints identifies it as "BASIC Cross Reference Listing Utility - Version 1.22", copyright 1987 MISOSYS, Inc. DOS version 6 replaces it with the separate BREF/CMD utility, which is run from the DOS Ready prompt rather than from inside BASIC.

The documented syntax is CMD"X devspec/filespec -V|=var,-L|=lnum,<title>". The device or file specification chooses where the listing goes; if it is omitted the listing goes to the video display, and if it names a disk file the default extension /TXT is supplied. A leading -V restricts the listing to variables and -L restricts it to line numbers; an =name or =number restricts it to that one entry; and any text between angle brackets becomes a title printed at the head of every page. Both BASIC/CMD and BASIC/OV2 must be present on the disk, and a program which contains a line number zero cannot be cross referenced.

The overlay is reached from LBASIC's CMD dispatcher. BASIC/CMD evaluates the quoted string at 57C6H, sends anything two characters or longer to 5454H, requires the second character to be a space, matches the first against N, X and V, and for X loads Register B with 32H. 54A5H then builds the file specification "BASIC/OV" plus the digit 2 into CFCB$ at 4480H and 5484H does LD HL,4319H / LD DE,4480H / JP 4433H, so @RUN loads this overlay over LBASIC's own image at 5200H and enters it at 5200H with Register Pair HL pointing at the parameter text inside INBUF$ at 4318H. That is the same entry convention BASIC/OV1 uses for CMD"N" and BASIC/OV4 uses for CMD"V". The overlay exits by planting "BASIC/CMD" in CFCB$ at 4480H and an asterisk in INBUF$ at 4318H and issuing @RUN again, so the interpreter is reloaded and re-entered with the program and the variables intact.

File Format and Load Map

BASIC/OV2 is a standard LDOS load module of 1647 bytes. It carries one type-1FH comment record holding "Copyright 1991 MISOSYS, Inc., All rights reserved", then six 256-byte type-01H load records at 5200H, 5300H, 5400H, 5500H, 5600H and 5700H, a 28-byte type-01H load record at 5800H, and a type-02H transfer record with the entry address 5200H. The image is therefore 5200H-581BH, 1564 bytes, contiguous with no gaps and with no byte loaded twice. Executable code occupies 5200H-5720H and data occupies 5721H-581BH. Everything the overlay uses above 581BH is uninitialised RAM which it simply claims.

Memory Map

Address RangeContents
5200H-5720H
1313 bytes
Executable code. Entry is at 5200H and every exit path converges on 568DH.
5721H-581BH
251 bytes
Data: the form feed byte, the title buffer, the column heading line, the rule fragments, the two run-time work bytes 5793H and 5794H, the BREAK message, the default extension, the sign-on banner and the out-of-memory message.
581CH-5866H
75 bytes
Work cells above the loaded image. Name buffers, the output field, the list pointers, the switch flags and the 32-byte file control block of the listing output file.
5900H-59FFH
256 bytes
The sector buffer handed to @INIT for the listing output file.
STREND+5 upward
2 bytes per entry
The list of line numbers collected for the entry currently being listed. It grows above STREND at 40FDH and is refused room at STKTOP at 40A0H.

How the Listing is Produced

There is no sort table anywhere in the overlay. Instead one complete pass is made over the BASIC program for every entry that is printed. Each pass starts with the current-entry cell 5824H filled with 0FFH, which is higher than any character that can start a name, and with the previous-entry cell 581CH holding the name that was printed last. Every reference the scanner finds is compared against both: it is discarded unless it is higher than the name already printed and lower than or equal to the best candidate found so far in this pass. When a candidate displaces the current best the line number list is reset and collection starts again; when a candidate matches the current best its line number is appended. At the end of the pass the winner is printed together with its line numbers, it becomes the new previous entry, and another pass is run. When a pass finds nothing at all the listing is complete.

The program text scanner at 538AH is what makes the references reliable. It reads the tokenised line through Register Pair IY as (IY+04H), because a Level II BASIC line record is a two-byte link to the next line, a two-byte line number, the tokenised text and a 00H terminator. It returns at once on the REM token 93H, skips the whole of a string literal, skips a DATA item list to its closing colon or to the next token, and skips numeric constants including the hexadecimal and octal forms introduced by an ampersand. A variable name is collected as its first letter, its second character, any type declaration character and any opening parenthesis, which is exactly the identity Level II BASIC itself gives a variable, so A, A1, A$ and A( are listed as different entries while ALPHA and ALTITUDE are correctly listed as the same one. A line number is collected only after one of the seven tokens that may precede one - THEN, ELSE, RESUME, GOTO, GOSUB, RUN and ERL - and is right-justified in five characters with leading zeros so that the same character comparison that orders names also orders numbers correctly.

Variable and Work Cell List

Address RangePurpose
55FBH-55FCH
2 bytes
Output Control Block Operand
Self-modifying code. The operand of the LD DE,0000H at 55FAH inside the string output routine. 5255H writes the listing file control block address 5847H here, 55E8H writes the video control block address DODCB$ 401DH and 55F2H writes the printer control block address PRDCB$ 4025H.
5721H
1 byte
Page Break Form Feed
The 0CH printed immediately before the title at every page break.
5722H-575FH
62 bytes
Title Buffer
Cleared to a single 00H at 5578H and filled by 55C6H from the text between angle brackets, up to 58 characters plus a carriage return and a terminator.
5793H
1 byte
Output Destination Flag
The first byte of the output file control block as @FSPEC left it. 00H means no output was specified and the listing goes to the video, 2AH means a device, and a letter means a disk file which 5710H must close.
5794H
1 byte
Page Line Counter
Incremented at 5609H for every carriage return sent and cleared at 5613H for every form feed. 50 lines force a page at the start of a new entry, 55 lines force one at the end of an output line.
581CH-5823H
8 bytes
Previous Entry
The reference that was listed last. Filled with blanks at 526DH so the first pass accepts anything, and updated at 5303H after each entry is printed.
5824H-582BH
8 bytes
Current Entry
The lowest acceptable reference found so far in the pass now running. Filled with 0FFH at 5285H at the start of each pass, unless an =name or =linenumber parameter has put a specific request there.
582CH-5833H
8 bytes
Candidate Reference
The buffer the scanner writes each name or line number into. Blanked at 5299H before every call.
5834H-583BH
8 bytes
Output Field
The seven-character field every piece of the listing is built in, plus its 00H terminator. 5834H and 583AH hold the colons that bracket the reference column.
583CH-583DH
2 bytes
Line Number List Pointer
Set to STREND+5 by 5515H, advanced by 552FH while the list is built and by 5555H while it is read back.
583EH-583FH
2 bytes
Previous Line Number
Cleared by 5521H and used by 5555H so that several references to the same name in one program line print that line number only once.
5840H
1 byte
Pass Result Flag
Cleared at 5274H and set to 01H at 52EAH when a pass accepts any reference. A pass that leaves it clear ends the listing.
5841H
1 byte
Output Field Counter
The number of fields already placed on the current output line. A count of 1 makes the field the bracketed reference column; a count of 10 forces a continuation line.
5842H
1 byte
Line Number List State
Set to 01H at 5440H while a comma-separated list of line numbers such as an ON n GOTO is being read, so the next call to the scanner resumes at 5416H instead of restarting the token scan.
5843H
1 byte
Restriction Switch
56H for -V, variables only; 4CH for -L, line numbers only; 00H for both. Written at 558CH and read at 52AAH.
5844H
1 byte
Specific Entry Flag
Set to 01H at 55BAH when the parameter text carried an =name or =linenumber. It stops 5273H from resetting the current entry, makes 52C9H reject every other name, and makes 534DH end after a single pass.
5845H-5846H
2 bytes
Parameter Text Pointer
The position reached in the CMD"X parameter text. Written at 5213H and again at 5229H once @FSPEC has consumed the file specification, and read at 5258H before the switches are parsed.
5847H-5866H
32 bytes
Listing File Control Block
Filled by @FSPEC at 5223H, extended by @FEXT at 5234H, opened by @INIT at 5240H and closed by @CLOSE at 571DH.
5900H-59FFH
256 bytes
Listing File Sector Buffer
Handed to @INIT at 5237H with a logical record length of 00H, meaning 256 bytes, so the listing is written as a plain byte stream.

Major Routines

AddressRoutine
5200HEntry Point
Entry Register Pair HL at the CMD"X parameter text in INBUF$ 4318H. Skips blanks, prints the banner through @DSPLY, folds the text to upper case, and opens the listing file with @FSPEC, @FEXT and @INIT. Exit is into 5246H.
5273HSelection Pass
Entry with 581CH holding the entry listed last. Walks every program line from TXTTAB 40A4H, keeps the lowest reference above 581CH in 5824H and its line numbers in the list above STREND, and sets 5840H if anything was found. Exit into 52EFH.
52EFHPrint One Entry
Entry with 5824H holding the entry and the line number list terminated. Prints the bracketed reference column and eight line numbers per line, wrapping onto continuation lines. Exit to 534DH.
5360HCompare Two Strings
Entry Register Pair HL and Register Pair DE at two 00H terminated strings. Exit with the Z FLAG set when they match and the CARRY FLAG set when the string at Register Pair DE is the lower; both registers are preserved.
5374HCopy a String
Entry Register Pair HL at the source and Register Pair DE at the destination. Copies up to but not including the 00H terminator, so trailing blanks in the destination survive.
537BHFill a Name Field
Entry Register Pair HL at an eight-byte field. 537BH fills with blanks; 537DH fills with the character in Register A. Register Pair HL and Register Pair BC are preserved.
538AHProgram Text Scanner
Entry Register Pair IY at the current program line record and Register Pair HL at the candidate buffer. Exit with the next variable name or line number reference in the buffer, or with the buffer still blank at the end of the line.
5414HLine Number Collector
Entry Register Pair IY on a reference token. Skips blanks, commas and the equals token, drops leading zeros, takes up to five digits and right-justifies them with leading zeros. Sets 5842H so an ON n GOTO list is followed through.
5479HCharacter Classifier
Entry Register Pair IY on the character. Exit Register A = 0 for a token or other non-name character, 1 for a digit, 2 for a letter, 3 for one of ! # $ %, and 4 for an opening parenthesis, with the Z FLAG set only for 0.
54AEHLine and Page Control
54AEH ends an output line and turns that into a page break past 55 lines. 54B9H starts a new entry, drawing the rule and throwing a page past 50 lines. 54CFH draws the seven-character rule.
54F6HOutput Field Manager
54F6H starts a new output line; 54FAH blanks the field at 5834H, counts it in 5841H and brackets it with colons when it is the first field of the line. Exit Register Pair HL at 5834H and Register A holding the count.
5515HLine Number List
5515H points the list at STREND+5; 5521H terminates it and rewinds it; 552FH appends the line number from IX+02H and IX+03H and checks the list against STKTOP 40A0H; 5555H reads the next number back, suppressing repeats.
5570HParameter Parser
Entry Register Pair HL after the output specification. Sets 5843H from -V or -L, builds an =name or =linenumber into 5824H and sets 5844H, and copies a title between angle brackets into 5722H.
55F6HString Output
Entry Register Pair HL at a 00H terminated string. Sends every character through $PUT 001BH to the control block whose address is in the self-modified operand at 55FBH, counts lines in 5794H, calls @KITSK 4300H between characters, and honours PAUSE and BREAK through KFLAG$ 4423H. Register Pair HL, Register Pair DE and Register Pair IY are preserved.
5661HKeyboard Flag Poll
Reads KFLAG$ 4423H, drains the type-ahead through @KBD 002BH when BREAK or PAUSE is pending, and returns Register A holding the flag byte with the Z FLAG reflecting the BREAK bit. 5673H clears the low three bits.
568DHCommon Exit
The single way out. Closes the listing file through 5710H, plants "BASIC/CMD" in CFCB$ 4480H and an asterisk in INBUF$ 4318H, and jumps to @RUN 4433H so the interpreter is reloaded over this image and re-entered with the program intact.
56B0HUpper Case Conversion
Entry Register Pair HL at the parameter text. Converts every lower case letter in place and stops at the first byte below 20H. Register A, the flags and Register Pair HL are preserved.
56C8HLine Number to ASCII
Entry Register Pair HL holding the number. Uses ROM MAKINT 0A9AH, FOUINI 1034H and FOUT2 0FD9H. Exit Register Pair DE one past the text in FBUFFR 412FH, Register Pair HL unchanged.
56D8HProgram Line Navigation
56D8H steps Register Pair IX to the next line record; 56E8H reports a 0000H link word, the end of the program, with the Z FLAG.
56F2HReference Token Test
Entry Register A holding a program byte. Exit with the Z FLAG set for THEN 0CAH, ELSE 95H, RESUME 9FH, GOTO 8DH, GOSUB 91H, RUN 8EH or ERL 0C2H.
5708HDOS Error Exit
Entry Register A holding a DOS error number. ORs it with 0C0H, reports it through @ERROR 4409H and falls out through 568DH.

Cross Reference Notes

BASIC/OV2 is called only by BASIC/CMD, through the CMD statement dispatcher at 57C6H and the overlay dispatcher at 5454H, and it calls only BASIC/CMD, by reloading it at 56A2H. It issues no RST 28H supervisor request of its own; everything it asks of the operating system goes through a resident SYS0 vector or a Level II ROM entry point, so no request code row on the main LDOS disassembly index changes.

The resident LDOS vectors it uses are @DSPLY at 4467H for the banner, @FSPEC at 441CH and @FEXT at 4473H to build the output file control block, @INIT at 4420H to create the listing file, @CLOSE at 4428H to close it, @ERROR at 4409H for both error paths, @KITSK at 4300H between output characters, and @RUN at 4433H to reload the interpreter. It reads KFLAG$ at 4423H directly and writes it back with the low three bits cleared. The device control blocks DODCB$ at 401DH and PRDCB$ at 4025H are used as output destinations.

The Level II ROM entry points it uses are $PUT at 001BH for every character of the listing, @KBD at 002BH to drain the type-ahead, $KEY at 0049H to hold the display during a pause, and MAKINT at 0A9AH, FOUINI at 1034H and FOUT2 at 0FD9H to convert a line number to text in FBUFFR at 412FH. The Level II BASIC workspace cells it reads are TXTTAB at 40A4H, the start of the program text; STREND at 40FDH, above which the line number list is built; and STKTOP at 40A0H, which is the ceiling that list may not cross.

Two details are shared with BASIC/OV1 and are worth reading together. The seven-token reference set tested at 56F2H here is the same set BASIC/OV1 tests at 55A8H when it renumbers a program. The exit stub is the same too, down to the unused letter L that sits immediately below the "BASIC/CMD" string: BASIC/OV1 carries it at 55C7H and BASIC/OV2 carries it at 56A5H, and in both overlays the copy into CFCB$ starts one byte later.

One routine in the image has no caller. 55EEH is the printer counterpart of 55E4H and would aim the output routine at PRDCB$ at 4025H; nothing in the overlay reaches it, because the printer is selected by naming *PR as the output device rather than by a switch.

Disassembly:

5200H - Entry Point, Sign On and the Output File

Register Pair HL arrives pointing at 4319H, one byte into INBUF$ at 4318H, at whatever followed CMD"X and its separating space. This block skips leading blanks, displays the banner, folds the whole parameter text to upper case and, if a device or file specification was given, parses it, applies the default extension /TXT and opens it with @INIT.

5200
LD A,(HL) 7E
Loop Start
Load Register A with the character Register Pair HL is pointing at. On entry Register Pair HL points at 4319H, one byte into the DOS command buffer INBUF$ at 4318H, because BASIC/CMD entered this overlay with LD HL,4319H / LD DE,4480H / JP 4433H (@RUN) after matching the letter X in a CMD"X statement. The text there is everything the programmer typed after CMD"X and its separating space.
5201
CP 20H FE 20
Compare Register A, the current character of the CMD"X parameter text, against 20H (ASCII: blank). If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
5203
If the NZ FLAG (Not Zero) has been set because the character in Register A is not a blank, JUMP to 5208H to begin the listing with Register Pair HL pointing at the first non-blank character.
5205
INC HL 23
INCrement Register Pair HL by 1 so it points at the next character of the CMD"X parameter text.
5206
Loop End
LOOP BACK to 5200H to test the next character, so that any number of leading blanks between the X and the parameters is skipped.
5208
PUSH HL E5
Save Register Pair HL, which now points at the first non-blank character of the CMD"X parameter text, onto the stack while the sign-on banner is displayed.
5209
Point Register Pair HL to 579EH, the sign-on banner: 1CH (home the cursor), 1FH (clear to the end of the frame), the text "BASIC Cross Reference Listing Utility - Version 1.22", a line feed, the MISOSYS copyright line and the 0DH that terminates it.
520C
GOSUB to the resident LDOS vector @DSPLY at 4467H to send the string at Register Pair HL to the video display. @DSPLY stops at the 0DH which ends the copyright line at 580AH, so the "Out of memory." text that follows it at 580BH is not displayed.
520F
POP HL E1
Restore Register Pair HL from the stack; it points once more at the first non-blank character of the CMD"X parameter text.
5210
GOSUB to 56B0H to fold the whole of the CMD"X parameter text to upper case in place. Register Pair HL points at the first character; 56B0H converts every lower case letter and stops at the first byte below 20H, which is the 0DH that ends the line in INBUF$.
5213
LD (5845H),HL 22 45 58
Store the CMD"X parameter text pointer (Register Pair HL) to memory location 5845H, the two-byte cell that holds the position reached in the parameter text. It is re-read at 5258H once the output file has been dealt with, so that switch parsing resumes at the right place.
5216
LD A,(HL) 7E
Fetch the first character of the parameter text from the address in Register Pair HL into Register A. This is the character that decides whether an output devspec or filespec was given.
5217
CP 2AH FE 2A
Compare Register A, the first character of the parameter text, against 2AH (ASCII: *). If Register A equals 2AH, the Z FLAG is set; otherwise the NZ FLAG is set. An asterisk introduces a device specification such as *PR or *DO.
5219
If the Z FLAG (Zero) has been set because the first character is an asterisk, JUMP to 5220H to parse the device specification.
521B
CP 41H FE 41
Compare Register A, the first character of the parameter text, against 41H (ASCII: A). If Register A is less than 41H, the CARRY FLAG is set; if Register A is 41H or greater, the NO CARRY FLAG is set. A filename must begin with a letter, so anything below 41H means no output file was named.
521D
If the CARRY FLAG has been set because the first character is not a letter and not an asterisk, JUMP to 5246H. No output specification was given, so the cross reference listing goes to the video display.
5220
LD DE,5847H 11 47 58
Point Register Pair DE to 5847H, the 32-byte file control block this overlay uses for the listing output file. 5847H lies above the loaded image, which ends at 581BH, so it is uninitialised RAM that the overlay claims for itself.
5223
GOSUB to the resident LDOS vector @FSPEC at 441CH to parse the file or device specification. Register Pair HL points at the text, Register Pair DE points at the file control block at 5847H. @FSPEC fills in the control block and returns Register Pair HL past the specification, with the Z FLAG set on success.
5226
If the NZ FLAG (Not Zero) has been set because @FSPEC rejected the specification, JUMP to 5708H, the DOS error exit, which reports the error number left in Register A and returns to LBASIC.
5229
LD (5845H),HL 22 45 58
Store the updated parameter text pointer (Register Pair HL), which @FSPEC advanced past the file or device specification, to memory location 5845H so that switch parsing at 5258H starts after the specification.
522C
LD A,(DE) 1A
Fetch the first byte of the file control block at 5847H, through Register Pair DE, into Register A. @FSPEC leaves 2AH (ASCII: *) there for a device specification and the first letter of the filename for a disk file.
522D
CP 2AH FE 2A
Compare Register A, the first byte of the file control block at 5847H, against 2AH (ASCII: *). If Register A equals 2AH, the Z FLAG is set; otherwise the NZ FLAG is set.
522F
If the Z FLAG (Zero) has been set because the output is a device rather than a disk file, JUMP to 5237H. A device specification takes no file extension.
5231
Point Register Pair HL to 579BH, the three characters "TXT" which are the default extension for a cross reference listing file.
5234
GOSUB to the resident LDOS vector @FEXT at 4473H to attach the default extension. Register Pair HL points at the three-character extension "TXT" at 579BH and Register Pair DE points at the file control block at 5847H. @FEXT supplies the extension only when the specification did not carry one of its own.
5237
LD HL,5900H 21 00 59
Point Register Pair HL to 5900H, the 256-byte sector buffer for the listing output file. 5900H is above the loaded image and above the overlay work cells at 581CH-5866H, so nothing else uses it.
523A
LD B,00H 06 00
Load Register B with 00H, the logical record length passed to @INIT. A value of zero means a record length of 256 bytes, so the listing is written as a plain byte stream.
523C
LD A,(DE) 1A
Fetch the first byte of the file control block at 5847H, through Register Pair DE, into Register A once more. It is 2AH (ASCII: *) for a device and the first letter of the filename for a disk file.
523D
Store the first byte of the file control block (Register A) to memory location 5793H. 5793H is the output destination flag: 00H means no output specification was given and the listing goes to the video, 2AH means a device, and a letter of 41H or above means a disk file that will have to be closed at 5710H.
5240
GOSUB to the resident LDOS vector @INIT at 4420H to create or overwrite the listing file. Register Pair DE points at the file control block at 5847H, Register Pair HL points at the 256-byte buffer at 5900H and Register B holds the logical record length of 00H, meaning 256.
5243
If the NZ FLAG (Not Zero) has been set because @INIT could not create the file, JUMP to 5708H, the DOS error exit, which reports the error number left in Register A and returns to LBASIC.

5246H - Select the Output Destination and Print the Headings

With the output file open, the string output routine is aimed at either the video display control block DODCB$ at 401DH or the file control block at 5847H, the remaining parameters are parsed, and the title and column headings are printed. The line number list is pointed at the free memory above STREND at 40FDH.

5246
Point Register Pair HL to 578FH, the two-byte string 0DH,00H, which is a bare carriage return.
5249
GOSUB to 55E4H, which points the output routine at the video display control block DODCB$ at 401DH and then prints the string at Register Pair HL. The carriage return moves the cursor off the copyright line of the banner.
524C
Fetch the output destination flag from 5793H into Register A. It was set at 523DH from the first byte of the file control block at 5847H, and is still the 00H the overlay was loaded with when no output specification was given.
524F
OR A B7
OR Register A with itself to set the flags from the output destination flag without changing it. If it is zero, the Z FLAG is set.
5250
If the Z FLAG (Zero) has been set because no output file or device was named, JUMP to 5258H and leave the output routine pointing at the video display control block DODCB$ at 401DH.
5252
LD HL,5847H 21 47 58
Point Register Pair HL to 5847H, the file control block of the listing output file that @INIT has just opened.
5255
LD (55FBH),HL 22 FB 55
Self-Modifying Code
Store the file control block address (Register Pair HL) to memory location 55FBH. 55FBH is the operand of the LD DE,0000H instruction at 55FAH inside the string output routine, so every character the listing produces from here on is sent to the file at 5847H instead of the video. The assembled operand is 0000H; 55E4H writes the video control block address 401DH there and 55EEH writes the printer control block address 4025H there.
5258
LD HL,(5845H) 2A 45 58
Fetch the parameter text pointer from 5845H into Register Pair HL. It was stored at 5229H and points at the character following the output file or device specification, or at 5213H's value when no specification was given.
525B
GOSUB to 5570H to parse the remaining parameters: the -V or -L restriction switch, an optional =name or =linenumber that limits the listing to one entry, and an optional title enclosed in angle brackets.
525E
Point Register Pair HL to 5722H, the title buffer. It ships as a single 00H so that an empty title prints nothing; 55C6H fills it in when a < title > was supplied.
5261
GOSUB to 55F6H to send the title at 5722H to the current output destination. Nothing is printed when no title was given.
5264
Point Register Pair HL to 5760H, the column heading line: a carriage return followed by " Ref" and, after padding blanks, "Line Numbers".
5267
GOSUB to 55F6H to send the column heading line at 5760H to the current output destination.
526A
LD HL,581CH 21 1C 58
Point Register Pair HL to 581CH, the eight-byte cell holding the last reference name that was listed. 581CH is the first byte above the loaded image, which ends at 581BH.
526D
GOSUB to 537BH to fill the eight bytes at 581CH with seven blanks and a 00H terminator. Blanks are lower than every character a variable name or line number can start with, so the first selection pass will accept anything.
5270
GOSUB to 5515H to point the line number list at STREND+5. 5515H reads STREND from 40FDH, the first free byte above all of the BASIC program's variables, adds five and stores the result in the list pointer 583CH.

5273H - The Selection Pass Over the Program Text

This is the outer loop of the utility. One pass walks every line of the BASIC program, collects every variable name and line number reference, and keeps the lowest one that is still higher than the name printed by the previous pass, together with the numbers of the lines that mention it. No sort table is used; the ordering falls out of running the pass once per entry.

5273
XOR A AF
Loop Start
Set Register A to ZERO and clear all flags. This begins one complete selection pass over the BASIC program text.
5274
LD (5840H),A 32 40 58
Store zero (Register A) to memory location 5840H, the flag that records whether this pass found any reference at all. It is set to 01H at 52E8H the moment a reference is accepted, and tested at 52F2H to decide whether the listing is finished.
5277
LD (5842H),A 32 42 58
Store zero (Register A) to memory location 5842H, the flag that says the scanner is part way through a list of line numbers such as the targets of an ON n GOTO. A non-zero value makes 538AH resume inside 5416H instead of restarting the token scan.
527A
LD A,(5844H) 3A 44 58
Fetch the specific-entry flag from 5844H into Register A. It is 01H when the parameter text carried an =name or =linenumber, meaning only that one entry is to be listed, and 00H otherwise.
527D
OR A B7
OR Register A with itself to set the flags from the specific-entry flag without changing it. If it is zero, the Z FLAG is set.
527E
If the NZ FLAG (Not Zero) has been set because a single named entry was requested, JUMP to 5288H. The requested name is already in the current-entry cell at 5824H and must not be overwritten.
5280
LD HL,5824H 21 24 58
Point Register Pair HL to 5824H, the eight-byte cell that holds the smallest reference name found so far during this pass.
5283
LD A,0FFH 3E FF
Load Register A with 0FFH, the fill byte for the current-entry cell. 0FFH is higher than any character that can appear in a name, so the first candidate the scan produces is always accepted as the new smallest.
5285
GOSUB to 537DH to fill the seven bytes at 5824H with 0FFH and place a 00H terminator at 582BH.
5288
LD IX,(40A4H) DD 2A A4 40
Point Register Pair IX to the start of the BASIC program text by loading it from TXTTAB at 40A4H, the pointer Level II BASIC keeps to the first byte of the first program line record. Each record is a two-byte link to the next line, a two-byte line number, the tokenised text and a 00H terminator.
528C
Loop Start
GOSUB to 56E8H to test whether Register Pair IX is at the end of the program. 56E8H reads the two-byte link word at IX+00H and IX+01H and returns with the Z FLAG set when it is 0000H.
528F
If the Z FLAG (Zero) has been set because the link word is 0000H and the whole program has been scanned, JUMP to 52EFH to print whatever this pass collected.
5291
PUSH IX DD E5
Save Register Pair IX, which points at the first byte of the current program line record, onto the stack.
5293
POP IY FD E1
Restore that same value into Register Pair IY. The scanner at 538AH walks the line with Register Pair IY and reads its characters as (IY+04H), which is the first token byte of the record because the link word occupies offsets 0 and 1 and the line number offsets 2 and 3. Register Pair IX is left pointing at the record start so that 552FH can read the line number from IX+02H and IX+03H.
5295
LD HL,582CH 21 2C 58
Loop Start
Point Register Pair HL to 582CH, the eight-byte cell that receives the next reference the scanner finds. Like 581CH and 5824H it lies above the loaded image and is claimed by the overlay as work space.
5298
PUSH HL E5
Save the candidate cell address 582CH (Register Pair HL) onto the stack; the scanner returns with Register Pair HL advanced past whatever it stored.
5299
GOSUB to 537BH to fill the eight bytes at 582CH with seven blanks and a 00H terminator, clearing the previous candidate.
529C
GOSUB to 538AH, the program text scanner. It walks the current line with Register Pair IY, ignores string literals, REM text and DATA lists, and writes the next variable name or line number reference it meets into the buffer at Register Pair HL.
529F
POP HL E1
Restore the candidate cell address 582CH from the stack into Register Pair HL.
52A0
LD A,(HL) 7E
Fetch the first byte of the candidate at 582CH into Register A. It is still 20H (ASCII: blank) when 538AH reached the end of the line without finding anything.
52A1
CP 20H FE 20
Compare Register A, the first byte of the candidate at 582CH, against 20H (ASCII: blank). If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
52A3
If the NZ FLAG (Not Zero) has been set because the scanner did store a name or a line number, JUMP to 52AAH to test the candidate against the listing restrictions.
52A5
GOSUB to 56D8H to advance Register Pair IX to the first byte of the next program line record. 56D8H steps past the two-byte link and the two-byte line number and then runs forward to the 00H that ends the line.
52A8
LOOP BACK to 528CH to test the new value of Register Pair IX against the end of the program and scan the next line.
52AA
LD A,(5843H) 3A 43 58
Fetch the restriction switch from 5843H into Register A. 5570H stores 56H (ASCII: V) there for -V, 4CH (ASCII: L) for -L, and leaves 00H when no switch was given, in which case both variables and line numbers are listed.
52AD
CP 56H FE 56
Compare Register A, the restriction switch from 5843H, against 56H (ASCII: V). If Register A equals 56H, the Z FLAG is set; otherwise the NZ FLAG is set.
52AF
If the NZ FLAG (Not Zero) has been set because the switch is not -V, JUMP to 52B8H to test for -L.
52B1
LD A,(HL) 7E
Fetch the first byte of the candidate at 582CH, through Register Pair HL, into Register A.
52B2
CP 41H FE 41
Compare Register A, the first character of the candidate, against 41H (ASCII: A). If Register A is less than 41H, the CARRY FLAG is set; if it is 41H or greater, the NO CARRY FLAG is set. A variable name always starts with a letter and a line number always starts with a digit.
52B4
If the CARRY FLAG has been set because the candidate is a line number rather than a variable name, LOOP BACK to 5295H to discard it and scan on. The -V switch restricts the listing to variables.
52B6
JUMP to 52C1H to compare this accepted candidate against the current entry.
52B8
CP 4CH FE 4C
Compare Register A, the restriction switch from 5843H, against 4CH (ASCII: L). If Register A equals 4CH, the Z FLAG is set; otherwise the NZ FLAG is set.
52BA
If the NZ FLAG (Not Zero) has been set because no switch was given at all, JUMP to 52C1H; with 5843H holding 00H both variables and line numbers are listed.
52BC
LD A,(HL) 7E
Fetch the first byte of the candidate at 582CH, through Register Pair HL, into Register A.
52BD
CP 3AH FE 3A
Compare Register A, the first character of the candidate, against 3AH (ASCII: :). If Register A is less than 3AH, the CARRY FLAG is set; if it is 3AH or greater, the NO CARRY FLAG is set. 3AH is one above ASCII 9, so carry means the candidate begins with a digit.
52BF
If the NO CARRY FLAG has been set because the candidate begins with a letter and is therefore a variable name, LOOP BACK to 5295H to discard it. The -L switch restricts the listing to line numbers.
52C1
LD DE,5824H 11 24 58
Point Register Pair DE to 5824H, the smallest reference name accepted so far in this pass. Register Pair HL still points at the candidate at 582CH.
52C4
GOSUB to 5360H to compare the candidate at Register Pair HL against the current entry at Register Pair DE. 5360H walks both strings and returns with the Z FLAG set when they match and with the CARRY FLAG set when the string at Register Pair DE is the lower of the two.
52C7
If the Z FLAG (Zero) has been set because this reference is another occurrence of the entry already being collected, JUMP to 52E5H to add the current line number to its list.
52C9
LD A,(5844H) 3A 44 58
Fetch the specific-entry flag from 5844H into Register A. It is 01H when the parameter text carried an =name or =linenumber.
52CC
OR A B7
OR Register A with itself to set the flags from the specific-entry flag without changing it.
52CD
If the NZ FLAG (Not Zero) has been set because only one named entry is wanted and this candidate is not it, LOOP BACK to 5295H to discard the candidate and scan on.
52CF
LD DE,581CH 11 1C 58
Point Register Pair DE to 581CH, the reference name that was listed on the previous pass. Register Pair HL still points at the candidate at 582CH.
52D2
GOSUB to 5360H to compare the candidate at Register Pair HL against the last name listed at Register Pair DE. The CARRY FLAG comes back set when the string at Register Pair DE is the lower of the two.
52D5
If the NO CARRY FLAG has been set because the candidate is not higher than the name already listed, LOOP BACK to 5295H to discard it. This is what stops an entry being listed twice: each pass takes only names above the previous one.
52D7
LD DE,5824H 11 24 58
Point Register Pair DE to 5824H, the smallest reference name accepted so far in this pass. Register Pair HL still points at the candidate at 582CH.
52DA
GOSUB to 5360H to compare the candidate at Register Pair HL against the current smallest at Register Pair DE. The CARRY FLAG comes back set when the string at Register Pair DE is the lower of the two.
52DD
If the CARRY FLAG has been set because the current smallest is lower than the candidate, LOOP BACK to 5295H to discard the candidate. Only a name that is lower than the current smallest, and higher than the name already listed, becomes the new entry, which is how one pass finds the next entry in collating order without a sort table.
52DF
GOSUB to 5374H to copy the candidate string from Register Pair HL at 582CH to Register Pair DE at 5824H, making it the new smallest entry of this pass.
52E2
GOSUB to 5515H to reset the line number list pointer 583CH to STREND+5, discarding the line numbers collected for the entry this candidate has just displaced.
52E5
GOSUB to 552FH to append the current line number to the list. 552FH reads the line number from IX+02H and IX+03H, the line number field of the program line record Register Pair IX is standing on, and stores it at the address in the list pointer 583CH.
52E8
LD A,01H 3E 01
Load Register A with 01H, the value that marks this pass as having produced an entry.
52EA
LD (5840H),A 32 40 58
Store 01H (Register A) to memory location 5840H, the flag that 52F2H tests to decide whether there is anything left to list.
52ED
LOOP BACK to 5295H to look for the next reference in the same program line.

52EFH - Print One Cross Reference Entry

The entry selected by the pass just finished is printed as a seven-character reference column followed by its line numbers, eight to a line, wrapping onto continuation lines with an empty reference column.

52EF
GOSUB to 5521H to close the line number list. 5521H writes a 0000H terminator at the address in the list pointer 583CH, clears the previous-line-number cell 583EH, and then resets 583CH to STREND+5 so that the same pointer can be used to read the list back.
52F2
LD A,(5840H) 3A 40 58
Fetch the pass result flag from 5840H into Register A. It was set to 01H at 52EAH if any reference was accepted during the pass just finished.
52F5
OR A B7
OR Register A with itself to set the flags from the pass result flag without changing it.
52F6
If the Z FLAG (Zero) has been set because the pass found nothing at all, every entry has now been listed, so JUMP to 5354H to finish the listing.
52F9
XOR A AF
Set Register A to ZERO and clear all flags.
52FA
LD (5842H),A 32 42 58
Store zero (Register A) to memory location 5842H, clearing the flag that says the scanner is part way through a list of line numbers. Printing is about to begin and the scanner state must not carry into the next pass.
52FD
LD HL,5824H 21 24 58
Point Register Pair HL to 5824H, the entry name this pass selected.
5300
LD DE,581CH 11 1C 58
Point Register Pair DE to 581CH, the cell holding the name that was listed last.
5303
GOSUB to 5374H to copy the string at Register Pair HL to Register Pair DE, so that 581CH now records this entry as the last one listed and the next pass will only accept names above it.
5306
GOSUB to 54B9H to start a new entry on the listing: it draws the +-----+ rule and, when the line counter 5794H has reached 50, throws a page and reprints the title and the column headings first.
5309
GOSUB to 54F6H to start a new output line. 54F6H zeroes the field counter 5841H and then falls into 54FAH, which blanks the seven-character field at 5834H-583AH, places a 00H terminator at 583BH, bumps the counter to 1 and, because the count is 1, writes 3AH (ASCII: :) into both 5834H and 583AH. It returns with Register Pair HL pointing at 5834H and Register A holding the new field count.
530C
PUSH HL E5
Save the output field address 5834H (Register Pair HL) onto the stack.
530D
LD HL,5828H 21 28 58
Point Register Pair HL to 5828H, the fifth and last byte of the entry name at 5824H that will be shown.
5310
LD DE,5839H 11 39 58
Point Register Pair DE to 5839H, the last of the five character positions between the two colons of the reference field at 5834H.
5313
LD BC,0005H 01 05 00
Load Register Pair BC with 0005H, the number of characters of the entry name that fit in the reference field.
5316
LDDR ED B8
Block move five bytes downwards: Source is Register Pair HL at 5828H, Destination is Register Pair DE at 5839H, byte count is Register Pair BC = 5, and both pointers decrement. This copies 5824H-5828H to 5835H-5839H so the field reads a colon, five characters of the entry name and a closing colon, matching the seven-character +-----+ rule drawn by 54CFH.
5318
POP HL E1
Restore the output field address 5834H from the stack into Register Pair HL.
5319
GOSUB to 55F6H to send the completed reference field at 5834H to the current output destination.
531C
Loop Start
GOSUB to 5555H to read the next line number from the collected list. 5555H advances the list pointer 583CH, returns the number in Register Pair HL with the NZ FLAG set, skips a number identical to the one before it, and returns with the Z FLAG set when it reaches the 0000H terminator.
531F
If the Z FLAG (Zero) has been set because the whole list for this entry has been printed, JUMP to 534DH to decide whether another pass is needed.
5322
PUSH HL E5
Save the line number just read (Register Pair HL) onto the stack while the output field is prepared.
5323
GOSUB to 54FAH to blank the seven-character output field at 5834H-583AH, place a 00H terminator at 583BH and bump the field counter 5841H. Register A comes back holding the new count and Register Pair HL points at 5834H.
5326
CP 0AH FE 0A
Compare Register A, the number of fields now used on this output line, against 0AH. If Register A is less than 0AH, the CARRY FLAG is set; if it is 0AH or greater, the NO CARRY FLAG is set.
5328
If the CARRY FLAG has been set because fewer than ten fields have been used, JUMP to 5336H and print the number on the current line. The reference field counts as the first, so eight line numbers fit on a line.
532A
GOSUB to 54AEH to end the current output line. 54AEH prints a carriage return when the page line counter 5794H is below 55, and falls into the page-break code at 54B9H when the page is full.
532D
GOSUB to 54F6H to start the continuation line: the field counter 5841H is zeroed and 54FAH then makes the field read a colon, five blanks and a colon, which is the reference column left empty.
5330
GOSUB to 55F6H to send that empty reference field at 5834H to the current output destination, so the line numbers on a continuation line stay in their columns.
5333
GOSUB to 54FAH to blank the output field again and bump the field counter 5841H to 2, ready for the first line number of the continuation line.
5336
POP HL E1
Restore the line number from the stack into Register Pair HL.
5337
GOSUB to 56C8H to convert the 16-bit line number in Register Pair HL to ASCII. 56C8H hands it to the ROM through MAKINT at 0A9AH, FOUINI at 1034H and FOUT2 at 0FD9H, leaves Register Pair HL unchanged and returns Register Pair DE pointing one byte past the start of the text in the ROM number buffer FBUFFR at 412FH.
533A
DEC DE 1B
DECrement Register Pair DE by 1, cancelling the INC DE that 56C8H performed at 56D5H, so Register Pair DE points at the first byte the ROM conversion produced.
533B
EX DE,HL EB
EXchange Register Pair DE with Register Pair HL, so Register Pair HL now points at the ASCII line number in FBUFFR at 412FH.
533C
LD DE,5834H 11 34 58
Point Register Pair DE to 5834H, the seven-character output field that 5323H or 5333H has just blanked.
533F
PUSH DE D5
Save the output field address 5834H (Register Pair DE) onto the stack.
5340
GOSUB to 5374H to copy the ASCII line number from Register Pair HL into the field at Register Pair DE. 5374H stops at the 00H that ends the ROM text and does not copy it, so the blanks 54FAH placed in the rest of the field survive and the number is left-aligned in a seven-character column.
5343
POP HL E1
Restore the output field address 5834H from the stack into Register Pair HL.
5344
GOSUB to 55F6H to send the line number field at 5834H to the current output destination.
5347
GOSUB to 56D8H, which steps Register Pair IX past four bytes and then forward to the next 00H. Register Pair IX was left standing on the 0000H link word that ends the program when the selection pass finished at 528CH, and it is reloaded from TXTTAB at 40A4H at the head of every pass, so this movement has no effect on the listing.
534A
LOOP BACK to 531CH to fetch and print the next line number of this entry.

534DH - End of the Listing

Reached when a selection pass finds nothing left to list, or after the single entry named by an =name or =linenumber parameter has been printed.

534D
LD A,(5844H) 3A 44 58
Fetch the specific-entry flag from 5844H into Register A. It is 01H when the parameter text carried an =name or =linenumber and only that one entry was to be listed.
5350
OR A B7
OR Register A with itself to set the flags from the specific-entry flag without changing it.
5351
If the Z FLAG (Zero) has been set because the whole program is being cross referenced, LOOP BACK to 5273H to run another selection pass and find the next entry in collating order.
5354
GOSUB to 54CFH to print the closing rule: a carriage return, 2BH (ASCII: +), five copies of 2DH (ASCII: -), a further 2BH and a carriage return.
5357
Point Register Pair HL to 5791H, the two-byte string 0CH,00H. 0CH is the form feed the output routine at 560DH recognises, and it also resets the page line counter 5794H to zero.
535A
GOSUB to 55F6H to send the form feed to the current output destination, ejecting the page or clearing the screen at the end of the listing.
535D
JUMP to 568DH to close the listing file if one was opened and reload BASIC/CMD.

5360H - Compare Two Zero Terminated Strings

The comparison that orders the cross reference. Register Pair HL addresses one string, Register Pair DE the other; both registers are returned unchanged and the caller reads the Z FLAG and the CARRY FLAG.

5360
PUSH HL E5
Save Register Pair HL, which points at the first string to be compared, onto the stack so the caller gets it back unchanged.
5361
PUSH DE D5
Save Register Pair DE, which points at the second string to be compared, onto the stack so the caller gets it back unchanged.
5362
XOR A AF
Loop Start
Set Register A to ZERO and clear all flags.
5363
CP (HL) BE
Compare Register A, now zero, against the byte at the address in Register Pair HL, the current character of the first string. If that character is 00H, the Z FLAG is set.
5364
If the Z FLAG (Zero) has been set because the first string has reached its 00H terminator, JUMP to 5371H to return with the Z FLAG still set, meaning the two strings matched over their whole length.
5366
LD A,(DE) 1A
Fetch the current character of the second string from the address in Register Pair DE into Register A.
5367
OR A B7
OR Register A with itself to set the flags from that character without changing it.
5368
If the Z FLAG (Zero) has been set because the second string has reached its 00H terminator, JUMP to 5371H to return with the Z FLAG set.
536A
CP (HL) BE
Compare Register A, the current character of the second string, against the byte at the address in Register Pair HL, the current character of the first string. If they are equal the Z FLAG is set; if the character of the second string is the lower of the two the CARRY FLAG is set.
536B
If the NZ FLAG (Not Zero) has been set because the two characters differ, JUMP to 5371H to return, carrying both the Z FLAG state and the CARRY FLAG state that this comparison produced.
536D
INC HL 23
INCrement Register Pair HL by 1 to step to the next character of the first string.
536E
INC DE 13
INCrement Register Pair DE by 1 to step to the next character of the second string.
536F
Loop End
LOOP BACK to 5362H to compare the next pair of characters.
5371
POP DE D1
Restore Register Pair DE from the stack. POP does not disturb the flags, so the comparison result survives.
5372
POP HL E1
Restore Register Pair HL from the stack. POP does not disturb the flags, so the comparison result survives.
5373
RET C9
RETurn to the caller with the Z FLAG set when the strings are equal, and the CARRY FLAG set when the string addressed by Register Pair DE is the lower of the two.

5374H - Copy a Zero Terminated String

Copies from Register Pair HL to Register Pair DE, stopping at but not copying the 00H terminator so that trailing blanks already in the destination survive.

5374
LD A,(HL) 7E
Loop Start
Fetch the next source character from the address in Register Pair HL into Register A.
5375
OR A B7
OR Register A with itself to set the flags from that character without changing it.
5376
RET Z C8
RETurn to the caller if the Z FLAG is set, because the 00H terminator has been reached. The terminator itself is not copied, so any blanks already sitting in the destination beyond the copied text are left alone.
5377
LDI ED A0
Block move one byte: Source is Register Pair HL, Destination is Register Pair DE, both incrementing. Register Pair BC is decremented by the instruction but is not used to control this loop, which ends on the 00H terminator instead.
5379
Loop End
LOOP BACK to 5374H to copy the next character.

537BH - Fill an Eight Byte Name Field

Writes seven copies of a fill character followed by a 00H terminator. Entering at 537BH fills with blanks; entering at 537DH fills with whatever the caller has put in Register A.

537B
LD A,20H 3E 20
Load Register A with 20H (ASCII: blank), the fill character used when a name buffer is being cleared for a fresh comparison.
537D
PUSH HL E5
Save Register Pair HL, which points at the eight-byte field to be filled, onto the stack. This is also the entry point used at 5285H when Register A has already been loaded with 0FFH.
537E
PUSH BC C5
Save Register Pair BC onto the stack; Register B is about to be used as the fill counter and the caller's value must survive.
537F
LD B,07H 06 07
Load Register B with 07H, the number of fill bytes. A name field is seven characters plus a terminator.
5381
LD (HL),A 77
Loop Start
Store the fill character (Register A) to the address in Register Pair HL.
5382
INC HL 23
INCrement Register Pair HL by 1 to step to the next byte of the field.
5383
Loop End
DECrement Register B and loop back to 5381H if not zero, so that seven copies of the fill character are written.
5385
XOR A AF
Set Register A to ZERO and clear all flags.
5386
LD (HL),A 77
Store the 00H terminator (Register A) to the address in Register Pair HL, the eighth byte of the field.
5387
POP BC C1
Restore Register Pair BC from the stack.
5388
POP HL E1
Restore Register Pair HL from the stack, so the caller still has the address of the field it asked to be filled.
5389
RET C9
RETurn to the caller.

538AH - The Program Text Scanner

Walks the tokenised BASIC line with Register Pair IY, reading each byte as (IY+04H) because the line record begins with a two-byte link and a two-byte line number. It skips string literals, REM comment text, DATA item lists and numeric constants, recognises the seven tokens a line number may follow, and otherwise collects a variable name.

538A
LD A,(5842H) 3A 42 58
Fetch the line number list flag from 5842H into Register A. It holds 01H when the previous call left the scanner part way through a comma-separated list of line numbers, as in ON n GOTO 100,200,300.
538D
OR A B7
OR Register A with itself to set the flags from that flag without changing it.
538E
If the NZ FLAG (Not Zero) has been set because a list of line numbers is still being read, JUMP to 5416H to take the next number from it instead of restarting the token scan.
5391
JUMP to 5395H, stepping over the INC IY at 5393H so that the character Register Pair IY is already standing on is examined first.
5393
INC IY FD 23
INCrement Register Pair IY by 1 to step to the next byte of the tokenised program line. This entry is used by the paths at 53CCH, 53DEH and 5411H, which have already dealt with the byte under the pointer.
5395
LD A,(IY+04H) FD 7E 04
Loop Start
Fetch the current byte of the program line into Register A through (IY+04H). Register Pair IY was set from Register Pair IX at 5293H, and the line record is a two-byte link, a two-byte line number and then the tokenised text, so offset 4 addresses the text.
5398
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
5399
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line and there is nothing more to find on it.
539A
CP 93H FE 93
Compare Register A, the current byte of the program line, against 93H, the Level II BASIC token for REM. If Register A equals 93H, the Z FLAG is set.
539C
RET Z C8
RETurn to the caller if the Z FLAG is set. Everything after REM is comment text and must not be scanned for names or line numbers.
539D
CP 22H FE 22
Compare Register A, the current byte of the program line, against 22H (ASCII: "). If Register A equals 22H, the Z FLAG is set.
539F
If the Z FLAG (Zero) has been set because a string literal begins here, JUMP to 5406H to skip forward to the closing quotation mark.
53A1
GOSUB to 56F2H to test whether the byte in Register A is one of the seven Level II tokens that can be followed by a line number: 0CAH THEN, 95H ELSE, 9FH RESUME, 8DH GOTO, 91H GOSUB, 8EH RUN and 0C2H ERL. It returns with the Z FLAG set on a match.
53A4
If the Z FLAG (Zero) has been set because the byte is a line number reference token, JUMP to 5414H to step past it and collect the number that follows.
53A7
CP 88H FE 88
Compare Register A, the current byte of the program line, against 88H, the Level II BASIC token for DATA. If Register A equals 88H, the Z FLAG is set.
53A9
If the Z FLAG (Zero) has been set because a DATA statement begins here, JUMP to 53C3H to skip its item list, which is literal text rather than references.
53AB
CP 26H FE 26
Compare Register A, the current byte of the program line, against 26H (ASCII: &), the prefix Level II BASIC uses for a hexadecimal or octal constant. If Register A equals 26H, the Z FLAG is set.
53AD
If the NZ FLAG (Not Zero) has been set because this is not a constant prefix, JUMP to 53D5H to test the byte as the possible start of a variable name.
53AF
INC IY FD 23
Loop Start
INCrement Register Pair IY by 1 to step past the current character of the numeric constant.
53B1
LD A,(IY+04H) FD 7E 04
Fetch the next byte of the program line into Register A through (IY+04H).
53B4
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
53B5
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line.
53B6
CP 2EH FE 2E
Compare Register A, the current byte of the program line, against 2EH (ASCII: .). If Register A equals 2EH, the Z FLAG is set.
53B8
If the Z FLAG (Zero) has been set because a decimal point belongs to this constant, LOOP BACK to 53AFH to skip it.
53BA
GOSUB to 5479H, the character classifier. It reads (IY+04H) and returns Register A as 0 for a token or punctuation, 1 for a digit, 2 for a letter, 3 for one of the type declaration characters ! # $ %, and 4 for an opening parenthesis.
53BD
OR A B7
OR Register A with itself to set the flags from the classification code without changing it.
53BE
If the NZ FLAG (Not Zero) has been set because the character still belongs to the constant, LOOP BACK to 53AFH to skip it as well. Digits and the letters A to F of a hexadecimal constant are both consumed here.
53C0
JUMP to 5395H to resume the ordinary token scan at the first character beyond the constant.
53C3
INC IY FD 23
Loop Start
INCrement Register Pair IY by 1 to step past the DATA token or the item character just examined.
53C5
LD A,(IY+04H) FD 7E 04
Fetch the next byte of the program line into Register A through (IY+04H).
53C8
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
53C9
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line and the DATA list ran to the end of it.
53CA
CP 3AH FE 3A
Compare Register A, the current byte of the program line, against 3AH (ASCII: :), the statement separator that ends a DATA list. If Register A equals 3AH, the Z FLAG is set.
53CC
If the Z FLAG (Zero) has been set because the DATA list has ended at a colon, JUMP to 5393H to step past the colon and resume the ordinary token scan.
53CE
CP 80H FE 80
Compare Register A, the current byte of the program line, against 80H, the lowest Level II BASIC token value. If Register A is less than 80H, the CARRY FLAG is set; if it is 80H or greater, the NO CARRY FLAG is set.
53D0
If the CARRY FLAG has been set because the byte is ordinary text rather than a token, LOOP BACK to 53C3H to keep skipping the DATA items.
53D2
JUMP to 5395H to resume the ordinary token scan at the token that ended the DATA list.
53D5
GOSUB to 5479H, the character classifier, to find out what the byte at (IY+04H) is. Register A comes back as 0, 1, 2, 3 or 4 as described at 53BAH.
53D8
CP 01H FE 01
Compare Register A, the classification code, against 01H, the code for a digit. If Register A equals 01H, the Z FLAG is set.
53DA
If the Z FLAG (Zero) has been set because a numeric constant begins here, JUMP to 53AFH to skip the whole constant. A number in the body of a statement is a value, not a line number reference.
53DC
CP 02H FE 02
Compare Register A, the classification code, against 02H, the code for a letter. If Register A equals 02H, the Z FLAG is set.
53DE
If the NZ FLAG (Not Zero) has been set because the byte is neither a digit nor a letter, JUMP to 5393H to step past it and carry on scanning.
53E0
GOSUB to 5472H to store this first letter of the variable name at the address in Register Pair HL, advance both Register Pair HL and Register Pair IY, and classify the following character into Register A.
53E3
RET Z C8
RETurn to the caller if the Z FLAG is set, because the classifier returned 0 and the name is complete with a single letter.
53E4
CP 03H FE 03
Compare Register A, the classification code of the second character, against 03H, the code for one of the type declaration characters ! # $ %. If Register A equals 03H, the Z FLAG is set.
53E6
If the Z FLAG (Zero) has been set because a type declaration character follows the first letter, JUMP to 53FBH to store it as part of the name.
53E8
If the NO CARRY FLAG has been set because the classification code is 04H, an opening parenthesis, JUMP to 5401H to store it and finish the name.
53EA
LD A,(IY+04H) FD 7E 04
Fetch the second character of the variable name into Register A through (IY+04H). The classifier has already established that it is a letter or a digit.
53ED
LD (HL),A 77
Store that character (Register A) to the address in Register Pair HL, the second position of the name buffer.
53EE
INC HL 23
INCrement Register Pair HL by 1 to step to the next free position in the name buffer.
53EF
INC IY FD 23
Loop Start
INCrement Register Pair IY by 1 to step past the character just dealt with.
53F1
GOSUB to 5479H, the character classifier, to classify the next character of the program line into Register A.
53F4
RET Z C8
RETurn to the caller if the Z FLAG is set, because the classifier returned 0 and the name has ended.
53F5
CP 03H FE 03
Compare Register A, the classification code, against 03H. If Register A is less than 03H, the CARRY FLAG is set; if it is 03H or greater, the NO CARRY FLAG is set.
53F7
Loop End
If the CARRY FLAG has been set because the character is another letter or digit, LOOP BACK to 53EFH to step over it without storing it. Level II BASIC distinguishes variables by their first two characters only, so the buffer keeps exactly those two and the rest of the name is discarded.
53F9
If the NZ FLAG (Not Zero) has been set because the classification code is 04H, an opening parenthesis, JUMP to 5401H to store it and finish the name.
53FB
GOSUB to 5472H to store the type declaration character at the address in Register Pair HL, advance both Register Pair HL and Register Pair IY, and classify the following character into Register A.
53FE
CP 04H FE 04
Compare Register A, the classification code of the character after the type declaration, against 04H, the code for an opening parenthesis. If Register A equals 04H, the Z FLAG is set.
5400
RET NZ C0
RETurn to the caller if the NZ FLAG is set, because no subscript follows and the name is complete.
5401
LD A,(IY+04H) FD 7E 04
Fetch the opening parenthesis into Register A through (IY+04H). It marks the variable as an array and is kept as part of the name so that A and A( are listed separately.
5404
LD (HL),A 77
Store the opening parenthesis (Register A) to the address in Register Pair HL, the last position of the name buffer to be filled.
5405
RET C9
RETurn to the caller with the variable name complete in the buffer at 582CH: first letter, second character, optional type declaration character and optional opening parenthesis.

5406H - Skip a Quoted String Literal

Runs forward to the closing quotation mark so that names and numbers inside a string constant are never listed.

5406
INC IY FD 23
Loop Start
INCrement Register Pair IY by 1 to step past the opening quotation mark, or past the literal character just examined.
5408
LD A,(IY+04H) FD 7E 04
Fetch the next byte of the string literal into Register A through (IY+04H).
540B
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
540C
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line and the literal was left unclosed.
540D
CP 22H FE 22
Compare Register A, the current byte of the string literal, against 22H (ASCII: "). If Register A equals 22H, the Z FLAG is set.
540F
Loop End
If the NZ FLAG (Not Zero) has been set because the closing quotation mark has not been reached, LOOP BACK to 5406H.
5411
JUMP to 5393H to step past the closing quotation mark and resume the ordinary token scan.

5414H - Collect a Line Number Reference

Entered after one of the seven reference tokens. Blanks, commas and the equals token are skipped so that an ON n GOTO list is followed all the way through; leading zeros are dropped; up to five digits are taken and the result is right-justified with leading zeros so that a character comparison orders line numbers numerically.

5414
INC IY FD 23
Loop Start
INCrement Register Pair IY by 1 to step past the line number reference token, or past the separator just examined.
5416
XOR A AF
Set Register A to ZERO and clear all flags. This is also the entry taken from 538EH when the previous call left a comma-separated list of line numbers part way through.
5417
LD (5842H),A 32 42 58
Store zero (Register A) to memory location 5842H, clearing the flag that says a list of line numbers is being read. It is set again at 5440H if another number is actually found.
541A
LD A,(IY+04H) FD 7E 04
Fetch the current byte of the program line into Register A through (IY+04H).
541D
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
541E
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line.
541F
CP 20H FE 20
Compare Register A, the current byte, against 20H (ASCII: blank). If Register A equals 20H, the Z FLAG is set.
5421
If the Z FLAG (Zero) has been set because a blank separates the token from its line number, LOOP BACK to 5414H to step past it.
5423
CP 2CH FE 2C
Compare Register A, the current byte, against 2CH (ASCII: ,). If Register A equals 2CH, the Z FLAG is set. A comma separates the targets of an ON n GOTO or ON n GOSUB.
5425
If the Z FLAG (Zero) has been set because a comma was found, LOOP BACK to 5414H to step past it and read the next target.
5427
CP 0D5H FE D5
Compare Register A, the current byte, against 0D5H, the Level II BASIC token for the equals sign. If Register A equals 0D5H, the Z FLAG is set. This is what lets ERL = 100 be recognised.
5429
If the Z FLAG (Zero) has been set because the equals token was found, LOOP BACK to 5414H to step past it.
542B
CP 30H FE 30
Loop Start
Compare Register A, the current byte, against 30H (ASCII: 0). If Register A equals 30H, the Z FLAG is set.
542D
If the NZ FLAG (Not Zero) has been set because the character is not a leading zero, JUMP to 5438H to classify it properly.
542F
INC IY FD 23
INCrement Register Pair IY by 1 to step past a leading zero, which carries no value and must not be copied into the reference.
5431
LD A,(IY+04H) FD 7E 04
Fetch the next byte of the program line into Register A through (IY+04H).
5434
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
5435
RET Z C8
RETurn to the caller if the Z FLAG is set, because 00H terminates the tokenised line.
5436
Loop End
LOOP BACK to 542BH to test the next character for a further leading zero.
5438
GOSUB to 5479H, the character classifier, to classify the byte at (IY+04H) into Register A.
543B
CP 01H FE 01
Compare Register A, the classification code, against 01H, the code for a digit. If Register A equals 01H, the Z FLAG is set.
543D
If the NZ FLAG (Not Zero) has been set because no line number actually follows the reference token, JUMP to 5395H to resume the ordinary token scan.
5440
LD (5842H),A 32 42 58
Store 01H (Register A) to memory location 5842H, marking the scanner as being inside a list of line numbers. The next call at 538AH will therefore re-enter at 5416H and look for a further comma-separated target instead of restarting the token scan.
5443
PUSH HL E5
Save Register Pair HL, which points at the start of the reference buffer at 582CH, onto the stack.
5444
LD B,05H 06 05
Load Register B with 05H, the width of the line number field. Level II BASIC line numbers run to five digits.
5446
PUSH BC C5
Loop Start
Save Register Pair BC onto the stack; 5472H and 5479H both use Register C.
5447
GOSUB to 5472H to store the current digit at the address in Register Pair HL, advance both Register Pair HL and Register Pair IY, and classify the following character into Register A.
544A
POP BC C1
Restore Register Pair BC from the stack, recovering the remaining field width in Register B.
544B
CP 01H FE 01
Compare Register A, the classification code of the next character, against 01H, the code for a digit. If Register A equals 01H, the Z FLAG is set.
544D
If the NZ FLAG (Not Zero) has been set because the line number has ended, JUMP to 5453H to right-justify the digits collected so far.
544F
Loop End
DECrement Register B and loop back to 5446H if not zero, so that at most five digits are taken.
5451
POP HL E1
Restore the reference buffer address 582CH from the stack into Register Pair HL. All five digit positions were filled, so no padding is needed.
5452
RET C9
RETurn to the caller with the five-digit line number in the buffer at 582CH.
5453
POP HL E1
Restore the reference buffer address 582CH from the stack into Register Pair HL.
5454
DEC B 05
DECrement Register B by 1. Register B held the number of field positions still unused when the digits ran out, and one of those was consumed by the test that failed, so Register B now holds the number of leading zeros the number needs.
5455
RET Z C8
RETurn to the caller if the Z FLAG is set, because the number already fills the field and no padding is required.
5456
INC HL 23
INCrement Register Pair HL by 1, the first of three steps that move it from 582CH to 582FH.
5457
INC HL 23
INCrement Register Pair HL by 1, the second of those three steps.
5458
INC HL 23
INCrement Register Pair HL by 1, so Register Pair HL now addresses 582FH, the fourth byte of the five-character line number field.
5459
PUSH HL E5
Save Register Pair HL, holding 582FH, onto the stack.
545A
POP DE D1
Restore it into Register Pair DE, so Register Pair DE also addresses 582FH.
545B
INC DE 13
INCrement Register Pair DE by 1 so it addresses 5830H, one position to the right of Register Pair HL. This is the one-place shift the padding loop performs.
545C
PUSH HL E5
Loop Start
Save Register Pair HL, the source address 582FH, onto the stack.
545D
PUSH DE D5
Save Register Pair DE, the destination address 5830H, onto the stack.
545E
PUSH BC C5
Save Register Pair BC, holding the remaining pad count in Register B, onto the stack.
545F
LD BC,0004H 01 04 00
Load Register Pair BC with 0004H, the number of bytes to be shifted right by one place.
5462
LDDR ED B8
Block move four bytes downwards: Source is Register Pair HL at 582FH, Destination is Register Pair DE at 5830H, byte count is Register Pair BC = 4, and both pointers decrement. This shifts the digits at 582CH-582FH one place to the right into 582DH-5830H.
5464
POP BC C1
Restore Register Pair BC from the stack, recovering the pad count in Register B.
5465
POP DE D1
Restore Register Pair DE from the stack, recovering the destination address 5830H.
5466
POP HL E1
Restore Register Pair HL from the stack, recovering the source address 582FH.
5467
PUSH HL E5
Save Register Pair HL, holding 582FH, onto the stack again while the vacated position is filled.
5468
DEC HL 2B
DECrement Register Pair HL by 1, the first of three steps back towards the start of the field.
5469
DEC HL 2B
DECrement Register Pair HL by 1, the second of those three steps.
546A
DEC HL 2B
DECrement Register Pair HL by 1, so Register Pair HL now addresses 582CH, the position the shift has vacated.
546B
LD A,30H 3E 30
Load Register A with 30H (ASCII: 0), the pad character.
546D
LD (HL),A 77
Store the zero digit (Register A) to the address in Register Pair HL at 582CH.
546E
POP HL E1
Restore Register Pair HL from the stack, so it addresses 582FH again ready for another shift.
546F
Loop End
DECrement Register B and loop back to 545CH if not zero, so that the line number ends up right-justified in five characters with leading zeros. That makes 5360H's character-by-character comparison order the line numbers numerically.
5471
RET C9
RETurn to the caller with the padded line number in the buffer at 582CH.

5472H - Store a Character and Classify the Next

A two-part helper: it stores the character under Register Pair IY into the buffer at Register Pair HL, advances both pointers, and then falls through into the classifier so the caller is told what the next character is.

5472
LD A,(IY+04H) FD 7E 04
Fetch the current character of the program line into Register A through (IY+04H).
5475
LD (HL),A 77
Store that character (Register A) to the address in Register Pair HL, the next free position of the reference buffer.
5476
INC HL 23
INCrement Register Pair HL by 1 to step to the next free position of the reference buffer.
5477
INC IY FD 23
INCrement Register Pair IY by 1 to step past the character just stored, then fall through into the classifier at 5479H so the caller is told what the following character is.

5479H - The Character Classifier

Returns Register A as 0 for a BASIC token or any other character that cannot be part of a name, 1 for a digit, 2 for a letter, 3 for one of the type declaration characters ! # $ %, and 4 for an opening parenthesis.

5479
LD C,01H 0E 01
Load Register C with 01H, the classification code for a digit. Register C is stepped up as each test fails, so the code is built by walking the tests in order.
547B
LD A,(IY+04H) FD 7E 04
Fetch the character to be classified into Register A through (IY+04H).
547E
CP 80H FE 80
Compare Register A against 80H, the lowest Level II BASIC token value. If Register A is less than 80H, the CARRY FLAG is set; if it is 80H or greater, the NO CARRY FLAG is set.
5480
If the NO CARRY FLAG has been set because the byte is a BASIC token rather than text, JUMP to 54A9H to return the classification code 0.
5482
CP 30H FE 30
Compare Register A against 30H (ASCII: 0). If Register A is less than 30H, the CARRY FLAG is set.
5484
If the CARRY FLAG has been set because the character is below ASCII 0, JUMP to 548AH; it cannot be a digit.
5486
CP 3AH FE 3A
Compare Register A against 3AH, one above ASCII 9. If Register A is less than 3AH, the CARRY FLAG is set.
5488
If the CARRY FLAG has been set because the character is in the range ASCII 0 to 9, JUMP to 54ABH to return the classification code 1, a digit.
548A
INC C 0C
INCrement Register C by 1, making it 02H, the classification code for a letter.
548B
CP 41H FE 41
Compare Register A against 41H (ASCII: A). If Register A is less than 41H, the CARRY FLAG is set.
548D
If the CARRY FLAG has been set because the character is below ASCII A, JUMP to 5493H; it cannot be a letter.
548F
CP 5BH FE 5B
Compare Register A against 5BH, one above ASCII Z. If Register A is less than 5BH, the CARRY FLAG is set.
5491
If the CARRY FLAG has been set because the character is in the range ASCII A to Z, JUMP to 54ABH to return the classification code 2, a letter.
5493
INC C 0C
INCrement Register C by 1, making it 03H, the classification code for a type declaration character.
5494
CP 25H FE 25
Compare Register A against 25H (ASCII: %), the integer type declaration character. If Register A equals 25H, the Z FLAG is set.
5496
If the Z FLAG (Zero) has been set, JUMP to 54ABH to return the classification code 3.
5498
CP 24H FE 24
Compare Register A against 24H (ASCII: $), the string type declaration character. If Register A equals 24H, the Z FLAG is set.
549A
If the Z FLAG (Zero) has been set, JUMP to 54ABH to return the classification code 3.
549C
CP 23H FE 23
Compare Register A against 23H (ASCII: #), the double precision type declaration character. If Register A equals 23H, the Z FLAG is set.
549E
If the Z FLAG (Zero) has been set, JUMP to 54ABH to return the classification code 3.
54A0
CP 21H FE 21
Compare Register A against 21H (ASCII: !), the single precision type declaration character. If Register A equals 21H, the Z FLAG is set.
54A2
If the Z FLAG (Zero) has been set, JUMP to 54ABH to return the classification code 3.
54A4
INC C 0C
INCrement Register C by 1, making it 04H, the classification code for an opening parenthesis.
54A5
CP 28H FE 28
Compare Register A against 28H (ASCII: (), which marks the variable as an array. If Register A equals 28H, the Z FLAG is set.
54A7
If the Z FLAG (Zero) has been set, JUMP to 54ABH to return the classification code 4.
54A9
LD C,00H 0E 00
Load Register C with 00H, the classification code meaning the character is neither part of a name nor a digit.
54AB
LD A,C 79
Load Register A with the classification code from Register C.
54AC
OR A B7
OR Register A with itself so the caller gets the Z FLAG set when the code is 0 and the NZ FLAG when it is 1, 2, 3 or 4.
54AD
RET C9
RETurn to the caller with Register A holding 0, 1, 2, 3 or 4 and Register Pair IY unchanged.

54AEH - End the Output Line and Break the Page

54AEH ends the current line, turning that into a page break when the page line counter 5794H has reached 55. 54B9H is the entry used when a new cross reference entry begins, which draws the separator rule and throws a page once 50 lines have been used.

54AE
Fetch the page line counter from 5794H into Register A. The string output routine at 5605H increments it for every carriage return sent and 5611H resets it to zero for every form feed.
54B1
Point Register Pair HL to 578FH, the two-byte string 0DH,00H, a bare carriage return.
54B4
CP 37H FE 37
Compare Register A, the number of lines already used on this page, against 37H. If Register A is less than 37H, the CARRY FLAG is set; if it is 37H or greater, the NO CARRY FLAG is set.
54B6
If the CARRY FLAG has been set because fewer than 55 lines have been printed on this page, JUMP to 55F6H to send the carriage return at 578FH. 55F6H returns straight to the caller of 54AEH.
54B9
Fetch the page line counter from 5794H into Register A. This is also the entry taken from 5306H when a new cross reference entry is about to be printed.
54BC
CP 32H FE 32
Compare Register A, the number of lines already used on this page, against 32H. If Register A is less than 32H, the CARRY FLAG is set; if it is 32H or greater, the NO CARRY FLAG is set.
54BE
If the CARRY FLAG has been set because fewer than 50 lines have been printed, JUMP to 54CFH to draw the entry separator only, leaving the page as it is.
54C0
GOSUB to 54CFH to draw the +-----+ separator rule at the foot of the page just filled.
54C3
Point Register Pair HL to 5721H, the byte 0CH followed by the title buffer at 5722H. Sending it throws a page and prints the title in one operation, and the form feed also resets the page line counter 5794H to zero.
54C6
GOSUB to 55F6H to send the form feed and title to the current output destination.
54C9
Point Register Pair HL to 5760H, the column heading line: a carriage return, " Ref", padding blanks and "Line Numbers".
54CC
GOSUB to 55F6H to print the column headings at the top of the new page, then fall through into 54CFH to draw the rule beneath them.

54CFH - Draw the Reference Column Rule

Prints a carriage return, a plus sign, five hyphens, a plus sign and a carriage return. The five hyphens match the five character positions between the colons of the reference field at 5834H.

54CF
PUSH IY FD E5
Save Register Pair IY onto the stack. The string output routine at 55F6H uses it, and the scanner's position in the program line must survive.
54D1
PUSH IX DD E5
Save Register Pair IX onto the stack, preserving the pointer to the current program line record.
54D3
Point Register Pair HL to 578FH, the two-byte string 0DH,00H, a bare carriage return.
54D6
GOSUB to 55F6H to send the carriage return, starting the rule on a line of its own.
54D9
Point Register Pair HL to 578CH, the two-byte string 2BH,00H, a single plus sign.
54DC
GOSUB to 55F6H to send the plus sign that opens the rule.
54DF
LD B,05H 06 05
Load Register B with 05H, the number of hyphens in the rule. It matches the five character positions between the two colons of the reference field at 5834H.
54E1
Loop Start
Point Register Pair HL to 578AH, the two-byte string 2DH,00H, a single hyphen.
54E4
PUSH BC C5
Save Register Pair BC onto the stack, since Register B is the loop counter and the output routine does not preserve it.
54E5
GOSUB to 55F6H to send one hyphen.
54E8
POP BC C1
Restore Register Pair BC from the stack, recovering the hyphen count in Register B.
54E9
Loop End
DECrement Register B and loop back to 54E1H if not zero, so five hyphens are printed.
54EB
Point Register Pair HL to 578EH, the three-byte string 2BH,0DH,00H, a plus sign followed by a carriage return. It overlaps the bare carriage return at 578FH, which is why both addresses are separate strings in the same three bytes.
54EE
GOSUB to 55F6H to close the rule with a plus sign and end the line.
54F1
POP IX DD E1
Restore Register Pair IX from the stack, recovering the pointer to the current program line record.
54F3
POP IY FD E1
Restore Register Pair IY from the stack, recovering the scanner's position in the program line.
54F5
RET C9
RETurn to the caller.

54F6H - The Seven Character Output Field

All listing output is built in the eight bytes at 5834H-583BH. 54F6H starts a new output line by zeroing the field counter 5841H; 54FAH blanks the field, counts it, and brackets it with colons when it is the first field of a line.

54F6
XOR A AF
Set Register A to ZERO and clear all flags.
54F7
LD (5841H),A 32 41 58
Store zero (Register A) to memory location 5841H, the count of fields already placed on the current output line. Clearing it here is what makes the next field the first of a new line.
54FA
LD HL,5834H 21 34 58
Point Register Pair HL to 5834H, the eight-byte output field. This is also the entry used at 5323H and 5333H, which want the next field on the same line rather than the start of a new one.
54FD
GOSUB to 537BH to fill 5834H-583AH with seven blanks and place a 00H terminator at 583BH, clearing whatever the previous field held. Register Pair HL is returned unchanged at 5834H.
5500
LD A,(5841H) 3A 41 58
Fetch the field count from 5841H into Register A.
5503
INC A 3C
INCrement Register A by 1 to count the field that is about to be built.
5504
LD (5841H),A 32 41 58
Store the new field count (Register A) to memory location 5841H.
5507
CP 01H FE 01
Compare Register A, the new field count, against 01H. If Register A equals 01H, the Z FLAG is set.
5509
RET NZ C0
RETurn to the caller if the NZ FLAG is set, because this is not the first field of the line and the field is to stay blank.
550A
PUSH AF F5
Save Register A, the field count, and the flags onto the stack so the caller still receives both.
550B
LD A,3AH 3E 3A
Load Register A with 3AH (ASCII: :), the character that brackets the reference column.
550D
LD (583AH),A 32 3A 58
Store the colon (Register A) to memory location 583AH, the seventh and last character position of the field.
5510
LD (5834H),A 32 34 58
Store the colon (Register A) to memory location 5834H, the first character position of the field, so the empty field reads as a colon, five blanks and a colon, exactly as wide as the +-----+ rule.
5513
POP AF F1
Restore Register A and the flags from the stack.
5514
RET C9
RETurn to the caller with Register Pair HL pointing at 5834H and Register A holding the new field count.

5515H - Reset the Line Number List Pointer

The collected line numbers are kept in the free memory above STREND at 40FDH, which is the first byte above all of the BASIC program's variables.

5515
LD HL,(40FDH) 2A FD 40
Load Register Pair HL with the contents of STREND at 40FDH, the Level II BASIC pointer to the first free byte above all of the program's simple variables and arrays.
5518
INC HL 23
INCrement Register Pair HL by 1, the first of five steps that clear the pointer of the last variable byte.
5519
INC HL 23
INCrement Register Pair HL by 1, the second of those five steps.
551A
INC HL 23
INCrement Register Pair HL by 1, the third of those five steps.
551B
INC HL 23
INCrement Register Pair HL by 1, the fourth of those five steps.
551C
INC HL 23
INCrement Register Pair HL by 1, so Register Pair HL now addresses STREND+5, where the list of collected line numbers begins.
551D
LD (583CH),HL 22 3C 58
Store that address (Register Pair HL) to memory location 583CH, the pointer that 552FH advances while the list is built and 5555H advances while it is read back.
5520
RET C9
RETurn to the caller.

5521H - Terminate the Line Number List

Writes the 0000H terminator, clears the duplicate suppression cell and resets the list pointer so the same pointer reads the list back.

5521
LD HL,(583CH) 2A 3C 58
Load Register Pair HL with the current list pointer from 583CH, which addresses the first free slot above the line numbers collected for this entry.
5524
XOR A AF
Set Register A to ZERO and clear all flags.
5525
LD (HL),A 77
Store the low byte of the 0000H list terminator (Register A) to the address in Register Pair HL.
5526
INC HL 23
INCrement Register Pair HL by 1 to address the second byte of the terminator.
5527
LD (HL),A 77
Store the high byte of the 0000H list terminator (Register A) to the address in Register Pair HL.
5528
LD H,A 67
Load Register H with zero from Register A, the first half of clearing Register Pair HL to 0000H.
5529
LD L,A 6F
Load Register L with zero from Register A, completing Register Pair HL = 0000H.
552A
LD (583EH),HL 22 3E 58
Store 0000H (Register Pair HL) to memory location 583EH, the cell that 5555H uses to remember the line number it returned last so that a repeated number is not printed twice.
552D
JUMP to 5515H to reset the list pointer 583CH to STREND+5, so that the same pointer now reads the list back from the beginning.

552FH - Append a Line Number to the List

Copies the line number field of the program line record Register Pair IX is standing on into the list, and checks that the list has not grown up into string space.

552F
LD HL,(583CH) 2A 3C 58
Load Register Pair HL with the current list pointer from 583CH, the address of the next free slot in the line number list.
5532
LD A,(IX+02H) DD 7E 02
Fetch the low byte of the current line number from (IX+02H). Register Pair IX points at the first byte of the program line record and the two-byte line number occupies offsets 2 and 3, immediately after the link word.
5535
LD (HL),A 77
Store that low byte (Register A) to the address in Register Pair HL, the next free slot of the list.
5536
INC HL 23
INCrement Register Pair HL by 1 to address the second byte of the slot.
5537
LD A,(IX+03H) DD 7E 03
Fetch the high byte of the current line number from (IX+03H).
553A
LD (HL),A 77
Store that high byte (Register A) to the address in Register Pair HL.
553B
INC HL 23
INCrement Register Pair HL by 1 so Register Pair HL addresses the next free slot of the list.
553C
PUSH HL E5
Save the new list pointer (Register Pair HL) onto the stack while the room remaining is checked.
553D
PUSH DE D5
Save Register Pair DE onto the stack so the caller gets it back unchanged.
553E
EX DE,HL EB
EXchange Register Pair DE with Register Pair HL, putting the new list pointer into Register Pair DE ready for the subtraction.
553F
LD HL,(40A0H) 2A A0 40
Load Register Pair HL with the contents of STKTOP at 40A0H, the Level II BASIC pointer to the top of string space, which is the ceiling of the free area the list is growing into.
5542
SBC HL,DE ED 52
SUBtract Register Pair DE, the new list pointer, from Register Pair HL, the top of string space. The CARRY FLAG is set if the list has grown past the ceiling.
5544
POP DE D1
Restore Register Pair DE from the stack.
5545
POP HL E1
Restore the new list pointer from the stack into Register Pair HL. POP does not disturb the flags, so the CARRY FLAG from the subtraction survives.
5546
If the CARRY FLAG has been set because the line number list has run into string space, JUMP to 554CH to report that memory is exhausted.
5548
LD (583CH),HL 22 3C 58
Store the new list pointer (Register Pair HL) to memory location 583CH.
554B
RET C9
RETurn to the caller.
554C
Point Register Pair HL to 580BH, the message 0DH, "Out of memory.", 0DH, 00H.
554F
GOSUB to 55E4H, which forces the output routine back to the video display control block DODCB$ at 401DH and prints the message there, so it is seen even when the listing was going to a disk file.
5552
JUMP to 568DH to close the listing file if one was opened and reload BASIC/CMD.

5555H - Read the Next Line Number from the List

Advances the list pointer, suppresses a number identical to the one before it, and reports the 0000H terminator with the Z FLAG.

5555
LD HL,(583CH) 2A 3C 58
Loop Start
Load Register Pair HL with the current list pointer from 583CH, the address of the next line number to be read back.
5558
LD E,(HL) 5E
Fetch the low byte of that line number from the address in Register Pair HL into Register E.
5559
INC HL 23
INCrement Register Pair HL by 1 to address the high byte.
555A
LD D,(HL) 56
Fetch the high byte of the line number from the address in Register Pair HL into Register D.
555B
INC HL 23
INCrement Register Pair HL by 1 so Register Pair HL addresses the following entry of the list.
555C
LD A,E 7B
Load Register A with the low byte of the line number from Register E.
555D
OR D B2
OR Register D, the high byte of the line number, into Register A. The result is zero only when the whole word is 0000H.
555E
RET Z C8
RETurn to the caller if the Z FLAG is set, because the 0000H terminator written by 5521H has been reached and the list is exhausted.
555F
LD (583CH),HL 22 3C 58
Store the advanced list pointer (Register Pair HL) to memory location 583CH.
5562
LD HL,(583EH) 2A 3E 58
Load Register Pair HL with the previous line number from 583EH, which 5521H cleared to 0000H at the start of the entry.
5565
EX DE,HL EB
EXchange Register Pair DE with Register Pair HL, so Register Pair HL now holds the line number just read and Register Pair DE holds the previous one.
5566
LD (583EH),HL 22 3E 58
Store the line number just read (Register Pair HL) to memory location 583EH, ready for the next comparison.
5569
PUSH HL E5
Save the line number (Register Pair HL) onto the stack.
556A
SBC HL,DE ED 52
SUBtract Register Pair DE, the previous line number, from Register Pair HL, the one just read. The Z FLAG is set when they are the same.
556C
POP HL E1
Restore the line number from the stack into Register Pair HL. POP does not disturb the flags, so the Z FLAG from the subtraction survives.
556D
Loop End
If the Z FLAG (Zero) has been set because this line number repeats the one before it, LOOP BACK to 5555H to fetch the next one. Several references to the same name in one program line therefore print that line number only once.
556F
RET C9
RETurn to the caller with Register Pair HL holding the line number and the NZ FLAG set.

5570H - Parse the Switches, the Named Entry and the Title

Handles the -V and -L restriction switches, the =name or =linenumber form that limits the listing to a single entry, and the title enclosed in angle brackets.

5570
PUSH HL E5
Save Register Pair HL, which points at the CMD"X parameter text following the output specification, onto the stack.
5571
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the value that clears both switch cells at once.
5574
LD (5843H),HL 22 43 58
Store 0000H (Register Pair HL) to memory location 5843H. This clears 5843H, the restriction switch letter, and 5844H, the specific-entry flag, in one instruction.
5577
XOR A AF
Set Register A to ZERO and clear all flags.
5578
Store zero (Register A) to memory location 5722H, the first byte of the title buffer, so that an absent title prints nothing.
557B
POP HL E1
Restore the parameter text pointer from the stack into Register Pair HL.
557C
LD A,(HL) 7E
Fetch the next character of the parameter text from the address in Register Pair HL into Register A.
557D
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line in INBUF$ at 4318H. If Register A equals 0DH, the Z FLAG is set.
557F
RET Z C8
RETurn to the caller if the Z FLAG is set, because the parameter text is exhausted and no switches were given.
5580
CP 2DH FE 2D
Compare Register A against 2DH (ASCII: -), the prefix of the -V and -L switches. If Register A equals 2DH, the Z FLAG is set.
5582
If the NZ FLAG (Not Zero) has been set because this is not a switch prefix, JUMP to 5590H to test for the equals sign that introduces a single named entry.
5584
INC HL 23
INCrement Register Pair HL by 1 to address the switch letter itself.
5585
LD DE,5843H 11 43 58
Point Register Pair DE to 5843H, the cell that holds the restriction switch letter.
5588
LD A,(HL) 7E
Fetch the switch letter from the address in Register Pair HL into Register A. 56B0H has already folded it to upper case.
5589
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line in INBUF$ at 4318H. If Register A equals 0DH, the Z FLAG is set.
558B
RET Z C8
RETurn to the caller if the Z FLAG is set, because the dash was the last character and no switch letter follows.
558C
LD (DE),A 12
Store the switch letter (Register A) to the address in Register Pair DE, which is 5843H. 56H selects variables only and 4CH selects line numbers only; 52AAH reads it back for every candidate.
558D
JUMP to 55BDH to scan the rest of the parameter text for the angle bracket that introduces a title.
5590
CP 3DH FE 3D
Compare Register A against 3DH (ASCII: =), which introduces the name or line number of a single entry to be listed. If Register A equals 3DH, the Z FLAG is set.
5592
If the NZ FLAG (Not Zero) has been set because this is neither a switch nor a single entry request, JUMP to 55BDH to look for a title.
5595
INC HL 23
INCrement Register Pair HL by 1 to address the first character of the requested name or line number.
5596
PUSH HL E5
Save that address (Register Pair HL) onto the stack; the parameter scan resumes from it at 55B7H.
5597
DEC HL 2B
DECrement Register Pair HL by 1, the first of four steps that bias the pointer for the scanner's (IY+04H) addressing.
5598
DEC HL 2B
DECrement Register Pair HL by 1, the second of those four steps.
5599
DEC HL 2B
DECrement Register Pair HL by 1, the third of those four steps.
559A
DEC HL 2B
DECrement Register Pair HL by 1, so Register Pair HL is now four below the requested text.
559B
PUSH HL E5
Save that biased address (Register Pair HL) onto the stack.
559C
POP IY FD E1
Restore it into Register Pair IY. Because the collectors at 5416H and 53D5H read their input as (IY+04H), setting Register Pair IY four bytes low makes them read the =name or =linenumber out of the command line exactly as if it were program text.
559E
LD HL,5824H 21 24 58
Point Register Pair HL to 5824H, the current entry cell, which is where the requested name is to be built.
55A1
GOSUB to 537BH to fill 5824H with seven blanks and a 00H terminator before the requested name is collected into it.
55A4
GOSUB to 5479H, the character classifier, to find out whether the requested entry begins with a digit or a letter. Register A comes back as 1 for a digit and 2 for a letter.
55A7
LD DE,55B7H 11 B7 55
Point Register Pair DE to 55B7H, the address that is to act as the return point of the collector routine.
55AA
PUSH DE D5
PUSH the return address 55B7H onto the stack, so that whichever collector is jumped to next returns there.
55AB
DEC A 3D
DECrement Register A by 1. If the classification code was 1, a digit, the Z FLAG is set.
55AC
If the Z FLAG (Zero) has been set because a line number was requested, JUMP to 5416H, the line number collector, which will build the five-digit right-justified number into the buffer at Register Pair HL.
55AF
DEC A 3D
DECrement Register A by 1. If the classification code was 2, a letter, the Z FLAG is now set.
55B0
If the Z FLAG (Zero) has been set because a variable name was requested, JUMP to 53D5H, the variable name collector, which will build the name into the buffer at Register Pair HL.
55B3
POP DE D1
Discard the return address 55B7H from the stack into Register Pair DE; neither collector was entered because the character after the equals sign was neither a digit nor a letter.
55B4
POP HL E1
Restore the parameter text pointer from the stack into Register Pair HL, recovering the address saved at 5596H.
55B5
JUMP to 55BDH to look for a title, leaving the specific-entry flag at 5844H clear so the whole program is listed.
55B7
POP HL E1
Restore the parameter text pointer from the stack into Register Pair HL, recovering the address saved at 5596H. This is where both collectors return.
55B8
LD A,01H 3E 01
Load Register A with 01H, the value that marks a single named entry as having been requested.
55BA
LD (5844H),A 32 44 58
Store 01H (Register A) to memory location 5844H. 527AH reads it so that the current entry cell 5824H is not reset between passes, 52C9H reads it so that every other name is rejected, and 534DH reads it so that only one pass is made.
55BD
LD A,(HL) 7E
Loop Start
Fetch the next character of the parameter text from the address in Register Pair HL into Register A.
55BE
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line in INBUF$ at 4318H. If Register A equals 0DH, the Z FLAG is set.
55C0
RET Z C8
RETurn to the caller if the Z FLAG is set, because the parameter text is exhausted and no title was given.
55C1
INC HL 23
INCrement Register Pair HL by 1 so that Register Pair HL addresses the character after the one now in Register A.
55C2
CP 3CH FE 3C
Compare Register A against 3CH (ASCII: <), which opens the optional page title. If Register A equals 3CH, the Z FLAG is set.
55C4
Loop End
If the NZ FLAG (Not Zero) has been set because the title has not started yet, LOOP BACK to 55BDH to test the next character.
55C6
LD BC,003AH 01 3A 00
Load Register Pair BC with 003AH, the 58-character capacity of the title buffer at 5722H.
55C9
Point Register Pair DE to 5722H, the first byte of the title buffer.
55CC
LDI ED A0
Loop Start
Block move one byte: Source is Register Pair HL in the parameter text, Destination is Register Pair DE in the title buffer, both incrementing, with Register Pair BC decremented so the capacity is counted down.
55CE
LD A,C 79
Load Register A with the low byte of the remaining capacity from Register C.
55CF
OR A B7
OR Register A with itself to set the flags from the remaining capacity without changing it.
55D0
If the Z FLAG (Zero) has been set because all 58 characters have been taken, JUMP to 55DDH to terminate the title.
55D2
LD A,(HL) 7E
Fetch the next character of the parameter text from the address in Register Pair HL into Register A.
55D3
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line in INBUF$ at 4318H. If Register A equals 0DH, the Z FLAG is set.
55D5
If the Z FLAG (Zero) has been set because the line ended before the closing angle bracket, JUMP to 55DDH to terminate the title.
55D7
CP 3EH FE 3E
Compare Register A against 3EH (ASCII: >), which closes the title. If Register A equals 3EH, the Z FLAG is set.
55D9
If the Z FLAG (Zero) has been set because the closing angle bracket has been reached, JUMP to 55DDH to terminate the title.
55DB
Loop End
LOOP BACK to 55CCH to copy the next character of the title.
55DD
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that is to follow the title so the column headings start on a new line.
55DF
LD (DE),A 12
Store the carriage return (Register A) to the address in Register Pair DE, the next free byte of the title buffer.
55E0
INC DE 13
INCrement Register Pair DE by 1 to address the byte after the carriage return.
55E1
XOR A AF
Set Register A to ZERO and clear all flags.
55E2
LD (DE),A 12
Store the 00H terminator (Register A) to the address in Register Pair DE, ending the title buffer for the string output routine.
55E3
RET C9
RETurn to the caller.

55E4H - Force the Output to the Video or the Printer

Two entry points that rewrite the self-modified output control block operand at 55FBH. 55E4H selects the video display and is used for the messages that must be seen even when the listing is going to a file. 55EEH selects the line printer and has no caller in this overlay.

55E4
PUSH HL E5
Save Register Pair HL, which points at the string to be printed, onto the stack.
55E5
Point Register Pair HL to 401DH, DODCB$, the resident LDOS device control block for the video display.
55E8
LD (55FBH),HL 22 FB 55
Self-Modifying Code
Store the video control block address 401DH (Register Pair HL) to memory location 55FBH, the operand of the LD DE,0000H instruction at 55FAH. Every character sent from now on goes to the video display, whatever the listing was being written to. The assembled operand is 0000H; 5255H writes the listing file control block address 5847H there when an output file was opened.
55EB
POP HL E1
Restore the string address from the stack into Register Pair HL.
55EC
JUMP to 55F6H to send the string at Register Pair HL to the video display.
55EE
PUSH HL E5
Save Register Pair HL, which points at the string to be printed, onto the stack. Nothing in this overlay calls 55EEH; it is the printer counterpart of 55E4H and is unreachable in this build.
55EF
Point Register Pair HL to 4025H, PRDCB$, the resident LDOS device control block for the line printer.
55F2
LD (55FBH),HL 22 FB 55
Self-Modifying Code
Store the printer control block address 4025H (Register Pair HL) to memory location 55FBH, the operand of the LD DE,0000H instruction at 55FAH, which would send everything that follows to the line printer.
55F5
POP HL E1
Restore the string address from the stack into Register Pair HL, then fall through into the string output routine at 55F6H.

55F6H - Send a String to the Current Output

The single output path of the utility. It counts lines for the page break logic, sends each character through the ROM routine $PUT at 001BH, gives any resident keyboard task its turn, and honours PAUSE and BREAK.

55F6
PUSH IY FD E5
Save Register Pair IY onto the stack. It holds the program text scanner's position within the current BASIC line and must survive the output.
55F8
PUSH HL E5
Save Register Pair HL, the address of the string being printed, onto the stack so the caller gets it back unchanged.
55F9
PUSH DE D5
Save Register Pair DE onto the stack so the caller gets it back unchanged.
55FA
LD DE,0000H 11 00 00
Self-Modifying Code
Point Register Pair DE to the current output control block. The operand at 55FBH is assembled as 0000H and is written at run time: 5255H puts the listing file control block address 5847H there, 55E8H puts the video control block address 401DH there and 55F2H puts the printer control block address 4025H there.
55FD
LD A,(HL) 7E
Loop Start
Fetch the next character of the string from the address in Register Pair HL into Register A.
55FE
OR A B7
OR Register A with itself to set the flags from that character without changing it.
55FF
If the Z FLAG (Zero) has been set because the 00H terminator has been reached, JUMP to 5648H to restore the registers and return.
5601
CP 0DH FE 0D
Compare Register A against 0DH, a carriage return. If Register A equals 0DH, the Z FLAG is set.
5603
If the NZ FLAG (Not Zero) has been set because the character is not a carriage return, JUMP to 560DH to test it for a form feed.
5605
PUSH HL E5
Save Register Pair HL, the position within the string being printed, onto the stack.
5606
Point Register Pair HL to 5794H, the count of lines already used on the current page.
5609
INC (HL) 34
INCrement the page line counter at 5794H by 1, because a carriage return is about to be sent.
560A
POP HL E1
Restore the string position from the stack into Register Pair HL.
560B
JUMP to 5617H to send the carriage return.
560D
CP 0CH FE 0C
Compare Register A against 0CH, a form feed. If Register A equals 0CH, the Z FLAG is set.
560F
If the NZ FLAG (Not Zero) has been set because the character is ordinary text, JUMP to 5617H to send it.
5611
PUSH AF F5
Save Register A, the form feed character, and the flags onto the stack.
5612
XOR A AF
Set Register A to ZERO and clear all flags.
5613
Store zero (Register A) to memory location 5794H, resetting the page line counter because a new page is beginning.
5616
POP AF F1
Restore the form feed character and the flags from the stack into Register A.
5617
GOSUB to the ROM output routine $PUT at 001BH to send the character in Register A to the control block addressed by Register Pair DE, which is the listing file at 5847H, the video display at 401DH or the line printer at 4025H. It returns with the Z FLAG set when the byte was accepted.
561A
If the NZ FLAG (Not Zero) has been set because $PUT reported a condition, GOSUB to 564DH to find out whether the destination is a disk file. 564DH returns with the Z FLAG set for a device, whose not-ready return is to be ignored.
561D
If the NZ FLAG (Not Zero) has been set because the destination is an open disk file and the write genuinely failed, JUMP to 5656H to report the DOS error.
561F
PUSH HL E5
Save Register Pair HL, the position within the string being printed, onto the stack.
5620
PUSH DE D5
Save Register Pair DE, the address of the current output control block, onto the stack.
5621
GOSUB to the resident LDOS vector @KITSK at 4300H, the keyboard interrupt task slot. SYS0 loads it with 0C9H, a bare RET, so it returns at once when nothing is hooked there; a resident task that has installed itself in the slot gets its turn between characters of the listing.
5624
GOSUB to 5661H to examine KFLAG$ at 4423H, the resident flag byte in which the keyboard driver records a BREAK, a PAUSE or an ENTER request. It returns with the Z FLAG reflecting bit 0, the BREAK request, and Register A holding the whole flag byte.
5627
If the NZ FLAG (Not Zero) has been set because bit 0 of KFLAG$ is set and BREAK has been pressed, JUMP to 563CH to load Register A with 01H and abandon the listing.
5629
BIT 1,A CB 4F
Test BIT 1 of Register A, the PAUSE request bit of KFLAG$ at 4423H. If it is clear the Z FLAG is set.
562B
If the Z FLAG (Zero) has been set because no pause was requested, JUMP to 563AH to clear Register A and carry on with the listing.
562D
Loop Start
GOSUB to the ROM keyboard routine $KEY at 0049H, which waits until a key is pressed and returns its code in Register A. This is what holds the listing still while the operator reads the screen.
5630
CP 60H FE 60
Compare Register A, the key just pressed, against 60H, the code the shift and at-sign combination produces. If Register A equals 60H, the Z FLAG is set.
5632
Loop End
If the Z FLAG (Zero) has been set because the key pressed is the one that caused the pause, LOOP BACK to 562DH and keep waiting, so the pause key cannot also release the pause.
5634
GOSUB to 5673H to clear the low three bits of KFLAG$ at 4423H, cancelling the pause request now that it has been answered.
5637
DEC A 3D
DECrement Register A by 1. Register A holds the key that released the pause, so the Z FLAG is set when that key was 01H, the BREAK code.
5638
If the Z FLAG (Zero) has been set because BREAK was used to release the pause, JUMP to 563CH to load Register A with 01H and abandon the listing.

Overlapping Instructions
The four bytes 563AH-563DH are AF 11 3E 01 and are entered at two different addresses. Entered at 563AH they are XOR A followed by LD DE,013EH, so Register A comes back as zero and the listing continues; the value loaded into Register Pair DE is thrown away by the POP DE at 563EH. Entered at 563CH, which is where 5627H and 5638H jump, the 3EH and 01H are read as LD A,01H, so Register A comes back as 1 and 5642H abandons the listing. Both readings are shown below.

563A
XOR A AF
Set Register A to ZERO and clear all flags. Register A = 0 means the listing is to continue. The 11H that follows is the opcode of the LD DE,013EH at 563BH, which is executed but immediately undone by the POP DE at 563EH, so entering here simply skips the LD A,01H at 563CH.
563B
LD DE,013EH 11 3E 01
Load Register Pair DE with 013EH. This instruction exists only because entering at 563CH reads its 3EH and 01H operand bytes as LD A,01H; the value loaded is discarded by the POP DE at 563EH.
563C
LD A,01H 3E 01
Load Register A with 01H, the value that tells 5640H that BREAK was pressed and the cross reference is to be abandoned. This instruction is the last two bytes of the LD DE,013EH at 563BH, read as an opcode in their own right by the jumps from 5627H and 5638H.
563E
POP DE D1
Restore the address of the current output control block from the stack into Register Pair DE.
563F
POP HL E1
Restore the position within the string being printed from the stack into Register Pair HL.
5640
CP 01H FE 01
Compare Register A against 01H, the value that means BREAK was pressed. If Register A equals 01H, the Z FLAG is set.
5642
If the Z FLAG (Zero) has been set because BREAK was pressed, JUMP to 567EH to print "Break" and abandon the cross reference.
5645
INC HL 23
INCrement Register Pair HL by 1 to step to the next character of the string.
5646
Loop End
LOOP BACK to 55FDH to send the next character.
5648
POP DE D1
Restore Register Pair DE from the stack, recovering the caller's value.
5649
POP HL E1
Restore Register Pair HL from the stack, recovering the address of the string that was printed.
564A
POP IY FD E1
Restore Register Pair IY from the stack, recovering the program text scanner's position.
564C
RET C9
RETurn to the caller. When this routine is reached by the CALL at 5658H the three POPs unwind the registers 55F6H saved and the RET then returns to 565BH.
564D
PUSH BC C5
Save Register Pair BC onto the stack.
564E
PUSH AF F5
Save Register A, the error code $PUT returned, and the flags onto the stack.
564F
LD A,(DE) 1A
Fetch the first byte of the current output control block from the address in Register Pair DE into Register A. For a device control block this is a type byte with bit 7 clear; for an open disk file control block bit 7 is set.
5650
LD B,A 47
Load Register B with that first byte from Register A so it can be tested while Register A is restored.
5651
POP AF F1
Restore the error code $PUT returned into Register A from the stack.
5652
BIT 7,B CB 78
Test BIT 7 of Register B, the first byte of the output control block. If it is clear, the destination is a device and the Z FLAG is set; if it is set, the destination is an open disk file and the NZ FLAG is set.
5654
POP BC C1
Restore Register Pair BC from the stack. POP does not disturb the flags, so the result of the bit test survives.
5655
RET C9
RETurn to the caller with the Z FLAG set when the output is a device, whose $PUT return is not an error, and the NZ FLAG set when it is a disk file and the write really did fail.
5656
OR 80H F6 80
OR Register A, the DOS error code $PUT returned, with 80H. Bit 7 tells @ERROR to display the message and return to the caller rather than aborting to DOS Ready.
5658
GOSUB to 5648H, which pops the Register Pair DE, Register Pair HL and Register Pair IY that 55F6H saved and then returns here, leaving the stack as it was before the string output routine was entered.
565B
GOSUB to the resident LDOS vector @ERROR at 4409H with the error code and option bits in Register A, so that the DOS message for the failed write is displayed.
565E
JUMP to 568DH to close the listing file if one was opened and reload BASIC/CMD.

5661H - Poll the Keyboard Flag Byte

Reads KFLAG$ at 4423H, the resident byte in which the LDOS keyboard driver records a BREAK, PAUSE or ENTER request, and drains the type-ahead before reporting the BREAK bit.

5661
Fetch KFLAG$ from 4423H into Register A. This is the resident flag byte in which the LDOS keyboard driver records that BREAK (bit 0), PAUSE (bit 1) or ENTER (bit 2) has been pressed.
5664
PUSH AF F5
Save Register A, the whole flag byte, and the flags onto the stack.
5665
AND 03H E6 03
AND Register A with 03H to isolate bits 0 and 1, the BREAK and PAUSE requests.
5667
If the Z FLAG (Zero) has been set because neither BREAK nor PAUSE is pending, JUMP to 566FH.
5669
Loop Start
GOSUB to the ROM keyboard routine @KBD at 002BH, which scans the keyboard once and returns the key code in Register A, or 00H if no key is down.
566C
OR A B7
OR Register A with itself to set the flags from the key code without changing it.
566D
Loop End
If the NZ FLAG (Not Zero) has been set because a key was returned, LOOP BACK to 5669H to keep draining the type-ahead until the keyboard is quiet.
566F
POP AF F1
Restore the whole KFLAG$ byte and the flags from the stack into Register A.
5670
BIT 0,A CB 47
Test BIT 0 of Register A, the BREAK request bit of KFLAG$ at 4423H. If it is clear the Z FLAG is set.
5672
RET C9
RETurn to the caller with Register A holding the whole KFLAG$ byte and the Z FLAG reflecting the BREAK request bit.

5673H - Clear the Pending Key Requests

Clears the low three bits of KFLAG$ at 4423H so that a key pressed during the listing does not fall through into the BASIC session afterwards.

5673
PUSH AF F5
Save Register A and the flags onto the stack so the caller's value is not lost.
5674
Fetch KFLAG$ from 4423H into Register A.
5677
AND 0F8H E6 F8
AND Register A with 0F8H to clear bits 0, 1 and 2, the BREAK, PAUSE and ENTER requests.
5679
Store the cleared flag byte (Register A) to memory location 4423H, so a key pressed during the listing cannot fall through into the BASIC session afterwards.
567C
POP AF F1
Restore Register A and the flags from the stack.
567D
RET C9
RETurn to the caller.

567EH - The BREAK Exit

Prints "Break" on the video display and falls into the common exit.

567E
GOSUB to 5673H to clear the low three bits of KFLAG$ at 4423H, cancelling the BREAK request so it is not seen again by LBASIC.
5681
Point Register Pair HL to 578FH, the two-byte string 0DH,00H, a bare carriage return.
5684
GOSUB to 55F6H to send the carriage return to the current output destination, so the abandoned listing ends on a clean line.
5687
Point Register Pair HL to 5795H, the message "Break" followed by its 00H terminator.
568A
GOSUB to 55E4H, which forces the output routine back to the video display control block DODCB$ at 401DH and prints "Break" there, so the operator sees it even when the listing was going to a file.

568DH - Close the Listing and Reload the Interpreter

The single exit from the overlay. Every path through the utility ends here. The listing file is closed if one was opened, the file specification of the interpreter is planted in CFCB$ at 4480H, an asterisk is planted in INBUF$ at 4318H so that BASIC/CMD re-enters with the program and the variables intact, and @RUN loads BASIC/CMD back over this image.

568D
GOSUB to 5710H to close the listing output file. 5710H returns immediately unless 5793H holds a letter, which is the case only when a disk file was opened.
5690
LD HL,56A6H 21 A6 56
Point Register Pair HL to 56A6H, the file specification "BASIC/CMD" followed by the 03H that terminates it.
5693
LD DE,4480H 11 80 44
Point Register Pair DE to 4480H, CFCB$, the resident LDOS command file control block that @RUN uses to load a program.
5696
PUSH DE D5
Save the control block address 4480H (Register Pair DE) onto the stack, since the LDIR will advance it.
5697
LD BC,000BH 01 0B 00
Load Register Pair BC with 000BH, the number of bytes to move: the nine characters of "BASIC/CMD", the 03H terminator, and one further byte which the terminator makes irrelevant.
569A
LDIR ED B0
Block move eleven bytes: Source is Register Pair HL at 56A6H, Destination is Register Pair DE at 4480H, byte count is Register Pair BC = 11, both pointers incrementing. The file specification of the interpreter is planted in the command file control block.
569C
POP DE D1
Restore the control block address 4480H from the stack into Register Pair DE, ready for @RUN.
569D
LD HL,4318H 21 18 43
Point Register Pair HL to 4318H, INBUF$, the DOS command buffer, which is where @RUN leaves the command tail for the program it loads.
56A0
LD (HL),2AH 36 2A
Store 2AH (ASCII: *) to the address in Register Pair HL, which is 4318H. BASIC/CMD tests that first character at 5355H and 53F4H: an asterisk means re-entry, so the interpreter comes back with the program and the variables intact instead of performing a cold start.
56A2
JUMP to the resident LDOS vector @RUN at 4433H to load and enter BASIC/CMD, whose image replaces this overlay at 5200H. Register Pair DE points at the command file control block at 4480H and Register Pair HL at the command tail in INBUF$ at 4318H.
56A5
DEFB 4CH 4C
DEFB 4CH. This byte is the ASCII letter L and is not copied: the LDIR at 569AH starts one byte later at 56A6H, so the file loaded is BASIC/CMD, not LBASIC/CMD. BASIC/OV1 carries the same unused byte ahead of the same string.
56A6-56AE
DEFM "BASIC/CMD" 42 41 53 49 43 2F 43 4D 44
Reload File Specification
The name of the interpreter, copied to CFCB$ at 4480H by the LDIR at 569AH so that @RUN can bring BASIC/CMD back over this overlay. The letter L that sits immediately below it at 56A5H is not part of the copy.
56AF
DEFB 03H 03
The 03H that terminates the file specification for @RUN. The LDIR at 569AH moves eleven bytes, so one further byte follows this terminator into CFCB$ at 4480H, where it is ignored.

56B0H - Fold the Parameter Text to Upper Case

Converts every lower case letter of the CMD"X parameter text in place and stops at the first control character, which is the carriage return ending the line in INBUF$ at 4318H.

56B0
PUSH AF F5
Save Register A and the flags onto the stack so the caller's value is not lost.
56B1
PUSH HL E5
Save Register Pair HL, which points at the first character of the CMD"X parameter text, onto the stack.
56B2
LD A,(HL) 7E
Loop Start
Fetch the current character of the parameter text from the address in Register Pair HL into Register A.
56B3
CP 20H FE 20
Compare Register A against 20H (ASCII: blank). If Register A is less than 20H, the CARRY FLAG is set; if it is 20H or greater, the NO CARRY FLAG is set.
56B5
If the CARRY FLAG has been set because a control character has been reached, JUMP to 56C5H. The 0DH that ends the line in INBUF$ at 4318H stops the conversion.
56B7
CP 61H FE 61
Compare Register A against 61H (ASCII: a). If Register A is less than 61H, the CARRY FLAG is set.
56B9
If the CARRY FLAG has been set because the character is not a lower case letter, JUMP to 56C2H to leave it alone.
56BB
CP 7BH FE 7B
Compare Register A against 7BH, one above ASCII z. If Register A is less than 7BH, the CARRY FLAG is set; otherwise the NO CARRY FLAG is set.
56BD
If the NO CARRY FLAG has been set because the character is above ASCII z, JUMP to 56C2H to leave it alone.
56BF
SUB 20H D6 20
SUBtract 20H from Register A, converting the lower case letter to its upper case equivalent.
56C1
LD (HL),A 77
Store the upper case letter (Register A) back to the address in Register Pair HL, changing the command line in place.
56C2
INC HL 23
INCrement Register Pair HL by 1 to step to the next character of the parameter text.
56C3
Loop End
LOOP BACK to 56B2H to deal with the next character.
56C5
POP HL E1
Restore the address of the first character of the parameter text from the stack into Register Pair HL.
56C6
POP AF F1
Restore Register A and the flags from the stack.
56C7
RET C9
RETurn to the caller.

56C8H - Convert a Line Number to ASCII

Hands the 16-bit value in Register Pair HL to the Level II ROM number formatting routines and returns Register Pair DE addressing the resulting text in the ROM buffer FBUFFR at 412FH.

56C8
PUSH HL E5
Save Register Pair HL, the 16-bit line number that is to be converted, onto the stack so the caller gets it back unchanged.
56C9
GOSUB to the ROM routine MAKINT at 0A9AH, which places the integer in Register Pair HL into the floating point accumulator FAC at 4121H and marks it as an integer.
56CC
XOR A AF
Set Register A to ZERO and clear all flags, the value FOUINI wants when no leading sign or field formatting is required.
56CD
GOSUB to the ROM routine FOUINI at 1034H, which prepares the number output buffer FBUFFR at 412FH and returns Register Pair HL pointing into it.
56D0
OR (HL) B6
OR the byte at the address in Register Pair HL into Register A, setting the flags FOUT2 expects from the buffer position FOUINI established.
56D1
GOSUB to the ROM routine FOUT2 at 0FD9H, which converts the value in the floating point accumulator FAC at 4121H into ASCII digits in FBUFFR at 412FH and returns Register Pair HL pointing at the text.
56D4
EX DE,HL EB
EXchange Register Pair DE with Register Pair HL, so Register Pair DE now points at the ASCII text in FBUFFR at 412FH.
56D5
INC DE 13
INCrement Register Pair DE by 1. The caller at 533AH immediately cancels this, so the address it works with is the first byte the ROM conversion produced.
56D6
POP HL E1
Restore the line number from the stack into Register Pair HL.
56D7
RET C9
RETurn to the caller with Register Pair DE addressing the converted number and Register Pair HL unchanged.

56D8H - Advance to the Next Program Line

Steps Register Pair IX past the link word and the line number and then forward to the 00H that ends the tokenised text, leaving it on the first byte of the following line record.

56D8
INC IX DD 23
INCrement Register Pair IX by 1, the first of four steps that carry it past the two-byte link word and the two-byte line number at the head of a program line record.
56DA
INC IX DD 23
INCrement Register Pair IX by 1, the second of those four steps.
56DC
INC IX DD 23
INCrement Register Pair IX by 1, the third of those four steps.
56DE
INC IX DD 23
INCrement Register Pair IX by 1, so Register Pair IX now addresses the first tokenised byte of the line.
56E0
LD A,(IX+00H) DD 7E 00
Loop Start
Fetch the current byte of the tokenised line into Register A through (IX+00H).
56E3
INC IX DD 23
INCrement Register Pair IX by 1 to step past the byte just fetched.
56E5
OR A B7
OR Register A with itself to set the flags from that byte without changing it.
56E6
Loop End
If the NZ FLAG (Not Zero) has been set because the 00H that ends the line has not been reached, LOOP BACK to 56E0H. When the loop falls through, Register Pair IX addresses the first byte of the next line record.

56E8H - Test for the End of the Program

Reads the two-byte link word of the record Register Pair IX is standing on and reports 0000H, the end of the BASIC program, with the Z FLAG.

56E8
LD A,(IX+00H) DD 7E 00
Fetch the low byte of the link word of the current program line record into Register A through (IX+00H). Level II BASIC stores the address of the next line there and 0000H at the end of the program.
56EB
OR A B7
OR Register A with itself to set the flags from the low byte without changing it.
56EC
RET NZ C0
RETurn to the caller if the NZ FLAG is set, because the link word cannot be 0000H and another line follows.
56ED
LD A,(IX+01H) DD 7E 01
Fetch the high byte of the link word into Register A through (IX+01H).
56F0
OR A B7
OR Register A with itself to set the flags from the high byte without changing it.
56F1
RET C9
RETurn to the caller with the Z FLAG set when the whole link word is 0000H, which marks the end of the BASIC program.

56F2H - Test for a Line Number Reference Token

The seven Level II BASIC tokens that may be followed by a line number. This is the same set BASIC/OV1 tests at 55A8H when it renumbers a program.

56F2
CP 0CAH FE CA
Compare Register A, the program byte being tested, against 0CAH, the Level II BASIC token for THEN. If Register A equals 0CAH, the Z FLAG is set.
56F4
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
56F5
CP 95H FE 95
Compare Register A against 95H, the Level II BASIC token for ELSE. If Register A equals 95H, the Z FLAG is set.
56F7
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
56F8
CP 9FH FE 9F
Compare Register A against 9FH, the Level II BASIC token for RESUME. If Register A equals 9FH, the Z FLAG is set.
56FA
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
56FB
CP 8DH FE 8D
Compare Register A against 8DH, the Level II BASIC token for GOTO. If Register A equals 8DH, the Z FLAG is set.
56FD
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
56FE
CP 91H FE 91
Compare Register A against 91H, the Level II BASIC token for GOSUB. If Register A equals 91H, the Z FLAG is set.
5700
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
5701
CP 8EH FE 8E
Compare Register A against 8EH, the Level II BASIC token for RUN. If Register A equals 8EH, the Z FLAG is set.
5703
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
5704
CP 0C2H FE C2
Compare Register A against 0C2H, the Level II BASIC token for ERL. If Register A equals 0C2H, the Z FLAG is set.
5706
RET Z C8
RETurn to the caller if the Z FLAG is set, reporting a line number reference token.
5707
RET C9
RETurn to the caller with the NZ FLAG set, because the byte is none of the seven tokens a line number can follow. This is the same token set BASIC/OV1 tests at 55A8H when it renumbers a program.

5708H - The DOS Error Exit

Reached when @FSPEC rejects the output specification or @INIT cannot create the file.

5708
OR 0C0H F6 C0
OR Register A, the DOS error code returned by @FSPEC or @INIT, with 0C0H. Bit 6 asks @ERROR for the message only and bit 7 asks it to return to the caller instead of aborting to DOS Ready.
570A
GOSUB to the resident LDOS vector @ERROR at 4409H with the error code and option bits in Register A, so the DOS message for the rejected file specification or failed create is displayed.
570D
JUMP to 568DH to close the listing file if one was opened and reload BASIC/CMD.

5710H - Close the Listing File

Closes the output file, but only when 5793H shows that a real disk file was opened rather than the video or a device.

5710
Fetch the output destination flag from 5793H into Register A. It holds 00H when no output specification was given, 2AH for a device and the first letter of the filename for a disk file.
5713
CP 41H FE 41
Compare Register A against 41H (ASCII: A). If Register A is less than 41H, the CARRY FLAG is set; if it is 41H or greater, the NO CARRY FLAG is set.
5715
RET C D8
RETurn to the caller if the CARRY FLAG is set, because the listing went to the video or to a device and there is no file to close.
5716
XOR A AF
Set Register A to ZERO and clear all flags.
5717
Store zero (Register A) to memory location 5793H so that a second entry to this routine cannot close the same file twice.
571A
LD DE,5847H 11 47 58
Point Register Pair DE to 5847H, the file control block of the listing output file.
571D
GOSUB to the resident LDOS vector @CLOSE at 4428H to write out the last sector, update the directory entry and close the file addressed by Register Pair DE.
5720
RET C9
RETurn to the caller.

5721H - Data - The Form Feed Byte and the Title Buffer

Not executable. 5721H is the form feed printed at a page break; the title buffer that follows it is 5722H-575FH and is large enough for the 58 characters the parser accepts plus a carriage return and a terminator.

5721
DEFB 0CH 0C
The form feed byte that precedes the title buffer. Printing the string that starts here throws a page and prints the title in one operation, and the string output routine at 5611H also uses the form feed to reset the page line counter 5794H. 54C3H is the only caller.
5722
DEFB 00H 00
The first byte of the title buffer. It ships as 00H so that a listing with no title prints nothing at 5261H; 5578H rewrites it as 00H at the start of every run and 55C6H fills the buffer in when the parameter text carried a title between angle brackets.
5723-575E
DEFB 20H x 60 20 x 60
The remaining 60 bytes of the title buffer, shipped as blanks. The copy at 55CCH accepts up to 58 characters of title and then appends a carriage return and a 00H terminator, so the buffer 5722H-575FH is exactly large enough for the longest title plus its two trailing bytes.
575F
DEFB 00H 00
The 00H that terminates the title buffer as shipped, so that the unused blanks are never printed.

5760H - Data - The Column Heading Line

Not executable. Printed when the listing starts and at the top of every new page.

5760
DEFB 0DH 0D
The carriage return that opens the column heading line, so the headings always begin on a fresh line.
5761-5788
DEFM " Ref Line Numbers" 20 20 52 65 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 4C 69 6E 65 20 4E 75 6D 62 65 72 73
The column heading text. "Ref" sits in the seven-character reference column that the +-----+ rule drawn by 54CFH underlines, and "Line Numbers" heads the eight seven-character line number fields that follow it. Printed at 5267H when the listing starts and at 54C9H at the top of every new page.
5789
DEFB 00H 00
The 00H that terminates the column heading line for the string output routine at 55FEH.

578AH - Data - Rule Fragments, Control Strings and Work Bytes

Not executable. Five short strings that build the +-----+ rule and end the output lines, followed by the two run-time work bytes that live inside the loaded image.

578A
DEFM "-" 2D
The hyphen that 54E1H prints five times to form the middle of the +-----+ rule under the reference column.
578B
DEFB 00H 00
The 00H that terminates the single hyphen string at 578AH.
578C
DEFM "+" 2B
The plus sign that 54D9H prints to open the +-----+ rule.
578D
DEFB 00H 00
The 00H that terminates the single plus sign string at 578CH.
578E
DEFM "+" 2B
The plus sign that 54EBH prints to close the +-----+ rule. The string that starts here is three bytes long because it runs on into the carriage return at 578FH and the terminator at 5790H.
578F
DEFB 0DH 0D
Overlapping Strings
The carriage return. Read as the start of a string at 5246H, 54B1H, 54D3H and 5681H it is a bare carriage return terminated by the 00H at 5790H; read as the second byte of the string that starts at 578EH it is the line ending that follows the closing plus sign of the rule. Both readings share these same bytes.
5790
DEFB 00H 00
The 00H that terminates both the plus-and-carriage-return string at 578EH and the bare carriage return string at 578FH.
5791
DEFB 0CH 0C
The form feed that 5357H prints to finish the listing, ejecting the page or clearing the screen. The string output routine at 5611H also uses it to reset the page line counter 5794H.
5792
DEFB 00H 00
The 00H that terminates the form feed string at 5791H.
5793
DEFB 00H 00
Output Destination Flag
Written at 523DH with the first byte of the file control block at 5847H as @FSPEC left it: 2AH for a device specification and the first letter of the filename for a disk file. It ships as 00H, which is the value that survives when no output specification was given and the listing goes to the video. Read at 524CH to decide whether to redirect the output routine, read at 5713H to decide whether a file has to be closed, and reset to 00H at 5717H once the file is closed.
5794
DEFB 00H 00
Page Line Counter
Counts the lines used on the current page. The string output routine increments it at 5609H for every carriage return sent and clears it at 5613H for every form feed. Read at 54AEH, where a count of 55 or more turns the end of an output line into a page break, and at 54B9H, where a count of 50 or more makes a new cross reference entry start on a fresh page.

5795H - Data - The BREAK Message and the Default Extension

Not executable.

5795-5799
DEFM "Break" 42 72 65 61 6B
The text of the BREAK message, printed by 5687H on the video display when the operator presses BREAK during the listing.
579A
DEFB 00H 00
The 00H that terminates the BREAK message at 5795H.
579B-579D
DEFM "TXT" 54 58 54
The default file extension for a cross reference listing file, handed to @FEXT at 5234H. @FEXT takes exactly three characters and needs no terminator, so this field runs straight into the banner at 579EH.

579EH - Data - The Sign On Banner

Not executable. Sent to @DSPLY at 4467H, which stops on the carriage return at 580AH.

579E
DEFB 1CH 1C
The home-cursor control code that opens the sign-on banner sent to @DSPLY at 520CH.
579F
DEFB 1FH 1F
The clear-to-end-of-frame control code that follows the home-cursor code, so the banner starts on a cleared screen.
57A0-57D3
DEFM "BASIC Cross Reference Listing Utility - Version 1.22" 42 41 53 49 43 20 43 72 6F 73 73 20 52 65 66 65 72 65 6E 63 65 20 4C 69 73 74 69 6E 67 20 55 74 69 6C 69 74 79 20 2D 20 56 65 72 73 69 6F 6E 20 31 2E 32 32
The product and version line of the sign-on banner.
57D4
DEFB 0AH 0A
The line feed that separates the product line of the banner from the copyright line.
57D5-5809
DEFM "Copyright 1987 by MISOSYS, Inc., All rights reserved" 43 6F 70 79 72 69 67 68 74 20 31 39 38 37 20 20 62 79 20 4D 49 53 4F 53 59 53 2C 20 49 6E 63 2E 2C 20 41 6C 6C 20 72 69 67 68 74 73 20 72 65 73 65 72 76 65 64
The MISOSYS copyright line of the sign-on banner.
580A
DEFB 0DH 0D
The carriage return that ends the sign-on banner. @DSPLY stops on a carriage return, so the "Out of memory." text that follows at 580BH is never displayed as part of the banner.

580BH - Data - The Out of Memory Message

Not executable. Printed on the video display when the line number list grows past STKTOP at 40A0H.

580B
DEFB 0DH 0D
The carriage return that opens the "Out of memory." message, so it always starts on a fresh line. 554CH points Register Pair HL here.
580C-5819
DEFM "Out of memory." 4F 75 74 20 6F 66 20 6D 65 6D 6F 72 79 2E
The text of the message issued when the collected line number list grows past STKTOP at 40A0H, the top of string space, which 5546H detects.
581A
DEFB 0DH 0D
The carriage return that ends the "Out of memory." message.
581B
DEFB 00H 00
The 00H that terminates the "Out of memory." message for the string output routine at 55FEH. It is the last byte of the loaded image; everything above it, from 581CH up, is uninitialised RAM that the overlay uses for work space.