TRS-80 DOS - TRSDOS v2.3 for the Model I - BASIC/CMD Disassembled

Page Customization

Introduction/Summary

TRSDOS v2.3 BASIC/CMD Disassembly - Disk BASIC (Model I)

BASIC/CMD is Radio Shack Disk BASIC version 2.2, the Disk BASIC of TRSDOS 2.3 (its copyright text, shown by CMD"#"#, names Microsoft, 1978). It does not hold a BASIC interpreter of its own: it extends the Level II BASIC in the ROM. At start-up it copies 49 jumps into the ROM's RAM vectors at 4152H-41E4H, so that the statements and functions the ROM leaves to Disk BASIC (OPEN, CLOSE, FIELD, GET, PUT, LSET, RSET, LOAD, SAVE, MERGE, KILL, CMD, DEF FN, DEF USR, LINE INPUT, CVI, MKI$, EOF, LOC, LOF, TIME$, INSTR, the &H and &O constants, MID$ on the left of =) come here, and so that the ROM's own PRINT, INPUT, LIST, its line input and character routines and its error messages can be turned to files.

The file is 5,120 bytes: 20 load records and a transfer record (5200H), then 16 bytes that are not part of the module (they repeat the bytes of 64A4H-64B3H). The records hold 5,020 bytes, 5200H-659BH: nineteen records of 256 bytes, whose length byte 02H means 256, and one of 156 bytes (6500H-659BH). There is no name record and no comment record. Every loaded byte is on one row, checked against S:\1\BASIC.CMD and its listing. RST 08H rows show the byte after the RST, which the ROM's syntax check compares with the next character of the program, as RST 08H => nnH.

Memory Map

Address RangeUse
5200H-54C2H
707 bytes
The start jump and the 44 error message texts.
54C3H-5555H
147 bytes
The 49 jumps copied to 4152H-41E4H.
5556H-56CAH
373 bytes
FN, DEF FN, USR and DEF USR; PRINT #.
56CBH-588AH
448 bytes
CMD, TIME$, LINE INPUT, the end of PRINT, INPUT #, the error text routine, the copyright text.
588BH-5A76H
492 bytes
INSTR, &H and &O, MID$ assignment, reading a line from a file, the character output and input links.
5A77H-5BB2H
316 bytes
The stand-in block, 255 unused bytes, the USR table, the work bytes and the file table.
5BB3H-5C05H
83 bytes
CMD"S" and CMD"A", the PRINT position and number links, the links around the ROM's CLEAR.
5C06H-5D52H
333 bytes
The start-up: links, FILES, the file blocks, MEM SIZE; the RST 28H hook.
5D53H-5EC2H
368 bytes
The input buffer (5D56H-5E55H), the start-up texts and the file name area.
5EC3H-5F34H
114 bytes
File numbers; MKI$, MKS$, MKD$, CVI, CVS, CVD.
5F35H-6065H
305 bytes
INPUT # and LINE INPUT # items; giving a character back.
6066H-61AEH
329 bytes
RUN with a name, LOAD, MERGE, SAVE, CLOSE.
61AFH-6353H
421 bytes
FIELD, LSET, RSET, EOF, closing a file, LOC, LOF, writing a character.
6354H-64F1H
414 bytes
GET, PUT, reading a character, file names, OPEN.
64F2H-659BH
170 bytes
The protection check, KILL, NAME, the error entries, the DOS error table.
659BH up
0122H a file
Not in the file (the last loaded byte is overwritten): the file blocks of file 0 and files 1-15, 0222H each with V; the program text follows them.

The ROM sets 4152H-41A5H to jumps to its L3 ERROR and 41A6H-41E4H to RET. BASIC/CMD's start-up (5C06H) saves the program start, the number of files and the start of string space, points SYS0/SYS's hook at 4313H to 5D4DH (so that the ROM's BREAK code 01H reaches BASIC), disarms the BREAK vector at 4315H, copies the ROM's 39 bytes of RAM routines to 4080H as the ROM does, moves the input buffer to 5D56H (40A7H) and copies the 49 jumps from 54C3H to 4152H. The table at 54C3H lists, for each jump, how the ROM reaches it and what it does. TRSDOS below version 2.2 (403EH) stops with USE TRSDOS 2.2 OR LATER.

BASIC followed by an asterisk keeps the program in memory and goes back to READY. Otherwise HOW MANY FILES? takes 0-15 (3 for ENTER), with V for record buffers, and MEM SIZE? the end of memory (the top of memory for ENTER); the file blocks are laid out from 659BH, the program starts after them, at least 300 bytes must be free and 50 bytes of string space are set aside. CMD"S" puts the hook at 4313H back and goes to DOS READY; CMD"A" goes to 4030H.

Disk Files

Each file has a block of 0122H bytes: byte 0 the mode (00H closed, 01H input, 02H output, 03H random), byte 1 the column for PRINT #, bytes 02H-21H the FCB, bytes 22H-121H the sector buffer; with V another 256 bytes follow, and a random file opened with a record length then has its sector buffer at byte 122H and its record buffer at byte 22H. The table at 5B8FH holds the block address of each file; file 0 is used by LOAD, RUN, MERGE, SAVE and KILL. The current file (5B8DH) is the one that PRINT #, INPUT #, LIST and the ROM's character routines use.

Sequential files are read and written a character at a time through the ROM's device routines (0013H, 001BH) with the FCB as the device control block. PRINT # keeps a column count in byte 1 for commas and TAB. INPUT # reads items ending at a comma or ENTER (numbers also at a space), strings in quotes up to the closing quote; LINE INPUT # reads a whole line. GET and PUT position the random file with 4442H and read or write one record with 4436H and 4439H; FIELD points string variables into the record buffer, and LSET and RSET fill them.

SAVE writes FFH and the tokenized program, or with A the program as text through LIST. LOAD and RUN read either form; a text file goes line by line through the ROM's command loop, with 59EAH and 5A30H taking the lines from the file. MERGE takes text files only. DOS errors become BASIC errors through the table at 6575H; CMD"E" shows the DOS text of the last one.

Statements and Functions

AddressWhat it is
558EH
5655H
FN and DEF FN, with parameters whose old values are saved and put back.
5679H
56ABH
USR0-USR9 and DEF USR (table at 5B77H).
56CBHCMD"D" DEBUG, "E" last DOS error, "T" and "R" interrupts off and on, "S" and "A" back to DOS, "#" copyright, "I" a DOS command (which ends at DOS READY).
5745HTIME$, MM/DD/YY HH:MM:SS from 4046H-4041H.
5786HLINE INPUT and LINE INPUT #.
588BHINSTR([n,]A$,B$).
5913H&H (up to four hexadecimal digits) and &O (octal).
5969HMID$(A$,n[,m])=B$.
5EFFH
5F18H
MKI$, MKS$, MKD$ and CVI, CVS, CVD.
6066H-6173HRUN "name", LOAD (,R), MERGE, SAVE (,A), CLOSE.
61AFH-6354HFIELD, LSET, RSET, EOF, LOC, LOF, GET, PUT.
6434H
6521H
6544H
OPEN, KILL, NAME (ILLEGAL FUNCTION CALL).

Notes from the Code

  • LOC starts with CALL 6547H (62FEH), the Bad file mode error entry, so every LOC ends with that error; LOF, which shares its code from 6307H, works.
  • OPEN tests whether a random file with a record length may use the second 256 bytes of its block by reading 0000H (64BBH), the ROM's first byte F3H, so the test never fails: without V the sector buffer then lies in the next file's block or past the last one.
  • The protection clearing at 64FEH-6519H depends on 6520H, which is set from bit 1 of 430FH after RUN of a file (64DBH-64E1H); no TRSDOS 2.3 module sets that bit, so the memory is never cleared.
  • LSET and RSET with string space short (62A0H) test flags popped at 62A0H, left by 29D7H at 621DH. When B$ was the newest temporary string whose text was the last allocated, 62ADH calls the ROM's 2884H, which is written to be jumped to: its POP HL takes the return address, and its RET goes to the address formed by Register Pair BC.
  • NAME is accepted by the ROM's tables but BASIC/CMD gives ILLEGAL FUNCTION CALL for it (6544H).
  • The texts for error codes 70H, 76H and 78H are only a question mark.
  • CMD"I" runs the DOS command through 4405H, which ends at DOS READY, so the program is left; the bytes after 572EH run only if 4405H returns.
  • CMD"T" stores RET at the interrupt vector 4012H: the next interrupt returns there with interrupts disabled, so the clock and the other interrupt work stop until CMD"R".
  • When reading a line from a file (59EAH), bit 7 is cleared from the characters until one below 80H has been read; a line feed at the start of a line is skipped.
  • The 255 bytes 5A78H-5B76H are not used; of the stand-in block at 5A77H only its mode byte matters.
  • 5A71H stores Register A, as the caller of the ROM's 0358H left it, into 40A9H whenever 0358H is called by anything other than the wait for a key.
  • The texts of the DOS error numbers go through the table at 6575H; numbers 27H and above count as 01H, and 5B8CH keeps 01H for them, so CMD"E" then shows the text of error 01H.

Variables

Variables and Changed Operands

Address RangePurpose
408EH-408FH
2 bytes
The number of files (5CCDH) and the V flag (5CBCH); the ROM's USR address word, not used by the ROM's USR here.
4152H-41E4H
147 bytes
The 49 jumps copied from 54C3H (5C5BH).
4313H-4314H
2 bytes
SYS0/SYS's hook address, set to 5D4DH (5C25H), put back by CMD"S" and CMD"A" (5BB8H).
5A77H
1 byte
The mode byte of the stand-in block for file 0 (5BE8H, 6092H).
5B77H-5B8AH
20 bytes
The addresses of USR0-USR9 (56B5H), read at 5682H.
5B8BH
1 byte
GET (00H) or PUT (6356H).
5B8CH
1 byte
The last DOS error number (656FH), for CMD"E" (5736H).
5B8DH-5B8EH
2 bytes
The block of the current file, or 0000H (5ED6H, 64ACH, 60A6H, 57B3H, 5BF1H).
5B8FH-5BAEH
32 bytes
The file table, a block address for each of files 0-15 (5CDDH).
5BAFH-5BB0H
2 bytes
The block of file 0, 659BH (5CD7H).
5BB1H
1 byte
Run after loading (608CH, 6119H), read at 5A57H and 60E5H.
5BB2H
1 byte
The number of files kept while 408EH is changed (6076H, 60D7H).
5C98H
1 byte
The first character after BASIC on the command line (5C07H).
5C99H-5C9EH
6 bytes
The saved program start, number of files and V flag, and start of string space (5C0DH-5C19H).
5D51H-5D52H
2 bytes
The old hook address, the operand of the JP at 5D50H (5C1FH), read by 5BB5H.
5D56H-5E55H
256 bytes
The input buffer (40A7H, 5C4FH).
5EA3H-5EC2H
32 bytes
The file name in capitals for 441CH (6403H-641BH).
651EH
1 byte
The record length during FIELD (61C0H).
651FH
1 byte
The RUN mark (606AH), cleared at 64D8H and 64F4H.
6520H
1 byte
The protection flag (64E1H), tested at 64F7H.

Disassembly

5200H - Start Jump and the Error Messages

The transfer address of BASIC/CMD is 5200H: the jump to the start-up code at 5C06H. Then the texts of the error messages, each ending with 00H, in the order of the error codes: 57E6H takes the code from Register E, turns it into a count and skips that many texts from 5203H, then shows the text with the ROM. Codes 00H-2CH are the ROM's own errors, 2EH is the first one Disk BASIC adds, and 64H-8AH are the disk errors; any other code shows Unprintable error.

5200
JUMP to 5C06H, the start-up code that links Disk BASIC into the ROM. SYS0/SYS jumps to 5200H, the transfer address of BASIC/CMD, after loading it.
5203
DEFB 00H 00
The 00H before the first text: 57E6H starts its count at 5203H, so the first skip (ROM 1F07H) stops here at once and the next text is message 1.
5204-5214
DEFM "NEXT without FOR" / DEFB 00H 4E 45 58 54 20 77 69 74 68 6F 75 74 20 46 4F 52 00
Message 1, for error code 00H, which the ROM shows as NF ERROR.
5215-5221
DEFM "Syntax error" / DEFB 00H 53 79 6E 74 61 78 20 65 72 72 6F 72 00
Message 2, for error code 02H, which the ROM shows as SN ERROR.
5222-5236
DEFM "RETURN without GOSUB" / DEFB 00H 52 45 54 55 52 4E 20 77 69 74 68 6F 75 74 20 47 4F 53 55 42 00
Message 3, for error code 04H, which the ROM shows as RG ERROR.
5237-5242
DEFM "Out of DATA" / DEFB 00H 4F 75 74 20 6F 66 20 44 41 54 41 00
Message 4, for error code 06H, which the ROM shows as OD ERROR.
5243-5258
DEFM "Illegal function call" / DEFB 00H 49 6C 6C 65 67 61 6C 20 66 75 6E 63 74 69 6F 6E 20 63 61 6C 6C 00
Message 5, for error code 08H, which the ROM shows as FC ERROR.
5259-5261
DEFM "Overflow" / DEFB 00H 4F 76 65 72 66 6C 6F 77 00
Message 6, for error code 0AH, which the ROM shows as OV ERROR.
5262-526F
DEFM "Out of memory" / DEFB 00H 4F 75 74 20 6F 66 20 6D 65 6D 6F 72 79 00
Message 7, for error code 0CH, which the ROM shows as OM ERROR.
5270-5285
DEFM "Undefined line number" / DEFB 00H 55 6E 64 65 66 69 6E 65 64 20 6C 69 6E 65 20 6E 75 6D 62 65 72 00
Message 8, for error code 0EH, which the ROM shows as UL ERROR.
5286-529C
DEFM "Subscript out of range" / DEFB 00H 53 75 62 73 63 72 69 70 74 20 6F 75 74 20 6F 66 20 72 61 6E 67 65 00
Message 9, for error code 10H, which the ROM shows as BS ERROR.
529D-52B0
DEFM "Redimensioned array" / DEFB 00H 52 65 64 69 6D 65 6E 73 69 6F 6E 65 64 20 61 72 72 61 79 00
Message 10, for error code 12H, which the ROM shows as DD ERROR.
52B1-52C1
DEFM "Division by zero" / DEFB 00H 44 69 76 69 73 69 6F 6E 20 62 79 20 7A 65 72 6F 00
Message 11, for error code 14H, which the ROM shows as /0 ERROR.
52C2-52D0
DEFM "Illegal direct" / DEFB 00H 49 6C 6C 65 67 61 6C 20 64 69 72 65 63 74 00
Message 12, for error code 16H, which the ROM shows as ID ERROR.
52D1-52DE
DEFM "Type mismatch" / DEFB 00H 54 79 70 65 20 6D 69 73 6D 61 74 63 68 00
Message 13, for error code 18H, which the ROM shows as TM ERROR.
52DF-52F2
DEFM "Out of string space" / DEFB 00H 4F 75 74 20 6F 66 20 73 74 72 69 6E 67 20 73 70 61 63 65 00
Message 14, for error code 1AH, which the ROM shows as OS ERROR.
52F3-5302
DEFM "String too long" / DEFB 00H 53 74 72 69 6E 67 20 74 6F 6F 20 6C 6F 6E 67 00
Message 15, for error code 1CH, which the ROM shows as LS ERROR.
5303-531D
DEFM "String formula too complex" / DEFB 00H 53 74 72 69 6E 67 20 66 6F 72 6D 75 6C 61 20 74 6F 6F 20 63 6F 6D 70 6C 65 78 00
Message 16, for error code 1EH, which the ROM shows as ST ERROR.
531E-532C
DEFM "Can't continue" / DEFB 00H 43 61 6E 27 74 20 63 6F 6E 74 69 6E 75 65 00
Message 17, for error code 20H, which the ROM shows as CN ERROR.
532D-5336
DEFM "No RESUME" / DEFB 00H 4E 6F 20 52 45 53 55 4D 45 00
Message 18, for error code 22H, which the ROM shows as NR ERROR.
5337-534B
DEFM "RESUME without error" / DEFB 00H 52 45 53 55 4D 45 20 77 69 74 68 6F 75 74 20 65 72 72 6F 72 00
Message 19, for error code 24H, which the ROM shows as RW ERROR.
534C-535D
DEFM "Unprintable error" / DEFB 00H 55 6E 70 72 69 6E 74 61 62 6C 65 20 65 72 72 6F 72 00
Message 20, for error code 26H, which the ROM shows as UE ERROR. 57E6H also shows this text for codes 2FH-62H and 8BH-FFH.
535E-536D
DEFM "Missing operand" / DEFB 00H 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 6E 64 00
Message 21, for error code 28H, which the ROM shows as MO ERROR.
536E-537B
DEFM "BAD FILE DATA" / DEFB 00H 42 41 44 20 46 49 4C 45 20 44 41 54 41 00
Message 22, for error code 2AH, which the ROM shows as FD ERROR.
537C-538E
DEFM "DISK BASIC FEATURE" / DEFB 00H 44 49 53 4B 20 42 41 53 49 43 20 46 45 41 54 55 52 45 00
Message 23, for error code 2CH, which the ROM shows as L3 ERROR.
538F-53A6
DEFM "Undefined user function" / DEFB 00H 55 6E 64 65 66 69 6E 65 64 20 75 73 65 72 20 66 75 6E 63 74 69 6F 6E 00
Message 24, for error code 2EH, the first code Disk BASIC adds (56BAH).
53A7-53B5
DEFM "FIELD overflow" / DEFB 00H 46 49 45 4C 44 20 6F 76 65 72 66 6C 6F 77 00
Message 25, for error code 64H, a disk error.
53B6-53C4
DEFM "Internal error" / DEFB 00H 49 6E 74 65 72 6E 61 6C 20 65 72 72 6F 72 00
Message 26, for error code 66H, a disk error.
53C5-53D4
DEFM "Bad file number" / DEFB 00H 42 61 64 20 66 69 6C 65 20 6E 75 6D 62 65 72 00
Message 27, for error code 68H, a disk error.
53D5-53E3
DEFM "File not found" / DEFB 00H 46 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64 00
Message 28, for error code 6AH, a disk error.
53E4-53F1
DEFM "Bad file mode" / DEFB 00H 42 61 64 20 66 69 6C 65 20 6D 6F 64 65 00
Message 29, for error code 6CH, a disk error.
53F2-5403
DEFM "File already open" / DEFB 00H 46 69 6C 65 20 61 6C 72 65 61 64 79 20 6F 70 65 6E 00
Message 30, for error code 6EH, a disk error.
5404-5405
DEFM "?" / DEFB 00H 3F 00
Message 31, for error code 70H, a disk error. This code has no text of its own: only a question mark is shown.
5406-5414
DEFM "Disk I/O error" / DEFB 00H 44 69 73 6B 20 49 2F 4F 20 65 72 72 6F 72 00
Message 32, for error code 72H, a disk error.
5415-5428
DEFM "File already exists" / DEFB 00H 46 69 6C 65 20 61 6C 72 65 61 64 79 20 65 78 69 73 74 73 00
Message 33, for error code 74H, a disk error.
5429-542A
DEFM "?" / DEFB 00H 3F 00
Message 34, for error code 76H, a disk error. This code has no text of its own: only a question mark is shown.
542B-542C
DEFM "?" / DEFB 00H 3F 00
Message 35, for error code 78H, a disk error. This code has no text of its own: only a question mark is shown.
542D-5436
DEFM "Disk full" / DEFB 00H 44 69 73 6B 20 66 75 6C 6C 00
Message 36, for error code 7AH, a disk error.
5437-5445
DEFM "Input past end" / DEFB 00H 49 6E 70 75 74 20 70 61 73 74 20 65 6E 64 00
Message 37, for error code 7CH, a disk error.
5446-5457
DEFM "Bad record number" / DEFB 00H 42 61 64 20 72 65 63 6F 72 64 20 6E 75 6D 62 65 72 00
Message 38, for error code 7EH, a disk error.
5458-5465
DEFM "Bad file name" / DEFB 00H 42 61 64 20 66 69 6C 65 20 6E 61 6D 65 00
Message 39, for error code 80H, a disk error.
5466-5473
DEFM "Mode-mismatch" / DEFB 00H 4D 6F 64 65 2D 6D 69 73 6D 61 74 63 68 00
Message 40, for error code 82H, a disk error.
5474-548C
DEFM "Direct statement in file" / DEFB 00H 44 69 72 65 63 74 20 73 74 61 74 65 6D 65 6E 74 20 69 6E 20 66 69 6C 65 00
Message 41, for error code 84H, a disk error.
548D-549B
DEFM "Too many files" / DEFB 00H 54 6F 6F 20 6D 61 6E 79 20 66 69 6C 65 73 00
Message 42, for error code 86H, a disk error.
549C-54B0
DEFM "Disk write protected" / DEFB 00H 44 69 73 6B 20 77 72 69 74 65 20 70 72 6F 74 65 63 74 65 64 00
Message 43, for error code 88H, a disk error.
54B1-54C2
DEFM "File acess DENIED" / DEFB 00H 46 69 6C 65 20 61 63 65 73 73 20 44 45 4E 49 45 44 00
Message 44, for error code 8AH, a disk error.

54C3H - The Link Table Copied into the ROM's RAM Vectors

49 jumps, copied as one block of 147 bytes to 4152H-41E4H by the LDIR at 5C5BH. 4152H-41A5H are the ROM's vectors for the Disk BASIC statements and functions: without Disk BASIC each one leads to the L3 error. 41A6H-41E4H are the links the ROM calls at fixed points of its own routines so that Disk BASIC can take over. The rows say where each jump lands in RAM, how the ROM reaches it, and where it goes in BASIC/CMD.

54C3
Copied to 4152H, the ROM's CVI vector, reached through the ROM's function table entry at 1626H: JUMP to 5F18H, CVI.
54C6
Copied to 4155H, the ROM's FN vector, reached through the ROM's JP Z,4155H at 2524H, taken for the FN token in an expression: JUMP to 558EH, FN.
54C9
Copied to 4158H, the ROM's CVS vector, reached through the function table entry at 1628H: JUMP to 5F1BH, CVS.
54CC
Copied to 415BH, the ROM's DEF vector, reached through the ROM's statement table entry at 1882H: JUMP to 5655H, DEF FN and DEF USR.
54CF
Copied to 415EH, the ROM's CVD vector, reached through the function table entry at 162AH: JUMP to 5F1EH, CVD.
54D2
Copied to 4161H, the ROM's EOF vector, reached through the function table entry at 162CH: JUMP to 62B8H, EOF.
54D5
Copied to 4164H, the ROM's LOC vector, reached through the function table entry at 162EH: JUMP to 62FEH, LOC.
54D8
Copied to 4167H, the ROM's LOF vector, reached through the function table entry at 1630H: JUMP to 630FH, LOF.
54DB
Copied to 416AH, the ROM's MKI$ vector, reached through the function table entry at 1632H: JUMP to 5EFFH, MKI$.
54DE
Copied to 416DH, the ROM's MKS$ vector, reached through the function table entry at 1634H: JUMP to 5F02H, MKS$.
54E1
Copied to 4170H, the ROM's MKD$ vector, reached through the function table entry at 1636H: JUMP to 5F05H, MKD$.
54E4
Copied to 4173H, the ROM's CMD vector, reached through the statement table entry at 182CH: JUMP to 56CBH, CMD.
54E7
Copied to 4176H, the ROM's TIME$ vector, reached through the ROM's JP Z,4176H at 2510H, taken for the TIME$ token: JUMP to 5745H, TIME$.
54EA
Copied to 4179H, the ROM's OPEN vector, reached through the statement table entry at 1866H: JUMP to 6434H, OPEN.
54ED
Copied to 417CH, the ROM's FIELD vector, reached through the statement table entry at 1868H: JUMP to 61AFH, FIELD.
54F0
Copied to 417FH, the ROM's GET vector, reached through the statement table entry at 186AH: JUMP to 6355H, GET.
54F3
Copied to 4182H, the ROM's PUT vector, reached through the statement table entry at 186CH: JUMP to 6354H, PUT.
54F6
Copied to 4185H, the ROM's CLOSE vector, reached through the statement table entry at 186EH: JUMP to 6173H, CLOSE.
54F9
Copied to 4188H, the ROM's LOAD vector, reached through the statement table entry at 1870H: JUMP to 606EH, LOAD.
54FC
Copied to 418BH, the ROM's MERGE vector, reached through the statement table entry at 1872H: JUMP to 6109H, MERGE.
54FF
Copied to 418EH, the ROM's NAME vector, reached through the statement table entry at 1874H: JUMP to 6544H, NAME.
5502
Copied to 4191H, the ROM's KILL vector, reached through the statement table entry at 1876H: JUMP to 6521H, KILL.
5505
Copied to 4194H, the ROM's & vector, reached through the ROM's JP Z,4194H at 24C8H, taken for an ampersand in an expression: JUMP to 5913H, the &H and &O constants.
5508
Copied to 4197H, the ROM's LSET vector, reached through the statement table entry at 1878H: JUMP to 620BH, LSET.
550B
Copied to 419AH, the ROM's RSET vector, reached through the statement table entry at 187AH: JUMP to 620AH, RSET.
550E
Copied to 419DH, the ROM's INSTR vector, reached through the ROM's JP Z,419DH at 2506H, taken for the INSTR token: JUMP to 588BH, INSTR.
5511
Copied to 41A0H, the ROM's SAVE vector, reached through the statement table entry at 187CH: JUMP to 6148H, SAVE.
5514
Copied to 41A3H, the ROM's LINE vector, reached through the statement table entry at 185AH: JUMP to 5786H, LINE INPUT.
5517
Copied to 41A6H, the link the ROM calls at 19ECH, in the ROM's error handler, with Register E = the error code: JUMP to 57E6H, which shows the error as text.
551A
Copied to 41A9H, the link the ROM calls at 27FEH, at the start of the ROM's USR function: JUMP to 5679H, which picks the USR0-USR9 address.
551D
Copied to 41ACH, the link the ROM calls at 1A1CH, as the ROM returns to READY: JUMP to 60EFH, which closes file 0 (the LOAD, MERGE or SAVE file).
5520
Copied to 41AFH, the link the ROM calls at 0368H, as the ROM starts to read a line from the keyboard: JUMP to 59EAH, which reads the line from the current file instead, as for LOAD or MERGE of a program saved as text.
5523
Copied to 41B2H, the link the ROM calls at 1AA1H, after the ROM has tokenized a line typed in: JUMP to 6133H, which refuses a line without a number read from a file and runs one typed at the keyboard.
5526
Copied to 41B5H, the link the ROM calls at 1AECH, after the ROM has put a program line in: JUMP to 5BDFH, which keeps the open file pointer over the ROM's CLEAR.
5529
Copied to 41B8H, the link the ROM calls at 1AF2H, just after 41B5H: JUMP to 5BEEH, which puts the open file pointer back.
552C
Copied to 41BBH, the link the ROM calls at 1B8CH (NEW) and 1DB0H (END): JUMP to 61A5H, which closes all files.
552F
Copied to 41BEH, the link the ROM calls at 2174H, at the end of PRINT: JUMP to 57B0H, which ends output to a file.
5532
Copied to 41C1H, the link the ROM calls at 032CH, as the ROM sends a character to the current device: JUMP to 5A21H, which sends it to a file when PRINT # is active.
5535
Copied to 41C4H, the link the ROM calls at 0358H, as the ROM takes a character from the keyboard: JUMP to 5A30H, which takes it from a file during LOAD or MERGE.
5538
Copied to 41C7H, the link the ROM calls at 1EA6H, for RUN followed by a file name: JUMP to 6066H, which loads and runs the program.
553B
Copied to 41CAH, the link the ROM calls at 206FH, at the start of PRINT: JUMP to 56BFH, which sees whether PRINT # names a file.
553E
Copied to 41CDH, the link the ROM calls at 20C6H, in PRINT after a number has been turned into text: JUMP to 5BFCH, which skips the line length test while printing to a file.
5541
Copied to 41D0H, the link the ROM calls at 2103H, in PRINT after a carriage return: JUMP to 5BFBH, a RET: nothing is changed.
5544
Copied to 41D3H, the link the ROM calls at 2108H (PRINT, comma) and 2141H (PRINT, TAB): JUMP to 5BC7H, which takes the print position from the file instead of the screen.
5547
Copied to 41D6H, the link the ROM calls at 219EH, at the start of INPUT: JUMP to 57B8H, which sees whether INPUT # names a file.
554A
Copied to 41D9H, the link the ROM calls at 2AECH, the ROM's jump for MID$ on the left side of an assignment: JUMP to 5969H, the MID$ assignment.
554D
Copied to 41DCH, the link the ROM calls at 222DH, in READ and INPUT before an item is stored: JUMP to 5F35H, which reads the item from a file during INPUT #.
5550
Copied to 41DFH, the link the ROM calls at 2278H (INPUT, after an item) and 2B44H (LIST): JUMP to 57D0H, which skips ?EXTRA IGNORED after INPUT # and the key test of a LIST into a file.
5553
Copied to 41E2H, the link the ROM calls at 02B2H, as the ROM's SYSTEM command shows its prompt: JUMP to 5BB3H, a RET: nothing is changed.

5556H - FN: Save the Value of a Parameter

Register Pair HL = the address of a parameter variable's value (from the ROM's 260DH), 40AFH = its type, the CARRY FLAG set. Before a user function is evaluated, the current value of each of its parameter variables is saved on the stack, so that the call can give them the argument values and put the old ones back afterwards (5604H). A number is pushed as one, two or four words of its value; a string's descriptor is copied into a new temporary string (ROM 2888H) instead. Then Register Pair HL (the address of the last byte saved) and Register Pair AF (the type flags) are pushed as well. 55BFH is the only entry, always with the CARRY FLAG set.

5556
LD A,(40AFH) 3A AF 40
Fetch the type of the parameter variable from 40AFH, the ROM's number type flag set by 260DH, into Register A: 2 integer, 3 string, 4 single, 8 double. 55BFH jumps here.
5559
DEC A 3D
DECrement Register A (the type) by 1, the first of three steps that subtract 3.
555A
DEC A 3D
DECrement Register A by 1 again: the type minus 2.
555B
DEC A 3D
DECrement Register A a third time: the type minus 3, which is 00H for a string, FFH for an integer, 01H for single and 05H for double.
555C
OR A B7
OR Register A with itself: the Z FLAG is set for a string, the SIGN FLAG for an integer, and the PARITY FLAG odd (PO) for single and even (PE) for double.
555D
SCF 37
Set the CARRY FLAG; OR A cleared it, and 5571H and 557FH test it.
555E
If the Z FLAG is set (a string), JUMP to 55C2H to save the string's descriptor in a temporary string.
5561
LD C,(HL) 4E
Fetch the first byte of the value from (HL) (Register Pair HL = the variable's value) into Register C.
5562
INC HL 23
INCrement Register Pair HL by 1, to the second byte of the value.
5563
LD B,(HL) 46
Fetch the second byte of the value from (HL) (Register Pair HL = its address) into Register B.
5564
PUSH BC C5
Save Register Pair BC (bytes 0-1 of the value) onto the stack.
5565
If the SIGN FLAG is set (an integer, two bytes), JUMP to 557FH: the value is saved; Register Pair HL = the address of its last byte.
5568
INC HL 23
INCrement Register Pair HL by 1, to the third byte of the value.
5569
LD C,(HL) 4E
Fetch the third byte of the value from (HL) (Register Pair HL = its address) into Register C.
556A
INC HL 23
INCrement Register Pair HL by 1, to the fourth byte of the value.
556B
LD B,(HL) 46
Fetch the fourth byte of the value from (HL) (Register Pair HL = its address) into Register B.
556C
PUSH BC C5
Save Register Pair BC (bytes 2-3 of the value) onto the stack.
556D
If the PARITY FLAG is odd (single precision, four bytes), JUMP to 557FH: the value is saved.
5570
INC HL 23
INCrement Register Pair HL by 1, to the fifth byte of a double precision value.
5571
If the CARRY FLAG is set (always: 555DH set it), JUMP to 5576H to go on reading from the variable.
5573
LD HL,411DH 21 1D 41
Point Register Pair HL to 411DH, the low end of the ROM's double precision accumulator. Not reached in this file, as the CARRY FLAG is always set at 5571H.
5576
LD C,(HL) 4E
Fetch the fifth byte of the value from (HL) (Register Pair HL = its address) into Register C. 5571H jumps here.
5577
INC HL 23
INCrement Register Pair HL by 1, to the sixth byte of the value.
5578
LD B,(HL) 46
Fetch the sixth byte of the value from (HL) (Register Pair HL = its address) into Register B.
5579
INC HL 23
INCrement Register Pair HL by 1, to the seventh byte of the value.
557A
PUSH BC C5
Save Register Pair BC (bytes 4-5 of the value) onto the stack.
557B
LD C,(HL) 4E
Fetch the seventh byte of the value from (HL) (Register Pair HL = its address) into Register C.
557C
INC HL 23
INCrement Register Pair HL by 1, to the eighth and last byte of the value.
557D
LD B,(HL) 46
Fetch the eighth byte of the value from (HL) (Register Pair HL = its address) into Register B.
557E
PUSH BC C5
Save Register Pair BC (bytes 6-7 of the value) onto the stack.
557F
If the CARRY FLAG is set (always, from 555DH), JUMP to 55CCH to push the address and the flags. 5565H and 556DH jump here.

5582H - Find a Function Name

Register Pair HL = the text at the FN token. Checks the FN token and finds the variable that holds the function, named by the letters after FN with bit 7 set in the first letter, so that it can never be the same as an ordinary variable. Returns Register Pair DE = the address of its two-byte value (the address of the function's text after its name, stored by DEF), Register Pair HL past the name, and 40AFH = the function's type. Called by 558EH and 5659H.

5582
RST 08H => BEH CF BE
Check that the next character at Register Pair HL is BEH, the FN token, with RST 08H, which moves Register Pair HL on past it or gives a syntax error.
5584
LD A,80H 3E 80
Load Register A with 80H, the value that makes the ROM's 260DH refuse an array.
5586
LD (40DCH),A 32 DC 40
Store Register A (80H) into 40DCH, the ROM's flag that forbids a subscripted variable: the function name is never taken as an array.
5589
OR (HL) B6
OR Register A (80H) with the first letter of the name at (HL) (Register Pair HL = the text after FN): Register A = the letter with bit 7 set.
558A
LD B,A 47
Copy Register A (the first letter with bit 7 set) into Register B, where the ROM's variable search keeps the first character of the name.
558B
JUMP to the ROM's 2612H, inside its variable search (260DH), with Register B already loaded: it finds or creates the variable and returns to the caller of 5582H with Register Pair DE = its address.

558EH - FN: Call a User Function

The ROM jumps to 4155H, and from there here, when an expression holds FN. Finds the function; an undefined one gives error 2EH. When the definition has parameters, each parameter variable's value is saved (5556H) and then given the value of the matching argument in the call (ROM 1F2BH). The definition's expression is evaluated, the parameter variables get their old values back (5604H), and the result is converted to the function's type (ROM 281AH).

558E
GOSUB to 5582H to check the FN token and find the function: Register Pair DE = the address of the function variable, Register Pair HL = the text after the name, 40AFH = the function's type.
5591
LD A,(40AFH) 3A AF 40
Fetch the function's type from 40AFH into Register A: 2, 3, 4 or 8.
5594
OR A B7
OR Register A with itself: the Z FLAG and the CARRY FLAG are clear, which marks this entry on the stack as the function's own (5604H).
5595
PUSH AF F5
Save Register Pair AF (the function's type and these flags) onto the stack, below the saved parameter values.
5596
LD (40F3H),HL 22 F3 40
Store Register Pair HL (the call text after the function name) into 40F3H, a ROM work word, for 55D4H.
5599
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the address of the function variable, Register Pair DE = the call text.
559A
LD A,(HL) 7E
Fetch the low byte of the function variable's value from (HL) (Register Pair HL = the function variable) into Register A.
559B
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the value.
559C
LD H,(HL) 66
Fetch the high byte of the value from (HL) (Register Pair HL = its address) into Register H.
559D
LD L,A 6F
Copy the low byte from Register A into Register L: Register Pair HL = the address of the definition text after the function name, as DEF stored it at 5660H.
559E
OR H B4
OR Register A (the low byte) with Register H: the Z FLAG is set when the value is 0000H, a function that was never defined.
559F
If the Z FLAG is set (not defined), JUMP to 56BAH for error 2EH, Undefined user function.
55A2
LD A,(HL) 7E
Fetch the character after the name in the definition from (HL) (Register Pair HL = the definition text) into Register A.
55A3
CP 28H FE 28
Compare Register A against 28H, the opening parenthesis of a parameter list.
55A5
If the NZ FLAG is set (no parameters), JUMP to 55F5H, which pushes the call text (Register Pair DE) and evaluates the definition.
55A8
RST 10H D7
Move Register Pair HL past the parenthesis to the first parameter name with RST 10H, which leaves the character there in Register A.
55A9
LD (40D8H),HL 22 D8 40
Store Register Pair HL (the definition text at the first parameter name) into 40D8H, a ROM work word, for 55DAH.
55AC
JUMP to 55B0H to save the first parameter's value.
55AE
RST 08H => 2CH CF 2C
Next Parameter
Check that the next character at Register Pair HL (the definition text) is 2CH, a comma, with RST 08H. 55D2H jumps here.
55B0
LD C,04H 0E 04
Load Register C with 04H, the number of words of stack room wanted for one parameter.
55B2
GOSUB to the ROM's 1963H to check that twice Register C bytes (8) are free between the end of the variables (40FDH) and the stack; if not, OUT OF MEMORY.
55B5
LD A,80H 3E 80
Load Register A with 80H, which forbids an array as the parameter.
55B7
LD (40DCH),A 32 DC 40
Store Register A (80H) into 40DCH, the ROM's flag that forbids a subscripted variable.
55BA
GOSUB to the ROM's 260DH to find or create the parameter variable named at Register Pair HL: Register Pair DE = the address of its value, Register Pair HL past the name, 40AFH = its type.
55BD
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the parameter's value, Register Pair DE = the definition text.
55BE
SCF 37
Set the CARRY FLAG, which 5556H expects on entry and tests at 5571H and 557FH.
55BF
JUMP to 5556H to push the parameter's present value onto the stack.
55C2
JP NC,2423H D2 23 24
Save a String Parameter
If the NO CARRY FLAG is set, JUMP to the ROM's 2423H. Not taken in this file: 555EH always arrives with the CARRY FLAG set. 555EH jumps here.
55C5
PUSH DE D5
Save Register Pair DE (the definition text) onto the stack.
55C6
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the string variable's descriptor.
55C7
GOSUB to the ROM's 2888H to copy the three-byte descriptor at Register Pair DE into a new temporary string descriptor (40B3H moves on); it returns Register Pair HL = the variable's descriptor address.
55CA
POP DE D1
Restore Register Pair DE (the definition text) from the stack.
55CB
XOR A AF
Set Register A to ZERO with XOR A: the Z FLAG set and the CARRY FLAG clear mark a string parameter for 5604H.
55CC
PUSH HL E5
Save Register Pair HL (the address of the last byte of the value saved, or the string descriptor) onto the stack. 557FH jumps here.
55CD
PUSH AF F5
Save Register Pair AF (the type flags: CARRY FLAG for a number, Z FLAG for a string) onto the stack.
55CE
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the definition text after the parameter name.
55CF
LD A,(HL) 7E
Fetch the character after the parameter name from (HL) (Register Pair HL = the definition text) into Register A.
55D0
CP 29H FE 29
Compare Register A against 29H, the closing parenthesis of the parameter list.
55D2
If the NZ FLAG is set (more parameters), LOOP BACK to 55AEH for the next one.
55D4
LD HL,(40F3H) 2A F3 40
Fetch the call text after the function name from 40F3H, stored at 5596H, into Register Pair HL.
55D7
RST 08H => 28H CF 28
Check that the next character at Register Pair HL (the call text) is 28H, the opening parenthesis of the arguments, with RST 08H.
55D9
PUSH HL E5
Save Register Pair HL (the call text at the first argument) onto the stack.
55DA
LD HL,(40D8H) 2A D8 40
Fetch the definition text at the first parameter name from 40D8H, stored at 55A9H, into Register Pair HL.
55DD
Argument Loop
GOSUB to the ROM's 260DH to find the parameter variable named at Register Pair HL again: Register Pair DE = the address of its value, Register Pair HL past its name. 55EEH loops back here.
55E0
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the call text at the argument, and the definition text is kept on the stack.
55E1
GOSUB to the ROM's 1F2BH, the part of LET after the variable is found: it evaluates the argument at Register Pair HL and stores it into the parameter variable at Register Pair DE, converting it to the variable's type.
55E4
LD A,(HL) 7E
Fetch the character after the argument from (HL) (Register Pair HL = the call text) into Register A.
55E5
CP 29H FE 29
Compare Register A against 29H, the closing parenthesis of the call.
55E7
If the Z FLAG is set (the last argument), JUMP to 55F0H.
55E9
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL (the call text) is 2CH, a comma, with RST 08H.
55EB
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the definition text, and the call text is kept on the stack.
55EC
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL (the definition text) is 2CH, a comma, with RST 08H; fewer parameters than arguments gives a syntax error here.
55EE
Argument Loop End
LOOP BACK to 55DDH for the next parameter and argument.
55F0
RST 10H D7
Move Register Pair HL (the call text) past the closing parenthesis with RST 10H, which leaves the next character in Register A. 55E7H jumps here.
55F1
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the definition text, and the call text after the parenthesis is kept on the stack.
55F2
RST 08H => 29H CF 29
Check that the next character at Register Pair HL (the definition text) is 29H, the closing parenthesis, with RST 08H; more parameters than arguments gives a syntax error here.
55F4
LD A,D5H 3E D5
Load Register A with D5H. The byte D5H at 55F5H is also an instruction of its own, PUSH DE, where 55A5H enters; from here it is the operand and the next instruction is 55F6H.
55F6
RST 08H => D5H CF D5
Check that the next character at Register Pair HL (the definition text) is D5H, the = token, with RST 08H. When entered at 55F5H, PUSH DE has just saved the call text.
55F8
GOSUB to the ROM's 2337H, the expression evaluator, to evaluate the definition's expression at Register Pair HL: the result is in the accumulator at 4121H, its type in 40AFH.
55FB
DEC HL 2B
DECrement Register Pair HL (the definition text after the expression) by 1, so that RST 10H looks at the character after the expression again.
55FC
RST 10H D7
Fetch the character after the expression into Register A with RST 10H, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement (00H or a colon).
55FD
If the NZ FLAG is set (anything else after the expression), JUMP to the ROM's 1997H, the syntax error.
5600
RST 20H E7
Test the type of the result with RST 20H (the ROM's type test of 40AFH): the Z FLAG is set for a string.
5601
If the Z FLAG is set (a string result), JUMP to 5632H to keep it safe from the parameters' temporary strings.
5603
POP DE D1
Restore Register Pair DE (the call text after the arguments) from the stack. 563FH jumps here.

5604H - FN: Give the Parameters Their Old Values

Takes the entries 5556H pushed off the stack, last parameter first, and puts each value back: for a number the words go back into the variable, for a string the descriptor saved in the newest temporary string goes back into the variable and that temporary is released. The entry 5595H pushed ends the loop, and the result is converted to the function's type.

5604
POP AF F1
Restore Loop
Restore Register Pair AF from the stack: a parameter's flags (CARRY FLAG = a number, Z FLAG = a string) or, with both clear, the function's own entry from 5595H. 560EH, 5616H, 5623H and 5653H loop back here.
5605
If the Z FLAG is set (a string parameter), JUMP to 5646H to put its descriptor back.
5607
If the NO CARRY FLAG is set (the function's own entry: every parameter is back), JUMP to 5625H.
5609
POP HL E1
Restore Register Pair HL (the address of the last byte of the parameter's value) from the stack.
560A
POP BC C1
Restore Register Pair BC (the last word pushed for this value) from the stack.
560B
LD (HL),B 70
Store Register B into (HL), the last byte of the value, Register Pair HL = its address.
560C
DEC HL 2B
DECrement Register Pair HL by 1, to the byte before.
560D
LD (HL),C 71
Store Register C into (HL) (Register Pair HL = the byte before): two bytes of the value are back.
560E
If the SIGN FLAG is set (an integer: two bytes only), LOOP BACK to 5604H for the next entry.
5611
DEC HL 2B
DECrement Register Pair HL by 1, to the second byte of the value.
5612
POP BC C1
Restore Register Pair BC (bytes 0-1 of a single, or 4-5 of a double) from the stack.
5613
LD (HL),B 70
Store Register B into (HL), Register Pair HL = the byte two below the last one stored.
5614
DEC HL 2B
DECrement Register Pair HL by 1, to the byte before.
5615
LD (HL),C 71
Store Register C into (HL) (Register Pair HL = the byte before): four bytes of the value are back.
5616
If the PARITY FLAG is odd (single precision), LOOP BACK to 5604H for the next entry.
5619
DEC HL 2B
DECrement Register Pair HL by 1, to byte 3 of a double precision value.
561A
POP BC C1
Restore Register Pair BC (bytes 2-3 of the double) from the stack.
561B
LD (HL),B 70
Store Register B (byte 3) into (HL), Register Pair HL = the address of byte 3.
561C
DEC HL 2B
DECrement Register Pair HL by 1, to byte 2 of the double precision value.
561D
LD (HL),C 71
Store Register C (byte 2) into (HL), Register Pair HL = the address of byte 2.
561E
DEC HL 2B
DECrement Register Pair HL by 1, to byte 1 of the double precision value.
561F
POP BC C1
Restore Register Pair BC (bytes 0-1 of the double) from the stack.
5620
LD (HL),B 70
Store Register B (byte 1) into (HL), Register Pair HL = the address of byte 1.
5621
DEC HL 2B
DECrement Register Pair HL by 1, to byte 0, the first byte of the value.
5622
LD (HL),C 71
Store Register C (byte 0) into (HL) (Register Pair HL = the address of byte 0): all eight bytes of the double are back.
5623
LOOP BACK to 5604H for the next entry on the stack, the parameter before.
5625
PUSH DE D5
Save Register Pair DE (the call text after the arguments) onto the stack, for the ROM's 2826H to pop into Register Pair HL. 5607H jumps here.
5626
PUSH AF F5
Save Register Pair AF (Register A = the function's type, from 5595H) onto the stack.
5627
RST 20H E7
Test the type of the result with RST 20H: the Z FLAG is set for a string.
5628
LD DE,40D3H 11 D3 40
Point Register Pair DE to 40D3H, the ROM's string descriptor work area, where 5632H-5653H left a string result.
562B
If the Z FLAG is set (a string result), GOSUB to the ROM's 2888H to make the descriptor at 40D3H a temporary string again, with its address in the accumulator at 4121H.
562E
POP AF F1
Restore Register Pair AF (Register A = the function's type) from the stack.
562F
JUMP to the ROM's 281AH, which converts the result to the function's type through its table at 18A1H (to double, to integer, string check, to single) and returns to the expression evaluator with Register Pair HL = the call text, popped from the stack.
5632
LD HL,(40B3H) 2A B3 40
Keep a String Result
Fetch the next free temporary string descriptor address from 40B3H into Register Pair HL. 5601H jumps here.
5635
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the next free temporary descriptor.
5636
LD HL,(4121H) 2A 21 41
Fetch the result's descriptor address from 4121H, the accumulator, into Register Pair HL.
5639
RST 18H DF
Compare Register Pair HL (the result's descriptor) with Register Pair DE (the next free temporary) with RST 18H: the CARRY FLAG is set when the result is a temporary string.
563A
If the CARRY FLAG is set (a temporary), JUMP to 5641H to move it to 40D3H.
563C
GOSUB to the ROM's 2843H to copy the string of the descriptor at Register Pair HL into new string space, with its new descriptor at 40D3H.
563F
JUMP to 5603H to take the call text off the stack and give the parameters their old values.
5641
POP DE D1
Restore Register Pair DE (the call text after the arguments) from the stack. 563AH jumps here.
5642
LD HL,40D3H 21 D3 40
Point Register Pair HL to 40D3H, the ROM's string descriptor work area.
5645
PUSH HL E5
Save Register Pair HL (40D3H) onto the stack, as the place to store the descriptor.
5646
Restore a String
GOSUB to the ROM's 29F5H: with Register Pair DE (the call text) never equal to it, it returns Register Pair HL = the newest temporary descriptor and Register Pair BC = its string address. 5605H jumps here, with the variable's descriptor address on the stack.
5649
LD A,(HL) 7E
Fetch the string length from (HL) (Register Pair HL = the newest temporary descriptor) into Register A.
564A
LD (40B3H),HL 22 B3 40
Store Register Pair HL into 40B3H: the newest temporary descriptor is released.
564D
POP HL E1
Restore Register Pair HL (the variable's descriptor, or 40D3H) from the stack.
564E
LD (HL),A 77
Store Register A (the length) into (HL), byte 0 of the descriptor at Register Pair HL.
564F
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
5650
LD (HL),C 71
Store Register C (the low byte of the string address) into (HL), Register Pair HL = byte 1 of the descriptor.
5651
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
5652
LD (HL),B 70
Store Register B (the high byte of the string address) into (HL) (Register Pair HL = byte 2 of the descriptor): the descriptor is back.
5653
LOOP BACK to 5604H for the next entry on the stack, the parameter before.

5655H - DEF: Define a Function or a USR Address

The ROM's statement table sends DEF to 415BH, and from there here. DEF USRn=address goes to 56ABH. DEF FN stores the address of the text after the function name into the function variable (it may not be typed as a direct statement), checks the names in the parameter list, and skips the rest of the statement with the ROM's DATA routine; the expression is only evaluated when the function is called.

5655
CP C1H FE C1
Compare Register A (the character after DEF, from the ROM's dispatch) against C1H, the USR token.
5657
If the Z FLAG is set (DEF USR), JUMP to 56ABH.
5659
GOSUB to 5582H to check the FN token and find the function variable: Register Pair DE = its address, Register Pair HL = the text after the name.
565C
GOSUB to the ROM's 2828H, which gives the error ILLEGAL DIRECT when the line number at 40A2H shows a direct statement; Register Pair HL is kept.
565F
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the function variable, Register Pair DE = the text after the name.
5660
LD (HL),E 73
Store Register E (the low byte of the text address) into (HL), Register Pair HL = the function variable.
5661
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the function variable.
5662
LD (HL),D 72
Store Register D (the high byte of the text address) into (HL) (Register Pair HL = the variable's second byte): the function now points to its definition.
5663
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the text after the name again.
5664
LD A,(HL) 7E
Fetch the character after the name from (HL) (Register Pair HL = the definition text) into Register A.
5665
CP 28H FE 28
Compare Register A against 28H, the opening parenthesis of a parameter list.
5667
If the NZ FLAG is set (no parameters), JUMP to the ROM's 1F05H, the DATA statement, which skips to the end of the statement.
566A
RST 10H D7
Move Register Pair HL past the parenthesis with RST 10H, which leaves the first character of the parameter name in Register A.
566B
Parameter Loop
GOSUB to the ROM's 260DH to find or create the parameter variable named at Register Pair HL, which checks that it is a variable name; Register Pair HL ends past it. 5676H loops back here.
566E
LD A,(HL) 7E
Fetch the character after the parameter name from (HL) (Register Pair HL = the definition text) into Register A.
566F
CP 29H FE 29
Compare Register A against 29H, the closing parenthesis.
5671
If the Z FLAG is set (the end of the list), JUMP to the ROM's 1F05H to skip the = and the expression to the end of the statement.
5674
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
5676
Parameter Loop End
JUMP to 566BH for the next parameter name.

5679H - USR: Call a Machine Language Routine

The ROM's USR function calls the link at 41A9H first (27FEH), and from there it comes here. The return address into the ROM is dropped: BASIC/CMD does the whole call. USR or USR0-USR9 picks one of ten addresses at 5B77H. The argument in parentheses is evaluated; the routine is entered with Register Pair HL = 4121H (the accumulator) and Register A = the argument's type, and its RET goes to the ROM's 26E7H, which puts the text pointer back into Register Pair HL.

5679
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 2801H that the ROM's CALL 41A9H pushed, so the ROM's own USR code does not run.
567A
GOSUB to 5699H to read the digit after USR: Register Pair DE = the address of its slot at 5B77H plus twice the digit, Register Pair HL = the text after it.
567D
PUSH DE D5
Save Register Pair DE (the slot address) onto the stack.
567E
GOSUB to the ROM's 252CH to evaluate the argument in parentheses at Register Pair HL: the value is in the accumulator at 4121H, its type in 40AFH.
5681
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the slot address, and the text after the argument is kept on the stack.
5682
LD C,(HL) 4E
Fetch the low byte of the routine address from (HL) (Register Pair HL = the slot) into Register C.
5683
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the slot.
5684
LD B,(HL) 46
Fetch the high byte of the routine address from (HL) (Register Pair HL = the slot's second byte) into Register B: Register Pair BC = the routine.
5685
LD HL,26E7H 21 E7 26
Point Register Pair HL to 26E7H, the ROM's POP HL / RET, the return address for the routine.
5688
PUSH HL E5
Save Register Pair HL (26E7H) onto the stack, above the text pointer.
5689
PUSH BC C5
Save Register Pair BC (the routine address) onto the stack, for the RET at 5698H to jump to.
568A
LD A,(40AFH) 3A AF 40
Fetch the argument's type from 40AFH into Register A.
568D
PUSH AF F5
Save Register Pair AF (the type) onto the stack.
568E
CP 03H FE 03
Compare Register A (the type) against 03H, a string.
5690
If the Z FLAG is set (a string argument), GOSUB to the ROM's 29DAH to release its temporary string; the descriptor address stays in 4121H.
5693
POP AF F1
Restore Register Pair AF (Register A = the argument's type) from the stack.
5694
EX DE,HL EB
Exchange Register Pairs DE and HL, as the ROM's own USR does at 2814H: Register Pair DE receives 26E7H (or what 29DAH left in Register Pair HL for a string), a value the routine is not given any use for.
5695
LD HL,4121H 21 21 41
Point Register Pair HL to 4121H, the accumulator holding the argument.
5698
RET C9
RETURN, which jumps to the routine address pushed at 5689H with Register A = the type and Register Pair HL = 4121H.

5699H - Read the Number after USR

Register Pair HL = the text at the USR token. Takes an optional digit 0-9 after it. Returns Register Pair DE = 5B77H plus twice the digit, the slot of that USR address, and Register Pair HL = the text after the token or the digit.

5699
RST 10H D7
Move Register Pair HL past the USR token with RST 10H: Register A = the next character, the CARRY FLAG set for a digit. 567AH and 56ABH call here.
569A
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the offset of USR0 (the CARRY FLAG is not changed).
569D
If the NO CARRY FLAG is set (no digit), JUMP to 56A4H with offset 0.
569F
SUB 30H D6 30
SUBtract 30H from Register A (the digit character): Register A = 0-9.
56A1
RLA 17
Rotate Register A left through the CARRY FLAG (clear after the SUB): the digit times two, the offset of its word.
56A2
LD C,A 4F
Copy the offset from Register A into Register C: Register Pair BC = twice the digit.
56A3
RST 10H D7
Move Register Pair HL past the digit with RST 10H, which leaves the next character in Register A.
56A4
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the text pointer. 569DH jumps here.
56A5
LD HL,5B77H 21 77 5B
Point Register Pair HL to 5B77H, the table of the ten USR addresses.
56A8
ADD HL,BC 09
ADD Register Pair BC (the offset) to Register Pair HL: Register Pair HL = the slot.
56A9
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the slot, Register Pair HL = the text pointer.
56AA
RET C9
RETURN to the caller with Register Pair DE = the slot and Register Pair HL = the text.

56ABH - DEF USR: Set a USR Address

DEF USRn=expression stores the value, converted to an integer, into the slot of USRn. 5657H jumps here.

56AB
GOSUB to 5699H to read the digit after USR: Register Pair DE = the slot address, Register Pair HL = the text after it.
56AE
PUSH DE D5
Save Register Pair DE (the slot address) onto the stack.
56AF
RST 08H => D5H CF D5
Check that the next character at Register Pair HL is D5H, the = token, with RST 08H.
56B1
GOSUB to the ROM's 2B02H to evaluate the expression at Register Pair HL and convert it to an integer in Register Pair DE (values above 32767 must be written as negative numbers or in hexadecimal).
56B4
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the slot address, and the text pointer is kept on the stack.
56B5
LD (HL),E 73
Store Register E (the low byte of the address) into (HL), Register Pair HL = the slot.
56B6
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the slot.
56B7
LD (HL),D 72
Store Register D (the high byte of the address) into (HL) (Register Pair HL = the slot's second byte): USRn now calls this address.
56B8
POP HL E1
Restore Register Pair HL (the text pointer after the expression) from the stack.
56B9
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the text after the statement.
56BA
LD E,2EH 1E 2E
Undefined User Function
Load Register E with 2EH, the error code Undefined user function. 559FH jumps here.
56BC
JUMP to the ROM's 19A2H, its error handler, with the error code in Register E.

56BFH - PRINT: Is It PRINT # to a File?

The ROM calls the link at 41CAH at the start of PRINT (206FH) with Register A = the first character after PRINT and Register Pair HL at it. PRINT #-1 (the cassette) is left to the ROM. Anything else goes to 5EC5H with mode 02H, which returns at once when there is no # and otherwise checks that the file is open for output and makes it the current file for the characters PRINT sends.

56BF
PUSH HL E5
Save Register Pair HL (the text at the character after PRINT) onto the stack. The link at 41CAH jumps here.
56C0
RST 10H D7
Move Register Pair HL to the next character with RST 10H, which leaves it in Register A.
56C1
CP CEH FE CE
Compare Register A against CEH, the minus token, as in PRINT #-1.
56C3
POP HL E1
Restore Register Pair HL (the text at the first character) from the stack.
56C4
LD A,(HL) 7E
Fetch the first character from (HL) (Register Pair HL = the text) into Register A again, as the ROM expects it at 2072H.
56C5
RET Z C8
If the Z FLAG is set (a minus sign follows: the cassette), RETURN to the ROM's PRINT.
56C6
LD C,02H 0E 02
Load Register C with 02H, the mode byte of a file open for output.
56C8
JUMP to 5EC5H to handle # and the file number for mode Register C.

56CBH - CMD: the Letter Commands

The ROM's statement table sends CMD to 4173H, and from there here. The argument is a string; its first character picks the command: D enters DEBUG, E shows the text of the last disk error, T stops the interrupts, R starts them again, S and A leave BASIC for DOS, # shows the copyright message and I runs a DOS command. Anything else, or an empty string, gives ILLEGAL FUNCTION CALL. Each command takes the text pointer, pushed at 56CEH, back off the stack before it returns.

56CB
GOSUB to the ROM's 2337H to evaluate the expression after CMD at Register Pair HL: the result is in the accumulator at 4121H.
56CE
PUSH HL E5
Save Register Pair HL (the text after the expression) onto the stack; every command takes it back.
56CF
GOSUB to the ROM's 29D7H, which gives TYPE MISMATCH unless the result is a string, releases its temporary and returns Register Pair HL = its descriptor.
56D2
LD A,(HL) 7E
Fetch the string length from (HL) (Register Pair HL = the descriptor) into Register A.
56D3
OR A B7
OR Register A with itself: the Z FLAG is set for an empty string.
56D4
If the Z FLAG is set (empty), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
56D7
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
56D8
LD E,(HL) 5E
Fetch the low byte of the string address from (HL) (Register Pair HL = the descriptor) into Register E.
56D9
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
56DA
LD D,(HL) 56
Fetch the high byte of the string address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = the text of the string.
56DB
LD A,(DE) 1A
Fetch the first character of the string from (DE) (Register Pair DE = the string) into Register A.
56DC
CP 44H FE 44
Compare Register A against 44H, the letter D.
56DE
If the Z FLAG is set (CMD"D"), JUMP to 5740H to enter DEBUG.
56E1
CP 45H FE 45
Compare Register A against 45H, the letter E.
56E3
If the Z FLAG is set (CMD"E"), JUMP to 5736H to show the last disk error.
56E6
CP 54H FE 54
Compare Register A against 54H, the letter T.
56E8
If the Z FLAG is set (CMD"T"), JUMP to 5709H to stop the interrupts.
56EA
CP 52H FE 52
Compare Register A against 52H, the letter R.
56EC
If the Z FLAG is set (CMD"R"), JUMP to 5706H to start the interrupts again.
56EE
CP 53H FE 53
Compare Register A against 53H, the letter S; equal leaves the CARRY FLAG clear.
56F0
If the Z FLAG is set (CMD"S"), JUMP to 5BB4H with the CARRY FLAG clear, to go to DOS READY.
56F3
CP 41H FE 41
Compare Register A against 41H, the letter A.
56F5
SCF 37
Set the CARRY FLAG, which tells 5BB4H to leave through 4030H, the exit after an error; the Z FLAG of the compare is kept.
56F6
If the Z FLAG is set (CMD"A"), JUMP to 5BB4H with the CARRY FLAG set.
56F9
CP 23H FE 23
Compare Register A against 23H, the character #.
56FB
If the Z FLAG is set (CMD"#"), JUMP to 5818H to show the copyright message.
56FE
CP 49H FE 49
Compare Register A against 49H, the letter I.
5700
If the Z FLAG is set (CMD"I"), JUMP to 5711H to run a DOS command.
5703
JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL, for any other letter.
5706
LD A,C3H 3E C3
CMD"R"
Load Register A with C3H, the opcode JP, which puts the interrupt vector at 4012H back to a jump. 56ECH jumps here.
5708
LD BC,C93EH 01 3E C9
Load Register Pair BC with C93EH: from 5706H this only skips the two bytes at 5709H; Register Pair BC is not used.
570B
LD (4012H),A 32 12 40
Store Register A into 4012H, the first byte of the RST 38H interrupt vector: C3H (JP, its address at 4013H-4014H unchanged) for CMD"R", C9H (RET) for CMD"T". Entered at 5709H, the bytes 3EH C9H are LD A,C9H, the RET opcode. An interrupt then reaches the RET, which returns with interrupts disabled, as accepting the interrupt disabled them.
570E
POP HL E1
Restore Register Pair HL (the text after the CMD expression, pushed at 56CEH) from the stack.
570F
EI FB
Enable interrupts; after CMD"T" the first interrupt disables them again at the RET in 4012H.
5710
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the text after the statement.
5711
POP HL E1
CMD"I"
Restore Register Pair HL (the text after the first string, pushed at 56CEH) from the stack. 5700H jumps here.
5712
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
5714
GOSUB to the ROM's 2337H to evaluate the second expression, the DOS command, at Register Pair HL.
5717
PUSH HL E5
Save Register Pair HL (the text after the second expression) onto the stack.
5718
GOSUB to the ROM's 29D7H, which checks that the result is a string, releases its temporary and returns Register Pair HL = its descriptor.
571B
LD A,(HL) 7E
Fetch the string length from (HL) (Register Pair HL = the descriptor) into Register A.
571C
OR A B7
OR Register A with itself: the Z FLAG is set for an empty string.
571D
If the Z FLAG is set (empty), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
5720
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
5721
LD E,(HL) 5E
Fetch the low byte of the string address from (HL) (Register Pair HL = the descriptor) into Register E.
5722
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
5723
LD D,(HL) 56
Fetch the high byte of the string address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = the command text.
5724
LD L,A 6F
Copy the length from Register A into Register L.
5725
LD H,00H 26 00
Load Register H with 00H: Register Pair HL = the length.
5727
ADD HL,DE 19
ADD Register Pair DE (the text) to Register Pair HL (the length): Register Pair HL = the byte after the string.
5728
LD A,(HL) 7E
Fetch the byte after the string from (HL) (Register Pair HL = its address) into Register A.
5729
PUSH AF F5
Save Register Pair AF (Register A = that byte) onto the stack.
572A
LD (HL),0DH 36 0D
Store 0DH, ENTER, at (HL) (Register Pair HL = the byte after the string): the command line ends there, as the DOS expects.
572C
PUSH HL E5
Save Register Pair HL (the address of that byte) onto the stack.
572D
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the command text.
572E
GOSUB to SYS0/SYS's 4405H, which loads SYS1/SYS and runs the command at Register Pair HL. SYS1/SYS's 4E4EH pushes 402DH first, so the command ends at DOS READY and BASIC is left; the rows up to 5735H run only if 4405H comes back.
5731
POP HL E1
Restore Register Pair HL (the address of the byte after the string) from the stack.
5732
POP AF F1
Restore Register Pair AF (Register A = the byte that was there) from the stack.
5733
LD (HL),A 77
Store Register A back into (HL) (Register Pair HL = the byte after the string).
5734
POP HL E1
Restore Register Pair HL (the text after the statement) from the stack.
5735
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the text after the statement.
5736
LD A,(5B8CH) 3A 8C 5B
CMD"E"
Fetch the number of the last DOS error from 5B8CH, stored by 656FH, into Register A. 56E3H jumps here.
5739
OR C0H F6 C0
OR Register A with C0H: bit 7 makes the message routine return, bit 6 shows the text only.
573B
GOSUB to SYS0/SYS's 4409H to show the text of the DOS error in Register A.
573E
POP HL E1
Restore Register Pair HL (the text after the statement, pushed at 56CEH) from the stack.
573F
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the text after the statement.
5740
CMD"D"
GOSUB to SYS0/SYS's 440DH, which loads SYS5/SYS, the DEBUG monitor; its G command continues at the return address on the stack, 5743H. 56DEH jumps here.
5743
POP HL E1
Restore Register Pair HL (the text after the statement, pushed at 56CEH) from the stack.
5744
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the text after the statement.

5745H - TIME$: the Date and Time as a String

The ROM jumps to 4176H for the TIME$ token, and from there here. Builds a 17-character string MM/DD/YY HH:MM:SS from SYS0/SYS's clock bytes at 4046H down to 4041H (month, day, year, hours, minutes, seconds).

5745
RST 10H D7
Move Register Pair HL past the TIME$ token with RST 10H, which leaves the next character in Register A.
5746
PUSH HL E5
Save Register Pair HL (the text after TIME$) onto the stack, for the ROM's 2884H to take back.
5747
LD A,11H 3E 11
Load Register A with 11H, the 17 characters of the result.
5749
GOSUB to the ROM's 2857H to make room for a string of Register A characters in string space, with its descriptor at 40D3H.
574C
LD HL,(40D4H) 2A D4 40
Fetch the address of the new string from 40D4H, the address word of the descriptor at 40D3H, into Register Pair HL.
574F
LD DE,4046H 11 46 40
Point Register Pair DE to 4046H, SYS0/SYS's month byte; 5776H reads downward from it.
5752
GOSUB to 5776H to store the month at Register Pair DE as two digits at Register Pair HL.
5755
LD (HL),2FH 36 2F
Store 2FH, a slash, at (HL) (Register Pair HL = the next character of the string).
5757
INC HL 23
INCrement Register Pair HL by 1, to the next character.
5758
GOSUB to 5776H to store the day (4045H) as two digits.
575B
LD (HL),2FH 36 2F
Store 2FH, a slash, at (HL) (Register Pair HL = the next character of the string).
575D
INC HL 23
INCrement Register Pair HL by 1, to the next character.
575E
GOSUB to 5776H to store the year (4044H) as two digits.
5761
LD (HL),20H 36 20
Store 20H, a space, at (HL) (Register Pair HL = the next character of the string).
5763
INC HL 23
INCrement Register Pair HL by 1, to the next character.
5764
GOSUB to 5776H to store the hours (4043H) as two digits.
5767
LD (HL),3AH 36 3A
Store 3AH, a colon, at (HL) (Register Pair HL = the next character of the string).
5769
INC HL 23
INCrement Register Pair HL by 1, to the next character.
576A
GOSUB to 5776H to store the minutes (4042H) as two digits.
576D
LD (HL),3AH 36 3A
Store 3AH, a colon, at (HL) (Register Pair HL = the next character of the string).
576F
INC HL 23
INCrement Register Pair HL by 1, to the next character.
5770
GOSUB to 5776H to store the seconds (4041H) as two digits.
5773
JUMP to the ROM's 2884H, which makes the descriptor at 40D3H a temporary string in the accumulator, takes the text pointer off the stack into Register Pair HL and returns to the expression evaluator.

5776H - Two Digits

Register Pair DE = a clock byte (binary, 0-99), Register Pair HL = where to store. Stores it as two digit characters and moves Register Pair HL on by two and Register Pair DE back by one.

5776
LD A,(DE) 1A
Fetch the clock byte from (DE) (Register Pair DE = its address) into Register A. Called by 5752H-5770H.
5777
DEC DE 1B
DECrement Register Pair DE by 1, to the next clock byte down.
5778
LD B,2FH 06 2F
Load Register B with 2FH, one less than the digit 0: it becomes the tens digit.
577A
SUB 0AH D6 0A
Tens Loop
SUBtract 0AH from Register A: the CARRY FLAG is set when it goes below zero. 577DH loops back here.
577C
INC B 04
INCrement Register B (the tens digit) by 1, one for each ten taken off.
577D
Tens Loop End
If the NO CARRY FLAG is set, LOOP BACK to 577AH to take another ten off.
577F
ADD A,3AH C6 3A
ADD 3AH to Register A (the units minus ten): the ten back plus 30H, the units digit character.
5781
LD (HL),B 70
Store Register B (the tens digit) into (HL) (Register Pair HL = the string).
5782
INC HL 23
INCrement Register Pair HL by 1, to the next character.
5783
LD (HL),A 77
Store Register A (the units digit) into (HL) (Register Pair HL = the string).
5784
INC HL 23
INCrement Register Pair HL by 1, past the two digits.
5785
RET C9
RETURN to the caller with Register Pair HL past the digits.

5786H - LINE INPUT

The ROM's statement table sends LINE to 41A3H, and from there here. LINE INPUT # reads from a file (5F4CH). Otherwise it is not allowed as a direct statement; it shows an optional prompt, reads a whole line from the keyboard (commas and quotes included) and assigns it to a string variable.

5786
RST 08H => 89H CF 89
Check that the next character at Register Pair HL is 89H, the INPUT token, with RST 08H.
5788
GOSUB to the ROM's 2828H, which gives ILLEGAL DIRECT for a direct statement; Register Pair HL is kept.
578B
LD A,(HL) 7E
Fetch the character after INPUT from (HL) (Register Pair HL = the text) into Register A.
578C
CP 23H FE 23
Compare Register A against 23H, the character #.
578E
If the Z FLAG is set (LINE INPUT #), JUMP to 5F4CH to read the line from a file.
5791
GOSUB to the ROM's 21CDH to show the prompt string at Register Pair HL, if there is one (a quoted text and a semicolon).
5794
GOSUB to the ROM's 260DH to find or create the variable named at Register Pair HL: Register Pair DE = its address.
5797
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the variable is a string.
579A
PUSH DE D5
Save Register Pair DE (the variable's address) onto the stack.
579B
PUSH HL E5
Save Register Pair HL (the text after the variable) onto the stack.
579C
GOSUB to the ROM's 0361H to read a line from the keyboard into the input buffer: Register Pair HL returns pointing to it, the CARRY FLAG is set for BREAK.
579F
POP DE D1
Restore Register Pair DE (the text after the variable) from the stack.
57A0
POP BC C1
Restore Register Pair BC (the variable's address) from the stack.
57A1
If the CARRY FLAG is set (BREAK), JUMP to the ROM's 1DBEH, its STOP handling with Register Pair DE as the text pointer.
57A4
PUSH BC C5
Save Register Pair BC (the variable's address) onto the stack again, for the ROM's assignment.
57A5
PUSH DE D5
Save Register Pair DE (the text after the variable) onto the stack.
57A6
LD B,00H 06 00
Load Register B with 00H: the line ends only at its 00H byte, so commas and quotes stay in it.
57A8
GOSUB to the ROM's 2868H to make a string of the text at Register Pair HL up to the 00H in Register B, with its descriptor at 40D3H.
57AB
POP HL E1
Restore Register Pair HL (the text after the variable) from the stack.
57AC
XOR A AF
Set Register A to ZERO with XOR A; the ROM's 1F32H adds 3 to it, the type of a string.
57AD
JUMP to the ROM's 1F32H, inside LET, which assigns the string to the variable whose address is on the stack and returns to the statement loop.

57B0H - End of PRINT: No Current File

The ROM calls the link at 41BEH at the end of PRINT (2174H) with Register A = 00H. Stores 0000H into 5B8DH, the current file: the characters go to the screen or printer again.

57B0
PUSH HL E5
Save Register Pair HL (the ROM's text pointer) onto the stack. The link at 41BEH jumps here.
57B1
LD L,A 6F
Copy Register A (00H, cleared by the ROM at 2170H) into Register L.
57B2
LD H,A 67
Copy Register A (00H) into Register H: Register Pair HL = 0000H.
57B3
LD (5B8DH),HL 22 8D 5B
Store Register Pair HL (0000H) into 5B8DH, the current file pointer: no file.
57B6
POP HL E1
Restore Register Pair HL (the ROM's text pointer) from the stack.
57B7
RET C9
RETURN to the ROM's PRINT with Register Pair HL unchanged.

57B8H - INPUT: Is It INPUT # from a File?

The ROM calls the link at 41D6H at the start of INPUT (219EH) with Register A = the character after INPUT. Without # it returns. INPUT #-1 is left to the ROM. For a file number, the ROM's own INPUT start is dropped: 5EC3H checks that the file is open for input and makes it current, and the ROM goes on at 21EBH as if a line had been typed, with the input buffer pointer at the comma it stores there, so the items are read by 5F35H.

57B8
PUSH HL E5
Save Register Pair HL (the text at the character after INPUT) onto the stack. The link at 41D6H jumps here.
57B9
CP 23H FE 23
Compare Register A (the character after INPUT) against 23H, the character #.
57BB
If the NZ FLAG is set (no #), JUMP to the ROM's 26E7H, which restores Register Pair HL from the stack and returns to the ROM's INPUT.
57BE
RST 10H D7
Move Register Pair HL to the character after # with RST 10H, which leaves it in Register A.
57BF
CP CEH FE CE
Compare Register A against CEH, the minus token, as in INPUT #-1.
57C1
POP HL E1
Restore Register Pair HL (the text at the #) from the stack.
57C2
LD A,(HL) 7E
Fetch the # from (HL) (Register Pair HL = the text) into Register A again.
57C3
RET Z C8
If the Z FLAG is set (the cassette), RETURN to the ROM's INPUT.
57C4
POP BC C1
Restore Register Pair BC from the stack: this takes off the return address into the ROM's INPUT (21A1H), which is not used.
57C5
GOSUB to 5EC3H to read the file number, check that the file is open for input, expect a comma and make it the current file (5B8DH).
57C8
PUSH HL E5
Save Register Pair HL (the text at the first variable) onto the stack, as the ROM's INPUT does.
57C9
LD HL,(40A7H) 2A A7 40
Fetch the input buffer pointer from 40A7H into Register Pair HL.
57CC
DEC HL 2B
DECrement Register Pair HL by 1, to the byte before the buffer.
57CD
JUMP to the ROM's 21EBH, which stores a comma at Register Pair HL and reads the items as if a line had been typed.

57D0H - INPUT # and LIST to a File

The ROM calls the link at 41DFH in INPUT after the items (2278H) and in LIST before each line (2B44H). Without a current file it returns. With one, the return address picks the case: in INPUT the ?EXTRA IGNORED message is skipped (2282H); in LIST the test for a key between lines (1D9BH) is skipped (2B4AH).

57D0
PUSH HL E5
Save Register Pair HL onto the stack. The link at 41DFH jumps here.
57D1
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
57D4
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
57D5
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
57D6
POP HL E1
Restore Register Pair HL (the ROM's value, pushed at 57D0H) from the stack.
57D7
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM.
57D8
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the return address into the ROM (227BH or 2B47H), and the ROM's Register Pair HL is kept on the stack.
57D9
PUSH DE D5
Save Register Pair DE (the ROM's value) onto the stack while it is used for 2B2EH.
57DA
LD DE,2B2EH 11 2E 2B
Point Register Pair DE to 2B2EH, the start of the ROM's LIST, between the two calling places.
57DD
RST 18H DF
Compare Register Pair HL (the return address) with Register Pair DE (2B2EH) with RST 18H: the CARRY FLAG is set for the INPUT call at 2278H.
57DE
POP DE D1
Restore Register Pair DE (the ROM's value, pushed at 57D9H) from the stack.
57DF
POP HL E1
Restore Register Pair HL (the ROM's own value) from the stack; the return address is dropped.
57E0
If the NO CARRY FLAG is set (LIST), JUMP to the ROM's 2B4AH, after LIST's test for a key.
57E3
JUMP to the ROM's 2282H, the end of INPUT, after the ?EXTRA IGNORED message.

57E6H - Show an Error as Text

The ROM calls the link at 41A6H in its error handler (19ECH) with Register E = the error code. The ROM would show a two-letter code; BASIC/CMD drops that return and shows the error's text from 5203H instead. An error during the start-up questions (line number FFFEH) starts BASIC/CMD again at 5C06H. Otherwise 64F2H clears a protected program, and the ROM goes on at 1A11H, which adds IN and the line number and returns to READY.

57E6
POP HL E1
Restore Register Pair HL from the stack: this takes off the return address 19EFH, so the ROM's two-letter message is not shown. The link at 41A6H jumps here.
57E7
LD HL,5203H 21 03 52
Point Register Pair HL to 5203H, the 00H before the first message.
57EA
LD A,E 7B
Copy the error code from Register E into Register A.
57EB
CP 8BH FE 8B
Compare Register A against 8BH: the NO CARRY FLAG is set for codes above the last disk error.
57ED
If the NO CARRY FLAG is set (8BH or more), JUMP to 57F7H for Unprintable error.
57EF
CP 63H FE 63
Compare Register A against 63H: the NO CARRY FLAG is set for the disk errors 64H-8AH.
57F1
If the NO CARRY FLAG is set (a disk error), JUMP to 57F9H to move it down by 34H.
57F3
CP 2FH FE 2F
Compare Register A against 2FH: the CARRY FLAG is set for the codes 00H-2EH that have their own texts.
57F5
If the CARRY FLAG is set, JUMP to 57FBH with the code as it is.
57F7
LD A,5AH 3E 5A
Load Register A with 5AH, which becomes 26H, the code of Unprintable error. 57EDH jumps here.
57F9
SUB 34H D6 34
SUBtract 34H from Register A: 64H-8AH become 30H-56H, which follow 2EH. 57F1H jumps here.
57FB
RRCA 0F
Rotate Register A right, circularly: the even code divided by two, the message's place. 57F5H jumps here.
57FC
INC A 3C
INCrement Register A by 1, as the count also passes the 00H at 5203H.
57FD
LD E,A 5F
Copy the count from Register A into Register E.
57FE
Skip Loop
GOSUB to the ROM's 1F07H to move Register Pair HL to the next 00H byte (it stays where it is when Register Pair HL already points to one). 5803H loops back here.
5801
DEC E 1D
DECrement Register E (the texts still to pass) by 1.
5802
INC HL 23
INCrement Register Pair HL by 1, past the 00H to the next text.
5803
Skip Loop End
If the NZ FLAG is set, LOOP BACK to 57FEH; Register Pair HL ends at the message.
5805
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
5808
LD HL,(40A2H) 2A A2 40
Fetch the line number being run from 40A2H into Register Pair HL.
580B
LD DE,FFFEH 11 FE FF
Load Register Pair DE with FFFEH, the line number the ROM and the start-up code use while starting.
580E
RST 18H DF
Compare Register Pair HL (the line number) with Register Pair DE (FFFEH) with RST 18H: the Z FLAG is set during the start-up.
580F
If the Z FLAG is set (an error during the start-up questions), JUMP to 5C06H to start BASIC/CMD again.
5812
GOSUB to 64F2H, which clears memory when a protected program was loaded (6520H).
5815
JP 1A11H C3 11 1A
JUMP to the ROM's 1A11H, which shows IN and the line number unless Register Pair HL = FFFFH (a direct statement) and returns to READY.

5818H - CMD"#": the Copyright Message

CMD"#" must be followed by # and the end of the statement; it shows the copyright text at 582CH.

5818
POP HL E1
Restore Register Pair HL (the text after the CMD string, pushed at 56CEH) from the stack. 56FBH jumps here.
5819
LD A,(HL) 7E
Fetch the character after the string from (HL) (Register Pair HL = the text) into Register A.
581A
CP 23H FE 23
Compare Register A against 23H, the character #.
581C
If the NZ FLAG is set (no # after the string), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
581F
RST 10H D7
Move Register Pair HL past the # with RST 10H, which leaves the next character in Register A and sets the Z FLAG at the end of the statement.
5820
If the NZ FLAG is set (more text), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
5823
PUSH HL E5
Save Register Pair HL (the text at the end of the statement) onto the stack.
5824
LD HL,582CH 21 2C 58
Point Register Pair HL to 582CH, the copyright text.
5827
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
582A
POP HL E1
Restore Register Pair HL (the text at the end of the statement) from the stack.
582B
RET C9
RETURN to the ROM's statement loop with Register Pair HL = the end of the statement.
582C-586A
DEFM "THIS BASIC WAS AUTHORED AND IS COPYRIGHTED BY MICROSOFT, 1978" / DEFB 0DH, 00H 54 48 49 53 20 42 41 53 49 43 20 57 41 53 20 41 55 54 48 4F 52 45 44 20 41 4E 44 20 49 53 20 43 4F 50 59 52 49 47 48 54 45 44 20 42 59 20 4D 49 43 52 4F 53 4F 46 54 2C 20 31 39 37 38 0D 00
The copyright text, shown by 5824H for CMD"#"#.
586B-588A
DEFB 0DH / DEFM "PROTECTION HAS CLEARED MEMORY" / DEFB 0DH, 00H 0D 50 52 4F 54 45 43 54 49 4F 4E 20 48 41 53 20 43 4C 45 41 52 45 44 20 4D 45 4D 4F 52 59 0D 00
Shown by 6513H after 64F2H has cleared a protected program.

588BH - INSTR: Find One String in Another

The ROM jumps to 419DH for the INSTR token (2506H), and from there here. INSTR([n,]A$,B$) gives the position of B$ in A$, searching from position n (1 when it is left out; 0 gives ILLEGAL FUNCTION CALL). The result is 0 when n is past the end of A$, when A$ is empty or when B$ is not found, and n itself when B$ is empty. It returns through the ROM's 27F8H, which makes Register A an integer result, and 26E7H, which takes the text pointer back.

588B
RST 10H D7
Move Register Pair HL past the INSTR token with RST 10H, which leaves the opening parenthesis in Register A.
588C
GOSUB to the ROM's 2335H, which checks the opening parenthesis and evaluates the first expression at Register Pair HL into the accumulator (4121H).
588F
RST 20H E7
Test the type of the first expression with RST 20H: the Z FLAG is set for a string, the form INSTR(A$,B$).
5890
LD A,01H 3E 01
Load Register A with 01H, the starting position used when none is given; LD does not change the flags.
5892
PUSH AF F5
Save Register Pair AF (Register A = 1 and the type flags) onto the stack.
5893
If the Z FLAG is set (the first expression is A$), JUMP to 58A6H with position 1 on the stack.
5895
POP AF F1
Restore Register Pair AF from the stack: the 1 is not wanted, as a position was given.
5896
GOSUB to the ROM's 2B1FH to convert the first expression to a byte in Register A (ILLEGAL FUNCTION CALL above 255).
5899
OR A B7
OR Register A (the position) with itself: the Z FLAG is set for 0.
589A
If the Z FLAG is set (position 0), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
589D
PUSH AF F5
Save Register Pair AF (Register A = the starting position) onto the stack.
589E
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
58A0
GOSUB to the ROM's 2337H to evaluate A$ at Register Pair HL.
58A3
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the result is a string.
58A6
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H. 5893H jumps here.
58A8
PUSH HL E5
Save Register Pair HL (the text at B$) onto the stack.
58A9
LD HL,(4121H) 2A 21 41
Fetch the address of A$'s descriptor from 4121H, the accumulator, into Register Pair HL.
58AC
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the text at B$, and A$'s descriptor is kept on the stack.
58AD
GOSUB to the ROM's 2337H to evaluate B$ at Register Pair HL.
58B0
RST 08H => 29H CF 29
Check that the next character at Register Pair HL is 29H, the closing parenthesis, with RST 08H.
58B2
PUSH HL E5
Save Register Pair HL (the text after the parenthesis) onto the stack.
58B3
GOSUB to the ROM's 29D7H, which checks that B$ is a string, releases its temporary and returns Register Pair HL = its descriptor.
58B6
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = B$'s descriptor.
58B7
POP BC C1
Restore Register Pair BC (the text after the parenthesis) from the stack.
58B8
POP HL E1
Restore Register Pair HL (A$'s descriptor) from the stack.
58B9
POP AF F1
Restore Register Pair AF (Register A = the starting position) from the stack.
58BA
PUSH BC C5
Save Register Pair BC (the text after the parenthesis) onto the stack, for 26E7H to take back.
58BB
LD BC,26E7H 01 E7 26
Load Register Pair BC with 26E7H, the ROM's POP HL / RET.
58BE
PUSH BC C5
Save Register Pair BC (26E7H) onto the stack, as the return after 27F8H.
58BF
LD BC,27F8H 01 F8 27
Load Register Pair BC with 27F8H, the ROM's code that makes Register A an integer in the accumulator (0A9AH).
58C2
PUSH BC C5
Save Register Pair BC (27F8H) onto the stack: every RET below goes there with the result in Register A.
58C3
PUSH AF F5
Save Register Pair AF (the starting position) onto the stack.
58C4
PUSH DE D5
Save Register Pair DE (B$'s descriptor) onto the stack.
58C5
GOSUB to the ROM's 29DDH, inside 29DAH, to release A$'s temporary string if it is the newest one; Register Pair HL stays A$'s descriptor.
58C8
POP DE D1
Restore Register Pair DE (B$'s descriptor) from the stack.
58C9
POP AF F1
Restore Register Pair AF (Register A = the starting position) from the stack.
58CA
LD B,A 47
Copy the starting position from Register A into Register B.
58CB
DEC A 3D
DECrement Register A by 1: the number of characters of A$ to skip.
58CC
LD C,A 4F
Copy the characters to skip from Register A into Register C.
58CD
CP (HL) BE
Compare Register A (the characters to skip) against the length of A$ at (HL) (Register Pair HL = A$'s descriptor): the NO CARRY FLAG is set when nothing of A$ is left to search.
58CE
LD A,00H 3E 00
Load Register A with 00H, the result for not found; LD does not change the flags.
58D0
RET NC D0
If the NO CARRY FLAG is set (the start is past the end of A$), RETURN through 27F8H with the result 0.
58D1
LD A,(HL) 7E
Fetch the length of A$ from (HL) (Register Pair HL = A$'s descriptor) into Register A.
58D2
OR A B7
OR Register A with itself: the Z FLAG is set when A$ is empty.
58D3
RET Z C8
If the Z FLAG is set (A$ is empty), RETURN through 27F8H with the result 0.
58D4
LD A,(DE) 1A
Fetch the length of B$ from (DE) (Register Pair DE = B$'s descriptor) into Register A.
58D5
OR A B7
OR Register A with itself: the Z FLAG is set when B$ is empty.
58D6
LD A,B 78
Copy the starting position from Register B into Register A; LD does not change the flags.
58D7
RET Z C8
If the Z FLAG is set (B$ is empty), RETURN through 27F8H with the result = the starting position.
58D8
LD A,(HL) 7E
Fetch the length of A$ from (HL) (Register Pair HL = A$'s descriptor) into Register A.
58D9
INC HL 23
INCrement Register Pair HL by 1, to the address word of A$'s descriptor.
58DA
LD B,(HL) 46
Fetch the low byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register B.
58DB
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
58DC
LD H,(HL) 66
Fetch the high byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register H.
58DD
LD L,B 68
Copy the low byte from Register B into Register L: Register Pair HL = the text of A$.
58DE
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the characters to skip.
58E0
ADD HL,BC 09
ADD Register Pair BC (the characters to skip) to Register Pair HL: Register Pair HL = the first character of A$ to search.
58E1
SUB C 91
SUBtract Register C (the characters skipped) from Register A (the length of A$): the characters left to search.
58E2
LD B,A 47
Copy the characters left from Register A into Register B.
58E3
PUSH BC C5
Save Register Pair BC (Register B = the characters left at the start, Register C = the characters skipped) onto the stack, for working out the position at 5901H.
58E4
PUSH DE D5
Save Register Pair DE (B$'s descriptor) onto the stack.
58E5
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = B$'s descriptor, and the search position in A$ is kept on the stack.
58E6
LD C,(HL) 4E
Fetch the length of B$ from (HL) (Register Pair HL = B$'s descriptor) into Register C.
58E7
INC HL 23
INCrement Register Pair HL by 1, to the address word of B$'s descriptor.
58E8
LD E,(HL) 5E
Fetch the low byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register E.
58E9
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
58EA
LD D,(HL) 56
Fetch the high byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = the text of B$.
58EB
POP HL E1
Restore Register Pair HL (the search position in A$) from the stack.
58EC
PUSH HL E5
Try a Position
Save Register Pair HL (the position in A$ being tried) onto the stack. 5911H loops back here.
58ED
PUSH DE D5
Save Register Pair DE (the text of B$) onto the stack.
58EE
PUSH BC C5
Save Register Pair BC (Register B = the characters of A$ left from this position, Register C = the length of B$) onto the stack.
58EF
LD A,(DE) 1A
Compare Loop
Fetch the next character of B$ from (DE) (Register Pair DE = the text of B$) into Register A. 58F9H loops back here.
58F0
CP (HL) BE
Compare Register A against the character of A$ at (HL) (Register Pair HL = the position in A$).
58F1
If the NZ FLAG is set (they differ), JUMP to 590AH to try the next position.
58F3
INC DE 13
INCrement Register Pair DE by 1, to the next character of B$.
58F4
DEC C 0D
DECrement Register C (the characters of B$ left to match) by 1.
58F5
If the Z FLAG is set (all of B$ matched), JUMP to 5901H to work out the position.
58F7
INC HL 23
INCrement Register Pair HL by 1, to the next character of A$.
58F8
DEC B 05
DECrement Register B (the characters of A$ left) by 1.
58F9
Compare Loop End
If the NZ FLAG is set (A$ goes on), LOOP BACK to 58EFH.
58FB
POP DE D1
Restore Register Pair DE from the stack: the loop's saved Register Pair BC, not used. A$ ended in the middle of a match.
58FC
POP DE D1
Restore Register Pair DE from the stack: the loop's saved text of B$, not used.
58FD
POP BC C1
Restore Register Pair BC from the stack: the loop's saved position in A$, not used.
58FE
POP DE D1
Restore Register Pair DE from the stack: the values saved at 58E3H, not used. 590FH jumps here.
58FF
XOR A AF
Set Register A to ZERO with XOR A, the result for not found.
5900
RET C9
RETURN through 27F8H with the result 0, B$ not found in A$.
5901
POP HL E1
Found
Restore Register Pair HL (the loop's Register Pair BC: Register H = the characters of A$ left at the position where the match started) from the stack. 58F5H jumps here.
5902
POP DE D1
Restore Register Pair DE from the stack: the text of B$, not used.
5903
POP DE D1
Restore Register Pair DE from the stack: the matching position in A$, not used.
5904
POP BC C1
Restore Register Pair BC (Register B = the characters left at the first position, Register C = the characters skipped) from the stack.
5905
LD A,B 78
Copy Register B (the characters left at the first position) into Register A.
5906
SUB H 94
SUBtract Register H (the characters left at the matching position) from Register A: how far the match lies after the first position.
5907
ADD A,C 81
ADD Register C (the characters skipped) to Register A.
5908
INC A 3C
INCrement Register A by 1: the position of B$ in A$, counted from 1.
5909
RET C9
RETURN through 27F8H with the position in Register A.
590A
POP BC C1
Next Position
Restore Register Pair BC (Register B = the characters left from this position, Register C = the length of B$) from the stack. 58F1H jumps here.
590B
POP DE D1
Restore Register Pair DE (the text of B$, back at its start) from the stack.
590C
POP HL E1
Restore Register Pair HL (the position just tried) from the stack.
590D
INC HL 23
INCrement Register Pair HL by 1, to the next position in A$.
590E
DEC B 05
DECrement Register B (the characters left) by 1.
590F
If the Z FLAG is set (no characters left), JUMP to 58FEH: not found.
5911
LOOP BACK to 58ECH to try B$ at the next position of A$.

5913H - &H and &O: Hexadecimal and Octal Constants

The ROM jumps to 4194H when an expression holds an ampersand (24C8H), and from there here. &H takes up to four hexadecimal digits (a fifth gives OVERFLOW); &O, or & followed straight by digits, takes octal digits (8 or 9 gives a syntax error, more than 16 bits OVERFLOW). The value goes into the accumulator as an integer, and Register Pair HL is left at the character after the digits.

5913
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the value so far.
5916
RST 10H D7
Move Register Pair HL past the ampersand with RST 10H, which leaves the next character in Register A.
5917
CP 4FH FE 4F
Compare Register A against 4FH, the letter O.
5919
If the Z FLAG is set (&O), JUMP to 5947H for octal digits.
591B
CP 48H FE 48
Compare Register A against 48H, the letter H.
591D
If the NZ FLAG is set (neither H nor O), JUMP to 5946H to read octal digits from this character on.
591F
LD B,05H 06 05
Load Register B with 05H: the fifth digit gives OVERFLOW.
5921
INC HL 23
Hex Loop
INCrement Register Pair HL by 1, to the next character of the text. 5944H loops back here.
5922
LD A,(HL) 7E
Fetch the character from (HL) (Register Pair HL = the text) into Register A.
5923
GOSUB to the ROM's 1E3EH, which compares Register A with A-Z: the NO CARRY FLAG is set for a letter.
5926
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the value so far, Register Pair DE = the text.
5927
If the NO CARRY FLAG is set (a letter), JUMP to 5933H.
5929
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9.
592B
If the NO CARRY FLAG is set (not a digit), JUMP to 5964H: the constant ends.
592D
SUB 30H D6 30
SUBtract 30H from Register A: the digits 0-9 become 0-9.
592F
If the CARRY FLAG is set (below 0), JUMP to 5964H: the constant ends.
5931
JUMP to 5939H to add the digit value in Register A.
5933
CP 47H FE 47
Compare Register A (a letter) against 47H, the letter after F. 5927H jumps here.
5935
If the NO CARRY FLAG is set (G-Z), JUMP to 5964H: the constant ends.
5937
SUB 37H D6 37
SUBtract 37H from Register A: the letters A-F become 0AH-0FH.
5939
ADD HL,HL 29
ADD Register Pair HL (the value so far) to itself: times 2. 5931H jumps here.
593A
ADD HL,HL 29
ADD Register Pair HL to itself again: times 4.
593B
ADD HL,HL 29
ADD Register Pair HL to itself a third time: times 8.
593C
ADD HL,HL 29
ADD Register Pair HL to itself a fourth time: the value times 16, with room for the new digit.
593D
OR L B5
OR Register A (the digit) with Register L, whose low four bits are now zero.
593E
LD L,A 6F
Copy Register A into Register L: the digit is in the low four bits of the value.
593F
DEC B 05
DECrement Register B (the digits allowed) by 1.
5940
If the Z FLAG is set (a fifth digit), JUMP to the ROM's 07B2H, OVERFLOW.
5943
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the value, Register Pair HL = the text.
5944
LOOP BACK to 5921H for the next hexadecimal digit.
5946
DEC HL 2B
DECrement Register Pair HL by 1, back to the character after the ampersand, so that it is read as the first octal digit. 591DH jumps here.
5947
RST 10H D7
Octal Loop
Move Register Pair HL to the next character with RST 10H, which leaves it in Register A with the CARRY FLAG set for a digit. 5919H and 5962H come here.
5948
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the value so far, Register Pair DE = the text.
5949
If the NO CARRY FLAG is set (not a digit), JUMP to 5964H: the constant ends.
594B
CP 38H FE 38
Compare Register A against 38H, the digit 8, the first one that is not octal.
594D
If the NO CARRY FLAG is set (8 or 9), JUMP to the ROM's 1997H, the syntax error.
5950
LD BC,07B2H 01 B2 07
Load Register Pair BC with 07B2H, the ROM's OVERFLOW error.
5953
PUSH BC C5
Save Register Pair BC (07B2H) onto the stack, so that a RET C below goes to OVERFLOW.
5954
ADD HL,HL 29
ADD Register Pair HL (the value) to itself: times 2, the CARRY FLAG set when a bit leaves the top.
5955
RET C D8
If the CARRY FLAG is set (too big), RETURN to 07B2H, OVERFLOW.
5956
ADD HL,HL 29
ADD Register Pair HL to itself again: times 4.
5957
RET C D8
If the CARRY FLAG is set (too big), RETURN to 07B2H, OVERFLOW.
5958
ADD HL,HL 29
ADD Register Pair HL to itself a third time: the value times 8.
5959
RET C D8
If the CARRY FLAG is set (too big), RETURN to 07B2H, OVERFLOW.
595A
POP BC C1
Restore Register Pair BC from the stack: the 07B2H is not needed.
595B
LD B,00H 06 00
Load Register B with 00H, the high byte of the digit.
595D
SUB 30H D6 30
SUBtract 30H from Register A: the digit character becomes 0-7.
595F
LD C,A 4F
Copy the digit from Register A into Register C: Register Pair BC = the digit.
5960
ADD HL,BC 09
ADD Register Pair BC (the digit) to Register Pair HL (the value times 8).
5961
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the value, Register Pair HL = the text.
5962
LOOP BACK to 5947H for the next octal digit of the constant.
5964
GOSUB to the ROM's 0A9AH to store Register Pair HL (the value) into the accumulator at 4121H as an integer (40AFH = 2). 592BH, 592FH, 5935H and 5949H jump here.
5967
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the text at the character after the digits.
5968
RET C9
RETURN to the ROM's expression evaluator with the integer in the accumulator.

5969H - MID$ on the Left of =

The ROM jumps to 41D9H (2AECH) for a statement that starts with MID$, and from there here. MID$(A$,n[,m])=B$ puts the characters of B$ into A$ from position n, at most m of them, at most as many as B$ has, and never past the end of A$; the length of A$ does not change. A string that is not in string space (one assigned from a constant in the program text) is first copied there so that the program is not changed.

5969
INC HL 23
INCrement Register Pair HL by 1, past the MID$ token.
596A
RST 08H => 28H CF 28
Check that the next character at Register Pair HL is 28H, the opening parenthesis, with RST 08H.
596C
GOSUB to the ROM's 260DH to find or create the variable named at Register Pair HL: Register Pair DE = its descriptor, 40AFH = its type.
596F
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the variable is a string.
5972
PUSH HL E5
Save Register Pair HL (the text after the variable) onto the stack.
5973
PUSH DE D5
Save Register Pair DE (the variable's descriptor) onto the stack.
5974
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the descriptor.
5975
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
5976
LD E,(HL) 5E
Fetch the low byte of the string's address from (HL) (Register Pair HL = the descriptor) into Register E.
5977
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
5978
LD D,(HL) 56
Fetch the high byte of the string's address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = the text of A$.
5979
LD HL,(40A0H) 2A A0 40
Fetch the start of string space from 40A0H into Register Pair HL.
597C
RST 18H DF
Compare Register Pair HL (the start of string space) with Register Pair DE (the text of A$) with RST 18H: the CARRY FLAG is set when A$ lies in string space.
597D
If the CARRY FLAG is set (in string space), JUMP to 5989H: it can be changed where it is.
597F
POP HL E1
Restore Register Pair HL (the variable's descriptor) from the stack.
5980
PUSH HL E5
Save Register Pair HL (the descriptor) onto the stack again.
5981
GOSUB to the ROM's 2843H to copy the string of the descriptor at Register Pair HL into string space, with the new descriptor at 40D3H in Register Pair DE.
5984
POP HL E1
Restore Register Pair HL (the variable's descriptor) from the stack.
5985
PUSH HL E5
Save Register Pair HL (the descriptor) onto the stack again.
5986
GOSUB to the ROM's 09D3H to copy the new descriptor at Register Pair DE (40D3H) into the variable's descriptor at Register Pair HL (three bytes, 40AFH = 3).
5989
POP HL E1
Restore Register Pair HL (the variable's descriptor) from the stack. 597DH jumps here.
598A
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the text, and the descriptor is kept on the stack.
598B
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
598D
GOSUB to the ROM's 2B1CH to evaluate the position at Register Pair HL as a byte in Register A.
5990
OR A B7
OR Register A (the position) with itself: the Z FLAG is set for 0.
5991
If the Z FLAG is set (position 0), JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
5994
PUSH AF F5
Save Register Pair AF (Register A = the position) onto the stack.
5995
LD A,(HL) 7E
Fetch the character after the position from (HL) (Register Pair HL = the text) into Register A.
5996
GOSUB to 59DCH to read the optional length and the closing parenthesis: Register E = the length, FFH when none was given.
5999
PUSH DE D5
Save Register Pair DE (Register E = the length) onto the stack.
599A
RST 08H => D5H CF D5
Check that the next character at Register Pair HL is D5H, the = token, with RST 08H.
599C
GOSUB to the ROM's 2337H to evaluate B$ at Register Pair HL.
599F
PUSH HL E5
Save Register Pair HL (the text after B$) onto the stack.
59A0
GOSUB to the ROM's 29D7H, which checks that B$ is a string, releases its temporary and returns Register Pair HL = its descriptor.
59A3
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = B$'s descriptor.
59A4
POP HL E1
Restore Register Pair HL (the text after B$) from the stack.
59A5
POP BC C1
Restore Register Pair BC (Register C = the length) from the stack.
59A6
POP AF F1
Restore Register Pair AF (Register A = the position) from the stack.
59A7
LD B,A 47
Copy the position from Register A into Register B.
59A8
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = A$'s descriptor, and the text after the statement is kept on the stack.
59A9
PUSH HL E5
Save Register Pair HL (A$'s descriptor) onto the stack.
59AA
LD HL,26E7H 21 E7 26
Point Register Pair HL to 26E7H, the ROM's POP HL / RET.
59AD
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): 26E7H becomes the return address and Register Pair HL = A$'s descriptor again.
59AE
LD A,C 79
Copy the length from Register C into Register A.
59AF
OR A B7
OR Register A with itself: the Z FLAG is set for a length of 0.
59B0
RET Z C8
If the Z FLAG is set (length 0), RETURN through 26E7H: nothing is changed.
59B1
LD A,(HL) 7E
Fetch the length of A$ from (HL) (Register Pair HL = A$'s descriptor) into Register A.
59B2
SUB B 90
SUBtract Register B (the position) from Register A (the length of A$): the CARRY FLAG is set when the position is beyond the end.
59B3
If the CARRY FLAG is set, JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
59B6
INC A 3C
INCrement Register A by 1: the characters of A$ from the position to the end.
59B7
CP C B9
Compare Register A against Register C (the length asked for): the CARRY FLAG is set when fewer characters are left than asked for.
59B8
If the CARRY FLAG is set, JUMP to 59BBH with the characters left as the count.
59BA
LD A,C 79
Copy the length asked for from Register C into Register A: the count.
59BB
LD C,B 48
Copy the position from Register B into Register C. 59B8H jumps here.
59BC
DEC C 0D
DECrement Register C by 1: the offset of the position in A$.
59BD
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset.
59BF
PUSH DE D5
Save Register Pair DE (B$'s descriptor) onto the stack.
59C0
INC HL 23
INCrement Register Pair HL by 1, to the address word of A$'s descriptor.
59C1
LD E,(HL) 5E
Fetch the low byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register E.
59C2
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
59C3
LD H,(HL) 66
Fetch the high byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register H.
59C4
LD L,E 6B
Copy the low byte from Register E into Register L: Register Pair HL = the text of A$.
59C5
ADD HL,BC 09
ADD Register Pair BC (the offset) to Register Pair HL: Register Pair HL = the first character of A$ to replace.
59C6
LD B,A 47
Copy the count from Register A into Register B.
59C7
POP DE D1
Restore Register Pair DE (B$'s descriptor) from the stack.
59C8
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = B$'s descriptor, Register Pair DE = the place in A$.
59C9
LD C,(HL) 4E
Fetch the length of B$ from (HL) (Register Pair HL = B$'s descriptor) into Register C.
59CA
INC HL 23
INCrement Register Pair HL by 1, to the address word of B$'s descriptor.
59CB
LD A,(HL) 7E
Fetch the low byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register A.
59CC
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
59CD
LD H,(HL) 66
Fetch the high byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register H.
59CE
LD L,A 6F
Copy the low byte from Register A into Register L: Register Pair HL = the text of B$.
59CF
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the place in A$, Register Pair DE = the text of B$.
59D0
LD A,C 79
Copy the length of B$ from Register C into Register A.
59D1
OR A B7
OR Register A with itself: the Z FLAG is set when B$ is empty.
59D2
RET Z C8
If the Z FLAG is set (B$ empty), RETURN through 26E7H: nothing is changed.
59D3
LD A,(DE) 1A
Copy Loop
Fetch the next character of B$ from (DE) (Register Pair DE = the text of B$) into Register A. 59D9H loops back here.
59D4
LD (HL),A 77
Store the character from Register A into (HL) (Register Pair HL = the place in A$).
59D5
INC DE 13
INCrement Register Pair DE by 1, to the next character of B$.
59D6
INC HL 23
INCrement Register Pair HL by 1, to the next character of A$.
59D7
DEC C 0D
DECrement Register C (the characters of B$ left) by 1.
59D8
RET Z C8
If the Z FLAG is set (B$ used up), RETURN through 26E7H.
59D9
Copy Loop End
DECrement Register B (the count) and LOOP BACK to 59D3H until it reaches zero.
59DB
RET C9
RETURN through 26E7H, which takes the text pointer back into Register Pair HL.

59DCH - The Optional Length in MID$

Register Pair HL = the text after the position, Register A = its character. Returns Register E = the length after a comma, or FFH when the closing parenthesis comes first; checks the closing parenthesis.

59DC
LD E,FFH 1E FF
Load Register E with FFH, the length when none is given. Called by 5996H.
59DE
CP 29H FE 29
Compare Register A (the character) against 29H, the closing parenthesis.
59E0
If the Z FLAG is set (no length), JUMP to 59E7H.
59E2
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
59E4
GOSUB to the ROM's 2B1CH to evaluate the length at Register Pair HL as a byte: Register A and Register E = the length.
59E7
RST 08H => 29H CF 29
Check that the next character at Register Pair HL is 29H, the closing parenthesis, with RST 08H. 59E0H jumps here.
59E9
RET C9
RETURN to 5999H with Register E = the length.

59EAH - Read a Line from the Current File

The ROM calls the link at 41AFH when it starts to read a line from the keyboard (0368H, inside 0361H). With no current file it returns. With one, the rest of the ROM's routine is dropped: up to 240 characters are read with 0384H (whose 0358H then takes them from the file through 5A30H) into the input buffer, a line feed at the very start of the line is skipped, the line ends at ENTER, and the routine returns to 0361H's caller as the ROM would. Until a character below 80H has been read, bit 7 is cleared from each character.

59EA
PUSH HL E5
Save Register Pair HL onto the stack. The link at 41AFH jumps here.
59EB
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
59EE
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
59EF
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
59F0
POP HL E1
Restore Register Pair HL (the ROM's value, pushed at 59EAH) from the stack.
59F1
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM, which reads the keyboard.
59F2
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 036BH, so the rest of the ROM's 0361H does not run.
59F3
PUSH BC C5
Save Register Pair BC (the caller's value) onto the stack; 5A1BH restores it.
59F4
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack; 5A1AH restores it.
59F5
LD B,F0H 06 F0
Load Register B with F0H, the 240 characters the buffer takes.
59F7
LD D,7FH 16 7F
Load Register D with 7FH, the mask that clears bit 7, used until a character below 80H comes.
59F9
LD HL,(40A7H) 2A A7 40
Fetch the input buffer pointer from 40A7H into Register Pair HL.
59FC
Character Loop
GOSUB to the ROM's 0384H, which waits for a character through 0358H; with a current file, 5A30H takes it from the file. Register A = the character. 5A13H and 5A16H loop back here.
59FF
LD E,A 5F
Copy the character from Register A into Register E.
5A00
SUB 80H D6 80
SUBtract 80H from Register A: the CARRY FLAG is set for a character below 80H.
5A02
SBC A,A 9F
SUBtract Register A from itself with the CARRY FLAG: FFH for a character below 80H, 00H otherwise.
5A03
OR D B2
OR Register A with Register D (the mask so far): once FFH, the mask stays FFH.
5A04
LD D,A 57
Copy the mask from Register A into Register D.
5A05
LD A,E 7B
Copy the character from Register E into Register A.
5A06
AND D A2
AND Register A with Register D, the mask: bit 7 is cleared while the mask is 7FH.
5A07
LD (HL),A 77
Store the character from Register A into (HL) (Register Pair HL = the place in the input buffer).
5A08
CP 0DH FE 0D
Compare Register A (the character stored) against 0DH, ENTER.
5A0A
If the Z FLAG is set (the end of the line), JUMP to 5A18H.
5A0C
CP 0AH FE 0A
Compare Register A (the character stored) against 0AH, a line feed.
5A0E
If the NZ FLAG is set (another character), JUMP to 5A15H to keep it.
5A10
LD A,B 78
Copy the characters left from Register B into Register A.
5A11
CP F0H FE F0
Compare Register A against F0H: the Z FLAG is set when nothing has been stored yet.
5A13
If the Z FLAG is set (a line feed at the start of the line), LOOP BACK to 59FCH without keeping it.
5A15
INC HL 23
INCrement Register Pair HL by 1, to the next place in the buffer. 5A0EH jumps here.
5A16
Character Loop End
DECrement Register B (the room left) and LOOP BACK to 59FCH until the buffer is full.
5A18
XOR A AF
Set Register A to ZERO with XOR A, which also clears the CARRY FLAG (no BREAK). 5A0AH jumps here.
5A19
LD (HL),A 77
Store Register A (00H) into (HL) (Register Pair HL = the end of the line in the buffer), over the ENTER.
5A1A
POP DE D1
Restore Register Pair DE (the caller's value, pushed at 59F4H) from the stack.
5A1B
POP BC C1
Restore Register Pair BC (the caller's value, pushed at 59F3H) from the stack.
5A1C
LD HL,(40A7H) 2A A7 40
Fetch the input buffer pointer from 40A7H into Register Pair HL.
5A1F
DEC HL 2B
DECrement Register Pair HL by 1, to the byte before the buffer, as the ROM's 0361H returns it.
5A20
RET C9
RETURN to the caller of the ROM's 0361H with the line in the buffer.

5A21H - Send a Character to the Current File

The ROM calls the link at 41C1H as it sends a character to the current device (032CH, with the character in Register C and the caller's Register Pair BC pushed at 032AH). With no current file it returns. With one, the ROM's output is dropped and the character goes into the file through 631CH.

5A21
PUSH HL E5
Save Register Pair HL onto the stack. The link at 41C1H jumps here.
5A22
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
5A25
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
5A26
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
5A27
POP HL E1
Restore Register Pair HL (the ROM's value, pushed at 5A21H) from the stack.
5A28
LD A,C 79
Copy the character from Register C into Register A; LD does not change the flags.
5A29
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM's output at 032FH.
5A2A
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 032FH.
5A2B
LD A,C 79
Copy the character from Register C into Register A.
5A2C
POP BC C1
Restore Register Pair BC (the caller's value, pushed by the ROM at 032AH) from the stack.
5A2D
JUMP to 631CH to put the character in Register A into the current file; it returns to the caller of the ROM's 032AH.

5A30H - Take a Character from the Current File

The ROM calls the link at 41C4H as it reads the keyboard (0358H). Only a call from the ROM's wait for a key (0384H) is taken over, and only while a file is current: the character comes from the file (63C4H). At the end of the file the file is closed; after a LOAD with R the program is run, otherwise READY is shown and ENTER is given to end the line. Every other call stores Register A into 40A9H and goes on with the ROM's keyboard code.

5A30
INC SP 33
INCrement the Stack Pointer by 1, the first half of dropping the return address 035BH. The link at 41C4H jumps here.
5A31
INC SP 33
INCrement the Stack Pointer by 1 again: the top of the stack is now 0358H's own return address.
5A32
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = 0358H's return address.
5A33
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack while it holds 0387H.
5A34
LD DE,0387H 11 87 03
Point Register Pair DE to 0387H, the return address of the call at 0384H, the wait for a key.
5A37
RST 18H DF
Compare Register Pair HL (the return address) with Register Pair DE (0387H) with RST 18H: the Z FLAG is set for a call from 0384H.
5A38
POP DE D1
Restore Register Pair DE (the caller's value, pushed at 5A33H) from the stack.
5A39
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): the return address goes back and Register Pair HL is the caller's again.
5A3A
If the NZ FLAG is set (another caller of 0358H), JUMP to 5A71H.
5A3D
PUSH HL E5
Save Register Pair HL (the caller's value) onto the stack while it holds the file pointer.
5A3E
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
5A41
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
5A42
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
5A43
POP HL E1
Restore Register Pair HL (the caller's value, pushed at 5A3DH) from the stack.
5A44
If the Z FLAG is set (no file), JUMP to the ROM's 035BH, the rest of 0358H, to read the keyboard.
5A47
PUSH HL E5
Save Register Pair HL onto the stack, for 26E7H.
5A48
GOSUB to 63C4H to read the next character of the current file into Register A; the CARRY FLAG is set at the end of the file.
5A4B
If the NO CARRY FLAG is set (a character), JUMP to the ROM's 26E7H, which restores Register Pair HL and returns to 0387H with the character in Register A.
5A4E
PUSH BC C5
Save Register Pair BC (the caller's value) onto the stack while 60EFH runs.
5A4F
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack while 60EFH runs.
5A50
PUSH HL E5
Save Register Pair HL (the caller's value) onto the stack while 60EFH runs.
5A51
GOSUB to 60EFH to close the file and end the LOAD or MERGE.
5A54
POP HL E1
Restore Register Pair HL (the caller's value, pushed at 5A50H) from the stack.
5A55
POP DE D1
Restore Register Pair DE (the caller's value, pushed at 5A4FH) from the stack.
5A56
POP BC C1
Restore Register Pair BC (the caller's value, pushed at 5A4EH) from the stack.
5A57
LD A,(5BB1H) 3A B1 5B
Fetch the run flag from 5BB1H, set by LOAD with R or by RUN with a file name, into Register A.
5A5A
OR A B7
OR Register A with itself: the NZ FLAG is set when the program is to be run.
5A5B
LD HL,1D1EH 21 1E 1D
Point Register Pair HL to 1D1EH, the ROM's statement loop; LD does not change the flags.
5A5E
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): 1D1EH goes onto the stack and Register Pair HL is the value saved at 5A47H.
5A5F
If the NZ FLAG is set (run it), JUMP to the ROM's 1B5DH, RUN, which returns to 1D1EH and starts the program.
5A62
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): the saved value goes back onto the stack and Register Pair HL = 1D1EH.
5A63
PUSH BC C5
Save Register Pair BC (the caller's value) onto the stack while READY is shown.
5A64
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack while READY is shown.
5A65
LD HL,1929H 21 29 19
Point Register Pair HL to 1929H, the ROM's READY text.
5A68
GOSUB to the ROM's 28A7H to show the text at Register Pair HL, READY.
5A6B
POP DE D1
Restore Register Pair DE (the caller's value, pushed at 5A64H) from the stack.
5A6C
POP BC C1
Restore Register Pair BC (the caller's value, pushed at 5A63H) from the stack.
5A6D
LD A,0DH 3E 0D
Load Register A with 0DH, ENTER, which ends the line being read.
5A6F
POP HL E1
Restore Register Pair HL (the value saved at 5A47H) from the stack.
5A70
RET C9
RETURN to 0387H with Register A = 0DH, which ends the ROM's line input.
5A71
LD (40A9H),A 32 A9 40
Store Register A, as 0358H's caller left it, into 40A9H, the ROM's flag that is 00H only while input comes from the cassette. 5A3AH jumps here.
5A74
JUMP to the ROM's 035BH, the rest of 0358H, to read the keyboard.

5A77H - Variables, the USR Table and the File Table

Work bytes of Disk BASIC, all 00H in the file except the USR table. A file block is 0122H bytes: byte 0 the mode (00H closed, 01H input, 02H output, 03H random), byte 1 the print column, bytes 02H-21H the FCB given to the DOS, bytes 22H-121H the sector buffer; FILES with V adds 256 bytes for a record buffer. The blocks themselves lie after BASIC/CMD from 659BH (5CD0H).

5A77
DEFB 00H 00
A stand-in for the block of file 0: 5BE5H and 608FH point the first entry of the file table here, with its mode byte 00H (closed), while the ROM's CLEAR runs and closes all files, so that the real file 0 is not closed. Only this mode byte is used.
5A78-5B76
DEFB 00H 00 x 255
Not used: no code in BASIC/CMD reads or writes these 255 bytes.
5B77-5B8A
DEFW 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH, 1E4AH 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E 4A 1E
The addresses of USR0-USR9, two bytes each, read by 5682H and set by DEF USR at 56B5H. 1E4AH is the ROM's ILLEGAL FUNCTION CALL, so a USR that was never defined gives that error.
5B8B
DEFB 00H 00
GET or PUT: 00H for GET, nonzero for PUT, stored by 6356H and tested at 6398H and 63A7H.
5B8C
DEFB 00H 00
The number of the last DOS error, stored by 656FH (01H for numbers 27H and above); CMD"E" shows its text (5736H).
5B8D-5B8E
DEFW 0000H 00 00
The current file: the address of the block of the file that PRINT, INPUT, LIST and the ROM's character routines use now, or 0000H for none. Set by 5ED6H, 64ACH and 60A6H, cleared by 57B3H.
5B8F-5BAE
DEFW 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H, 0000H 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The file table: the block address of file 0 and of files 1-15, filled by 5CDDH-5CDFH for as many files as FILES allows; 5EF3H finds a file's block here. File 0 serves LOAD, RUN, MERGE, SAVE and KILL.
5BAF-5BB0
DEFW 0000H 00 00
The address of the real block of file 0 (659BH), stored by 5CD7H; 5BF4H and 60A0H put it back into the file table, and 6529H and 653DH use it.
5BB1
DEFB 00H 00
Run after loading: stored by 608CH (FFH for RUN with a file name, F1H for LOAD or RUN with R, 00H for LOAD) and cleared by MERGE (6119H); read at 5A57H and 60E5H.
5BB2
DEFB 00H 00
A copy of the number of files from 408EH, kept by 6076H and 60D7H while 408EH is changed, and put back at 609AH and 60DFH.

5BB3H - End of SYSTEM Prompt: Nothing to Do

The ROM calls the link at 41E2H each time its SYSTEM command shows its prompt (02B2H). Disk BASIC does nothing there.

5BB3
RET C9
RETURN at once to the ROM's SYSTEM command; nothing is changed. The link at 41E2H jumps here.

5BB4H - CMD"S" and CMD"A": Back to DOS

Puts SYS0/SYS's hook at 4313H back as it was before BASIC/CMD started (5C1CH), arms the BREAK vector at 4315H with the jump opcode, and leaves for DOS READY (CMD"S") or for the exit after an error at 4030H (CMD"A", with the CARRY FLAG set). The program in memory stays as it is.

5BB4
PUSH AF F5
Save Register Pair AF (the CARRY FLAG: set for CMD"A") onto the stack. 56F0H and 56F6H jump here.
5BB5
LD HL,(5D51H) 2A 51 5D
Fetch the old address of SYS0/SYS's hook from 5D51H, saved at 5C1FH, into Register Pair HL.
5BB8
LD (4313H),HL 22 13 43
Store Register Pair HL into 4313H, the address of the JP at 4312H: SYS0/SYS's hook for RST 28H codes below 80H is as it was.
5BBB
LD A,C3H 3E C3
Load Register A with C3H, the opcode JP, the first byte of an armed BREAK vector.
5BBD
LD (4315H),A 32 15 43
Store Register A (C3H) into 4315H: the BREAK vector is armed, with the address already at 4316H-4317H.
5BC0
POP AF F1
Restore Register Pair AF (the CARRY FLAG) from the stack.
5BC1
If the CARRY FLAG is set (CMD"A"), JUMP to 4030H, the exit after an error.
5BC4
JUMP to 402DH, DOS READY (CMD"S"); BASIC/CMD and its program stay in memory.

5BC7H - PRINT Comma and TAB in a File

The ROM calls the link at 41D3H for a comma in PRINT (2108H) and for TAB (2141H). With a current file, the column is taken from byte 1 of its block instead of the screen, and the ROM goes on with its own computation: at 2130H for the comma (the next zone of 16 columns) or at 2156H for TAB.

5BC7
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL. The link at 41D3H jumps here.
5BCA
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
5BCB
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
5BCC
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM, which uses the screen or printer column.
5BCD
INC HL 23
INCrement Register Pair HL by 1, to byte 1 of the file's block, its print column.
5BCE
LD A,(HL) 7E
Fetch the column from (HL) (Register Pair HL = byte 1 of the block) into Register A.
5BCF
POP HL E1
Restore Register Pair HL from the stack: the return address into the ROM, 210BH or 2144H.
5BD0
PUSH DE D5
Save Register Pair DE (the ROM's value: Register E holds the TAB position) onto the stack.
5BD1
PUSH AF F5
Save Register Pair AF (Register A = the file's column) onto the stack.
5BD2
LD DE,2130H 11 30 21
Point Register Pair DE to 2130H, between the two calling places.
5BD5
RST 18H DF
Compare Register Pair HL (the return address) with Register Pair DE (2130H) with RST 18H: the CARRY FLAG is set for the comma's call at 2108H.
5BD6
POP DE D1
Restore Register Pair DE from the stack: Register D = the file's column, from the AF pushed at 5BD1H.
5BD7
LD A,D 7A
Copy the column from Register D into Register A.
5BD8
POP DE D1
Restore Register Pair DE (the ROM's value) from the stack.
5BD9
If the CARRY FLAG is set (the comma), JUMP to the ROM's 2130H, which works out the spaces to the next zone from the column in Register A.
5BDC
JUMP to the ROM's 2156H, which works out the spaces for TAB from the column in Register A and the position in Register E.

5BDFH - Around the ROM's CLEAR after a Line Is Put In

The ROM calls the link at 41B5H after it has put a program line in (1AECH), then runs its CLEAR (1B5DH, which closes all files through 41BBH) and calls 41B8H (1AF2H). 5BDFH keeps the current file pointer in 40F3H and points file 0 at the closed stand-in block 5A77H; 5BEEH puts both back. So a file being loaded or merged line by line stays open while the lines go in.

5BDF
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL. The link at 41B5H jumps here.
5BE2
LD (40F3H),HL 22 F3 40
Store Register Pair HL (the current file) into 40F3H, a ROM work word that the CLEAR does not change, until 5BEEH.
5BE5
LD HL,5A77H 21 77 5A
Point Register Pair HL to 5A77H, the stand-in block.
5BE8
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = 5A77H): its mode is closed, so 62DDH leaves it alone.
5BEA
LD (5B8FH),HL 22 8F 5B
Store Register Pair HL (5A77H) into 5B8FH, the file table entry of file 0.
5BED
RET C9
RETURN to the ROM, which runs its CLEAR at 1B5DH.
5BEE
LD HL,(40F3H) 2A F3 40
Fetch the saved current file pointer from 40F3H into Register Pair HL. The link at 41B8H jumps here.
5BF1
LD (5B8DH),HL 22 8D 5B
Store Register Pair HL into 5B8DH: the current file is back.
5BF4
LD HL,(5BAFH) 2A AF 5B
Fetch the address of the real block of file 0 from 5BAFH into Register Pair HL.
5BF7
LD (5B8FH),HL 22 8F 5B
Store Register Pair HL into 5B8FH: file 0 is its own block again.
5BFA
RET C9
RETURN to the ROM, which goes on reading lines at 1A33H.

5BFBH - After a Carriage Return in PRINT: Nothing to Do

The ROM calls the link at 41D0H after PRINT has sent a carriage return (2103H). Disk BASIC does nothing there.

5BFB
RET C9
RETURN at once to the ROM's PRINT; nothing is changed. The link at 41D0H jumps here.

5BFCH - PRINT a Number to a File

The ROM calls the link at 41CDH in PRINT after a number has been turned into text (20C6H). With a current file, the ROM's test whether the number still fits on the line is skipped: the text and the space after it are sent at once (20E9H).

5BFC
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL. The link at 41CDH jumps here.
5BFF
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
5C00
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
5C01
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM at 20C9H for its line length test.
5C02
POP HL E1
Restore Register Pair HL from the stack: this takes off the return address 20C9H.
5C03
JUMP to the ROM's 20E9H, which sends the number's text and a space, without the line length test.

5C06H - Start: Link Disk BASIC into the ROM

5200H jumps here after SYS0/SYS has loaded BASIC/CMD, with Register Pair HL at the command line after BASIC. Saves the ROM's program start, the number of files and the start of string space, puts its own hook at 4313H, copies the ROM's RAM routines to 4080H as the ROM does at start-up, moves the input buffer to 5D56H and copies the 49 links to 4152H. TRSDOS older than 2.2 (403EH below 22H) gets USE TRSDOS 2.2 OR LATER for ever. BASIC followed by an asterisk goes back to READY with the program already in memory; otherwise FILES and MEM SIZE are asked for.

5C06
LD A,(HL) 7E
Fetch the first character after BASIC on the command line from (HL) (Register Pair HL = the command line) into Register A. 5200H, 580FH and 5C95H come here.
5C07
LD (5C98H),A 32 98 5C
Store Register A into 5C98H: an asterisk there (BASIC followed by an asterisk) means start again with the program kept.
5C0A
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
5C0D
LD (5C99H),HL 22 99 5C
Store Register Pair HL (the program start) into 5C99H, for an asterisk start (5C8FH).
5C10
LD HL,(408EH) 2A 8E 40
Fetch the number of files from 408EH (Disk BASIC keeps it there) into Register Pair HL: Register L = the number of files, Register H = the V flag from 408FH.
5C13
LD (5C9BH),HL 22 9B 5C
Store Register Pair HL into 5C9BH, as the ROM's copy at 5C35H writes over 408EH.
5C16
LD HL,(40A0H) 2A A0 40
Fetch the start of string space from 40A0H into Register Pair HL.
5C19
LD (5C9DH),HL 22 9D 5C
Store Register Pair HL (the start of string space) into 5C9DH, for an asterisk start (5C89H).
5C1C
LD HL,(4313H) 2A 13 43
Fetch the address of SYS0/SYS's hook for RST 28H codes below 80H from 4313H into Register Pair HL.
5C1F
LD (5D51H),HL 22 51 5D
Store Register Pair HL into 5D51H, the operand of the JP at 5D50H, which passes the other codes on to it, and from where CMD"S" puts it back (5BB5H).
5C22
LD HL,5D4DH 21 4D 5D
Point Register Pair HL to 5D4DH, Disk BASIC's own hook.
5C25
LD (4313H),HL 22 13 43
Store Register Pair HL (5D4DH) into 4313H: the JP at 4312H now goes to 5D4DH.
5C28
XOR A AF
Set Register A to ZERO with XOR A, the value that disarms the BREAK vector.
5C29
LD (4315H),A 32 15 43
Store Register A (00H) into 4315H: the BREAK vector is not armed.
5C2C
LD DE,4080H 11 80 40
Point Register Pair DE to 4080H, the ROM's RAM routines and work bytes.
5C2F
LD HL,18F7H 21 F7 18
Point Register Pair HL to 18F7H, the ROM's table of their first values.
5C32
LD BC,0027H 01 27 00
Load Register Pair BC with 0027H, the 39 bytes 4080H-40A6H.
5C35
LDIR ED B0
Copy them: LDIR moves 39 bytes from (HL) (Register Pair HL = 18F7H) to (DE) (Register Pair DE = 4080H), counting Register Pair BC down to 0000H, as the ROM does at 0075H.
5C37
LD HL,(5C9BH) 2A 9B 5C
Fetch the saved number of files from 5C9BH into Register Pair HL.
5C3A
LD (408EH),HL 22 8E 40
Store Register Pair HL into 408EH: the number of files is back after the copy.
5C3D
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H, set by SYS0/SYS, into Register Pair HL.
5C40
LD (40A0H),HL 22 A0 40
Store Register Pair HL into 40A0H, the start of string space, for now at the top of memory.
5C43
LD SP,HL F9
Load the Stack Pointer from Register Pair HL: the stack starts at the top of memory.
5C44
LD HL,5D53H 21 53 5D
Point Register Pair HL to 5D53H, the three bytes before the new input buffer.
5C47
LD (HL),3AH 36 3A
Store 3AH, a colon, at (HL) (Register Pair HL = 5D53H), as the ROM puts one before its buffer at 0083H.
5C49
INC HL 23
INCrement Register Pair HL by 1, to 5D54H, the second byte before the buffer.
5C4A
LD (HL),B 70
Store Register B (00H, left by the LDIR) into (HL), Register Pair HL = 5D54H.
5C4B
INC HL 23
INCrement Register Pair HL by 1, to 5D55H, the byte just before the buffer.
5C4C
LD (HL),2CH 36 2C
Store 2CH, a comma, at (HL) (Register Pair HL = 5D55H).
5C4E
INC HL 23
INCrement Register Pair HL by 1, to 5D56H, the start of the input buffer.
5C4F
LD (40A7H),HL 22 A7 40
Store Register Pair HL (5D56H) into 40A7H, the ROM's input buffer pointer: lines are read into 5D56H-5E55H from now on.
5C52
LD DE,4152H 11 52 41
Point Register Pair DE to 4152H, the ROM's Disk BASIC vectors and links.
5C55
LD HL,54C3H 21 C3 54
Point Register Pair HL to 54C3H, the table of 49 jumps.
5C58
LD BC,0093H 01 93 00
Load Register Pair BC with 0093H, the 147 bytes of 49 three-byte jumps.
5C5B
LDIR ED B0
Copy them: LDIR moves 147 bytes from (HL) (Register Pair HL = 54C3H) to (DE) (Register Pair DE = 4152H), counting Register Pair BC down: 4152H-41E4H now lead into BASIC/CMD.
5C5D
LD HL,5E56H 21 56 5E
Point Register Pair HL to 5E56H, the byte after the input buffer.
5C60
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = 5E56H): a line in the buffer always ends there.
5C62
GOSUB to the ROM's 1B8FH, which sets the Stack Pointer below the start of string space (40A0H), empties the temporary string pool and sets output to the screen.
5C65
GOSUB to the ROM's 01C9H to clear the screen.
5C68
LD A,(403EH) 3A 3E 40
Fetch the DOS version from 403EH into Register A (22H for TRSDOS 2.2 and 2.3).
5C6B
CP 22H FE 22
Compare Register A against 22H: the NO CARRY FLAG is set for version 2.2 or later.
5C6D
If the NO CARRY FLAG is set, JUMP to 5C78H to go on.
5C6F
LD HL,5E57H 21 57 5E
Too Old
Point Register Pair HL to 5E57H, the text USE TRSDOS 2.2 OR LATER. 5C75H loops back here.
5C72
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
5C75
LOOP BACK to 5C6FH for ever: only RESET leaves.
5C78
LD A,(5C98H) 3A 98 5C
Fetch the first character of the command line from 5C98H, saved at 5C07H, into Register A. 5C6DH jumps here.
5C7B
CP 2AH FE 2A
Compare Register A (the first character of the command line) against 2AH, an asterisk.
5C7D
If the NZ FLAG is set (no asterisk), JUMP to 5C9FH to ask HOW MANY FILES.
5C80
LD A,(408EH) 3A 8E 40
Fetch the number of files from 408EH into Register A.
5C83
GOSUB to 5CD0H to set up the file blocks again for Register A files; with the asterisk at 5C98H it returns before the MEM SIZE question.
5C86
LD BC,1A18H 01 18 1A
Load Register Pair BC with 1A18H, the ROM's POP BC before READY, the return address for 1B9AH.
5C89
LD HL,(5C9DH) 2A 9D 5C
Fetch the saved start of string space from 5C9DH into Register Pair HL.
5C8C
LD (40A0H),HL 22 A0 40
Store Register Pair HL into 40A0H: string space is as it was.
5C8F
LD HL,(5C99H) 2A 99 5C
Fetch the saved program start from 5C99H into Register Pair HL.
5C92
LD (40A4H),HL 22 A4 40
Store Register Pair HL into 40A4H: the program in memory is used again.
5C95
JUMP to the ROM's 19AEH, which sets the Stack Pointer from 40E8H (1B9AH) and returns through Register Pair BC (1A18H) to READY.
5C98
DEFB 00H 00
The first character after BASIC on the command line, stored by 5C07H: an asterisk means start again with the program kept.
5C99-5C9A
DEFW 0000H 00 00
The program start (40A4H), saved at 5C0DH and put back at 5C8FH.
5C9B-5C9C
DEFW 0000H 00 00
The number of files (408EH) and the V flag (408FH), saved at 5C13H and put back at 5C3AH.
5C9D-5C9E
DEFW 0000H 00 00
The start of string space (40A0H), saved at 5C19H and put back at 5C89H.

5C9FH - Start: HOW MANY FILES and MEM SIZE

Asks HOW MANY FILES? ; ENTER alone gives 3, a number 0-15 is taken, and a V after the number adds a 256-byte record buffer to each file. Then sets up the file blocks from 659BH and puts the program after them. Then asks MEM SIZE? (ENTER alone: the top of memory, at most FFF8H); at least 300 bytes must be left for the program, and 50 bytes of string space are set aside. NEW, the banner and READY follow. A wrong answer asks again; a syntax error goes through 57E6H back to 5C06H, as the line number is FFFEH.

5C9F
LD HL,5E70H 21 70 5E
Point Register Pair HL to 5E70H, the text HOW MANY FILES. 5C7DH, 5CA8H, 5CC6H and 5CCBH jump here.
5CA2
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
5CA5
GOSUB to the ROM's 1BB3H to show a question mark and a space and read a line from the keyboard: Register Pair HL = the byte before the line, the CARRY FLAG set for BREAK.
5CA8
If the CARRY FLAG is set (BREAK), LOOP BACK to 5C9FH to ask again.
5CAA
XOR A AF
Set Register A to ZERO with XOR A, the value of the V flag without V.
5CAB
LD (408FH),A 32 8F 40
Store Register A (00H) into 408FH, the V flag: no record buffers for now.
5CAE
RST 10H D7
Move Register Pair HL to the first character of the answer with RST 10H, which leaves it in Register A (00H for an empty line).
5CAF
OR A B7
OR Register A with itself: the Z FLAG is set for an empty answer.
5CB0
LD A,03H 3E 03
Load Register A with 03H, the number of files for an empty answer; LD does not change the flags.
5CB2
If the Z FLAG is set (ENTER alone), JUMP to 5CCDH with 3 files.
5CB4
LD A,(HL) 7E
Fetch the first character from (HL) (Register Pair HL = the answer) into Register A.
5CB5
GOSUB to the ROM's 1E5AH to read the decimal number at Register Pair HL into Register Pair DE; Register A returns the character after it.
5CB8
CP 56H FE 56
Compare Register A (the character after the number) against 56H, the letter V.
5CBA
If the NZ FLAG is set (no V), JUMP to 5CC0H with Register A = the character after the number.
5CBC
LD (408FH),A 32 8F 40
Store Register A (56H) into 408FH: each file gets a record buffer.
5CBF
RST 10H D7
Move Register Pair HL past the V with RST 10H, which leaves the next character in Register A.
5CC0
OR A B7
OR Register A (the character after the answer) with itself: the Z FLAG is set at the end of the line. 5CBAH jumps here.
5CC1
If the NZ FLAG is set (anything more), JUMP to the ROM's 1997H, the syntax error.
5CC4
LD A,D 7A
Copy the high byte of the number from Register D into Register A.
5CC5
OR A B7
OR Register A with itself: the NZ FLAG is set for 256 or more.
5CC6
If the NZ FLAG is set, LOOP BACK to 5C9FH to ask again.
5CC8
LD A,E 7B
Copy the low byte of the number from Register E into Register A.
5CC9
CP 10H FE 10
Compare Register A against 10H: the NO CARRY FLAG is set for 16 or more.
5CCB
If the NO CARRY FLAG is set, LOOP BACK to 5C9FH to ask again.
5CCD
LD (408EH),A 32 8E 40
Store Register A (the number of files, 0-15) into 408EH. 5CB2H jumps here.

5CD0H - Set Up the File Blocks

Register A = the number of files. Makes Register A plus 1 blocks (file 0 and files 1 to Register A) of 0122H bytes from 659BH, 0222H with V, marks each closed and stores its address into the file table at 5B8FH. After an asterisk start it returns there; otherwise the program text starts after the last block and the MEM SIZE question follows.

5CD0
INC A 3C
INCrement Register A (the number of files) by 1, for file 0. 5C83H calls here.
5CD1
LD HL,659BH 21 9B 65
Point Register Pair HL to 659BH, the first byte after BASIC/CMD, the block of file 0.
5CD4
LD DE,5B8FH 11 8F 5B
Point Register Pair DE to 5B8FH, the file table.
5CD7
LD (5BAFH),HL 22 AF 5B
Store Register Pair HL (659BH) into 5BAFH, the address of the real block of file 0.
5CDA
LD (HL),00H 36 00
Block Loop
Store 00H at (HL) (Register Pair HL = the block), its mode byte: the file is closed. 5CF0H loops back here.
5CDC
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the file table entry, Register Pair DE = the block.
5CDD
LD (HL),E 73
Store Register E (the low byte of the block address) into (HL) (Register Pair HL = the table entry).
5CDE
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the entry.
5CDF
LD (HL),D 72
Store Register D (the high byte of the block address) into (HL) (Register Pair HL = the entry's second byte).
5CE0
INC HL 23
INCrement Register Pair HL by 1, to the next table entry.
5CE1
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the next table entry, Register Pair HL = the block.
5CE2
LD BC,0122H 01 22 01
Load Register Pair BC with 0122H, the size of a block.
5CE5
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the next block.
5CE6
LD B,A 47
Copy the number of blocks left from Register A into Register B.
5CE7
LD A,(408FH) 3A 8F 40
Fetch the V flag from 408FH into Register A: 56H after a V, 00H without.
5CEA
OR A B7
OR Register A with itself: the Z FLAG is set without V.
5CEB
If the Z FLAG is set (no V), JUMP to 5CEEH: the block stays 0122H bytes.
5CED
INC H 24
INCrement Register H by 1: 256 bytes more for the record buffer of this block.
5CEE
LD A,B 78
Copy the number of blocks left from Register B into Register A. 5CEBH jumps here.
5CEF
DEC A 3D
DECrement Register A (the blocks left) by 1: the Z FLAG is set after the last one.
5CF0
If the NZ FLAG is set (more blocks), JUMP to 5CDAH for the next one.
5CF3
LD A,(5C98H) 3A 98 5C
Fetch the first character of the command line from 5C98H into Register A.
5CF6
CP 2AH FE 2A
Compare Register A (the first character of the command line) against 2AH, an asterisk.
5CF8
RET Z C8
If the Z FLAG is set (an asterisk start), RETURN to 5C86H: the program stays where it is.
5CF9
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = the byte after the last block), the 00H the ROM needs before the program text.
5CFB
INC HL 23
INCrement Register Pair HL by 1, to the start of the program text.
5CFC
LD (40A4H),HL 22 A4 40
Store Register Pair HL into 40A4H, the start of the program text.
5CFF
LD HL,0105H 21 05 01
MEM SIZE
Point Register Pair HL to 0105H, the ROM's text MEM SIZE. 5D08H and 5D27H jump here.
5D02
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
5D05
GOSUB to the ROM's 1BB3H to show a question mark and a space and read a line: Register Pair HL = the byte before it, the CARRY FLAG set for BREAK.
5D08
If the CARRY FLAG is set (BREAK), LOOP BACK to 5CFFH to ask again.
5D0A
RST 10H D7
Move Register Pair HL to the first character of the answer with RST 10H, which leaves it in Register A.
5D0B
OR A B7
OR Register A with itself: the Z FLAG is set for ENTER alone.
5D0C
If the NZ FLAG is set (a number was typed), JUMP to 5D1AH.
5D0E
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H into Register Pair HL.
5D11
LD DE,FFF9H 11 F9 FF
Load Register Pair DE with FFF9H, the highest value used.
5D14
RST 18H DF
Compare Register Pair HL (the top of memory) with Register Pair DE (FFF9H) with RST 18H: the CARRY FLAG is set when it is lower.
5D15
If the CARRY FLAG is set, JUMP to 5D29H with the top of memory in Register Pair HL.
5D17
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = FFF9H.
5D18
JUMP to 5D29H with Register Pair HL = FFF9H, the highest end used.
5D1A
GOSUB to the ROM's 1E5AH to read the decimal number at Register Pair HL into Register Pair DE; Register A returns the character after it. 5D0CH jumps here.
5D1D
OR A B7
OR Register A with itself: the Z FLAG is set when the number ends the line.
5D1E
If the NZ FLAG is set (anything more), JUMP to the ROM's 1997H, the syntax error.
5D21
DEC DE 1B
DECrement Register Pair DE (the number typed) by 1: the last byte BASIC may use.
5D22
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H into Register Pair HL.
5D25
RST 18H DF
Compare Register Pair HL (the top of memory) with Register Pair DE (the number minus 1) with RST 18H: the CARRY FLAG is set when the number is too high.
5D26
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the number minus 1; EX does not change the flags.
5D27
If the CARRY FLAG is set (above the top of memory), LOOP BACK to 5CFFH to ask again.
5D29
DEC HL 2B
DECrement Register Pair HL (the end chosen) by 1. 5D15H and 5D18H jump here.
5D2A
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the end of memory for BASIC.
5D2B
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
5D2E
LD BC,012CH 01 2C 01
Load Register Pair BC with 012CH, the 300 bytes that must at least be free.
5D31
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the program start plus 300.
5D32
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the end of memory, Register Pair DE = the program start plus 300.
5D33
RST 18H DF
Compare Register Pair HL with Register Pair DE with RST 18H: the CARRY FLAG is set when less than 300 bytes are left.
5D34
If the CARRY FLAG is set, JUMP to the ROM's 197AH, OUT OF MEMORY.
5D37
LD DE,FFCEH 11 CE FF
Load Register Pair DE with FFCEH, minus 50, the string space set aside.
5D3A
LD (40B1H),HL 22 B1 40
Store Register Pair HL (the end of memory) into 40B1H, the ROM's top of memory for BASIC.
5D3D
ADD HL,DE 19
ADD Register Pair DE (minus 50) to Register Pair HL: Register Pair HL = the start of string space.
5D3E
LD (40A0H),HL 22 A0 40
Store Register Pair HL into 40A0H, the start of string space: 50 bytes of strings.
5D41
GOSUB to the ROM's 1B4DH, NEW, to clear the program and the variables.
5D44
LD HL,5E7FH 21 7F 5E
Point Register Pair HL to 5E7FH, the banner RADIO SHACK DISK BASIC VERSION 2.2.
5D47
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
5D4A
JUMP to the ROM's 1A19H, READY, which waits for the first command.

5D4DH - Disk BASIC's Hook for RST 28H Codes Below 80H

SYS0/SYS's RST 28H code jumps through 4312H to here for a function code with bit 7 clear (4BA5H), having dropped the RST's return address. The ROM's keyboard routine passes 01H when BREAK is pressed (0456H): it is returned to the keyboard routine's caller as it is, so BASIC sees BREAK; SYS0/SYS's own hook (4BA0H) would return 00H. Any other code goes to the old hook, whose address 5C1FH stored at 5D51H.

5D4D
CP 01H FE 01
Compare Register A (the function code) against 01H, the ROM's code for BREAK.
5D4F
RET Z C8
If the Z FLAG is set (BREAK), RETURN with Register A = 01H to the caller of the routine that executed RST 28H.
5D50
JUMP to the old hook, whose address 5C1FH stored into this operand at 5D51H (0000H in the file).

5D53H - The Input Buffer and the Start-up Texts

5D53H-5D55H get a colon, 00H and a comma (5C44H-5C4EH), and 40A7H points to 5D56H: the ROM reads typed lines into 5D56H-5E55H, and 5E56H stays 00H. The three texts are used only at the start. 5EA3H-5EC2H holds a file name for 441CH.

5D53-5D55
DEFB 00H 00 x 3
00H in the file: 5C47H-5C4CH store a colon, 00H and a comma here before the input buffer, as the ROM puts them before its own buffer at 0083H-0087H.
5D56-5E55
DEFB 00H 00 x 256
The input buffer: 40A7H points here from 5C4FH, so the ROM's line input (0361H, 1BB3H) and 59EAH read lines into these 256 bytes; INPUT # and LINE INPUT # build their items here (5F88H).
5E56
DEFB 00H 00
Set to 00H by 5C60H: the end of a line that fills the whole input buffer.
5E57-5E6F
DEFM "USE TRSDOS 2.2 OR LATER" / DEFB 0DH, 00H 55 53 45 20 54 52 53 44 4F 53 20 32 2E 32 20 4F 52 20 4C 41 54 45 52 0D 00
Shown for ever by 5C6FH-5C75H when the DOS version at 403EH is below 22H.
5E70-5E7E
DEFM "HOW MANY FILES" / DEFB 00H 48 4F 57 20 4D 41 4E 59 20 46 49 4C 45 53 00
Shown by 5C9FH; the ROM's 1BB3H adds the question mark.
5E7F-5EA2
DEFM "RADIO SHACK DISK BASIC VERSION 2.2" / DEFB 0DH, 00H 52 41 44 49 4F 20 53 48 41 43 4B 20 44 49 53 4B 20 42 41 53 49 43 20 56 45 52 53 49 4F 4E 20 32 2E 32 0D 00
The banner shown by 5D44H before READY at the end of the start-up.
5EA3-5EC2
DEFB 00H 00 x 32
The file name: 63EDH copies the name given to OPEN, LOAD, RUN, SAVE, MERGE or KILL here in capitals with a 00H after it (at most 22 characters), and 441CH reads it into the file's FCB.

5EC3H - # and a File Number for INPUT # and PRINT #

5EC3H is for input (mode 01H), 5EC5H takes the mode in Register C (02H from PRINT, 56C6H). Register A = the character at Register Pair HL. Without # it returns at once. Otherwise it reads the file number, checks that the file is open in that mode (Bad file mode, 6547H, if not), expects a comma after the number and makes the file current at 5B8DH.

5EC3
LD C,01H 0E 01
Load Register C with 01H, the mode byte of a file open for input. 57C5H and 5F4CH call here.
5EC5
CP 23H FE 23
Compare Register A (the character at Register Pair HL) against 23H, the character #. 56C8H jumps here with Register C = 02H.
5EC7
RET NZ C0
If the NZ FLAG is set (no #), RETURN: there is no file.
5EC8
PUSH BC C5
Save Register Pair BC (Register C = the mode wanted) onto the stack.
5EC9
GOSUB to 5EDBH to read the file number: Register Pair BC = the file's block, Register A = its mode byte.
5ECC
POP DE D1
Restore Register Pair DE from the stack: Register E = the mode wanted.
5ECD
CP E BB
Compare Register A (the file's mode) against Register E (the mode wanted).
5ECE
If the NZ FLAG is set (closed, or open in another mode), JUMP to 6547H, Bad file mode.
5ED1
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
5ED3
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the text after the comma.
5ED4
LD H,B 60
Copy the high byte of the block address from Register B into Register H.
5ED5
LD L,C 69
Copy the low byte of the block address from Register C into Register L: Register Pair HL = the block.
5ED6
LD (5B8DH),HL 22 8D 5B
Store Register Pair HL (the block) into 5B8DH: this is the current file.
5ED9
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the text after the comma again.
5EDA
RET C9
RETURN to the caller with the file current and Register Pair HL after the comma.

5EDBH - Read a File Number and Find Its Block

Register Pair HL = the text at the file number, with or without #. 5EE5H takes the number from the accumulator instead, 5EE8H from Register A. A number above the number of files (408EH) gives Bad file number (654AH). Returns Register Pair BC = the file's block from the table at 5B8FH, Register A = its mode byte and the Z FLAG for a closed file; Register Pair HL is kept.

5EDB
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the current character again. Called by 5EC9H, 61AFH and 6359H.
5EDC
RST 10H D7
Fetch the character with RST 10H into Register A, Register Pair HL moving onto it.
5EDD
CP 23H FE 23
Compare Register A against 23H, the character #.
5EDF
If the Z FLAG is set (a #), GOSUB to the ROM's 1D78H, the RST 10H code, to move Register Pair HL past it.
5EE2
GOSUB to the ROM's 2337H to evaluate the file number at Register Pair HL into the accumulator.
5EE5
GOSUB to the ROM's 2B1FH to convert the accumulator to a byte in Register A (ILLEGAL FUNCTION CALL above 255). EOF and LOF call here (62B8H, 630FH).
5EE8
LD E,A 5F
Copy the file number from Register A into Register E. 6475H, 62DDH and 6522H call here.
5EE9
LD A,(408EH) 3A 8E 40
Fetch the number of files from 408EH into Register A.
5EEC
CP E BB
Compare Register A (the number of files) against Register E (the file number): the CARRY FLAG is set when the number is too high.
5EED
If the CARRY FLAG is set, JUMP to 654AH, Bad file number.
5EF0
LD D,00H 16 00
Load Register D with 00H: Register Pair DE = the file number.
5EF2
PUSH HL E5
Save Register Pair HL (the text) onto the stack.
5EF3
LD HL,5B8FH 21 8F 5B
Point Register Pair HL to 5B8FH, the file table.
5EF6
ADD HL,DE 19
ADD Register Pair DE (the file number) to Register Pair HL once.
5EF7
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL again: Register Pair HL = 5B8FH plus twice the number, the file's entry.
5EF8
LD C,(HL) 4E
Fetch the low byte of the block address from (HL) (Register Pair HL = the entry) into Register C.
5EF9
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the entry.
5EFA
LD B,(HL) 46
Fetch the high byte of the block address from (HL) (Register Pair HL = the entry's second byte) into Register B: Register Pair BC = the block.
5EFB
LD A,(BC) 0A
Fetch the mode byte from (BC) (Register Pair BC = the block) into Register A.
5EFC
OR A B7
OR Register A (the mode) with itself: the Z FLAG is set for a closed file.
5EFD
POP HL E1
Restore Register Pair HL (the text) from the stack.
5EFE
RET C9
RETURN to the caller with Register Pair BC = the block and Register A = the mode.

5EFFH - MKI$, MKS$ and MKD$

The ROM's function table sends MKI$ to 416AH, MKS$ to 416DH and MKD$ to 4170H, and from there to 5EFFH, 5F02H and 5F05H. The number in the accumulator is converted to an integer (2 bytes), single (4) or double (8) and its bytes become a string of that length, for a random file's field.

5EFF
LD A,02H 3E 02
Load Register A with 02H, the type and length of an integer (MKI$).
5F01
LD BC,043EH 01 3E 04
Load Register Pair BC with 043EH: from 5EFFH this only skips the two bytes at 5F02H, LD A,04H for MKS$; Register Pair BC is not used.
5F04
LD BC,083EH 01 3E 08
Load Register Pair BC with 083EH: this skips the two bytes at 5F05H, LD A,08H for MKD$; Register Pair BC is not used.
5F07
PUSH AF F5
Save Register Pair AF (Register A = the type and length: 2, 4 or 8) onto the stack.
5F08
GOSUB to the ROM's 2819H to convert the accumulator to the type in Register A; Register Pair HL is kept.
5F0B
POP AF F1
Restore Register Pair AF (Register A = the length) from the stack.
5F0C
GOSUB to the ROM's 2857H to make room for a string of Register A bytes, with its descriptor at 40D3H.
5F0F
LD HL,(40D4H) 2A D4 40
Fetch the address of the new string from 40D4H into Register Pair HL.
5F12
GOSUB to the ROM's 09FFH to copy the number from the accumulator to the string at Register Pair HL (as many bytes as its type, 40AFH).
5F15
JUMP to the ROM's 2A2BH, the end of a string function: it drops the return for a number result and makes the descriptor at 40D3H a temporary string.

5F18H - CVI, CVS and CVD

The ROM's function table sends CVI to 4152H, CVS to 4158H and CVD to 415EH, and from there to 5F18H, 5F1BH and 5F1EH. The first 2, 4 or 8 bytes of the string argument become the value of an integer, single or double; a shorter string gives ILLEGAL FUNCTION CALL.

5F18
LD A,01H 3E 01
Load Register A with 01H, one less than the length of an integer (CVI).
5F1A
LD BC,033EH 01 3E 03
Load Register Pair BC with 033EH: from 5F18H this only skips the two bytes at 5F1BH, LD A,03H for CVS; Register Pair BC is not used.
5F1D
LD BC,073EH 01 3E 07
Load Register Pair BC with 073EH: this skips the two bytes at 5F1EH, LD A,07H for CVD; Register Pair BC is not used.
5F20
PUSH AF F5
Save Register Pair AF (Register A = the length minus 1: 1, 3 or 7) onto the stack.
5F21
GOSUB to the ROM's 29D7H, which checks that the argument is a string, releases its temporary and returns Register Pair HL = its descriptor.
5F24
POP AF F1
Restore Register Pair AF (Register A = the length minus 1) from the stack.
5F25
CP (HL) BE
Compare Register A against the string length at (HL) (Register Pair HL = the descriptor): the NO CARRY FLAG is set when the string is too short.
5F26
If the NO CARRY FLAG is set, JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL.
5F29
INC A 3C
INCrement Register A by 1: the type and length, 2, 4 or 8.
5F2A
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
5F2B
LD C,(HL) 4E
Fetch the low byte of the string address from (HL) (Register Pair HL = the descriptor) into Register C.
5F2C
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
5F2D
LD H,(HL) 66
Fetch the high byte of the string address from (HL) (Register Pair HL = the descriptor) into Register H.
5F2E
LD L,C 69
Copy the low byte from Register C into Register L: Register Pair HL = the bytes of the string.
5F2F
LD (40AFH),A 32 AF 40
Store Register A (the type) into 40AFH, the ROM's number type flag.
5F32
JUMP to the ROM's 09F7H, which copies the bytes at Register Pair HL into the accumulator (as many as the type) and returns to the expression evaluator.

5F35H - INPUT #: Read One Item from the File

The ROM calls the link at 41DCH in READ and INPUT before it stores an item into a variable (222DH). With no current file it returns. With one, the ROM's own reading is dropped and the item comes from the file: a number ends at a comma, a space or ENTER, a string at a comma or ENTER, a string in quotes at the closing quote. The common reader at 5F60H also serves LINE INPUT #, which takes the whole line. The item is built in the input buffer and becomes a number (ROM 0E6CH) or a string (ROM 2868H).

5F35
EX DE,HL EB
Exchange Register Pairs DE and HL, keeping Register Pair HL (the ROM's text) in Register Pair DE. The link at 41DCH jumps here.
5F36
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
5F39
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
5F3A
OR L B5
OR Register A with Register L: the Z FLAG is set when there is no current file.
5F3B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the ROM's text again; EX does not change the flags.
5F3C
RET Z C8
If the Z FLAG is set (no file), RETURN to the ROM's READ or INPUT at 2230H.
5F3D
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 2230H.
5F3E
RST 20H E7
Test the type of the variable to be stored with RST 20H (the ROM's 40AFH, set when the variable was found): the Z FLAG is set for a string.
5F3F
LD BC,2243H 01 43 22
Load Register Pair BC with 2243H, the place in the ROM's READ and INPUT where the item is stored, the return address of the reader.
5F42
LD DE,2C20H 11 20 2C
Load Register Pair DE with 2C20H: Register D = a comma and Register E = a space, the two characters that end a number.
5F45
If the NZ FLAG is set (a numeric variable), JUMP to 5F60H with these two.
5F48
LD E,D 5A
Copy Register D (a comma) into Register E: a string ends only at a comma (or ENTER).
5F49
JUMP to 5F60H to read the string item with Register D = Register E = a comma.

5F4CH - LINE INPUT #

578EH jumps here for LINE INPUT #. The file must be open for input. A whole line, up to ENTER (commas, quotes and spaces kept, at most 255 characters), is stored into the string variable.

5F4C
GOSUB to 5EC3H to read # and the file number, check that the file is open for input, expect a comma and make it the current file. 578EH jumps here.
5F4F
GOSUB to the ROM's 260DH to find or create the variable named at Register Pair HL: Register Pair DE = its address.
5F52
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the variable is a string.
5F55
LD BC,2169H 01 69 21
Load Register Pair BC with 2169H, the ROM's end of PRINT and INPUT, which clears the current file.
5F58
PUSH BC C5
Save Register Pair BC (2169H) onto the stack, the final return address.
5F59
PUSH DE D5
Save Register Pair DE (the variable's address) onto the stack, for the ROM's assignment at 1F31H.
5F5A
LD BC,1F31H 01 31 1F
Load Register Pair BC with 1F31H, the part of the ROM's LET that stores a value, the return address of the reader.
5F5D
XOR A AF
Set Register A to ZERO with XOR A: with the 3 that 1F33H adds, the type of a string.
5F5E
LD D,A 57
Copy Register A (00H) into Register D: no character ends the line but ENTER.
5F5F
LD E,A 5F
Copy Register A (00H) into Register E, the second end character, also none.
5F60
PUSH AF F5
Read an Item
Save Register Pair AF (the variable's type flags, or 00H for LINE INPUT #) onto the stack, where the ROM's code at Register Pair BC expects it. 5F45H and 5F49H jump here.
5F61
PUSH BC C5
Save Register Pair BC (the ROM's return address, 2243H or 1F31H) onto the stack.
5F62
PUSH HL E5
Save Register Pair HL (the program text) onto the stack.
5F63
Skip Leading Spaces
GOSUB to 63C4H to read the next character of the file into Register A; the CARRY FLAG is set at the end of the file. 5F70H loops back here.
5F66
If the CARRY FLAG is set (no more data), JUMP to 6550H, Input past end.
5F69
CP 20H FE 20
Compare Register A (the character read) against 20H, a space.
5F6B
If the NZ FLAG is set (not a space), JUMP to 5F73H.
5F6E
INC D 14
INCrement Register D (the first end character) by 1, which with the DEC below only tests it.
5F6F
DEC D 15
DECrement Register D by 1 again: the Z FLAG is set when Register D is 00H (LINE INPUT #).
5F70
If the NZ FLAG is set (an item, not a line), JUMP to 5F63H to skip the space.
5F73
CP 22H FE 22
Compare Register A (the first character) against 22H, a quotation mark. 5F6BH jumps here.
5F75
If the NZ FLAG is set (no quotation mark), JUMP to 5F88H.
5F78
LD B,A 47
Copy the character from Register A into Register B.
5F79
LD A,E 7B
Copy the second end character from Register E into Register A.
5F7A
CP 2CH FE 2C
Compare Register A against 2CH, the comma that marks a string item.
5F7C
LD A,B 78
Copy the quotation mark from Register B back into Register A; LD does not change the flags.
5F7D
If the NZ FLAG is set (a number or a line), JUMP to 5F88H: the quotation mark is an ordinary character.
5F80
LD D,B 50
Copy the quotation mark from Register B into Register D: the string ends at the next quotation mark.
5F81
LD E,B 58
Copy the quotation mark from Register B into Register E as well.
5F82
GOSUB to 63C4H to read the first character after the opening quotation mark into Register A.
5F85
If the CARRY FLAG is set (the end of the file), JUMP to 5FD6H to end the item.
5F88
LD HL,(40A7H) 2A A7 40
Fetch the input buffer pointer from 40A7H into Register Pair HL: the item is built there. 5F75H and 5F7DH jump here.
5F8B
LD B,FFH 06 FF
Load Register B with FFH, the 255 characters the item may have.
5F8D
LD C,A 4F
Character Loop
Copy the character from Register A into Register C. 5FD3H jumps here.
5F8E
LD A,D 7A
Copy the first end character from Register D into Register A.
5F8F
CP 22H FE 22
Compare Register A against 22H, a quotation mark: the Z FLAG is set inside a quoted string.
5F91
LD A,C 79
Copy the character from Register C back into Register A; LD does not change the flags.
5F92
If the Z FLAG is set (inside quotes), JUMP to 5FC1H: ENTER and line feed are ordinary characters there.
5F95
CP 0DH FE 0D
Compare Register A (the character read) against 0DH, ENTER.
5F97
PUSH HL E5
Save Register Pair HL (the place in the buffer) onto the stack; PUSH does not change the flags.
5F98
If the Z FLAG is set (ENTER), JUMP to 5FF6H to end the item and skip a line feed after it.
5F9B
POP HL E1
Restore Register Pair HL (the place in the buffer) from the stack.
5F9C
CP 0AH FE 0A
Compare Register A (the character read) against 0AH, a line feed.
5F9E
If the NZ FLAG is set (another character), JUMP to 5FC1H.
5FA1
LD C,A 4F
Copy the line feed from Register A into Register C.
5FA2
LD A,E 7B
Copy the second end character from Register E into Register A.
5FA3
CP 2CH FE 2C
Compare Register A against 2CH: the Z FLAG is set for a string item.
5FA5
LD A,C 79
Copy the line feed from Register C back into Register A; LD does not change the flags.
5FA6
If the NZ FLAG is set (a number or a line), GOSUB to 6056H to store the line feed into the buffer; a string item leaves it out.
5FA9
GOSUB to 63C4H to read the character after the line feed into Register A.
5FAC
If the CARRY FLAG is set (the end of the file), JUMP to 5FD6H to end the item.
5FAF
CP 0DH FE 0D
Compare Register A (the character after the line feed) against 0DH, ENTER.
5FB1
If the NZ FLAG is set (not ENTER), JUMP to 5FC1H to take the character.
5FB4
LD A,E 7B
Copy the second end character from Register E into Register A: an ENTER after a line feed is looked at by the kind of item.
5FB5
CP 20H FE 20
Compare Register A against 20H, the space that marks a number.
5FB7
If the Z FLAG is set (a number), JUMP to 5FD0H: the ENTER is skipped.
5FBA
CP 2CH FE 2C
Compare Register A against 2CH, the comma that marks a string item.
5FBC
LD A,0DH 3E 0D
Load Register A with 0DH, the ENTER again; LD does not change the flags.
5FBE
If the Z FLAG is set (a string item), JUMP to 5FD0H: the ENTER is skipped; for LINE INPUT # it is stored below.
5FC1
OR A B7
OR Register A (the character) with itself: the Z FLAG is set for 00H. 5F92H, 5F9EH and 5FB1H jump here.
5FC2
If the Z FLAG is set (a 00H byte), JUMP to 5FD0H: it is skipped.
5FC5
CP D BA
Compare Register A against Register D, the first end character.
5FC6
If the Z FLAG is set (the item ends here), JUMP to 5FD6H.
5FC9
CP E BB
Compare Register A against Register E, the second end character.
5FCA
If the Z FLAG is set (the item ends here), JUMP to 5FD6H.
5FCD
GOSUB to 6056H to store the character from Register A into the buffer at Register Pair HL.
5FD0
GOSUB to 63C4H to read the next character into Register A. 5FB7H, 5FBEH and 5FC2H jump here.
5FD3
Character Loop End
If the NO CARRY FLAG is set (a character came), JUMP to 5F8DH.
5FD6
PUSH HL E5
End of the Item
Save Register Pair HL (the end of the item in the buffer) onto the stack. 5F85H, 5FACH, 5FC6H, 5FCAH and 5FD3H come here, with Register A = the character that ended it.
5FD7
CP 22H FE 22
Compare Register A against 22H, the closing quotation mark.
5FD9
If the Z FLAG is set, JUMP to 5FE1H to skip the spaces after it.
5FDC
CP 20H FE 20
Compare Register A against 20H, the space that ended a number.
5FDE
If the NZ FLAG is set (a comma, or the end of the file), JUMP to 603CH: the item is complete.
5FE1
Skip Trailing Spaces
GOSUB to 63C4H to read the next character into Register A. 5FD9H jumps here; 5FE9H loops back here.
5FE4
If the CARRY FLAG is set (the end of the file), JUMP to 603CH.
5FE7
CP 20H FE 20
Compare Register A (the character read) against 20H, a space.
5FE9
If the Z FLAG is set, JUMP to 5FE1H to skip it.
5FEC
CP 2CH FE 2C
Compare Register A (the character read) against 2CH, a comma.
5FEE
If the Z FLAG is set (the comma after the item), JUMP to 603CH.
5FF1
CP 0DH FE 0D
Compare Register A (the character read) against 0DH, ENTER.
5FF3
If the NZ FLAG is set (the start of the next item), JUMP to 6001H to give the character back.
5FF6
GOSUB to 63C4H to read the character after the ENTER into Register A. 5F98H jumps here.
5FF9
If the CARRY FLAG is set (the end of the file), JUMP to 603CH.
5FFC
CP 0AH FE 0A
Compare Register A against 0AH, a line feed after the ENTER.
5FFE
If the Z FLAG is set, JUMP to 603CH: the line feed is used up.
6001
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL. 5FF3H jumps here.
6004
LD BC,0007H 01 07 00
Load Register Pair BC with 0007H, the offset of the FCB's byte position in the block (FCB byte 05H).
6007
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the byte position.
6008
GOSUB to 600EH to step the file back by one character, so that the next read gets it again.
600B
JUMP to 603CH: the item is complete and the next one starts with that character.

600EH - Give One Character Back to the File

Register Pair HL = byte 07H of the file's block, the FCB's byte position (FCB byte 05H). Steps it back by one. When it becomes 00H, bit 5 of the FCB's flags is set (read the buffer again before the next byte) and the next record number is stepped back. When it wraps to FFH, the file is moved back one record (4445H) and the position set to FFH.

600E
DEC (HL) 35
DECrement the byte position at (HL) (Register Pair HL = block byte 07H) by 1. 6008H and 612DH call here.
600F
LD A,(HL) 7E
Fetch the new byte position from (HL) (Register Pair HL = block byte 07H) into Register A.
6010
OR A B7
OR Register A with itself: the Z FLAG is set for 00H.
6011
If the NZ FLAG is set, JUMP to 6027H to look for a wrap to FFH.
6013
LD BC,FFFCH 01 FC FF
Load Register Pair BC with FFFCH, minus 4, from block byte 07H back to byte 03H.
6016
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = block byte 03H, the FCB's flags (FCB byte 01H).
6017
LD A,(HL) 7E
Fetch the FCB's flags from (HL) (Register Pair HL = block byte 03H) into Register A.
6018
OR 20H F6 20
OR Register A with 20H: bit 5 makes SYS0/SYS read the buffer again before the next byte.
601A
LD (HL),A 77
Store Register A (the flags) back into (HL), Register Pair HL = block byte 03H.
601B
LD BC,0009H 01 09 00
Load Register Pair BC with 0009H, from the flags to the next record number.
601E
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = block byte 0CH, the FCB's next record number (FCB bytes 0AH-0BH).
601F
LD C,(HL) 4E
Fetch the low byte of the next record number from (HL) (Register Pair HL = block byte 0CH) into Register C.
6020
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6021
LD B,(HL) 46
Fetch the high byte of the next record number from (HL) (Register Pair HL = block byte 0DH) into Register B.
6022
DEC BC 0B
DECrement Register Pair BC (the next record number) by 1.
6023
LD (HL),B 70
Store Register B (the high byte) back into (HL), Register Pair HL = block byte 0DH.
6024
DEC HL 2B
DECrement Register Pair HL by 1, to the low byte.
6025
LD (HL),C 71
Store Register C (the low byte) back into (HL), Register Pair HL = block byte 0CH.
6026
RET C9
RETURN to the caller: the record is read again on the next character.
6027
CP FFH FE FF
Compare Register A (the new byte position) against FFH. 6011H jumps here.
6029
RET NZ C0
If the NZ FLAG is set (no wrap), RETURN: the character is in the buffer.
602A
PUSH HL E5
Save Register Pair HL (block byte 07H) onto the stack.
602B
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack while it holds the FCB.
602C
LD BC,FFFBH 01 FB FF
Load Register Pair BC with FFFBH, minus 5, from block byte 07H back to byte 02H.
602F
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = block byte 02H, the FCB.
6030
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the FCB.
6031
GOSUB to SYS0/SYS's 4445H to move the file in the FCB at Register Pair DE back by one record.
6034
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
6037
POP DE D1
Restore Register Pair DE (the caller's value, pushed at 602BH) from the stack.
6038
POP HL E1
Restore Register Pair HL (block byte 07H) from the stack.
6039
LD (HL),FFH 36 FF
Store FFH at (HL) (Register Pair HL = block byte 07H): the position of the last byte of that record.
603B
RET C9
RETURN to the caller with the file one character back.
603C
POP HL E1
Make the Value
Restore Register Pair HL (the end of the item in the buffer) from the stack. 5FDEH, 5FE4H, 5FEEH, 5FF9H, 5FFEH and 600BH jump here.
603D
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = the end of the item), which ends it. 605DH jumps here.
603F
LD HL,(40A7H) 2A A7 40
Fetch the input buffer pointer from 40A7H into Register Pair HL.
6042
DEC HL 2B
DECrement Register Pair HL by 1, to the byte before the item.
6043
LD A,E 7B
Copy the second end character from Register E into Register A.
6044
SUB 20H D6 20
SUBtract 20H from Register A: the Z FLAG is set for a number (a space).
6046
If the Z FLAG is set (a number), JUMP to 6050H.
6049
LD B,00H 06 00
Load Register B with 00H: the string ends only at the 00H stored above.
604B
GOSUB to the ROM's 2868H to make a temporary string of the text after Register Pair HL, with its descriptor in the accumulator.
604E
POP HL E1
Restore Register Pair HL (the program text) from the stack.
604F
RET C9
RETURN to the ROM's code pushed at 5F61H (2243H or 1F31H), which stores the string into the variable.
6050
RST 10H D7
Move Register Pair HL to the first character of the item with RST 10H, which leaves it in Register A. 6046H jumps here.
6051
GOSUB to the ROM's 0E6CH to turn the number text at Register Pair HL into a value in the accumulator.
6054
POP HL E1
Restore Register Pair HL (the program text) from the stack.
6055
RET C9
RETURN to the ROM's code at 2243H, which stores the number into the variable.

6056H - Store a Character of the Item

Register A = the character, Register Pair HL = the place in the buffer, Register B = the room left. A 00H is not stored. When 255 characters are stored, the item ends at once (603DH).

6056
OR A B7
OR Register A (the character) with itself: the Z FLAG is set for 00H. 5FA6H and 5FCDH call here.
6057
RET Z C8
If the Z FLAG is set (00H), RETURN without storing it.
6058
LD (HL),A 77
Store the character from Register A into (HL) (Register Pair HL = the place in the buffer).
6059
INC HL 23
INCrement Register Pair HL by 1, to the next place.
605A
DEC B 05
DECrement Register B (the room left) by 1: the Z FLAG is set when the buffer is full.
605B
RET NZ C0
If the NZ FLAG is set (room left), RETURN to the reader.
605C
POP BC C1
Restore Register Pair BC from the stack: this takes off the return address into the reader.
605D
JUMP to 603DH to end the item at Register Pair HL.

6060H - Open File 0

6060H opens file 0 for input (LOAD, RUN, MERGE), 6062H with the mode in Register D (SAVE, 02H). It joins OPEN at 6474H with the file name at Register Pair HL.

6060
LD D,01H 16 01
Load Register D with 01H, the mode of a file open for input. 6070H and 610AH call here.
6062
XOR A AF
Set Register A to ZERO with XOR A: file 0. 614AH calls here with Register D = 02H.
6063
JUMP to 6474H, inside OPEN, which saves Register Pair DE (the mode in Register D), finds file 0 and opens the named file.

6066H - RUN with a File Name, and LOAD

The ROM calls the link at 41C7H for RUN followed by something other than a line number (1EA6H); LOAD comes through 4188H to 606EH. File 0 is opened for input. NEW clears the old program; without R it also closes all files, with R the open files stay open (408EH is 0 during NEW). A file starting with FFH is a program saved in its tokenized form: it is read into memory from 40A4H and the ROM's CLEAR runs; RUN or R then starts it. Any other file is a program saved as text: its lines are read through the ROM's command loop (1A33H), and at the end 5A30H runs it or shows READY.

6066
RET C D8
If the CARRY FLAG is set (a digit after RUN, from the ROM's RST 10H), RETURN: the ROM runs from that line number. The link at 41C7H jumps here.
6067
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 1EA9H, so the ROM's own RUN does not go on.
6068
LD A,FFH 3E FF
Load Register A with FFH, the mark of RUN with a file name.
606A
LD (651FH),A 32 1F 65
Store Register A (FFH) into 651FH, which makes OPEN set bit 2 of 430FH (6497H-64A6H).
606D
OR AFH F6 AF
OR Register A with AFH: Register A stays FFH for RUN. The byte AFH at 606EH is XOR A, where LOAD enters, giving Register A = 00H.
606F
PUSH AF F5
Save Register Pair AF (Register A = FFH for RUN, 00H for LOAD) onto the stack.
6070
GOSUB to 6060H to open file 0 for input with the file name at Register Pair HL; it returns Register Pair HL = the text after the name.
6073
LD A,(408EH) 3A 8E 40
Fetch the number of files from 408EH into Register A.
6076
LD (5BB2H),A 32 B2 5B
Store Register A into 5BB2H, to be put back after NEW.
6079
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the character after the name again.
607A
RST 10H D7
Fetch it with RST 10H into Register A, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement.
607B
If the Z FLAG is set (nothing more), JUMP to 608BH.
607E
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
6080
RST 08H => 52H CF 52
Check that the next character at Register Pair HL is 52H, the letter R, with RST 08H; it leaves the Z FLAG set at the end of the statement.
6082
If the NZ FLAG is set (more after R), JUMP to the ROM's 1997H, the syntax error.
6085
POP AF F1
Restore Register Pair AF from the stack: the RUN or LOAD mark is not needed with R.
6086
XOR A AF
Set Register A to ZERO with XOR A, the number of files during NEW.
6087
LD (408EH),A 32 8E 40
Store Register A (00H) into 408EH: NEW then closes no file but file 0, so the open files stay open.
608A
OR F1H F6 F1
OR Register A with F1H: Register A = F1H, run after loading. The byte F1H at 608BH is POP AF, where 607BH enters to take the RUN or LOAD mark.
608C
LD (5BB1H),A 32 B1 5B
Store Register A into 5BB1H, the run flag: FFH for RUN, F1H with R, 00H for LOAD.
608F
LD HL,5A77H 21 77 5A
Point Register Pair HL to 5A77H, the stand-in block.
6092
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = 5A77H): its mode is closed.
6094
LD (5B8FH),HL 22 8F 5B
Store Register Pair HL (5A77H) into 5B8FH, the file table entry of file 0, so that NEW does not close the file just opened.
6097
GOSUB to the ROM's 1B4DH, NEW: the old program and the variables are cleared, and the files 0 to 408EH are closed through 41BBH.
609A
LD A,(5BB2H) 3A B2 5B
Fetch the number of files from 5BB2H, saved at 6076H, into Register A.
609D
LD (408EH),A 32 8E 40
Store Register A into 408EH: the number of files is back.
60A0
LD HL,(5BAFH) 2A AF 5B
Fetch the address of the real block of file 0 from 5BAFH into Register Pair HL.
60A3
LD (5B8FH),HL 22 8F 5B
Store Register Pair HL into 5B8FH: file 0 is its own block again.
60A6
LD (5B8DH),HL 22 8D 5B
Store Register Pair HL (the block of file 0) into 5B8DH: file 0 is the current file.
60A9
GOSUB to 63C4H to read the first byte of the file into Register A; the CARRY FLAG is set for an empty file.
60AC
If the CARRY FLAG is set (empty), JUMP to the ROM's 1A33H, its command loop, which meets the end of the file at once (5A30H).
60AF
INC A 3C
INCrement Register A by 1: the Z FLAG is set when the first byte is FFH, a tokenized program.
60B0
If the NZ FLAG is set (a program saved as text), JUMP to 6126H to give the byte back and read the lines.
60B3
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
60B6
EX DE,HL EB
Load Loop
Exchange Register Pairs DE and HL: Register Pair DE = the place for the next byte. 60C8H loops back here.
60B7
LD HL,(40A0H) 2A A0 40
Fetch the start of string space from 40A0H into Register Pair HL.
60BA
LD BC,FFAAH 01 AA FF
Load Register Pair BC with FFAAH, minus 86, the room kept free below string space.
60BD
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the highest place a byte may go.
60BE
RST 18H DF
Compare Register Pair HL (the limit) with Register Pair DE (the place) with RST 18H: the CARRY FLAG is set when the program does not fit.
60BF
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the place; EX does not change the flags.
60C0
If the CARRY FLAG is set (no room), JUMP to 6103H for NEW and OUT OF MEMORY.
60C3
GOSUB to 63C4H to read the next byte of the file into Register A; the CARRY FLAG is set at the end of the file.
60C6
LD (HL),A 77
Store Register A into (HL), Register Pair HL = the place in the program text.
60C7
INC HL 23
INCrement Register Pair HL by 1, to the next place.
60C8
Load Loop End
If the NO CARRY FLAG is set (more bytes), JUMP to 60B6H.
60CB
GOSUB to the ROM's 1AF8H to set the link of every line from 40A4H on; Register Pair HL returns at the second byte of the 0000H link that ends the program.
60CE
INC HL 23
INCrement Register Pair HL by 1, past the end of the program.
60CF
INC HL 23
INCrement Register Pair HL by 1 again: the first byte after the program.
60D0
LD (40F9H),HL 22 F9 40
Store Register Pair HL into 40F9H, the start of the variables after the program.
60D3
LD HL,408EH 21 8E 40
Point Register Pair HL to 408EH, the number of files.
60D6
LD A,(HL) 7E
Fetch the number of files from (HL) (Register Pair HL = 408EH) into Register A.
60D7
LD (5BB2H),A 32 B2 5B
Store Register A into 5BB2H, to be put back after the CLEAR.
60DA
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = 408EH): the CLEAR closes only file 0, the program file.
60DC
GOSUB to the ROM's 1B5DH, its CLEAR (the RUN preparation), which clears the variables and closes file 0 through 41BBH.
60DF
LD A,(5BB2H) 3A B2 5B
Fetch the number of files from 5BB2H into Register A.
60E2
LD (408EH),A 32 8E 40
Store Register A into 408EH: the number of files is back.
60E5
LD A,(5BB1H) 3A B1 5B
Fetch the run flag from 5BB1H into Register A.
60E8
OR A B7
OR Register A with itself: the Z FLAG is set for LOAD without R.
60E9
If the Z FLAG is set (LOAD), JUMP to the ROM's 1A19H, READY.
60EC
JUMP to the ROM's 1D1EH, its statement loop, which starts the program from its first line.

60EFH - End of LOAD, MERGE or SAVE: Close File 0

The ROM calls the link at 41ACH as it returns to READY (1A1CH); 5A51H calls here at the end of a LOAD or MERGE, and SAVE and MERGE jump here. Ends output to the cassette or printer (ROM 2169H, which also clears the current file), closes file 0, and at READY calls 64F2H. Returns with Register Pair HL = the text pointer from 40DFH (ROM 1BAFH).

60EF
GOSUB to the ROM's 2169H, which stops the cassette if it was in use, sets output to the screen and calls 41BEH (no current file); Register A returns 00H. The link at 41ACH jumps here.
60F2
GOSUB to 62DDH to close file 0 (Register A = 00H).
60F5
POP HL E1
Restore Register Pair HL from the stack: the return address.
60F6
PUSH DE D5
Save Register Pair DE onto the stack while it holds 1A1FH.
60F7
LD DE,1A1FH 11 1F 1A
Point Register Pair DE to 1A1FH, the return address of READY's call to 41ACH.
60FA
RST 18H DF
Compare Register Pair HL (the return address) with Register Pair DE (1A1FH) with RST 18H: the Z FLAG is set at READY.
60FB
POP DE D1
Restore Register Pair DE (the caller's value) from the stack.
60FC
PUSH HL E5
Save Register Pair HL (the return address) onto the stack again.
60FD
If the Z FLAG is set (at READY), GOSUB to 64F2H, which clears memory when a protected program was loaded.
6100
JUMP to the ROM's 1BAFH, which loads Register Pair HL from 40DFH and returns.
6103
No Room
GOSUB to the ROM's 1B4DH, NEW, to clear what was loaded. 60C0H jumps here.
6106
JUMP to the ROM's 197AH, OUT OF MEMORY, as the program does not fit.

6109H - MERGE

The ROM's statement table sends MERGE to 418BH, and from there here. Opens file 0 for input. A file saved in tokenized form (first byte FFH) gives Bad file mode; a text file's lines are read through the ROM's command loop and go in among the lines already there.

6109
POP BC C1
Restore Register Pair BC from the stack: this takes off the return address into the ROM's statement loop, as MERGE goes on in the command loop.
610A
GOSUB to 6060H to open file 0 for input with the file name at Register Pair HL; Register Pair HL returns after the name.
610D
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the character after the name again.
610E
RST 10H D7
Fetch it with RST 10H into Register A, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement.
610F
If the Z FLAG is set (nothing more), JUMP to 6118H.
6112
GOSUB to 60EFH to close file 0 again, as the statement is wrong.
6115
JUMP to the ROM's 1997H, the syntax error for the text after the name.
6118
XOR A AF
Set Register A to ZERO with XOR A. 610FH jumps here.
6119
LD (5BB1H),A 32 B1 5B
Store Register A (00H) into 5BB1H: the program is not run at the end.
611C
GOSUB to 63C4H to read the first byte of the file into Register A; the CARRY FLAG is set for an empty file.
611F
If the CARRY FLAG is set (empty), JUMP to the ROM's 1A33H, its command loop.
6122
INC A 3C
INCrement Register A by 1: the Z FLAG is set when the first byte is FFH.
6123
If the Z FLAG is set (a tokenized program), JUMP to 6547H, Bad file mode.
6126
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer (the block of file 0) from 5B8DH into Register Pair HL. 60B0H jumps here.
6129
LD BC,0007H 01 07 00
Load Register Pair BC with 0007H, the offset of the FCB's byte position in the block.
612C
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = block byte 07H.
612D
GOSUB to 600EH to give the first byte back to the file.
6130
JUMP to the ROM's 1A33H, its command loop, which reads the lines from the file (59EAH and 5A30H).

6133H - A Direct Statement Typed or Read

The ROM calls the link at 41B2H after a line has been tokenized (1AA1H), with the CARRY FLAG set for a line with a number. A line without a number read from a file gives Direct statement in file (84H). One typed at the keyboard is run after 64F2H.

6133
RET C D8
If the CARRY FLAG is set (a numbered line), RETURN: the ROM puts it into the program. The link at 41B2H jumps here.
6134
POP AF F1
Restore Register Pair AF from the stack: this takes off the return address 1AA4H.
6135
PUSH HL E5
Save Register Pair HL (the tokenized line) onto the stack.
6136
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
6139
LD A,H 7C
Copy Register H (the high byte of the pointer) into Register A.
613A
OR L B5
OR Register A with Register L: the NZ FLAG is set when the line came from a file.
613B
LD DE,0084H 11 84 00
Load Register Pair DE with 0084H: Register E = 84H, Direct statement in file.
613E
If the NZ FLAG is set (from a file), JUMP to the ROM's 19A2H, its error handler, with the error code in Register E.
6141
POP HL E1
Restore Register Pair HL (the tokenized line) from the stack.
6142
GOSUB to 64F2H, which clears memory when a protected program was loaded.
6145
JUMP to the ROM's 1D5AH, which runs the direct statement at Register Pair HL.

6148H - SAVE

The ROM's statement table sends SAVE to 41A0H, and from there here. Opens file 0 for output. SAVE "name" writes FFH and the program text as it is in memory; SAVE "name",A sends the program through the ROM's LIST into the file as text (the rest of the statement goes to LIST as its line range). File 0 is closed at the end (60EFH, or READY for LIST).

6148
LD D,02H 16 02
Load Register D with 02H, the mode of a file open for output.
614A
GOSUB to 6062H to open file 0 for output with the file name at Register Pair HL; Register Pair HL returns after the name.
614D
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the character after the name again.
614E
RST 10H D7
Fetch it with RST 10H into Register A, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement.
614F
If the Z FLAG is set (no A), JUMP to 6159H for the tokenized form.
6152
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
6154
RST 08H => 41H CF 41
Check that the next character at Register Pair HL is 41H, the letter A, with RST 08H.
6156
JUMP to the ROM's 2B2EH, LIST, which sends the program as text to the current file, file 0.
6159
LD A,FFH 3E FF
Load Register A with FFH, the first byte of a tokenized program file. 614FH jumps here.
615B
GOSUB to 631CH to put Register A (FFH) into file 0.
615E
LD HL,(40F9H) 2A F9 40
Fetch the start of the variables (the end of the program) from 40F9H into Register Pair HL.
6161
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the end of the program.
6162
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
6165
RST 18H DF
Save Loop
Compare Register Pair HL (the next byte) with Register Pair DE (the end) with RST 18H: the Z FLAG is set when all is written. 6170H loops back here.
6166
If the Z FLAG is set (done), JUMP to 60EFH to close file 0.
6169
LD A,(HL) 7E
Fetch the next byte of the program from (HL) (Register Pair HL = its address) into Register A.
616A
INC HL 23
INCrement Register Pair HL by 1, to the next byte.
616B
PUSH DE D5
Save Register Pair DE (the end of the program) onto the stack.
616C
GOSUB to 631CH to put Register A into file 0.
616F
POP DE D1
Restore Register Pair DE (the end of the program) from the stack.
6170
Save Loop End
JUMP to 6165H for the next byte.

6173H - CLOSE

The ROM's statement table sends CLOSE to 4185H, and from there here, with the Z FLAG set when nothing follows CLOSE. CLOSE alone closes every file from the number in 408EH down to 0; CLOSE n,m closes the files listed (# is allowed before each). Each file is closed by 62DDH, called through a RET with 618DH or 6185H as the return.

6173
LD BC,62DDH 01 DD 62
Load Register Pair BC with 62DDH, the routine that closes the file in Register A.
6176
LD A,(408EH) 3A 8E 40
Fetch the number of files from 408EH into Register A; LD does not change the flags.
6179
If the NZ FLAG is set (file numbers follow), JUMP to 6194H.
617C
PUSH HL E5
Save Register Pair HL (the text) onto the stack.
617D
PUSH BC C5
All Files Loop
Save Register Pair BC (62DDH) onto the stack. 6188H loops back here.
617E
PUSH AF F5
Save Register Pair AF (Register A = the file to close) onto the stack.
617F
LD DE,6185H 11 85 61
Point Register Pair DE to 6185H, where the close returns to.
6182
PUSH DE D5
Save Register Pair DE (6185H) onto the stack, the return address.
6183
PUSH BC C5
Save Register Pair BC (62DDH) onto the stack.
6184
RET C9
RETURN, which jumps to 62DDH to close the file in Register A, returning to 6185H.
6185
POP AF F1
Restore Register Pair AF (Register A = the file just closed) from the stack.
6186
POP BC C1
Restore Register Pair BC (62DDH) from the stack.
6187
DEC A 3D
DECrement Register A by 1, to the next file down.
6188
All Files Loop End
If the SIGN FLAG is clear (file 0 not yet done), JUMP to 617DH.
618B
POP HL E1
Restore Register Pair HL (the text) from the stack.
618C
RET C9
RETURN to the caller (the statement loop or 61ABH) with all files closed.
618D
POP BC C1
After One File
Restore Register Pair BC (62DDH) from the stack. The close at 61A4H returns here.
618E
POP HL E1
Restore Register Pair HL (the text after the file number) from the stack.
618F
LD A,(HL) 7E
Fetch the character after the file number from (HL) (Register Pair HL = the text) into Register A.
6190
CP 2CH FE 2C
Compare Register A (the character after the number) against 2CH, a comma.
6192
RET NZ C0
If the NZ FLAG is set (no more numbers), RETURN to the statement loop.
6193
RST 10H D7
Move Register Pair HL past the comma with RST 10H, which leaves the next character in Register A.
6194
PUSH BC C5
One File
Save Register Pair BC (62DDH) onto the stack. 6179H jumps here.
6195
LD A,(HL) 7E
Fetch the next character from (HL) (Register Pair HL = the text) into Register A.
6196
CP 23H FE 23
Compare Register A against 23H, the character #.
6198
If the Z FLAG is set (a #), GOSUB to the ROM's 1D78H, the RST 10H code, to move Register Pair HL past it.
619B
GOSUB to the ROM's 2B1CH to evaluate the file number at Register Pair HL as a byte in Register A.
619E
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = 62DDH, and the text is kept on the stack.
619F
PUSH HL E5
Save Register Pair HL (62DDH) onto the stack.
61A0
LD DE,618DH 11 8D 61
Point Register Pair DE to 618DH, where the close returns to.
61A3
PUSH DE D5
Save Register Pair DE (618DH) onto the stack, the return address.
61A4
JP (HL) E9
JUMP to the address in Register Pair HL, 62DDH, to close the file in Register A.

61A5H - Close All Files

The ROM calls the link at 41BBH from NEW (1B8CH, also part of its CLEAR) and from END (1DB0H). Closes files 0 to the number in 408EH through CLOSE with the Z FLAG set, and returns Register A = 00H with the Z FLAG set.

61A5
PUSH DE D5
Save Register Pair DE (the ROM's value) onto the stack. The link at 41BBH jumps here.
61A6
PUSH BC C5
Save Register Pair BC (the ROM's value) onto the stack.
61A7
XOR A AF
Set Register A to ZERO with XOR A, which sets the Z FLAG that 6179H tests: all files.
61A8
GOSUB to 6173H, CLOSE, to close every file from 408EH down to 0.
61AB
POP BC C1
Restore Register Pair BC (the ROM's value) from the stack.
61AC
POP DE D1
Restore Register Pair DE (the ROM's value) from the stack.
61AD
XOR A AF
Set Register A to ZERO with XOR A, which sets the Z FLAG for the ROM.
61AE
RET C9
RETURN to the ROM's NEW or END with Register A = 00H.

61AFH - FIELD

The ROM's statement table sends FIELD to 417CH, and from there here. FIELD #n, w AS A$, w AS B$ ... makes each string variable describe the next w bytes of the file's record buffer at block byte 22H on, without copying anything. The file must be open for random access (mode 03H). The widths together may not go past the record length (block byte 0BH, the FCB's record length; 00H means 256) nor past 256: FIELD overflow (655CH).

61AF
GOSUB to 5EDBH to read the file number: Register Pair BC = the file's block, Register A = its mode, the Z FLAG for a closed file.
61B2
If the Z FLAG is set (closed), JUMP to 654AH, Bad file number.
61B5
SUB 03H D6 03
SUBtract 03H from Register A (the mode): zero for a random file.
61B7
If the NZ FLAG is set (not random), JUMP to 6547H, Bad file mode.
61BA
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the text.
61BB
LD HL,000BH 21 0B 00
Load Register Pair HL with 000BH, the offset of the record length in the block (FCB byte 09H).
61BE
ADD HL,BC 09
ADD Register Pair BC (the block) to Register Pair HL: Register Pair HL = block byte 0BH.
61BF
LD A,(HL) 7E
Fetch the record length from (HL) (Register Pair HL = block byte 0BH) into Register A.
61C0
LD (651EH),A 32 1E 65
Store Register A (the record length) into 651EH, for the test at 61ECH.
61C3
XOR A AF
Set Register A to ZERO with XOR A: no bytes given to fields yet.
61C4
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the text.
61C5
LD DE,0022H 11 22 00
Load Register Pair DE with 0022H, the offset of the buffer in the block.
61C8
EX DE,HL EB
Field Loop
Exchange Register Pairs DE and HL: Register Pair HL = the offset (first time) or the place of the last field, Register Pair DE = the text. 6201H and 6207H jump here.
61C9
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: the block plus 22H the first time, the last field's place plus its width later.
61CA
LD B,A 47
Copy Register A (the bytes given so far) into Register B.
61CB
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the place for the next field, Register Pair HL = the text.
61CC
LD A,(HL) 7E
Fetch the next character from (HL) (Register Pair HL = the text) into Register A.
61CD
CP 2CH FE 2C
Compare Register A (the character after the file number or the last field) against 2CH, a comma.
61CF
RET NZ C0
If the NZ FLAG is set (no more fields), RETURN to the statement loop.
61D0
PUSH DE D5
Save Register Pair DE (the place for this field) onto the stack.
61D1
PUSH BC C5
Save Register Pair BC (Register B = the bytes given so far) onto the stack.
61D2
GOSUB to the ROM's 2B1BH to move past the comma and evaluate the width as a byte in Register A.
61D5
PUSH AF F5
Save Register Pair AF (Register A = the width) onto the stack.
61D6
RST 08H => 41H CF 41
Check that the next character at Register Pair HL is 41H, the letter A, with RST 08H.
61D8
RST 08H => 53H CF 53
Check that the next character at Register Pair HL is 53H, the letter S, with RST 08H: the word AS.
61DA
GOSUB to the ROM's 260DH to find or create the variable named at Register Pair HL: Register Pair DE = its descriptor.
61DD
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the variable is a string.
61E0
POP AF F1
Restore Register Pair AF (Register A = the width) from the stack.
61E1
POP BC C1
Restore Register Pair BC (Register B = the bytes given so far) from the stack.
61E2
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the place for this field, and the text is kept on the stack.
61E3
LD C,A 4F
Copy the width from Register A into Register C.
61E4
ADD A,B 80
ADD Register B (the bytes given so far) to Register A: the new total, the CARRY FLAG set past 255.
61E5
If the NO CARRY FLAG is set (256 bytes or fewer so far), JUMP to 61EBH.
61E8
If the NZ FLAG is set (past 256), JUMP to 655CH, FIELD overflow; exactly 256 gives 00H with the Z FLAG and is allowed.
61EB
LD B,A 47
Copy the new total from Register A into Register B. 61E5H jumps here.
61EC
LD A,(651EH) 3A 1E 65
Fetch the record length from 651EH into Register A.
61EF
CP B B8
Compare Register A (the record length) against Register B (the total): the NO CARRY FLAG is set when the fields fit.
61F0
If the NO CARRY FLAG is set (within the record length), JUMP to 61F6H.
61F2
OR A B7
OR Register A (the record length) with itself: the Z FLAG is set for 00H, 256 bytes.
61F3
If the NZ FLAG is set (a record length the fields go past), JUMP to 655CH, FIELD overflow.
61F6
LD A,B 78
Copy the total from Register B into Register A. 61F0H jumps here.
61F7
OR A B7
OR Register A with itself: the Z FLAG is set when exactly 256 bytes are given.
61F8
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the variable's descriptor, Register Pair DE = the place for the field.
61F9
LD (HL),C 71
Store the width from Register C into (HL) (Register Pair HL = the descriptor), the string's length.
61FA
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
61FB
LD (HL),E 73
Store Register E (the low byte of the field's place) into (HL) (Register Pair HL = descriptor byte 1).
61FC
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
61FD
LD (HL),D 72
Store Register D (the high byte of the field's place) into (HL) (Register Pair HL = descriptor byte 2): the variable now describes the field.
61FE
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the width, to add at 61C9H.
6200
POP HL E1
Restore Register Pair HL (the text) from the stack.
6201
If the NZ FLAG is set (less than 256 given), JUMP to 61C8H for the next field.
6204
LD A,C 79
Copy the width from Register C into Register A.
6205
OR A B7
OR Register A with itself: the NZ FLAG is set unless the width was 0.
6206
RET NZ C0
If the NZ FLAG is set (the 256 bytes are used up), RETURN to the statement loop; a further field gives a syntax error there.
6207
JUMP to 61C8H for the next field with Register A = 00H.

620AH - LSET and RSET

The ROM's statement table sends LSET to 4197H and RSET to 419AH, and from there to 620BH and 620AH. LSET A$=B$ or RSET A$=B$ copies B$ into the space A$ already has (normally a field), without changing A$'s length: LSET puts it at the left and fills the rest with spaces, RSET at the right with spaces before it; extra characters of B$ are left out. A string variable whose text lies inside the program (assigned from a constant) gets a copy in string space first, so that the program is not changed.

620A
OR 37H F6 37
OR Register A with 37H: for RSET the CARRY FLAG is clear. The byte 37H at 620BH is SCF, where LSET enters, setting the CARRY FLAG.
620C
PUSH AF F5
Save Register Pair AF (the CARRY FLAG: set for LSET, clear for RSET) onto the stack.
620D
GOSUB to the ROM's 260DH to find or create the variable named at Register Pair HL: Register Pair DE = its descriptor.
6210
GOSUB to the ROM's 0AF4H, which gives TYPE MISMATCH unless the variable is a string.
6213
PUSH DE D5
Save Register Pair DE (A$'s descriptor) onto the stack.
6214
RST 08H => D5H CF D5
Check that the next character at Register Pair HL is D5H, the = token, with RST 08H.
6216
GOSUB to the ROM's 2337H to evaluate B$ at Register Pair HL.
6219
POP BC C1
Restore Register Pair BC (A$'s descriptor) from the stack.
621A
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the LSET or RSET flags, and the text is kept on the stack.
621B
PUSH HL E5
Save Register Pair HL (the flags) onto the stack.
621C
PUSH BC C5
Save Register Pair BC (A$'s descriptor) onto the stack.
621D
GOSUB to the ROM's 29D7H, which checks that B$ is a string, releases its temporary and returns Register Pair HL = its descriptor.
6220
LD B,(HL) 46
Fetch the length of B$ from (HL) (Register Pair HL = B$'s descriptor) into Register B.
6221
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): Register Pair HL = A$'s descriptor, and B$'s descriptor is kept.
6222
LD A,(HL) 7E
Fetch the length of A$ from (HL) (Register Pair HL = A$'s descriptor) into Register A.
6223
LD C,A 4F
Copy the length of A$ from Register A into Register C.
6224
PUSH BC C5
Save Register Pair BC (Register B = B$'s length, Register C = A$'s length) onto the stack.
6225
PUSH HL E5
Save Register Pair HL (A$'s descriptor) onto the stack.
6226
PUSH AF F5
Save Register Pair AF (Register A = A$'s length) onto the stack.
6227
INC HL 23
INCrement Register Pair HL by 1, to the address word of A$'s descriptor.
6228
LD E,(HL) 5E
Fetch the low byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register E.
6229
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
622A
LD D,(HL) 56
Fetch the high byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = A$'s text.
622B
OR A B7
OR Register A (A$'s length) with itself: the Z FLAG is set when A$ is empty.
622C
If the Z FLAG is set (nothing to fill), JUMP to 628CH.
622F
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
6232
RST 18H DF
Compare Register Pair HL (the program start) with Register Pair DE (A$'s text) with RST 18H: the NO CARRY FLAG is set when A$ lies below the program (in a file block).
6233
If the NO CARRY FLAG is set, JUMP to 6265H to fill A$ where it is.
6236
LD HL,(40F9H) 2A F9 40
Fetch the start of the variables from 40F9H into Register Pair HL.
6239
RST 18H DF
Compare Register Pair HL (the end of the program) with Register Pair DE (A$'s text) with RST 18H: the CARRY FLAG is set when A$ lies above the program.
623A
If the CARRY FLAG is set, JUMP to 6265H to fill A$ where it is.
623D
LD E,C 59
Copy A$'s length from Register C into Register E: A$'s text is inside the program and needs a copy.
623E
LD D,00H 16 00
Load Register D with 00H: Register Pair DE = A$'s length.
6240
LD HL,(40A0H) 2A A0 40
Fetch the start of string space from 40A0H into Register Pair HL.
6243
ADD HL,DE 19
ADD Register Pair DE (the length) to Register Pair HL.
6244
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the start of string space plus the length.
6245
LD HL,(40D6H) 2A D6 40
Fetch the string space pointer from 40D6H into Register Pair HL.
6248
GOSUB to the ROM's 1C90H, the RST 18H code, to compare Register Pair HL with Register Pair DE: the CARRY FLAG is set when string space is short.
624B
If the CARRY FLAG is set (string space short), JUMP to 62A0H.
624E
POP AF F1
Restore Register Pair AF (A$'s length) from the stack. 62B5H jumps here.
624F
LD A,C 79
Copy A$'s length from Register C into Register A.
6250
GOSUB to the ROM's 28BFH to take Register A bytes of string space (collecting garbage when needed): Register Pair DE = the new space.
6253
POP HL E1
Restore Register Pair HL (A$'s descriptor) from the stack.
6254
POP BC C1
Restore Register Pair BC (the two lengths) from the stack.
6255
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): A$'s descriptor goes onto the stack, Register Pair HL = the word that was there.
6256
PUSH DE D5
Save Register Pair DE (the new space) onto the stack.
6257
PUSH BC C5
Save Register Pair BC (the two lengths) onto the stack.
6258
GOSUB to the ROM's 29D7H to take B$'s descriptor from the accumulator again (garbage collection may have moved its text): Register Pair HL = B$'s descriptor.
625B
POP BC C1
Restore Register Pair BC (the two lengths) from the stack.
625C
POP DE D1
Restore Register Pair DE (the new space) from the stack.
625D
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): Register Pair HL = A$'s descriptor, and B$'s descriptor is kept.
625E
PUSH BC C5
Save Register Pair BC (the two lengths) onto the stack.
625F
PUSH HL E5
Save Register Pair HL (A$'s descriptor) onto the stack.
6260
INC HL 23
INCrement Register Pair HL by 1, to the address word of A$'s descriptor.
6261
LD (HL),E 73
Store Register E (the low byte of the new space) into (HL) (Register Pair HL = descriptor byte 1).
6262
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6263
LD (HL),D 72
Store Register D (the high byte of the new space) into (HL) (Register Pair HL = descriptor byte 2): A$ now lies in string space.
6264
PUSH AF F5
Save Register Pair AF onto the stack, for the POP at 6265H.
6265
POP AF F1
Restore Register Pair AF from the stack (A$'s length, or the value pushed at 6264H). 6233H and 623AH jump here.
6266
POP HL E1
Restore Register Pair HL (A$'s descriptor) from the stack.
6267
INC HL 23
INCrement Register Pair HL by 1, to the address word of A$'s descriptor.
6268
LD E,(HL) 5E
Fetch the low byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register E.
6269
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
626A
LD D,(HL) 56
Fetch the high byte of A$'s address from (HL) (Register Pair HL = the descriptor) into Register D: Register Pair DE = A$'s text, the destination.
626B
POP BC C1
Restore Register Pair BC (Register B = B$'s length, Register C = A$'s length) from the stack.
626C
POP HL E1
Restore Register Pair HL (B$'s descriptor) from the stack.
626D
PUSH DE D5
Save Register Pair DE (the destination) onto the stack.
626E
INC HL 23
INCrement Register Pair HL by 1, to the address word of B$'s descriptor.
626F
LD E,(HL) 5E
Fetch the low byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register E.
6270
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6271
LD D,(HL) 56
Fetch the high byte of B$'s address from (HL) (Register Pair HL = the descriptor) into Register D.
6272
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = B$'s text, the source.
6273
POP DE D1
Restore Register Pair DE (the destination) from the stack.
6274
LD A,C 79
Copy A$'s length from Register C into Register A.
6275
CP B B8
Compare Register A (A$'s length) against Register B (B$'s length): the NO CARRY FLAG is set when all of B$ fits.
6276
If the NO CARRY FLAG is set, JUMP to 627AH with Register B = B$'s length as the count.
6279
LD B,A 47
Copy A$'s length from Register A into Register B: only that much of B$ is copied.
627A
SUB B 90
SUBtract Register B (the count) from Register A (A$'s length): the spaces to fill. 6276H jumps here.
627B
LD C,A 4F
Copy the spaces to fill from Register A into Register C.
627C
POP AF F1
Restore Register Pair AF (the CARRY FLAG: set for LSET, clear for RSET) from the stack.
627D
If the NO CARRY FLAG is set (RSET), GOSUB to 6296H to store Register C spaces first.
6280
INC B 04
Copy Loop
INCrement Register B (the count) by 1, which with the DEC below only tests it. 6289H jumps here.
6281
DEC B 05
DECrement Register B by 1: the Z FLAG is set when nothing is left to copy.
6282
If the Z FLAG is set (all copied), JUMP to 6291H for the spaces after it.
6285
LD A,(HL) 7E
Fetch the next character of B$ from (HL) (Register Pair HL = the source) into Register A.
6286
LD (DE),A 12
Store the character from Register A into (DE) (Register Pair DE = the destination).
6287
INC HL 23
INCrement Register Pair HL by 1, to the next character of B$.
6288
INC DE 13
INCrement Register Pair DE by 1, to the next place in A$.
6289
Copy Loop End
JUMP to 6281H to count down the next character.
628C
POP BC C1
Restore Register Pair BC from the stack: A$'s length, not needed. 622CH jumps here with A$ empty.
628D
POP BC C1
Restore Register Pair BC from the stack: A$'s descriptor, not needed.
628E
POP BC C1
Restore Register Pair BC from the stack: the two lengths, not needed.
628F
POP BC C1
Restore Register Pair BC from the stack: B$'s descriptor, not needed.
6290
POP BC C1
Restore Register Pair BC from the stack: the LSET or RSET flags; the CARRY FLAG is still the one OR A cleared at 622BH.
6291
If the CARRY FLAG is set (LSET after the copy), GOSUB to 6296H to store Register C spaces after it. 6282H jumps here.
6294
POP HL E1
Restore Register Pair HL (the text after the statement) from the stack.
6295
RET C9
RETURN to the statement loop with Register Pair HL = the text after the statement.

6296H - Store Spaces

Register C = the number of spaces, Register Pair DE = where. Stores the spaces and returns with Register Pair DE after them.

6296
LD A,20H 3E 20
Load Register A with 20H, a space. Called by 627DH and 6291H.
6298
INC C 0C
Space Loop
INCrement Register C (the spaces left) by 1, which with the DEC below only tests it. 629DH jumps here.
6299
DEC C 0D
DECrement Register C by 1: the Z FLAG is set when no space is left to store.
629A
RET Z C8
If the Z FLAG is set (no spaces left), RETURN to the caller with Register Pair DE after them.
629B
LD (DE),A 12
Store the space from Register A into (DE) (Register Pair DE = the place in A$).
629C
INC DE 13
INCrement Register Pair DE by 1, to the next place.
629D
Space Loop End
JUMP to 6299H for the next space.

62A0H - LSET and RSET with String Space Short

624BH jumps here when string space may be too small for the copy of A$. The stack is set up again as 624EH expects, with A$'s address in place of B$'s descriptor (6258H fetches that descriptor again after the garbage collection), and 624EH takes the space. The flags tested at 62A5H are those of the Register Pair AF popped at 62A0H, pushed at 6226H: the flags 29D7H left at 621DH, the Z FLAG when B$ was the newest temporary string and its text the last string allocated. Only then do 62A8H-62B0H run, and their CALL 2884H goes wrong: 2884H is written to be jumped to with the text pointer on the stack, so its POP HL takes this CALL's return address and its RET goes to the address formed by Register Pair BC (the two lengths) pushed at 62A8H.

62A0
POP AF F1
Restore Register Pair AF (Register A = A$'s length, with the flags 29D7H left at 621DH) from the stack.
62A1
POP HL E1
Restore Register Pair HL (A$'s descriptor) from the stack.
62A2
POP BC C1
Restore Register Pair BC (the two lengths) from the stack.
62A3
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = B$'s descriptor, and A$'s descriptor goes onto the stack.
62A4
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = A$'s address, Register Pair DE = B$'s descriptor.
62A5
If the NZ FLAG is set (from 29D7H: B$ was not the newest string), JUMP to 62B1H.
62A8
PUSH BC C5
Save Register Pair BC (Register B = B$'s length, Register C = A$'s length) onto the stack.
62A9
LD A,B 78
Copy B$'s length from Register B into Register A, the length of the string to make room for.
62AA
GOSUB to the ROM's 2857H to make room for a string of Register A bytes, with its descriptor at 40D3H.
62AD
GOSUB to the ROM's 2884H, which makes the descriptor at 40D3H a temporary string and then executes POP HL and RET NZ: the POP takes this CALL's return address 62B0H, and the RET goes to the address in the Register Pair BC pushed at 62A8H.
62B0
POP BC C1
Restore Register Pair BC (the two lengths) from the stack; 2884H does not return here (see 62ADH).
62B1
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (Stack Pointer, SP): Register Pair HL = A$'s descriptor, and A$'s address goes onto the stack. 62A5H jumps here.
62B2
PUSH BC C5
Save Register Pair BC (the two lengths) onto the stack.
62B3
PUSH HL E5
Save Register Pair HL (A$'s descriptor) onto the stack.
62B4
PUSH AF F5
Save Register Pair AF (A$'s length) onto the stack.
62B5
JUMP to 624EH to take the string space and go on.

62B8H - EOF

The ROM's function table sends EOF to 4161H, and from there here. EOF(n) gives -1 at the end of file n and 0 otherwise: at the end means that the next record number (block bytes 0CH-0DH) equals the ending record number (bytes 0EH-0FH) and the byte position (byte 07H) equals the end-of-file byte (byte 0AH). When the record numbers differ, the differing byte of the ending record number is tested instead, which gives -1 only when that byte is 00H. A file open for output gives Bad file mode.

62B8
GOSUB to 5EE5H to take the file number from the accumulator: Register Pair BC = the file's block, Register A = its mode.
62BB
CP 02H FE 02
Compare Register A (the mode) against 02H, a file open for output.
62BD
If the Z FLAG is set (output), JUMP to 6547H, Bad file mode.
62C0
LD HL,000FH 21 0F 00
Load Register Pair HL with 000FH, the offset of the high byte of the ending record number (FCB byte 0DH).
62C3
ADD HL,BC 09
ADD Register Pair BC (the block) to Register Pair HL: Register Pair HL = block byte 0FH.
62C4
LD A,(HL) 7E
Fetch the high byte of the ending record number from (HL) (Register Pair HL = block byte 0FH) into Register A.
62C5
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 0EH.
62C6
LD E,(HL) 5E
Fetch the low byte of the ending record number from (HL) (Register Pair HL = block byte 0EH) into Register E.
62C7
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 0DH, the high byte of the next record number.
62C8
CP (HL) BE
Compare Register A (the high byte of the ending record) against (HL) (Register Pair HL = block byte 0DH).
62C9
If the NZ FLAG is set (they differ), JUMP to 62D7H with Register A = the ending record's high byte.
62CB
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 0CH, the low byte of the next record number.
62CC
LD A,E 7B
Copy the low byte of the ending record number from Register E into Register A.
62CD
CP (HL) BE
Compare Register A against (HL) (Register Pair HL = block byte 0CH).
62CE
If the NZ FLAG is set (they differ), JUMP to 62D7H with Register A = the ending record's low byte.
62D0
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 0BH.
62D1
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 0AH, the end-of-file byte (FCB byte 08H).
62D2
LD A,(HL) 7E
Fetch the end-of-file byte from (HL) (Register Pair HL = block byte 0AH) into Register A.
62D3
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 09H.
62D4
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 08H.
62D5
DEC HL 2B
DECrement Register Pair HL by 1, to block byte 07H, the byte position (FCB byte 05H).
62D6
SUB (HL) 96
SUBtract the byte position at (HL) (Register Pair HL = block byte 07H) from Register A (the end-of-file byte): 00H at the end.
62D7
SUB 01H D6 01
SUBtract 01H from Register A: the CARRY FLAG is set only when Register A was 00H. 62C9H and 62CEH jump here.
62D9
SBC A,A 9F
SUBtract Register A from itself with the CARRY FLAG: FFH at the end, 00H otherwise.
62DA
JUMP to the ROM's 098DH, which makes Register A a signed integer in the accumulator (-1 or 0).

62DDH - Close the File in Register A

Register A = the file number. A closed file is left alone. A file open for input is only cleared; any other is marked closed and closed by the DOS (4428H), which writes its last sector and its directory entry. Then bytes 00H-21H of the block (mode, column, FCB) are cleared.

62DD
GOSUB to 5EE8H to find the block of file Register A: Register Pair BC = the block, Register A = its mode, the Z FLAG for a closed file. Called by 60F2H and through 6173H.
62E0
RET Z C8
If the Z FLAG is set (closed), RETURN: there is nothing to close.
62E1
CP 01H FE 01
Compare Register A (the mode) against 01H, a file open for input.
62E3
If the Z FLAG is set (input), JUMP to 62F4H: there is nothing to write.
62E6
PUSH BC C5
Save Register Pair BC (the block) onto the stack.
62E7
XOR A AF
Set Register A to ZERO with XOR A, the mode of a closed file.
62E8
LD (BC),A 02
Store Register A (00H) into (BC), Register Pair BC = the block's mode byte.
62E9
INC BC 03
INCrement Register Pair BC by 1, to block byte 01H.
62EA
INC BC 03
INCrement Register Pair BC by 1, to block byte 02H, the FCB.
62EB
LD D,B 50
Copy Register B (the high byte of the FCB address) into Register D.
62EC
LD E,C 59
Copy Register C (the low byte) into Register E: Register Pair DE = the FCB.
62ED
GOSUB to SYS0/SYS's 4428H to close the file in the FCB at Register Pair DE.
62F0
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
62F3
POP BC C1
Restore Register Pair BC (the block) from the stack.
62F4
LD D,22H 16 22
Load Register D with 22H, the 34 bytes of mode, column and FCB. 62E3H jumps here.
62F6
XOR A AF
Set Register A to ZERO with XOR A, the value to clear with.
62F7
LD (BC),A 02
Clear Loop
Store Register A (00H) into (BC), Register Pair BC = the next byte of the block. 62FAH loops back here.
62F8
INC BC 03
INCrement Register Pair BC by 1, to the next byte.
62F9
DEC D 15
DECrement Register D (the bytes left) by 1: the Z FLAG is set after the last one.
62FA
Clear Loop End
If the NZ FLAG is set, LOOP BACK to 62F7H.
62FD
RET C9
RETURN to the caller with the file closed and its block cleared.

62FEH - LOC and LOF

The ROM's function table sends LOC to 4164H and LOF to 4167H, and from there to 62FEH and 630FH. LOF(n) gives the ending record number of file n (block bytes 0EH-0FH). LOC was meant to give the next record number (bytes 0CH-0DH), but its first instruction calls 6547H, which gives Bad file mode at once, so LOC always ends with that error; 6301H-630EH are reached only from LOF.

62FE
GOSUB to 6547H, which loads Register E with 6CH and jumps to the ROM's error handler: Bad file mode, for every LOC.
6301
If the Z FLAG is set, JUMP to 654AH, Bad file number. Not reached (see 62FEH).
6304
LD HL,000CH 21 0C 00
Load Register Pair HL with 000CH, the offset of the next record number. Not reached (see 62FEH).
6307
ADD HL,BC 09
ADD Register Pair BC (the block) to Register Pair HL: Register Pair HL = the record number in the block. 6318H jumps here.
6308
LD E,(HL) 5E
Fetch the low byte of the record number from (HL) (Register Pair HL = its address) into Register E.
6309
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
630A
LD D,(HL) 56
Fetch the high byte of the record number from (HL) (Register Pair HL = its address) into Register D.
630B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the record number.
630C
JUMP to the ROM's 0A9AH, which stores Register Pair HL into the accumulator as an integer and returns.
630F
GOSUB to 5EE5H to take the file number from the accumulator: Register Pair BC = the block, the Z FLAG for a closed file. LOF comes here.
6312
If the Z FLAG is set (closed), JUMP to 654AH, Bad file number.
6315
LD HL,000EH 21 0E 00
Load Register Pair HL with 000EH, the offset of the ending record number (FCB bytes 0CH-0DH).
6318
JUMP to 6307H to fetch the ending record number at block byte 0EH as the result.

631BH - Put a Character into the Current File

Register A = the character; the current file is at 5B8DH. A file open for input takes nothing (ROM 1DFDH). Otherwise byte 1 of the block counts the column (ENTER sets it to 0, characters 20H and above add 1) and the character goes to the DOS through the ROM's output (001BH) with the FCB as the device. A DOS error with the FCB open (bit 7) becomes a BASIC error.

631B
POP HL E1
Restore Register Pair HL from the stack. No code in BASIC/CMD jumps to 631BH: 5A2DH, 615BH and 616CH all go to 631CH.
631C
PUSH HL E5
Save Register Pair HL onto the stack. 5A2DH jumps here, 615BH and 616CH call here.
631D
PUSH AF F5
Save Register Pair AF (Register A = the character) onto the stack.
631E
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
6321
LD A,(HL) 7E
Fetch the mode from (HL) (Register Pair HL = the block) into Register A.
6322
CP 01H FE 01
Compare Register A against 01H, a file open for input.
6324
If the Z FLAG is set (input), JUMP to the ROM's 1DFDH, which pops Register Pairs AF and HL and returns: the character is dropped.
6327
POP AF F1
Restore Register Pair AF (Register A = the character) from the stack.
6328
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack.
6329
PUSH BC C5
Save Register Pair BC (the caller's value) onto the stack.
632A
INC HL 23
INCrement Register Pair HL by 1, to block byte 01H, the column.
632B
LD B,00H 06 00
Load Register B with 00H, the new column after ENTER and the zero added with carry at 6337H.
632D
PUSH AF F5
Save Register Pair AF (the character) onto the stack.
632E
LD D,(HL) 56
Fetch the column from (HL) (Register Pair HL = block byte 01H) into Register D.
632F
CP 0DH FE 0D
Compare Register A (the character) against 0DH, ENTER.
6331
LD (HL),B 70
Store Register B (00H) into (HL) (Register Pair HL = block byte 01H): the column is 0 for ENTER; LD does not change the flags.
6332
If the Z FLAG is set (ENTER), JUMP to 6339H with the column left at 0.
6334
ADD A,E0H C6 E0
ADD E0H to Register A (the character): the CARRY FLAG is set for 20H and above, a printing character.
6336
LD A,D 7A
Copy the old column from Register D into Register A.
6337
ADC A,B 88
ADD WITH CARRY Register B (00H) to Register A: the column plus 1 for a printing character.
6338
LD (HL),A 77
Store Register A (the new column) into (HL), Register Pair HL = block byte 01H.
6339
INC HL 23
INCrement Register Pair HL by 1, to block byte 02H, the FCB. 6332H jumps here.
633A
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the FCB.
633B
POP AF F1
Restore Register Pair AF (the character) from the stack.
633C
PUSH AF F5
Save Register Pair AF (the character) onto the stack again.
633D
PUSH DE D5
Save Register Pair DE (the FCB) onto the stack.
633E
GOSUB to the ROM's 001BH to send Register A to the device whose control block is at Register Pair DE, the FCB: SYS0/SYS writes it into the file.
6341
POP DE D1
Restore Register Pair DE (the FCB) from the stack.
6342
If the NZ FLAG is set (an error), JUMP to 634AH.
6345
POP AF F1
Restore Register Pair AF (the character) from the stack. 6351H jumps here.
6346
POP BC C1
Restore Register Pair BC (the caller's value) from the stack.
6347
POP DE D1
Restore Register Pair DE (the caller's value) from the stack.
6348
POP HL E1
Restore Register Pair HL (the caller's value) from the stack.
6349
RET C9
RETURN to the caller with Register A = the character.
634A
LD C,A 4F
Copy Register A (the DOS error number) into Register C. 6342H jumps here.
634B
LD A,(DE) 1A
Fetch the first byte of the FCB from (DE) (Register Pair DE = the FCB) into Register A: bit 7 is set for an open file.
634C
OR A B7
OR Register A with itself: the SIGN FLAG is set for an open file.
634D
LD A,C 79
Copy the error number from Register C back into Register A; LD does not change the flags.
634E
If the SIGN FLAG is set (an open file), JUMP to 6561H to turn the DOS error into a BASIC error.
6351
JUMP to 6345H: otherwise the error is passed over.

6354H - GET and PUT

The ROM's statement table sends GET to 417FH and PUT to 4182H, and from there to 6355H and 6354H. GET #n[,r] reads record r (the next record when r is left out) of a random file into its buffer; PUT #n[,r] writes the buffer as record r. Record 0 gives Bad record number. A GET beyond the end of the file fills the buffer with 00H; a PUT beyond the end writes the record, which makes the file longer.

6354
OR AFH F6 AF
OR Register A with AFH: Register A is not 00H, the mark of PUT. The byte AFH at 6355H is XOR A, where GET enters, giving 00H.
6356
LD (5B8BH),A 32 8B 5B
Store Register A into 5B8BH: 00H for GET, not 00H for PUT.
6359
GOSUB to 5EDBH to read the file number: Register Pair BC = the file's block, Register A = its mode.
635C
CP 03H FE 03
Compare Register A (the mode) against 03H, a random file.
635E
If the NZ FLAG is set (not random, or closed), JUMP to 6547H, Bad file mode.
6361
PUSH BC C5
Save Register Pair BC (the block) onto the stack.
6362
PUSH HL E5
Save Register Pair HL (the text) onto the stack.
6363
LD HL,000CH 21 0C 00
Load Register Pair HL with 000CH, the offset of the next record number in the block (FCB bytes 0AH-0BH).
6366
ADD HL,BC 09
ADD Register Pair BC (the block) to Register Pair HL: Register Pair HL = block byte 0CH.
6367
LD E,(HL) 5E
Fetch the low byte of the next record number from (HL) (Register Pair HL = block byte 0CH) into Register E.
6368
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6369
LD D,(HL) 56
Fetch the high byte of the next record number from (HL) (Register Pair HL = block byte 0DH) into Register D.
636A
INC DE 13
INCrement Register Pair DE by 1: the record number counted from 1, used when none is given.
636B
POP HL E1
Restore Register Pair HL (the text) from the stack.
636C
LD A,(HL) 7E
Fetch the character after the file number from (HL) (Register Pair HL = the text) into Register A.
636D
CP 2CH FE 2C
Compare Register A (the character after the file number) against 2CH, a comma.
636F
If the Z FLAG is set (a record number follows), GOSUB to the ROM's 1E45H to move past the comma and evaluate it as a positive integer in Register Pair DE.
6372
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the current character again.
6373
RST 10H D7
Fetch it with RST 10H into Register A, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement.
6374
If the NZ FLAG is set (more text), JUMP to the ROM's 1997H, the syntax error.
6377
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, at the address in the Stack Pointer (SP): Register Pair HL = the block, and the text is kept on the stack.
6378
PUSH HL E5
Save Register Pair HL (the block) onto the stack.
6379
LD A,E 7B
Copy the low byte of the record number from Register E into Register A.
637A
OR D B2
OR Register A with Register D: the Z FLAG is set for record 0.
637B
If the Z FLAG is set (record 0), JUMP to 6559H, Bad record number.
637E
DEC DE 1B
DECrement Register Pair DE by 1: the record number counted from 0, as the DOS counts.
637F
LD B,D 42
Copy the high byte of the record number from Register D into Register B.
6380
LD C,E 4B
Copy the low byte of the record number from Register E into Register C: Register Pair BC = the record number.
6381
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the block.
6382
INC DE 13
INCrement Register Pair DE by 1, to block byte 01H.
6383
INC DE 13
INCrement Register Pair DE by 1, to block byte 02H: Register Pair DE = the FCB.
6384
LD HL,0020H 21 20 00
Load Register Pair HL with 0020H, the length of the FCB.
6387
ADD HL,DE 19
ADD Register Pair DE (the FCB) to Register Pair HL: Register Pair HL = block byte 22H, the record buffer.
6388
PUSH HL E5
Save Register Pair HL (the record buffer) onto the stack.
6389
GOSUB to SYS0/SYS's 4442H to set the file in the FCB at Register Pair DE to record Register Pair BC.
638C
POP HL E1
Restore Register Pair HL (the record buffer) from the stack.
638D
If the Z FLAG is set (the record exists), JUMP to 63A7H.
638F
CP 1CH FE 1C
Compare Register A (the DOS error) against 1CH, END OF FILE ENCOUNTERED.
6391
If the Z FLAG is set, JUMP to 6398H: the record is beyond the end.
6393
CP 1DH FE 1D
Compare Register A (the DOS error) against 1DH, RECORD NUMBER OUT OF RANGE.
6395
If the NZ FLAG is set (another error), JUMP to 6561H to turn it into a BASIC error.
6398
LD A,(5B8BH) 3A 8B 5B
Fetch the GET or PUT mark from 5B8BH into Register A. 6391H jumps here.
639B
OR A B7
OR Register A with itself: the Z FLAG is set for GET.
639C
If the Z FLAG is set (GET beyond the end), JUMP to 63B6H to clear the buffer.
639E
GOSUB to SYS0/SYS's 4439H to write the record buffer as the record of the FCB at Register Pair DE. 63ABH jumps here.
63A1
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
63A4
POP AF F1
Restore Register Pair AF from the stack: the block, not needed.
63A5
POP HL E1
Restore Register Pair HL (the text after the statement) from the stack.
63A6
RET C9
RETURN to the statement loop after PUT with Register Pair HL = the text.
63A7
LD A,(5B8BH) 3A 8B 5B
Fetch the GET or PUT mark from 5B8BH into Register A. 638DH jumps here.
63AA
OR A B7
OR Register A with itself: the NZ FLAG is set for PUT.
63AB
If the NZ FLAG is set (PUT), JUMP to 639EH to write.
63AD
GOSUB to SYS0/SYS's 4436H to read the record of the FCB at Register Pair DE into the record buffer at Register Pair HL.
63B0
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
63B3
POP BC C1
Restore Register Pair BC from the stack: the block, not needed.
63B4
POP HL E1
Restore Register Pair HL (the text after the statement) from the stack.
63B5
RET C9
RETURN to the statement loop after GET with Register Pair HL = the text.
63B6
POP HL E1
GET beyond the End
Restore Register Pair HL (the block) from the stack. 639CH jumps here.
63B7
LD DE,0022H 11 22 00
Load Register Pair DE with 0022H, the offset of the record buffer.
63BA
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: Register Pair HL = the record buffer.
63BB
LD B,00H 06 00
Load Register B with 00H: 256 bytes to clear.
63BD
XOR A AF
Set Register A to ZERO with XOR A, the value to clear with.
63BE
LD (HL),A 77
Clear Loop
Store Register A (00H) into (HL), Register Pair HL = the next byte of the buffer. 63C0H loops back here.
63BF
INC HL 23
INCrement Register Pair HL by 1, to the next byte.
63C0
Clear Loop End
DECrement Register B and LOOP BACK to 63BEH until all 256 bytes are 00H.
63C2
POP HL E1
Restore Register Pair HL (the text after the statement) from the stack.
63C3
RET C9
RETURN to the statement loop after GET with Register Pair HL = the text.

63C4H - Read a Character from the Current File

Returns Register A = the next character of the current file, the CARRY FLAG set at the end of the file (DOS error 1CH); any other DOS error becomes a BASIC error. The character comes through the ROM's input (0013H) with the FCB as the device. When bit 7 of the FCB's first byte is clear (not an open file), an empty result is read again until a character comes. Register Pairs BC, DE and HL are kept.

63C4
PUSH BC C5
Save Register Pair BC (the caller's value) onto the stack. Called by 5A48H, 5F63H-5FF6H, 60A9H, 60C3H and 611CH.
63C5
PUSH HL E5
Save Register Pair HL (the caller's value) onto the stack.
63C6
LD HL,(5B8DH) 2A 8D 5B
Fetch the current file pointer from 5B8DH into Register Pair HL.
63C9
PUSH DE D5
Save Register Pair DE (the caller's value) onto the stack.
63CA
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the block.
63CB
INC DE 13
INCrement Register Pair DE by 1, to block byte 01H.
63CC
INC DE 13
INCrement Register Pair DE by 1, to block byte 02H: Register Pair DE = the FCB.
63CD
PUSH DE D5
Read Again
Save Register Pair DE (the FCB) onto the stack. 63E8H jumps here.
63CE
GOSUB to the ROM's 0013H to read a byte from the device whose control block is at Register Pair DE, the FCB: SYS0/SYS reads it from the file into Register A, with the Z FLAG when there is no error.
63D1
POP DE D1
Restore Register Pair DE (the FCB) from the stack.
63D2
PUSH AF F5
Save Register Pair AF (the character and the flags) onto the stack.
63D3
LD A,(DE) 1A
Fetch the first byte of the FCB from (DE) (Register Pair DE = the FCB) into Register A: bit 7 is set for an open file.
63D4
OR A B7
OR Register A with itself: the SIGN FLAG is set for an open file.
63D5
If the SIGN FLAG is clear (not an open file), JUMP to 63E7H.
63D8
POP AF F1
Restore Register Pair AF (the character and the flags) from the stack.
63D9
If the Z FLAG is set (a character), JUMP to 63E2H to return it.
63DB
CP 1CH FE 1C
Compare Register A (the DOS error) against 1CH, END OF FILE ENCOUNTERED.
63DD
If the NZ FLAG is set (another error), JUMP to 6561H to turn it into a BASIC error.
63E0
SCF 37
Set the CARRY FLAG: the end of the file, returned to the caller.
63E1
LD B,B7H 06 B7
Load Register B with B7H: from 63E0H this only skips the byte at 63E2H; Register B is restored at 63E5H.
63E3
POP DE D1
Restore Register Pair DE (the caller's value) from the stack. At 63E2H the byte B7H is OR A, which clears the CARRY FLAG for a character (63D9H and 63EAH jump there).
63E4
POP HL E1
Restore Register Pair HL (the caller's value) from the stack.
63E5
POP BC C1
Restore Register Pair BC (the caller's value) from the stack.
63E6
RET C9
RETURN with Register A = the character, the CARRY FLAG set at the end of the file.
63E7
POP AF F1
Restore Register Pair AF (the result) from the stack. 63D5H jumps here.
63E8
If the Z FLAG is set, JUMP to 63CDH to read again.
63EA
JUMP to 63E2H to return Register A with the CARRY FLAG clear.

63EDH - Put a File Name into the FCB

Register Pair HL = the text at the name, Register Pair BC = the file's block. The name is evaluated as a string, which must have 1 to 22 characters, copied in capitals to 5EA3H with a 00H after it, and read by SYS0/SYS's 441CH into the FCB at block byte 02H. A bad name gives Bad file name (6556H). Returns Register Pair BC = the block and Register Pair HL = the text after the name.

63ED
PUSH BC C5
Save Register Pair BC (the block) onto the stack. Called by 647CH and 6525H.
63EE
GOSUB to the ROM's 2337H to evaluate the file name at Register Pair HL.
63F1
PUSH HL E5
Save Register Pair HL (the text after the name) onto the stack.
63F2
GOSUB to the ROM's 29D7H, which checks that the name is a string, releases its temporary and returns Register Pair HL = its descriptor.
63F5
LD A,(HL) 7E
Fetch the length of the name from (HL) (Register Pair HL = the descriptor) into Register A.
63F6
OR A B7
OR Register A with itself: the Z FLAG is set for an empty name.
63F7
If the Z FLAG is set, JUMP to 6556H, Bad file name.
63FA
CP 17H FE 17
Compare Register A (the length) against 17H: the NO CARRY FLAG is set for 23 or more characters.
63FC
If the NO CARRY FLAG is set, JUMP to 6556H, Bad file name.
63FF
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
6400
LD C,(HL) 4E
Fetch the low byte of the name's address from (HL) (Register Pair HL = the descriptor) into Register C.
6401
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6402
LD B,(HL) 46
Fetch the high byte of the name's address from (HL) (Register Pair HL = the descriptor) into Register B: Register Pair BC = the text of the name.
6403
LD HL,5EA3H 21 A3 5E
Point Register Pair HL to 5EA3H, the place for the name.
6406
LD E,A 5F
Copy the length from Register A into Register E, the characters to copy.
6407
LD A,(BC) 0A
Copy Loop
Fetch the next character of the name from (BC) (Register Pair BC = the name) into Register A. 6418H loops back here.
6408
CP 61H FE 61
Compare Register A against 61H, a small a: the CARRY FLAG is set below it.
640A
If the CARRY FLAG is set, JUMP to 6414H to store it as it is.
640D
CP 7BH FE 7B
Compare Register A against 7BH, the character after a small z.
640F
If the NO CARRY FLAG is set, JUMP to 6414H to store it as it is.
6412
XOR 20H EE 20
XOR Register A with 20H: a small letter becomes a capital.
6414
LD (HL),A 77
Store the character from Register A into (HL) (Register Pair HL = the place at 5EA3H on). 640AH and 640FH jump here.
6415
INC HL 23
INCrement Register Pair HL by 1, to the next place.
6416
INC BC 03
INCrement Register Pair BC by 1, to the next character of the name.
6417
DEC E 1D
DECrement Register E (the characters left) by 1.
6418
Copy Loop End
If the NZ FLAG is set, JUMP to 6407H for the next character.
641B
LD (HL),E 73
Store Register E (00H) into (HL) (Register Pair HL = the place after the name): the name ends there.
641C
POP HL E1
Restore Register Pair HL (the text after the name) from the stack.
641D
POP DE D1
Restore Register Pair DE (the block, pushed at 63EDH) from the stack.
641E
LD B,D 42
Copy the high byte of the block from Register D into Register B.
641F
LD C,E 4B
Copy the low byte of the block from Register E into Register C: Register Pair BC = the block.
6420
PUSH BC C5
Save Register Pair BC (the block) onto the stack.
6421
PUSH HL E5
Save Register Pair HL (the text after the name) onto the stack.
6422
LD HL,5EA3H 21 A3 5E
Point Register Pair HL to 5EA3H, the name in capitals.
6425
INC DE 13
INCrement Register Pair DE by 1, to block byte 01H.
6426
INC DE 13
INCrement Register Pair DE by 1, to block byte 02H: Register Pair DE = the FCB.
6427
GOSUB to SYS0/SYS's 441CH to read the file specification at Register Pair HL into the FCB at Register Pair DE.
642A
If the NZ FLAG is set (not a valid name), JUMP to 6556H, Bad file name.
642D
OR A B7
OR Register A (the character where 441CH stopped) with itself: the Z FLAG is set when it is the 00H after the name.
642E
If the NZ FLAG is set (more after the name), JUMP to 6556H, Bad file name.
6431
POP HL E1
Restore Register Pair HL (the text after the name) from the stack.
6432
POP BC C1
Restore Register Pair BC (the block) from the stack.
6433
RET C9
RETURN to the caller with the name in the FCB.

6434H - OPEN

The ROM's statement table sends OPEN to 4179H, and from there here. OPEN "O"|"I"|"R", [#]n, "name" [,record length]: the first letter of the mode string picks output (02H), input (01H) or random (03H); file 0 cannot be opened this way. A file already open gives File already open. LOAD, RUN, MERGE, SAVE and KILL enter at 6474H for file 0 with the mode in Register D. The file is opened (4424H for input) or opened or created (4420H) with the buffer at block byte 22H; a random file with a record length uses the second 256 bytes of the block as its sector buffer. The mode is stored in byte 0 of the block and the column cleared.

6434
LD BC,2169H 01 69 21
Load Register Pair BC with 2169H, the ROM's end of PRINT and INPUT, which clears the current file.
6437
PUSH BC C5
Save Register Pair BC (2169H) onto the stack, the return address of OPEN.
6438
GOSUB to the ROM's 2337H to evaluate the mode string at Register Pair HL.
643B
PUSH HL E5
Save Register Pair HL (the text after it) onto the stack.
643C
GOSUB to the ROM's 29D7H, which checks that it is a string, releases its temporary and returns Register Pair HL = its descriptor.
643F
LD A,(HL) 7E
Fetch the length of the mode string from (HL) (Register Pair HL = the descriptor) into Register A.
6440
OR A B7
OR Register A with itself: the Z FLAG is set for an empty string.
6441
If the Z FLAG is set, JUMP to 6547H, Bad file mode.
6444
INC HL 23
INCrement Register Pair HL by 1, to the address word of the descriptor.
6445
LD C,(HL) 4E
Fetch the low byte of the string's address from (HL) (Register Pair HL = the descriptor) into Register C.
6446
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
6447
LD B,(HL) 46
Fetch the high byte of the string's address from (HL) (Register Pair HL = the descriptor) into Register B: Register Pair BC = the mode string.
6448
LD A,(BC) 0A
Fetch the first character of the mode string from (BC) (Register Pair BC = its text) into Register A.
6449
AND DFH E6 DF
AND Register A with DFH, clearing bit 5: a small letter becomes a capital.
644B
LD D,02H 16 02
Load Register D with 02H, the mode for output.
644D
CP 4FH FE 4F
Compare Register A against 4FH, the letter O.
644F
If the Z FLAG is set (O), JUMP to 6460H with mode 02H.
6452
LD D,01H 16 01
Load Register D with 01H, the mode for input.
6454
CP 49H FE 49
Compare Register A against 49H, the letter I.
6456
If the Z FLAG is set (I), JUMP to 6460H with mode 01H.
6459
LD D,03H 16 03
Load Register D with 03H, the mode for random access.
645B
CP 52H FE 52
Compare Register A against 52H, the letter R.
645D
If the NZ FLAG is set (none of O, I, R), JUMP to 6547H, Bad file mode.
6460
POP HL E1
Restore Register Pair HL (the text after the mode string) from the stack.
6461
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H, which leaves the character after it in Register A.
6463
PUSH DE D5
Save Register Pair DE (Register D = the mode) onto the stack.
6464
CP 23H FE 23
Compare Register A against 23H, the character #.
6466
If the Z FLAG is set (a #), GOSUB to the ROM's 1D78H, the RST 10H code, to move Register Pair HL past it.
6469
GOSUB to the ROM's 2B1CH to evaluate the file number at Register Pair HL as a byte in Register A and Register E.
646C
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
646E
LD A,E 7B
Copy the file number from Register E into Register A.
646F
OR A B7
OR Register A with itself: the Z FLAG is set for file 0.
6470
If the Z FLAG is set (file 0), JUMP to 654AH, Bad file number.
6473
CP D5H FE D5
Compare Register A against D5H, a compare whose result is not used. The byte D5H at 6474H is PUSH DE, where 6063H enters for file 0 with the mode in Register D.
6475
GOSUB to 5EE8H to find the block of file Register A: Register Pair BC = the block, the NZ FLAG when it is already open.
6478
If the NZ FLAG is set (open), JUMP to 6553H, File already open.
647B
PUSH BC C5
Save Register Pair BC (the block) onto the stack.
647C
GOSUB to 63EDH to put the file name at Register Pair HL into the block's FCB; Register Pair HL returns after the name.
647F
LD B,00H 06 00
Load Register B with 00H, the record length when none is given (256).
6481
POP DE D1
Restore Register Pair DE (the block) from the stack.
6482
POP AF F1
Restore Register Pair AF from the stack: Register A = the mode (the Register D pushed at 6463H or 6474H).
6483
PUSH AF F5
Save Register Pair AF (the mode) onto the stack again.
6484
PUSH DE D5
Save Register Pair DE (the block) onto the stack again.
6485
CP 03H FE 03
Compare Register A (the mode) against 03H, a random file.
6487
If the NZ FLAG is set (not random), JUMP to 6493H.
6489
DEC HL 2B
DECrement Register Pair HL by 1, so that RST 10H looks at the character after the name again.
648A
RST 10H D7
Fetch it with RST 10H into Register A, Register Pair HL moving onto it: the Z FLAG is set at the end of the statement.
648B
If the Z FLAG is set (no record length), JUMP to 6493H.
648D
RST 08H => 2CH CF 2C
Check that the next character at Register Pair HL is 2CH, a comma, with RST 08H.
648F
GOSUB to the ROM's 2B1CH to evaluate the record length at Register Pair HL as a byte in Register E.
6492
LD B,E 43
Copy the record length from Register E into Register B.
6493
LD (40DFH),HL 22 DF 40
Store Register Pair HL (the text after the statement) into 40DFH, a ROM work word, for 64EEH. 6487H and 648BH jump here.
6496
POP HL E1
Restore Register Pair HL (the block) from the stack.
6497
LD A,(430FH) 3A 0F 43
Fetch SYS0/SYS's system flags from 430FH into Register A.
649A
AND F9H E6 F9
AND Register A with F9H, clearing bits 1 and 2.
649C
LD C,A 4F
Copy the flags from Register A into Register C.
649D
LD A,(651FH) 3A 1F 65
Fetch the RUN mark from 651FH (FFH from 606AH) into Register A.
64A0
OR A B7
OR Register A with itself: the NZ FLAG is set during RUN with a file name.
64A1
LD A,C 79
Copy the flags from Register C into Register A; LD does not change the flags.
64A2
If the Z FLAG is set (not RUN), JUMP to 64A6H.
64A4
OR 04H F6 04
OR Register A with 04H, setting bit 2 of the system flags.
64A6
LD (430FH),A 32 0F 43
Store Register A into 430FH, the system flags. 64A2H jumps here.
64A9
POP AF F1
Restore Register Pair AF (Register A = the mode) from the stack.
64AA
PUSH AF F5
Save Register Pair AF (the mode) onto the stack again, for 64E9H.
64AB
PUSH HL E5
Save Register Pair HL (the block) onto the stack, for 64E8H.
64AC
LD (5B8DH),HL 22 8D 5B
Store Register Pair HL (the block) into 5B8DH: this is the current file.
64AF
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the block.
64B0
INC DE 13
INCrement Register Pair DE by 1, to block byte 01H.
64B1
INC DE 13
INCrement Register Pair DE by 1, to block byte 02H: Register Pair DE = the FCB.
64B2
LD HL,0020H 21 20 00
Load Register Pair HL with 0020H, the length of the FCB.
64B5
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: Register Pair HL = block byte 22H, the sector buffer.
64B6
LD C,A 4F
Copy the mode from Register A into Register C.
64B7
LD A,B 78
Copy the record length from Register B into Register A.
64B8
OR A B7
OR Register A with itself: the Z FLAG is set when no record length was given.
64B9
If the Z FLAG is set, JUMP to 64C3H with the buffer at block byte 22H.
64BB
LD A,(0000H) 3A 00 00
Fetch the byte at 0000H, the ROM's first byte F3H, into Register A. As it is never 00H, the test below never gives Bad file mode, also when FILES was answered without V.
64BE
OR A B7
OR Register A (F3H) with itself: the NZ FLAG is always set.
64BF
If the Z FLAG is set, JUMP to 6547H, Bad file mode. Never taken (see 64BBH).
64C2
INC H 24
INCrement Register H by 1: the sector buffer is block byte 122H, the 256 bytes FILES with V adds, and block byte 22H is the record buffer.
64C3
LD A,C 79
Copy the mode from Register C into Register A. 64B9H jumps here.
64C4
CP 01H FE 01
Compare Register A (the mode) against 01H, input.
64C6
If the Z FLAG is set (input), JUMP to 64CDH to open an existing file.
64C8
GOSUB to SYS0/SYS's 4420H to open the file of the FCB at Register Pair DE, or create it, with the buffer at Register Pair HL and the record length in Register B.
64CB
JUMP to 64E5H to check the DOS result in Register A and the flags.
64CD
GOSUB to SYS0/SYS's 4424H to open the existing file of the FCB at Register Pair DE with the buffer at Register Pair HL and the record length in Register B. 64C6H jumps here.
64D0
PUSH AF F5
Save Register Pair AF (the DOS result) onto the stack.
64D1
LD A,(651FH) 3A 1F 65
Fetch the RUN mark from 651FH into Register A.
64D4
OR A B7
OR Register A with itself: the Z FLAG is set when this is not RUN with a file name.
64D5
If the Z FLAG is set (not RUN), JUMP to 64E4H: 6520H is left as it is.
64D7
XOR A AF
Set Register A to ZERO with XOR A, to clear the RUN mark.
64D8
LD (651FH),A 32 1F 65
Store Register A (00H) into 651FH: the RUN mark is used up.
64DB
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
64DE
RRA 1F
Rotate Register A right through the CARRY FLAG: bit 0 goes into the CARRY FLAG.
64DF
RRA 1F
Rotate Register A right through the CARRY FLAG again: bit 1 is now in the CARRY FLAG.
64E0
SBC A,A 9F
SUBtract Register A from itself with the CARRY FLAG: FFH when bit 1 of 430FH is set, 00H otherwise. No TRSDOS 2.3 module sets bit 1 (6497H has just cleared it), so this is 00H.
64E1
LD (6520H),A 32 20 65
Store Register A into 6520H, the protection flag that 64F2H tests.
64E4
POP AF F1
Restore Register Pair AF (the DOS result) from the stack. 64D5H jumps here.
64E5
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error. 64CBH jumps here.
64E8
POP HL E1
Restore Register Pair HL (the block) from the stack.
64E9
POP AF F1
Restore Register Pair AF (Register A = the mode) from the stack.
64EA
LD (HL),A 77
Store Register A (the mode) into (HL), Register Pair HL = the block's mode byte: the file is open.
64EB
INC HL 23
INCrement Register Pair HL by 1, to block byte 01H, the column.
64EC
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = block byte 01H): the column is 0.
64EE
LD HL,(40DFH) 2A DF 40
Fetch the text after the statement from 40DFH, stored at 6493H, into Register Pair HL.
64F1
RET C9
RETURN to 2169H (OPEN) or to the caller of 6060H and 6062H.

64F2H - Clear a Protected Program

Called at READY (60FDH), before a direct statement (6142H) and after an error message (5812H). Clears 651FH. When 6520H is not 00H (set at 64E1H after RUN of a protected file), 1100 bytes from the program start are cleared, NEW is done, PROTECTION HAS CLEARED MEMORY is shown and BASIC returns to READY. In TRSDOS 2.3, 6520H always becomes 00H (see 64E0H), so the clearing never happens.

64F2
PUSH AF F5
Save Register Pair AF (the caller's value) onto the stack. Called by 5812H, 60FDH and 6142H.
64F3
XOR A AF
Set Register A to ZERO with XOR A, to clear the RUN mark.
64F4
LD (651FH),A 32 1F 65
Store Register A (00H) into 651FH, the RUN mark: it lasts only until the next READY, direct statement or error.
64F7
LD A,(6520H) 3A 20 65
Fetch the protection flag from 6520H into Register A.
64FA
OR A B7
OR Register A with itself: the Z FLAG is set when no protected program was loaded.
64FB
If the Z FLAG is set (not protected), JUMP to 651CH to return.
64FE
LD HL,(40A4H) 2A A4 40
Fetch the start of the program text from 40A4H into Register Pair HL.
6501
LD BC,044CH 01 4C 04
Load Register Pair BC with 044CH, 1100 bytes to clear.
6504
LD (HL),00H 36 00
Clear Loop
Store 00H at (HL) (Register Pair HL = the next byte of the program). 650AH loops back here.
6506
INC HL 23
INCrement Register Pair HL by 1, to the next byte.
6507
DEC BC 0B
DECrement Register Pair BC (the bytes left) by 1.
6508
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
6509
OR C B1
OR Register A with Register C: the Z FLAG is set when the count is 0000H.
650A
Clear Loop End
If the NZ FLAG is set, JUMP to 6504H.
650D
LD (6520H),A 32 20 65
Store Register A (00H) into 6520H: the protection flag is cleared.
6510
GOSUB to the ROM's 1B4DH, NEW, which also clears the variables.
6513
LD HL,586BH 21 6B 58
Point Register Pair HL to 586BH, the text PROTECTION HAS CLEARED MEMORY.
6516
GOSUB to the ROM's 28A7H to show the text at Register Pair HL up to its 00H.
6519
JUMP to the ROM's 1A19H, READY, with the program gone.
651C
POP AF F1
Restore Register Pair AF (the caller's value) from the stack. 64FBH jumps here.
651D
RET C9
RETURN to the caller with Register Pair AF restored; nothing is cleared.
651E
DEFB 00H 00
The record length of the file in FIELD (block byte 0BH, 00H for 256), stored by 61C0H and read at 61ECH.
651F
DEFB 00H 00
The RUN mark: FFH from RUN with a file name (606AH) until OPEN uses it (64D8H) or 64F4H clears it; while set, OPEN sets bit 2 of 430FH and sets 6520H from bit 1.
6520
DEFB 00H 00
The protection flag, set from bit 1 of 430FH at 64E1H and cleared at 650DH; 64F7H tests it.

6521H - KILL

The ROM's statement table sends KILL to 4191H, and from there here. KILL "name" puts the name into the FCB of file 0, opens the file (4424H) and kills it (442CH); file 0 is marked closed again.

6521
XOR A AF
Set Register A to ZERO with XOR A: file 0, whose block holds the FCB for the kill.
6522
GOSUB to 5EE8H to find the block of file 0: Register Pair BC = the block. Whether it is open is not tested.
6525
GOSUB to 63EDH to put the file name at Register Pair HL into the FCB of file 0; Register Pair HL returns after the name.
6528
PUSH HL E5
Save Register Pair HL (the text after the name) onto the stack.
6529
LD HL,(5B8FH) 2A 8F 5B
Fetch the address of the block of file 0 from 5B8FH into Register Pair HL.
652C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the block.
652D
INC DE 13
INCrement Register Pair DE by 1, to block byte 01H.
652E
INC DE 13
INCrement Register Pair DE by 1, to block byte 02H: Register Pair DE = the FCB.
652F
LD B,00H 06 00
Load Register B with 00H, the record length for the open (256).
6531
GOSUB to SYS0/SYS's 4424H to open the existing file of the FCB at Register Pair DE; Register Pair HL, which the exchange at 652CH left holding the FCB address from 63EDH, is given as the buffer address.
6534
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
6537
GOSUB to SYS0/SYS's 442CH to kill the open file of the FCB at Register Pair DE.
653A
If the NZ FLAG is set (Register A = a DOS error), JUMP to 6561H to turn it into a BASIC error.
653D
LD HL,(5B8FH) 2A 8F 5B
Fetch the address of the block of file 0 from 5B8FH into Register Pair HL.
6540
LD (HL),00H 36 00
Store 00H at (HL) (Register Pair HL = the block's mode byte): file 0 is closed.
6542
POP HL E1
Restore Register Pair HL (the text after the name) from the stack.
6543
RET C9
RETURN to the statement loop with Register Pair HL = the text after the statement.

6544H - NAME

The ROM's statement table sends NAME to 418EH, and from there here. NAME is not done by this Disk BASIC: it gives ILLEGAL FUNCTION CALL.

6544
JUMP to the ROM's 1E4AH, ILLEGAL FUNCTION CALL, for every NAME statement.

6547H - The Disk BASIC Error Entries

Each entry loads Register E with an error code and goes to the ROM's error handler (19A2H); the bytes in between are LD BC,nn instructions that only skip the LD E of the next entry. 6547H Bad file mode, 654AH Bad file number, 654DH Internal error, 6550H Input past end, 6553H File already open, 6556H Bad file name, 6559H Bad record number, 655CH FIELD overflow.

6547
LD E,6CH 1E 6C
Load Register E with 6CH, the error code Bad file mode.
6549
LD BC,681EH 01 1E 68
Load Register Pair BC with 681EH: from 6547H this only skips the LD E,68H at 654AH; Register Pair BC is not used.
654C
LD BC,661EH 01 1E 66
Load Register Pair BC with 661EH: this skips the LD E,66H at 654DH (Internal error); Register Pair BC is not used.
654F
LD BC,7C1EH 01 1E 7C
Load Register Pair BC with 7C1EH: this skips the LD E,7CH at 6550H (Input past end); Register Pair BC is not used.
6552
LD BC,6E1EH 01 1E 6E
Load Register Pair BC with 6E1EH: this skips the LD E,6EH at 6553H (File already open); Register Pair BC is not used.
6555
LD BC,801EH 01 1E 80
Load Register Pair BC with 801EH: this skips the LD E,80H at 6556H (Bad file name); Register Pair BC is not used.
6558
LD BC,7E1EH 01 1E 7E
Load Register Pair BC with 7E1EH: this skips the LD E,7EH at 6559H (Bad record number); Register Pair BC is not used.
655B
LD BC,641EH 01 1E 64
Load Register Pair BC with 641EH: this skips the LD E,64H at 655CH (FIELD overflow); Register Pair BC is not used.
655E
JUMP to the ROM's 19A2H, its error handler, with the error code in Register E.

6561H - Turn a DOS Error into a BASIC Error

Register A = the DOS error number from a SYS0/SYS call. Numbers 27H and above count as 01H. The number is kept at 5B8CH for CMD"E", and the table at 6575H gives the BASIC error code for the ROM's error handler.

6561
LD B,00H 06 00
Load Register B with 00H, the high byte of the table offset.
6563
LD HL,6574H 21 74 65
Point Register Pair HL to 6574H, one byte before the table, as the numbers start at 01H.
6566
CP 27H FE 27
Compare Register A (the DOS error) against 27H: the CARRY FLAG is set for the numbers the table covers.
6568
If the CARRY FLAG is set (01H-26H), JUMP to 656CH with the number as it is.
656A
LD A,01H 3E 01
Load Register A with 01H, used for any number 27H or above.
656C
LD C,A 4F
Copy the number from Register A into Register C: Register Pair BC = the offset. 6568H jumps here.
656D
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = 6574H plus the number, its table byte.
656E
LD E,(HL) 5E
Fetch the BASIC error code from (HL) (Register Pair HL = the table byte) into Register E.
656F
LD (5B8CH),A 32 8C 5B
Store Register A (the DOS error number) into 5B8CH, for CMD"E".
6572
JUMP to the ROM's 19A2H, its error handler, with the BASIC error code in Register E.

6575H - The DOS Error Table

One byte for each DOS error number 01H-26H, read by 656EH: the BASIC error code shown for it.

6575
DEFB 72H 72
DOS error 01H, PARITY ERROR DURING HEADER READ: BASIC error 72H, Disk I/O error. Also used for DOS error numbers 27H and above (6566H-656AH).
6576
DEFB 72H 72
DOS error 02H, SEEK ERROR DURING READ: BASIC error 72H, Disk I/O error.
6577
DEFB 72H 72
DOS error 03H, LOST DATA DURING READ: BASIC error 72H, Disk I/O error.
6578
DEFB 72H 72
DOS error 04H, PARITY ERROR DURING READ: BASIC error 72H, Disk I/O error.
6579
DEFB 72H 72
DOS error 05H, DATA RECORD NOT FOUND DURING READ: BASIC error 72H, Disk I/O error.
657A
DEFB 72H 72
DOS error 06H, ATTEMPTED TO READ LOCKED/DELETED DATA RECORD: BASIC error 72H, Disk I/O error.
657B
DEFB 72H 72
DOS error 07H, ATTEMPTED TO READ SYSTEM DATA RECORD: BASIC error 72H, Disk I/O error.
657C
DEFB 80H 80
DOS error 08H, DEVICE NOT AVAILABLE: BASIC error 80H, Bad file name.
657D
DEFB 72H 72
DOS error 09H, PARITY ERROR DURING HEADER WRITE: BASIC error 72H, Disk I/O error.
657E
DEFB 72H 72
DOS error 0AH, SEEK ERROR DURING WRITE: BASIC error 72H, Disk I/O error.
657F
DEFB 72H 72
DOS error 0BH, LOST DATA DURING WRITE: BASIC error 72H, Disk I/O error.
6580
DEFB 72H 72
DOS error 0CH, PARITY ERROR DURING WRITE: BASIC error 72H, Disk I/O error.
6581
DEFB 72H 72
DOS error 0DH, DATA RECORD NOT FOUND DURING WRITE: BASIC error 72H, Disk I/O error.
6582
DEFB 72H 72
DOS error 0EH, WRITE FAULT ON DISK DRIVE: BASIC error 72H, Disk I/O error.
6583
DEFB 88H 88
DOS error 0FH, WRITE PROTECTED DISKETTE: BASIC error 88H, Disk write protected.
6584
DEFB 66H 66
DOS error 10H, ILLEGAL LOGICAL FILE NUMBER: BASIC error 66H, Internal error.
6585
DEFB 72H 72
DOS error 11H, DIRECTORY READ ERROR: BASIC error 72H, Disk I/O error.
6586
DEFB 72H 72
DOS error 12H, DIRECTORY WRITE ERROR: BASIC error 72H, Disk I/O error.
6587
DEFB 80H 80
DOS error 13H, ILLEGAL FILE NAME: BASIC error 80H, Bad file name.
6588
DEFB 72H 72
DOS error 14H, GAT READ ERROR: BASIC error 72H, Disk I/O error.
6589
DEFB 72H 72
DOS error 15H, GAT WRITE ERROR: BASIC error 72H, Disk I/O error.
658A
DEFB 72H 72
DOS error 16H, HIT READ ERROR: BASIC error 72H, Disk I/O error.
658B
DEFB 72H 72
DOS error 17H, HIT WRITE ERROR: BASIC error 72H, Disk I/O error.
658C
DEFB 6AH 6A
DOS error 18H, FILE NOT IN DIRECTORY: BASIC error 6AH, File not found.
658D
DEFB 8AH 8A
DOS error 19H, FILE ACCESS DENIED: BASIC error 8AH, File acess DENIED.
658E
DEFB 86H 86
DOS error 1AH, DIRECTORY SPACE FULL: BASIC error 86H, Too many files.
658F
DEFB 7AH 7A
DOS error 1BH, DISK SPACE FULL: BASIC error 7AH, Disk full.
6590
DEFB 66H 66
DOS error 1CH, END OF FILE ENCOUNTERED: BASIC error 66H, Internal error.
6591
DEFB 66H 66
DOS error 1DH, RECORD NUMBER OUT OF RANGE: BASIC error 66H, Internal error.
6592
DEFB 7AH 7A
DOS error 1EH, DIRECTORY FULL - CAN'T EXTEND FILE: BASIC error 7AH, Disk full.
6593
DEFB 66H 66
DOS error 1FH, PROGRAM NOT FOUND: BASIC error 66H, Internal error.
6594
DEFB 80H 80
DOS error 20H, ILLEGAL DRIVE NUMBER: BASIC error 80H, Bad file name.
6595
DEFB 66H 66
DOS error 21H, NO DEVICE SPACE AVAILABLE: BASIC error 66H, Internal error.
6596
DEFB 66H 66
DOS error 22H, LOAD FILE FORMAT ERROR: BASIC error 66H, Internal error.
6597
DEFB 66H 66
DOS error 23H, MEMORY FAULT: BASIC error 66H, Internal error.
6598
DEFB 66H 66
DOS error 24H, ATTEMPTED TO LOAD READ ONLY MEMORY: BASIC error 66H, Internal error.
6599
DEFB 8AH 8A
DOS error 25H, ILLEGAL ACCESS ATTEMPTED TO PROTECTED FILE: BASIC error 8AH, File acess DENIED.
659A
DEFB 66H 66
DOS error 26H, FILE NOT OPEN: BASIC error 66H, Internal error.
659B
DEFB DEH DE
The last byte of the file, after the table. It is also the first byte of the block of file 0 (5CD1H): 5CDAH stores 00H over it at the start, its mode byte.