5200H - Member 1 (AUTO, Code 11H): Store the AUTO Command Line
SYS1/SYS's command interpreter runs this member for the word AUTO (member code 11H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL pointing at the rest of the command line after the word AUTO and its delimiter. The member reads the granule allocation table of drive 0 (sector 0 of the directory cylinder) into the buffer 4200H, copies the 32 bytes at Register Pair HL over the table's AUTO command line at 42E0H-42FFH (+E0H-+FFH), writes the table back with the directory data mark and reads it back as a check. SYS0/SYS's reset copies those 32 bytes to 4318H at every boot and executes them (an asterisk first makes the line non breakable). Success ends at 402DH (VTOS READY); a read error ends with error 14H (GAT READ ERROR), a write error with 15H (GAT WRITE ERROR), both shown through 4409H as text alone, then the abort exit.
5200
LD C,00H 0E 00
Load Register C with 00H, the drive number 0: the AUTO line is always written to the diskette in drive 0, the one the system boots from.
5202
GOSUB to 5221H to read the granule allocation table of drive Register C (0) into the buffer 4200H-42FFH; it returns the Z FLAG when read, else the NZ FLAG and Register A = 14H.
5205
If the NZ FLAG is set (the table could not be read), JUMP to 521CH to show the error in Register A (14H, GAT READ ERROR) and abort.
5208
LD D,42H 16 42
Load Register D with 42H, the high byte of the destination address 42E0H in Register Pair DE.
520A
LD E,E0H 1E E0
Load Register E with E0H: Register Pair DE = 42E0H, the AUTO command line of the table just read into 4200H (its bytes +E0H-+FFH).
520C
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of the AUTO command line field of the table.
520F
LDIR ED B0
Copy the 32 bytes from the command line at Register Pair HL (the text after the word AUTO, an asterisk first for a non breakable line) to 42E0H-42FFH at Register Pair DE. Nothing ends the copy early: the 0DH that ends the typed line and whatever follows it in memory are copied too. Register Pair HL ends 32 bytes on, Register Pair DE at 4300H, Register Pair BC at 0000H.
5211
LD C,00H 0E 00
Load Register C with 00H, drive 0 again (the LDIR left Register C at 00H as well), for the write of the table.
5213
GOSUB to 5234H to write the buffer 4200H back to sector 0 of the directory cylinder of drive Register C (0) and read it back; it returns the Z FLAG when written and checked, else the NZ FLAG with Register A = 15H.
5216
If the NZ FLAG is set (the write or the check failed), JUMP to 521CH to show the error in Register A (15H, GAT WRITE ERROR) and abort.
5219
JUMP to 402DH, the normal exit of the system: VTOS READY. The AUTO line is stored on the diskette.
521C
OR 40H F6 40
OR Register A (the error code 14H or 15H) with 40H: bit 6 set asks 4409H for the text of the error alone, without the ERRCOD line; bit 7 clear means 4409H does not return.
521E
JUMP to 4409H to display the error message of the code in Register A (54H: GAT READ ERROR, 55H: GAT WRITE ERROR); with bit 7 clear SYS4/SYS then takes the abort exit 4030H.
5221H - Read the Granule Allocation Table
Reads sector 0 of the directory cylinder of drive Register C (the granule allocation table, written with the directory data mark) into 4200H-42FFH. Register Pairs DE and HL are kept. Returns the Z FLAG (Register A = 00H) when read; otherwise the NZ FLAG and Register A = 14H, the code GAT READ ERROR.
5221
PUSH DE D5
Save Register Pair DE to the stack, as the read changes it.
5222
PUSH HL E5
Save Register Pair HL (the parameters text) to the stack, as the read uses Register Pair HL for the buffer.
5223
GOSUB to 4B65H: Register D = byte +09H of the drive code table of drive Register C, the directory cylinder of that drive.
5226
LD E,00H 1E 00
Load Register E with 00H: Register Pair DE = the directory cylinder (Register D), sector 0, the granule allocation table.
5228
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, where the table is read to.
522B
GOSUB to 4B45H to read cylinder Register D, sector Register E of drive Register C into the buffer at Register Pair HL (4200H); it returns the Z FLAG and Register A = 00H only for a sector with the directory data mark (driver result 06H).
522E
POP HL E1
Restore Register Pair HL (the parameters text) from the stack.
522F
POP DE D1
Restore Register Pair DE (the caller's value, saved at 5221H) from the stack.
5230
RET Z C8
If the Z FLAG is set (the table is in 4200H), RETURN with Register A = 00H.
5231
LD A,14H 3E 14
Load Register A with 14H, the error code GAT READ ERROR; the NZ FLAG of the read is still set.
5233
RET C9
RETURN with the NZ FLAG and Register A = 14H (GAT READ ERROR).
5234H - Write the Granule Allocation Table
Writes the buffer 4200H-42FFH to sector 0 of the directory cylinder of drive Register C with the directory data mark (driver function 0EH, through 4768H), then reads the sector back without storing it (function 0AH, through 4772H): a sector with the directory data mark gives the driver result 06H. Register Pairs DE and HL are kept. Returns the Z FLAG when written and checked, otherwise the NZ FLAG; Register A = 15H (GAT WRITE ERROR) in both cases.
5234
PUSH DE D5
Save Register Pair DE (4300H, where the LDIR at 520FH left it) to the stack, as the write changes it.
5235
PUSH HL E5
Save Register Pair HL (the command line pointer) to the stack, as the write uses Register Pair HL for the buffer.
5236
GOSUB to 4B65H: Register D = byte +09H of the drive code table of drive Register C, the directory cylinder of that drive.
5239
LD E,00H 1E 00
Load Register E with 00H: Register Pair DE = the directory cylinder (Register D), sector 0, the granule allocation table.
523B
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, the buffer that holds the table with its new AUTO line.
523E
GOSUB to 4768H to write the buffer at Register Pair HL (4200H) to cylinder Register D, sector Register E of drive Register C with the data mark FAH (driver function 0EH); the Z FLAG on success.
5241
If the NZ FLAG is set (the write failed), JUMP to 5248H with the NZ FLAG, which gives error 15H.
5243
GOSUB to 4772H to read cylinder Register D, sector Register E of drive Register C back without storing it (driver function 0AH); Register A = the driver's result.
5246
CP 06H FE 06
Compare Register A (the result of the read back) against 06H, the result for a sector with the directory data mark: the Z FLAG when the table was written correctly, else the NZ FLAG.
5248
LD A,15H 3E 15
Load Register A with 15H, the error code GAT WRITE ERROR; LD does not change the flags of the write or of the compare.
524A
POP HL E1
Restore Register Pair HL (the command line pointer) from the stack.
524B
POP DE D1
Restore Register Pair DE (4300H, saved at 5234H) from the stack.
524C
RET C9
RETURN with the Z FLAG (written and checked) or the NZ FLAG (error), Register A = 15H either way.
5200H - Member 2 (DATE and TIME, Codes 15H and 16H): DATE Sets the Date
SYS1/SYS's command interpreter runs this member for the word DATE (member code 15H, entry 5200H) and for the word TIME (code 16H, entry 522DH); the request handler of SYS0/SYS CALLs the entry with Register Pair HL pointing at the text after the command word and its delimiter. DATE takes mm/dd/yy: three numbers of exactly two decimal digits each, separated by a slash. The numbers go to the clock's date bytes 4044H (year), 4045H (day) and 4046H (month), and are packed into 4306H-4307H, the two bytes that keep the date across a reset: 4306H = month OR 50H, 4307H = day shifted left 3 OR (year less 80). No value is checked against a range. A text that does not have the form displays BAD FORMAT and takes the abort exit 4030H; a good one ends at 402DH (VTOS READY).
5200
LD C,2FH 0E 2F
Load Register C with 2FH, the slash: the separator 525AH expects between the three numbers of a date.
5202
GOSUB to 525AH to read three two digit numbers separated by Register C (a slash) from the text at Register Pair HL into 524EH (month), 524DH (day) and 524CH (year); the Z FLAG when all three were read.
5205
If the NZ FLAG is set (a missing digit or a wrong separator), JUMP to 5243H to display BAD FORMAT and abort.
5208
LD HL,524CH 21 4C 52
Point Register Pair HL to 524CH, the first of the three values just read: 524CH the year, 524DH the day, 524EH the month.
520B
LD DE,4044H 11 44 40
Point Register Pair DE to 4044H, the clock's date bytes 4044H year, 4045H day, 4046H month.
520E
LD BC,0003H 01 03 00
Load Register Pair BC with 0003H, the three bytes of the date.
5211
LDIR ED B0
Copy the three bytes from 524CH-524EH at Register Pair HL to 4044H-4046H at Register Pair DE: 4044H = the year, 4045H = the day, 4046H = the month, all binary. Register Pair BC ends at 0000H.
5213
LD DE,4044H 11 44 40
Point Register Pair DE to 4044H again, the year just stored, to build the packed date for 4306H-4307H.
5216
LD A,(DE) 1A
Fetch the year from 4044H at Register Pair DE into Register A (for example 80 for 1980).
5217
SUB 50H D6 50
SUBtract 50H (80) from Register A: Register A = the year less 80, which is meant to fit in bits 2-0 (80-87). A year below 80 or above 87 is not refused and spoils the day bits.
5219
LD B,A 47
Copy Register A (the year less 80) into Register B.
521A
INC DE 13
Increment Register Pair DE to 4045H, the day.
521B
LD A,(DE) 1A
Fetch the day from 4045H at Register Pair DE into Register A.
521C
RLCA 07
Rotate Register A left one bit (RLCA): the day times 2.
521D
RLCA 07
Rotate Register A left one bit (RLCA): the day times 4.
521E
RLCA 07
Rotate Register A left one bit (RLCA): the day times 8, in bits 7-3 (a day up to 31).
521F
OR B B0
OR Register A (the day in bits 7-3) with Register B (the year less 80): the packed byte, day in bits 7-3, year less 80 in bits 2-0.
5220
LD (4307H),A 32 07 43
Store Register A (the packed day and year) to 4307H, the second byte of the date kept across a reset, which SYS0/SYS's reset decodes.
5223
INC DE 13
Increment Register Pair DE to 4046H, the month.
5224
LD A,(DE) 1A
Fetch the month from 4046H at Register Pair DE into Register A.
5225
OR 50H F6 50
OR Register A (the month) with 50H, the mark the reset tests for (4306H XOR 50H must give a month 1-12, otherwise the boot shows no date).
5227
LD (4306H),A 32 06 43
Store Register A (the month OR 50H) to 4306H, the first byte of the date kept across a reset.
522A
JUMP to 402DH, the normal exit of the system: VTOS READY. The date is set.
522DH - TIME (Code 16H): Set the Time
Entry 522DH for the word TIME. TIME takes hh:mm:ss: three numbers of exactly two decimal digits each, separated by a colon. The hours go to 4043H, the minutes to 4042H and the seconds to 4041H, the clock task's counters; no value is checked against a range. A text that does not have the form displays BAD FORMAT and aborts.
522D
LD C,3AH 0E 3A
Load Register C with 3AH, the colon: the separator 525AH expects between the three numbers of a time.
522F
GOSUB to 525AH to read three two digit numbers separated by Register C (a colon) from the text at Register Pair HL into 524EH (hours), 524DH (minutes) and 524CH (seconds); the Z FLAG when all three were read.
5232
If the NZ FLAG is set (a missing digit or a wrong separator), JUMP to 5243H to display BAD FORMAT and abort.
5235
LD HL,524CH 21 4C 52
Point Register Pair HL to 524CH, the first of the three values just read: 524CH the seconds, 524DH the minutes, 524EH the hours.
5238
LD DE,4041H 11 41 40
Point Register Pair DE to 4041H, the clock's counters 4041H seconds, 4042H minutes, 4043H hours.
523B
LD BC,0003H 01 03 00
Load Register Pair BC with 0003H, the three bytes of the time.
523E
LDIR ED B0
Copy the three bytes from 524CH-524EH at Register Pair HL to 4041H-4043H at Register Pair DE: 4041H = the seconds, 4042H = the minutes, 4043H = the hours, all binary. Register Pair BC ends at 0000H.
5240
JUMP to 402DH, the normal exit of the system: VTOS READY. The time is set.
5243H - Bad Format
DATE and TIME come here when 525AH returns the NZ FLAG: the message BAD FORMAT is displayed and logged, and the command takes the abort exit.
5243
LD HL,524FH 21 4F 52
Point Register Pair HL to 524FH, the message BAD FORMAT ended by 0DH.
5246
GOSUB to 447BH to display the text at Register Pair HL (524FH) and write it to the job log.
5249
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
524C-524E
DEFS 3
Not in the file (the gap between the two load blocks): the three values 525AH reads, kept in reverse order of typing. 524CH the third number (the year of DATE, the seconds of TIME), 524DH the second (the day, the minutes), 524EH the first (the month, the hours); the stores are at 5265H, the LDIRs at 5211H and 523EH read them.
524F-5258
DEFM "BAD FORMAT" 42 41 44 20 46 4F 52 4D 41 54
The message of a date or time text that does not have the form, displayed by 5246H.
5259
DEFB 0DH 0D
The carriage return that ends the message BAD FORMAT and the line on the display.
525AH - Read Three Two Digit Numbers
Register C = the separator (2FH slash or 3AH colon), Register Pair HL = the text. Reads a two digit number, stores it at 524EH, and while Register B counts the three numbers takes one separator and the next number into 524DH and 524CH. Returns the Z FLAG when the third number is stored (the text after it is not looked at), the NZ FLAG when a digit is missing or the character after a number is not Register C. Register Pair HL ends past the last character read.
525A
LD DE,524EH 11 4E 52
Point Register Pair DE to 524EH, the place of the first number; each number lowers Register Pair DE by one.
525D
LD B,03H 06 03
Load Register B with 03H, the count of the three numbers.
525F
PUSH DE D5
Loop Start
Save Register Pair DE (the place of this number, 524EH down to 524CH) to the stack, as 526FH uses Register E.
5260
GOSUB to 526FH to read two decimal digits at Register Pair HL: Register A = the number with the Z FLAG, or the NZ FLAG when one of them is not a digit.
5263
POP DE D1
Restore Register Pair DE (the place of this number) from the stack.
5264
RET NZ C0
If the NZ FLAG is set (not two digits), RETURN with the NZ FLAG: BAD FORMAT.
5265
LD (DE),A 12
Store Register A (the number) to the place at Register Pair DE (524EH, 524DH or 524CH).
5266
DEC DE 1B
Decrement Register Pair DE to the place of the next number.
5267
DEC B 05
Decrement Register B, the count of the numbers still to read.
5268
RET Z C8
If the Z FLAG is set (Register B = 00H: three numbers stored), RETURN with the Z FLAG; whatever follows the third number is not read.
5269
LD A,(HL) 7E
Fetch the character after the number at Register Pair HL into Register A, the separator.
526A
INC HL 23
Increment Register Pair HL past the separator.
526B
CP C B9
Compare Register A (the character after the number) against Register C, the separator of this command (a slash for DATE, a colon for TIME).
526C
If the Z FLAG is set (the separator is there), JUMP back to 525FH for the next number.
526E
RET C9
RETURN with the NZ FLAG of the compare: the character after a number is not the separator, BAD FORMAT.
526FH - Read Two Decimal Digits
Reads two characters at Register Pair HL that must both be the digits 0-9 and returns their value 00-99 in Register A with the Z FLAG. Register E is used for the sum. When a character is not a digit the NZ FLAG is returned at once with Register Pair HL past that character.
526F
GOSUB to 5286H to fetch the first character at Register Pair HL less 30H into Register A; the CARRY FLAG when it is a digit 0-9.
5272
If the NC FLAG is set (the character is not a digit), JUMP to 5284H to return the NZ FLAG.
5274
LD E,A 5F
Copy Register A (the first digit, the tens) into Register E.
5275
RLCA 07
Rotate Register A left one bit (RLCA): the digit times 2.
5276
RLCA 07
Rotate Register A left one bit (RLCA): the digit times 4.
5277
ADD A,E 83
Add Register E (the digit) to Register A: the digit times 5.
5278
RLCA 07
Rotate Register A left one bit (RLCA): the digit times 10.
5279
LD E,A 5F
Copy Register A (the tens digit times 10) into Register E.
527A
GOSUB to 5286H to fetch the second character at Register Pair HL less 30H into Register A; the CARRY FLAG when it is a digit 0-9.
527D
If the NC FLAG is set (the character is not a digit), JUMP to 5284H to return the NZ FLAG.
527F
ADD A,E 83
Add Register E (the tens times 10) to Register A (the units digit): the number 0-99.
5280
LD E,A 5F
Copy Register A (the number) into Register E.
5281
XOR A AF
Set Register A to 00H (XOR A) to set the Z FLAG, the sign of two good digits.
5282
LD A,E 7B
Copy Register E (the number) into Register A; LD does not change the Z FLAG.
5283
RET C9
RETURN with Register A = the number 0-99 and the Z FLAG.
5284
OR A B7
OR Register A with itself: Register A is the character less 30H, 0AH or more (a character below 30H wrapped round to D0H or more), so the NZ FLAG is set.
5285
RET C9
RETURN with the NZ FLAG: the character was not a digit.
5286H - Fetch a Character as a Digit
Fetches the character at Register Pair HL, moves Register Pair HL past it and returns it less 30H in Register A with the CARRY FLAG when it is a digit 0-9 (Register A = 00H-09H), the NC FLAG otherwise.
5286
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
5287
INC HL 23
Increment Register Pair HL past the character.
5288
SUB 30H D6 30
SUBtract 30H (the character 0) from Register A: the digits 0-9 become 00H-09H.
528A
CP 0AH FE 0A
Compare Register A against 0AH: the CARRY FLAG when Register A is 00H-09H (a digit), the NC FLAG for any other character.
528C
RET C9
RETURN with Register A = the character less 30H and the CARRY FLAG for a digit.
5200H - Member 3 (ALLOC, Code 13H): Allocate Space to a File
SYS1/SYS's command interpreter runs this member for the word ALLOC (member code 13H); the request handler of SYS0/SYS CALLs 5200H with Register Pair HL pointing at the text after the command word. The syntax the code reads is ALLOC filespec (SIZE=n) or (S=n), n in K (1024 bytes, 4 sectors). The file is opened or created with 256 byte records; when n is not 0 the member positions to record 4 x n less 1, writes a sector of E5H bytes there (SYS0/SYS's write asks SYS8/SYS for space when no extent of the file holds that sector), puts the old ending record number back into the control block and writes it to the directory, so the file's size in records does not change. Then, with or without a size, it sets bit 7 of byte +01H of the file's directory record, the bit SYS3/SYS's close tests to keep the space of the file. Success ends at 402DH; errors end through 4409H or with the messages FILE SPEC REQUIRED and PARAMETER ERROR.
5200
LD DE,52A3H 11 A3 52
Point Register Pair DE to 52A3H, the file control block of the member (not in the file), for the file specification.
5203
GOSUB to 441CH (SYS1/SYS 4FCEH) to copy the file specification at Register Pair HL into the control block at Register Pair DE (52A3H); the Z FLAG when it is good, Register Pair HL past it.
5206
If the NZ FLAG is set (no file specification, or a bad one), JUMP to 526EH to display FILE SPEC REQUIRED and abort.
5208
LD DE,52C3H 11 C3 52
Point Register Pair DE to 52C3H, the parameter table of ALLOC: SIZE and S, both storing to 521EH.
520B
GOSUB to 4476H (SYS1/SYS 510FH) to read the parameter list in parentheses at Register Pair HL against the table at Register Pair DE (52C3H); a value of SIZE or S goes to 521EH-521FH. The Z FLAG when the list is good or absent.
520E
If the NZ FLAG is set (an unknown word or a bad value), JUMP to 528AH to display PARAMETER ERROR and abort.
5210
LD DE,52A3H 11 A3 52
Point Register Pair DE to 52A3H, the control block that holds the file specification.
5213
LD HL,52D4H 21 D4 52
Point Register Pair HL to 52D4H, the 256 byte sector buffer of the file (not in the file).
5216
LD B,00H 06 00
Load Register B with 00H, the record length 256 (whole sectors).
5218
GOSUB to 4420H (SYS2/SYS, request A4H) to open the file of the control block at Register Pair DE with the buffer at Register Pair HL and record length Register B, creating it when it is not in the directory; the Z FLAG on success, else the error code in Register A.
521B
If the NZ FLAG is set (the open or the create failed), JUMP to 5269H to display the error of Register A and abort.
521D
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the size in K. The operand at 521EH-521FH is 0000H in the file; SYS1/SYS's parameter reader (called at 520BH) stores the value of SIZE or S there, so Register Pair BC = n, or 0000H when no size was given (FFFFH for SIZE written without a value).
5220
LD A,B 78
Copy Register B (the high byte of the size) into Register A.
5221
OR C B1
OR Register A with Register C (the low byte of the size): the Z FLAG when the size is 0000H.
5222
If the Z FLAG is set (no size), JUMP to 5253H to mark the directory record only, with Register A = 00H and the Z FLAG for the end.
5224
LD HL,(52AFH) 2A AF 52
Fetch the ending record number from 52AFH-52B0H (byte +0CH-+0DH of the control block at 52A3H) into Register Pair HL: the size of the file in sectors as the open found it (0000H for a new file).
5227
PUSH HL E5
Save Register Pair HL (the ending record number) to the stack, to put it back after the write.
5228
SLA C CB 21
Shift Register C (the low byte of the size) left one bit: bit 7 goes to the CARRY FLAG.
522A
RL B CB 10
Rotate Register B (the high byte of the size) left through the CARRY FLAG: Register Pair BC = the size times 2.
522C
SLA C CB 21
Shift Register C left one bit again: bit 7 goes to the CARRY FLAG.
522E
RL B CB 10
Rotate Register B left through the CARRY FLAG: Register Pair BC = the size times 4, the number of 256 byte sectors in n K (the top two bits of the size are lost).
5230
DEC BC 0B
Decrement Register Pair BC: the number of the last sector of n K (sectors count from 0).
5231
GOSUB to 4442H to position the file of the control block at Register Pair DE (52A3H) to sector Register Pair BC. At or past the end of file it returns error 1CH or 1DH, which is not tested: the position is set all the same.
5234
LD HL,52D4H 21 D4 52
Point Register Pair HL to 52D4H, the file's sector buffer, to fill it.
5237
LD DE,52D5H 11 D5 52
Point Register Pair DE to 52D5H, one byte above, the destination of the fill.
523A
LD BC,00FFH 01 FF 00
Load Register Pair BC with 00FFH, the 255 bytes after the first.
523D
LD (HL),E5H 36 E5
Store E5H to the first byte of the buffer at Register Pair HL (52D4H), the byte the whole sector is filled with.
523F
LDIR ED B0
Copy 255 bytes from Register Pair HL to Register Pair DE, one byte above: each byte copies the one before it, so 52D4H-53D3H all hold E5H. Register Pair BC ends at 0000H.
5241
LD DE,52A3H 11 A3 52
Point Register Pair DE to 52A3H, the control block of the file.
5244
GOSUB to 4439H to write the buffer 52D4H (E5H bytes) as the sector of the position set at 5231H (Register Pair BC is 0000H after the LDIR and is not used by the write): SYS0/SYS asks SYS8/SYS (request 9AH) for space when no extent of the file holds that sector, and moves the ending record number past it when the sector is at or past the end of file. Register A and the flags return the result.
5247
POP HL E1
Restore Register Pair HL (the ending record number before the write) from the stack.
5248
LD (52AFH),HL 22 AF 52
Store Register Pair HL to 52AFH-52B0H, bytes +0CH-+0DH of the control block at 52A3H: the end of file is put back where it was, so the file keeps its records and only gains space.
524B
PUSH AF F5
Save Register Pair AF (the result of the write at 5244H) to the stack.
524C
GOSUB to 443FH to rewind the file of the control block at Register Pair DE (52A3H) to sector 0; the result is not tested.
524F
GOSUB to 444EH to write the ending record number of the control block at Register Pair DE (the old one, just put back) to bytes 14H-15H of the file's directory record; the result is not tested.
5252
POP AF F1
Restore Register Pair AF (the result of the write at 5244H) from the stack.
5253
PUSH AF F5
Save Register Pair AF (the result of the write, or Register A = 00H with the Z FLAG when there was no size) to the stack.
5254
LD BC,(52A9H) ED 4B A9 52
Fetch 52A9H-52AAH into Register Pair BC: Register C = byte +06H of the control block at 52A3H (the drive), Register B = byte +07H (the directory entry code of the file).
5258
GOSUB to 4B10H to read the directory sector of entry Register B on drive Register C into 4200H; Register Pair HL returns the address of the file's record in it.
525B
If the NZ FLAG is set (the directory could not be read), JUMP to 5269H to display the error of Register A (11H); the word pushed at 5253H is left on the stack, which the abort exit resets.
525D
INC HL 23
Increment Register Pair HL to byte +01H of the directory record.
525E
SET 7,(HL) CB FE
Set bit 7 of byte +01H of the directory record at Register Pair HL: SYS3/SYS's close (its 4E91H) gives back no space of a file with this bit set.
5260
GOSUB to 4B1FH to write the directory sector 4200H back for entry Register B on drive Register C and read it back; the Z FLAG when written, else error 12H or 0FH in Register A.
5263
If the NZ FLAG is set (the directory write failed), JUMP to 5269H to display the error of Register A, with the word of 5253H left on the stack.
5265
POP AF F1
Restore Register Pair AF (the result of the write, or 00H with the Z FLAG) from the stack.
5266
If the Z FLAG is set (the space was written, or no size was asked), JUMP to 402DH, the normal exit: VTOS READY.
5269
OR 40H F6 40
OR Register A (the error code of the open, of the write or of the directory) with 40H: bit 6 set asks for the text of the error alone; bit 7 clear means no return.
526B
JUMP to 4409H to display the error message of the code in Register A; with bit 7 clear SYS4/SYS then takes the abort exit 4030H.
526EH - The Two Messages
526EH displays FILE SPEC REQUIRED (no good file specification after ALLOC), 528AH displays PARAMETER ERROR (a bad parameter list); both are written to the job log as well, and both take the abort exit.
526E
LD HL,5277H 21 77 52
Point Register Pair HL to 5277H, the message FILE SPEC REQUIRED ended by 0DH.
5271
GOSUB to 447BH to display the text at Register Pair HL (5277H) and write it to the job log.
5274
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
5277-5288
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of a missing or bad file specification, displayed by 5271H.
5289
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED.
528A
LD HL,5293H 21 93 52
Point Register Pair HL to 5293H, the message PARAMETER ERROR ended by 0DH.
528D
GOSUB to 447BH to display the text at Register Pair HL (5293H) and write it to the job log.
5290
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
5293-52A1
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of a bad parameter list, displayed by 528DH.
52A2
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
52A3H - Work Areas and the Parameter Table
The control block of the file and the sector buffer are not in the file; the parameter table between them is.
52A3-52C2
DEFS 32
Not in the file (the gap between the two load blocks): the 32 byte file control block of the file to allocate. 441CH (5203H) writes the file specification into it, 4420H (5218H) opens it; 52A9H-52AAH (+06H drive, +07H directory entry code) are read at 5254H, 52AFH-52B0H (+0CH-+0DH, the ending record number) at 5224H and written at 5248H.
52C3-52C8
DEFM "SIZE " 53 49 5A 45 20 20
Parameter table, entry 1: the name SIZE, filled to 6 characters with spaces, for SYS1/SYS's parameter reader (520BH).
52C9-52CA
DEFW 521EH 1E 52
Entry 1: the address the value of SIZE is stored to, 521EH, the operand of LD BC,0000H at 521DH.
52CB-52D0
DEFM "S " 53 20 20 20 20 20
Parameter table, entry 2: the short name S, filled to 6 characters with spaces.
52D1-52D2
DEFW 521EH 1E 52
Entry 2: the value of S goes to 521EH as well, the operand of LD BC at 521DH.
52D3
DEFB 00H 00
The 00H in place of a first character that ends the parameter table of ALLOC.
52D4-53D3
DEFS 256
Not in the file: the file's 256 byte sector buffer, given to the open at 5213H. 523DH-523FH fill it with E5H and 4439H (5244H) writes it as the last sector of the size.
5200H - Member 4 (KILL, Code 18H): Remove a File or a Device
SYS1/SYS's command interpreter runs this member for the word KILL (member code 18H); the request handler of SYS0/SYS CALLs 5200H with Register Pair HL pointing at the text after the command word. The member reads a file specification (or an asterisk and a device name) into the control block at 5239H, opens it through 4424H (SYS2/SYS) and hands the open block to 442CH, request 9CH, which SYS10/SYS carries out: it removes the file from the directory and gives its space back, or removes the device control block of a device. Success ends at 402DH; an error of the open or of the removal is shown through 4409H; a missing specification displays FILE SPEC REQUIRED.
5200
LD DE,5239H 11 39 52
Point Register Pair DE to 5239H, the file control block of the member (above its last byte, not in the file).
5203
GOSUB to 441CH (SYS1/SYS 4FCEH) to copy the file specification at Register Pair HL into the control block at Register Pair DE (5239H); the Z FLAG when it is good.
5206
If the NZ FLAG is set (no file specification, or a bad one), JUMP to 521DH to display FILE SPEC REQUIRED and abort.
5209
GOSUB to 4424H (SYS2/SYS, request 94H) to open the file or device of the control block at Register Pair DE (5239H). Register Pair HL (the command line after the specification, as 441CH left it) is passed as the buffer and Register B (whatever 441CH's copy of the specification left in it; KILL does not set it) as the record length; KILL reads and writes no record, so neither is used. The Z FLAG when it is open, else the error code in Register A (for example 18H, FILE NOT IN DIRECTORY).
520C
If the NZ FLAG is set (the open failed), JUMP to 5218H to display the error of Register A.
520F
GOSUB to 442CH (request 9CH, SYS10/SYS) to remove the file or device of the open control block at Register Pair DE: for a file its directory record and its space are freed and the control block is cleared; the Z FLAG on success, else the error code in Register A (25H for a file whose access level forbids it).
5212
If the NZ FLAG is set (the removal failed), JUMP to 5218H to display the error of Register A.
5215
JUMP to 402DH, the normal exit of the system: VTOS READY.
5218
OR 40H F6 40
OR Register A (the error code of the open or of the removal) with 40H: bit 6 set asks for the text of the error alone; bit 7 clear means no return.
521A
JUMP to 4409H to display the error message of the code in Register A; with bit 7 clear SYS4/SYS then takes the abort exit 4030H.
521D
LD HL,5226H 21 26 52
Point Register Pair HL to 5226H, the message FILE SPEC REQUIRED ended by 0DH.
5220
GOSUB to 447BH to display the text at Register Pair HL (5226H) and write it to the job log.
5223
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
5226-5237
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of a missing or bad file specification after KILL, displayed by 5220H.
5238
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED.
5239-5258
DEFS 32
Not in the file (above the member's last byte): the 32 byte control block of the file or device to remove. 441CH (5203H) writes the specification into it, 4424H (5209H) opens it and 442CH (520FH) removes what it names.
5200H - Member 5 (LIB, Code 19H): Display the Library Commands
SYS1/SYS's command interpreter runs this member for the word LIB (member code 19H). SYS1/SYS is still the overlay at 4E00H-51FFH (LIB issues no request that would replace it), so the member reads SYS1/SYS's command table from its second entry at 4EADH: each entry is 8 bytes, a name of 6 characters filled with spaces and a word. LIB displays the names four to a line, each name after 2 spaces and followed by 8 spaces (the codes C2H and C8H, which the ROM's display driver shows as that many spaces), until an entry whose first byte is 00H (4FCDH). The table's first entry, the hidden word O! at 4EA5H, is not shown; the 36 entries from ALLOC to XFER, BOOT among them, are. The text after LIB is ignored. The member ends at 402DH (VTOS READY).
5200
LD HL,4EADH 21 AD 4E
Point Register Pair HL to 4EADH, the second entry of SYS1/SYS's command table (the first library command name, ALLOC), skipping entry 1 at 4EA5H.
5203
LD C,04H 0E 04
Line Start
Load Register C with 04H, the count of the names on one line of the display.
5205
LD A,C2H 3E C2
Load Register A with C2H, a space compression code: the ROM's display driver shows C0H plus n as n spaces, here 2.
5207
GOSUB to 0033H, the ROM's routine that displays the character in Register A (C2H, two spaces) at the cursor.
520A
LD B,06H 06 06
Name Start
Load Register B with 06H, the 6 characters of a name in the table.
520C
LD A,(HL) 7E
Fetch the next character of the name at Register Pair HL (in SYS1/SYS's table) into Register A.
520D
INC HL 23
Increment Register Pair HL to the next character of the entry.
520E
GOSUB to 0033H to display the character in Register A at the cursor.
5211
Decrement Register B (the characters of the name still to show) and JUMP to 520CH while it is not 00H.
5213
LD A,C8H 3E C8
Load Register A with C8H, the space compression code for 8 spaces between this name and the next.
5215
GOSUB to 0033H to display Register A (C8H, eight spaces) at the cursor.
5218
INC HL 23
Increment Register Pair HL past the low byte of the entry's word (the member code, or the address of BOOT).
5219
INC HL 23
Increment Register Pair HL past the high byte of the word: Register Pair HL = the first byte of the next entry.
521A
LD A,(HL) 7E
Fetch the first character of the next entry at Register Pair HL into Register A.
521B
OR A B7
OR Register A with itself: the Z FLAG when it is 00H, the end of the table at 4FCDH.
521C
If the Z FLAG is set (no more entries), JUMP to 5228H to end the last line and return to VTOS READY.
521E
DEC C 0D
Decrement Register C, the count of the names still to show on this line.
521F
If the NZ FLAG is set (room for another name on this line), JUMP to 520AH to show the next name.
5221
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends a line of four names.
5223
GOSUB to 0033H to display Register A (0DH) at the cursor.
5226
JUMP to 5203H to begin the next line with the count of four names in Register C.
5228
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the last line of names.
522A
GOSUB to 0033H to display Register A (0DH) at the cursor.
522D
JUMP to 402DH, the normal exit of the system: VTOS READY.
5200H - Member 6 (DEBUG, CLOCK, TRACE and VERIFY, Codes 14H, 17H, 1AH, 1BH): DEBUG Turns the Monitor On or Off
SYS1/SYS's command interpreter runs this member for four words: DEBUG (member code 14H, entry 5200H), CLOCK (17H, 5241H), TRACE (1AH, 5257H) and VERIFY (1BH, 5267H); the request handler of SYS0/SYS CALLs the entry with Register Pair HL pointing at the text after the command word. All four read an optional parameter list through 5276H or 527BH: the word OFF, NO or N (written alone) turns the function off; no list, ON, YES or Y turn it on. DEBUG also takes EXT or E. DEBUG on sets bit 7 of 430FH (SYS0/SYS's load and run routine 4CCBH then enters the monitor at the start of every program) and points the BREAK vector 4315H-4317H at JP 400FH (RST 30H, the monitor of SYS5/SYS); with EXT it first has SYS9/SYS (request 8BH) loaded and run. DEBUG off clears bit 7 of 430FH and stores C9H (RET) at 4315H, so BREAK does nothing. DEBUG ends at 402DH.
5200
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, to clear the value of the parameter EXT.
5203
LD (523CH),BC ED 43 3C 52
Store Register Pair BC (0000H) to 523CH-523DH, the word where SYS1/SYS's parameter reader puts the value of EXT or E (5285H clears it once more).
5207
GOSUB to 5276H to read the parameter list at Register Pair HL against DEBUG's table at 52B2H (EXT, E, ON, OFF, YES, NO, Y, N); it returns the Z FLAG when OFF, NO or N was given, the NZ FLAG for on.
520A
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags, whose bit 7 makes the request handler start each program it loads in the monitor.
520D
DI F3
Disable interrupts, so that a BREAK cannot use the BREAK vector 4315H-4317H while it is being changed.
520E
If the Z FLAG is set (DEBUG (OFF)), JUMP to 522CH to turn the monitor off.
5210
LD A,(523CH) 3A 3C 52
Fetch the low byte of the value of EXT from 523CH into Register A (00H when EXT was not given, FFH for EXT written alone).
5213
OR A B7
OR Register A (the low byte of EXT's value) with itself: the NZ FLAG when it is not 00H.
5214
PUSH HL E5
Save Register Pair HL (430FH) to the stack, as the load of the extended monitor changes it.
5215
If the NZ FLAG is set (EXT given), GOSUB to 523EH to have SYS9/SYS, the extended monitor, loaded and run through request 8BH.
5218
POP HL E1
Restore Register Pair HL (430FH) from the stack.
5219
SET 7,(HL) CB FE
Set bit 7 of 430FH at Register Pair HL: SYS0/SYS's load and run routine (4CCBH, its test at 4CDEH) now enters the monitor at the start of every program it runs, and SYS1/SYS's VTOS READY keeps BREAK on (its 4E3CH).
521B
LD HL,400FH 21 0F 40
Point Register Pair HL to 400FH, the RST 30H vector, JP 44B4H: the entry to the monitor of SYS5/SYS.
521E
LD A,C3H 3E C3
Load Register A with C3H, the opcode JP, for the BREAK vector byte.
5220
LD (4316H),HL 22 16 43
Store Register Pair HL (400FH) to 4316H-4317H, the address of the BREAK vector. 4315H still holds C9H (stored by the request handler), so a BREAK cannot take the half written address.
5223
LD (4315H),A 32 15 43
Store Register A (C3H) to 4315H: the BREAK vector is now JP 400FH, so BREAK enters the monitor.
5226
LD A,CDH 3E CD
Load Register A with CDH. Nothing reads this value: 402DH loads Register A itself.
5228
EI FB
Enable interrupts again: the BREAK vector is complete.
5229
JUMP to 402DH, the normal exit of the system: VTOS READY, with the monitor on.
522C
RES 7,(HL) CB BE
Reset bit 7 of 430FH at Register Pair HL: programs are started without the monitor, and SYS1/SYS's VTOS READY leaves BREAK off.
522E
LD A,C9H 3E C9
Load Register A with C9H, the opcode RET, for the BREAK vector byte.
5230
LD (4315H),A 32 15 43
Store Register A (C9H) to 4315H: the BREAK vector is a RET, so BREAK does nothing.
5233
LD A,3EH 3E 3E
Load Register A with 3EH. Nothing reads this value: 402DH loads Register A itself.
5235
LD HL,EFA3H 21 A3 EF
Load Register Pair HL with EFA3H. Nothing reads this value: 402DH does not use Register Pair HL.
5238
EI FB
Enable interrupts again: the BREAK vector byte is complete.
5239
JUMP to 402DH, the normal exit of the system: VTOS READY, with the monitor off.
523C-523D
DEFW 0000H 00 00
The value of the parameter EXT or E: 5203H and 5285H clear it, SYS1/SYS's parameter reader (5289H) stores it through the table entries at 52B8H and 52C0H, and 5210H tests its low byte.
523EH - Load the Extended Monitor
Request 8BH names SYS9/SYS (bits 3-0 = BH) and its function 0 (bits 6-4). The request handler drops the return address of the RST 28H, loads SYS9/SYS at 4E00H over SYS1/SYS and calls it; its RET comes back to the caller of 523EH, the CALL NZ at 5215H.
523E
LD A,8BH 3E 8B
Load Register A with 8BH, the request code of SYS9/SYS, function 0: the extended monitor.
5240
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H, which loads SYS9/SYS and runs it with Register A = 8BH; its result returns to 5218H, after the CALL NZ that reached 523EH.
5241H - CLOCK (Code 17H): The Clock Display
Entry 5241H for the word CLOCK. The clock display task's control block 4DABH in SYS0/SYS writes the time at 3C35H, the top line of the screen, once a second. CLOCK installs it in task slot 6 (4410H) or, with OFF, NO or N, empties slot 6 (4413H). The time last written stays on the screen.
5241
GOSUB to 527BH to read the parameter list at Register Pair HL against the table at 52C2H (ON, OFF, YES, NO, Y, N); the Z FLAG when OFF, NO or N was given, the NZ FLAG for on.
5244
LD DE,4DABH 11 AB 4D
Point Register Pair DE to 4DABH, the task control block of SYS0/SYS's clock display.
5247
LD A,06H 3E 06
Load Register A with 06H, task slot 6, the slot of the clock display. LD does not change the Z FLAG of 527BH.
5249
If the Z FLAG is set (CLOCK (OFF)), JUMP to 5251H to empty slot Register A (06H).
524B
GOSUB to 4410H to install the task control block at Register Pair DE (4DABH) in task slot Register A (06H): the clock is displayed from now on.
524E
JUMP to 402DH, the normal exit of the system: VTOS READY.
5251
GOSUB to 4413H to empty task slot Register A (06H for CLOCK, 0BH for TRACE): the slot gets the empty task control block 45BBH.
5254
JUMP to 402DH, the normal exit of the system: VTOS READY.
5257H - TRACE (Code 1AH): The Program Counter Display
Entry 5257H for the word TRACE. The trace task's control block 4DDBH in SYS0/SYS writes the interrupted program counter in hex at 3C2EH, on the top line of the screen, at every clock interrupt. TRACE installs it in task slot 11 (0BH) or, with OFF, NO or N, empties that slot through 5251H.
5257
GOSUB to 527BH to read the parameter list at Register Pair HL against the table at 52C2H (ON, OFF, YES, NO, Y, N); the Z FLAG when OFF, NO or N was given, the NZ FLAG for on.
525A
LD DE,4DDBH 11 DB 4D
Point Register Pair DE to 4DDBH, the task control block of SYS0/SYS's trace display.
525D
LD A,0BH 3E 0B
Load Register A with 0BH, task slot 11, the slot of the trace (run at every clock interrupt). LD does not change the Z FLAG.
525F
If the Z FLAG is set (TRACE (OFF)), JUMP to 5251H to empty slot Register A (0BH).
5261
GOSUB to 4410H to install the task control block at Register Pair DE (4DDBH) in task slot Register A (0BH): the program counter is displayed from now on.
5264
JUMP to 402DH, the normal exit of the system: VTOS READY.
5267H - VERIFY (Code 1BH): Read Back Every Record Written
Entry 5267H for the word VERIFY. 4439H, the system's write a record entry, is JP 48C0H; VERIFY changes its address to 48DBH, the write that reads every sector back (the routine of 443CH), and VERIFY with OFF, NO or N puts 48C0H back. VERIFY returns through the request handler instead of jumping to 402DH.
5267
GOSUB to 527BH to read the parameter list at Register Pair HL against the table at 52C2H (ON, OFF, YES, NO, Y, N); the Z FLAG when OFF, NO or N was given, the NZ FLAG for on.
526A
LD HL,48C0H 21 C0 48
Point Register Pair HL to 48C0H, SYS0/SYS's write a record without the read back, the address of 4439H for VERIFY (OFF). LD does not change the Z FLAG.
526D
If the Z FLAG is set (VERIFY (OFF)), JUMP to 5272H to store Register Pair HL (48C0H).
526F
LD HL,48DBH 21 DB 48
Point Register Pair HL to 48DBH, SYS0/SYS's write a record with every sector read back, for VERIFY on.
5272
LD (443AH),HL 22 3A 44
Store Register Pair HL (48C0H or 48DBH) to 443AH-443BH, the address of the JP at 4439H: every program's record write now goes to that routine.
5275
RET C9
RETURN to the request handler at 4C4BH, which puts the BREAK vector byte back and returns to 402DH (VTOS READY), the address SYS1/SYS pushed before it ran the member.
5276H - Read the On or Off Flag
5276H uses DEBUG's table at 52B2H, 527BH the table at 52C2H; both then clear the two cells, read the parameter list at Register Pair HL with SYS1/SYS's reader (4476H) and test the word of OFF, NO and N, the operand at 5290H. The words ON, YES and Y store to 5297H, which nothing reads. A bad list displays PARAMETER ERROR and aborts. Returns the Z FLAG when the value of OFF is FFFFH (the word written alone; any value whose two bytes ORed give FFH), the NZ FLAG otherwise; Register A = 00H or not.
5276
LD DE,52B2H 11 B2 52
Point Register Pair DE to 52B2H, DEBUG's parameter table: EXT and E, then the entries of 52C2H.
5279
JUMP to 527EH, past the load of the other table.
527B
LD DE,52C2H 11 C2 52
Point Register Pair DE to 52C2H, the parameter table of CLOCK, TRACE and VERIFY: ON, OFF, YES, NO, Y, N.
527E
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, to clear the value of OFF and of EXT.
5281
LD (5290H),BC ED 43 90 52
Store Register Pair BC (0000H) to 5290H-5291H, the operand of LD BC at 528FH, where the value of OFF, NO or N is stored.
5285
LD (523CH),BC ED 43 3C 52
Store Register Pair BC (0000H) to 523CH-523DH, the value of EXT or E.
5289
GOSUB to 4476H (SYS1/SYS 510FH) to read the parameter list in parentheses at Register Pair HL against the table at Register Pair DE; a word written alone stores FFFFH at the address of its entry. The Z FLAG when the list is good or absent.
528C
If the NZ FLAG is set (an unknown word or a bad value), JUMP to 5299H to display PARAMETER ERROR and abort.
528F
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of OFF, NO or N. The operand at 5290H-5291H is 0000H in the file and is cleared by 5281H; SYS1/SYS's reader (5289H) stores FFFFH there when one of these words was given.
5292
LD A,B 78
Copy Register B (the high byte of the value of OFF) into Register A.
5293
OR C B1
OR Register A with Register C (the low byte of the value of OFF): FFH when OFF, NO or N was written alone.
5294
XOR FFH EE FF
Exclusive OR Register A with FFH: Register A = 00H and the Z FLAG for OFF, a value other than 00H and the NZ FLAG for on.
5296
RET C9
RETURN with the Z FLAG for off, the NZ FLAG for on.
5297-5298
DEFW 0000H 00 00
The value of ON, YES or Y: SYS1/SYS's reader stores FFFFH here (table entries 52C8H, 52D8H, 52E8H), and nothing reads it. On is whatever is not off.
5299H - Parameter Error
A bad parameter list after DEBUG, CLOCK, TRACE or VERIFY: the message is displayed and logged and the command takes the abort exit.
5299
LD HL,52A2H 21 A2 52
Point Register Pair HL to 52A2H, the message PARAMETER ERROR ended by 0DH.
529C
GOSUB to 447BH to display the text at Register Pair HL (52A2H) and write it to the job log.
529F
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
52A2-52B0
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of a bad parameter list, displayed by 529CH.
52B1
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
52B2H - The Parameter Tables
Entries of 8 bytes for SYS1/SYS's reader: the name filled with spaces to 6 characters, then the address of the word the value goes to. DEBUG's table starts at 52B2H with EXT and E; the table of CLOCK, TRACE and VERIFY starts at 52C2H; both end at the 00H of 52F2H.
52B2-52B7
DEFM "EXT " 45 58 54 20 20 20
DEBUG's table, entry 1: the name EXT, filled to 6 characters with spaces.
52B8-52B9
DEFW 523CH 3C 52
Entry EXT: its value goes to 523CH, which 5210H tests.
52BA-52BF
DEFM "E " 45 20 20 20 20 20
DEBUG's table, entry 2: the short name E, filled to 6 characters with spaces.
52C0-52C1
DEFW 523CH 3C 52
Entry E: its value goes to 523CH as well, the word that 5210H tests.
52C2-52C7
DEFM "ON " 4F 4E 20 20 20 20
Start of the table of CLOCK, TRACE and VERIFY (entry 3 of DEBUG's): the name ON.
52C8-52C9
DEFW 5297H 97 52
Entry ON: its value goes to 5297H, which nothing reads.
52CA-52CF
DEFM "OFF " 4F 46 46 20 20 20
The name OFF, the word that turns a function off.
52D0-52D1
DEFW 5290H 90 52
Entry OFF: its value goes to 5290H, the operand of LD BC at 528FH.
52D2-52D7
DEFM "YES " 59 45 53 20 20 20
The name YES, filled with spaces: taken the same as ON.
52D8-52D9
DEFW 5297H 97 52
Entry YES: its value goes to 5297H, which nothing reads.
52DA-52DF
DEFM "NO " 4E 4F 20 20 20 20
The name NO, filled with spaces: taken the same as OFF.
52E0-52E1
DEFW 5290H 90 52
Entry NO: its value goes to 5290H, the operand of LD BC at 528FH.
52E2-52E7
DEFM "Y " 59 20 20 20 20 20
The short name Y, filled with spaces: taken the same as ON.
52E8-52E9
DEFW 5297H 97 52
Entry Y: its value goes to 5297H, which nothing reads.
52EA-52EF
DEFM "N " 4E 20 20 20 20 20
The short name N, filled with spaces: taken the same as OFF.
52F0-52F1
DEFW 5290H 90 52
Entry N: its value goes to 5290H, the operand of LD BC at 528FH.
52F2
DEFB 00H 00
The 00H in place of a first character that ends both parameter tables of the member.
5200H - Member 7 (O!, Code 1DH): Display the Copyright Notice
SYS1/SYS's command table has a hidden first entry (4EA5H) matched only by the command word O! (an O followed at once by an exclamation mark); its word 801DH runs this member, code 1DH. The member displays a copyright notice that is stored encoded: the byte at 520EH is a key (90H) and every following byte is a character plus the key, so the text cannot be read in the file. Each byte less the key goes to the ROM's display routine until a 00H byte. The notice reads COPYRIGHT (C) 1980 BY RANDOLPH V. COOK, ALL RIGHTS RESERVED and a carriage return. The text after O! is ignored. The member returns to the request handler with Register A = 00H and the Z FLAG, and so to 402DH (VTOS READY).
5200
LD HL,520EH 21 0E 52
Point Register Pair HL to 520EH, the key byte that starts the encoded notice.
5203
LD B,(HL) 46
Fetch the key from 520EH at Register Pair HL into Register B (90H): every character of the notice is stored plus this value.
5204
INC HL 23
Loop Start
Increment Register Pair HL to the next encoded byte of the notice (520FH first).
5205
LD A,(HL) 7E
Fetch the encoded byte at Register Pair HL into Register A.
5206
OR A B7
OR Register A with itself: the Z FLAG when the byte is 00H, the end of the notice at 524BH.
5207
RET Z C8
If the Z FLAG is set (the end byte 00H), RETURN with Register A = 00H to the request handler at 4C4BH, which returns to 402DH (VTOS READY).
5208
SUB B 90
SUBtract Register B (the key 90H) from Register A: Register A = the character of the notice.
5209
GOSUB to 0033H, the ROM's routine that displays the character in Register A at the cursor (0DH ends the line).
520C
JUMP back to 5204H for the next byte of the notice.
520EH - The Encoded Copyright Notice
A key byte and 60 encoded bytes (59 characters and the carriage return), each the character plus 90H, ended by 00H. Decoded: COPYRIGHT (C) 1980 BY RANDOLPH V. COOK, ALL RIGHTS RESERVED, then 0DH.
520E
DEFB 90H 90
The key of the encoded notice, 90H, which 5203H loads into Register B and 5208H subtracts from every byte.
520F-5218
DEFB D3H,DFH,E0H,E9H,E2H,D9H,D7H,D8H,E4H,B0H D3 DF E0 E9 E2 D9 D7 D8 E4 B0
Encoded text, the word COPYRIGHT and a space (B0H): each byte is its character plus 90H (C D3H O DFH P E0H Y E9H R E2H I D9H G D7H H D8H T E4H), shown by 5208H-5209H.
5219-521C
DEFB B8H,D3H,B9H,B0H B8 D3 B9 B0
Encoded text, the word (C) and a space (B0H): each byte is its character plus 90H (( B8H C D3H ) B9H), shown by 5208H-5209H.
521D-5221
DEFB C1H,C9H,C8H,C0H,B0H C1 C9 C8 C0 B0
Encoded text, the word 1980 and a space (B0H): each byte is its character plus 90H (1 C1H 9 C9H 8 C8H 0 C0H), shown by 5208H-5209H.
5222-5224
DEFB D2H,E9H,B0H D2 E9 B0
Encoded text, the word BY and a space (B0H): each byte is its character plus 90H (B D2H Y E9H), shown by 5208H-5209H.
5225-522D
DEFB E2H,D1H,DEH,D4H,DFH,DCH,E0H,D8H,B0H E2 D1 DE D4 DF DC E0 D8 B0
Encoded text, the word RANDOLPH and a space (B0H): each byte is its character plus 90H (R E2H A D1H N DEH D D4H O DFH L DCH P E0H H D8H), shown by 5208H-5209H.
522E-5230
DEFB E6H,BEH,B0H E6 BE B0
Encoded text, the word V. and a space (B0H): each byte is its character plus 90H (V E6H . BEH), shown by 5208H-5209H.
5231-5236
DEFB D3H,DFH,DFH,DBH,BCH,B0H D3 DF DF DB BC B0
Encoded text, the word COOK, and a space (B0H): each byte is its character plus 90H (C D3H O DFH O DFH K DBH , BCH), shown by 5208H-5209H.
5237-523A
DEFB D1H,DCH,DCH,B0H D1 DC DC B0
Encoded text, the word ALL and a space (B0H): each byte is its character plus 90H (A D1H L DCH L DCH), shown by 5208H-5209H.
523B-5241
DEFB E2H,D9H,D7H,D8H,E4H,E3H,B0H E2 D9 D7 D8 E4 E3 B0
Encoded text, the word RIGHTS and a space (B0H): each byte is its character plus 90H (R E2H I D9H G D7H H D8H T E4H S E3H), shown by 5208H-5209H.
5242-5249
DEFB E2H,D5H,E3H,D5H,E2H,E6H,D5H,D4H E2 D5 E3 D5 E2 E6 D5 D4
Encoded text, the word RESERVED: each byte is its character plus 90H (R E2H E D5H S E3H E D5H R E2H V E6H E D5H D D4H), shown by 5208H-5209H.
524A
DEFB 9DH 9D
Encoded byte 9DH: the carriage return 0DH plus 90H, which ends the line of the notice on the display.
524B
DEFB 00H 00
The 00H that ends the encoded notice: 5206H-5207H stop at it (it is not encoded).
5200H - Member 8 (MEMORY, Code 1EH): Show or Lower the Top of Memory
SYS1/SYS's command interpreter runs this member for the word MEMORY (member code 1EH); the request handler of SYS0/SYS CALLs 5200H with Register Pair HL pointing at the text after the command word. The member reads the parameter list (HIGH=addr) or (H=addr) with SYS1/SYS's reader. Without a value (MEMORY alone, or HIGH=0) it displays the top of memory, the word at 4049H-404AH, with the text HIGH = X' followed by four hex digits and an apostrophe. With a value above 5200H and not above the present top of memory it stores the value at 4049H-404AH, so that the memory above it is kept for other uses; any other value displays RANGE ERROR, a bad list PARAMETER ERROR, both ending at the abort exit. The other paths end at 402DH (VTOS READY).
5200
LD DE,5267H 11 67 52
Point Register Pair DE to 5267H, the parameter table of MEMORY: HIGH and H, both storing to 5209H.
5203
GOSUB to 4476H (SYS1/SYS 510FH) to read the parameter list in parentheses at Register Pair HL against the table at Register Pair DE (5267H); a value of HIGH or H goes to 5209H-520AH. The Z FLAG when the list is good or absent.
5206
If the NZ FLAG is set (an unknown word or a bad value), JUMP to 5239H to display PARAMETER ERROR and abort.
5208
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the new top of memory. The operand at 5209H-520AH is 0000H in the file; SYS1/SYS's parameter reader (called at 5203H) stores the value of HIGH or H there (FFFFH for the word written alone), so Register Pair BC = 0000H when no value was given.
520B
LD A,B 78
Copy Register B (the high byte of the value) into Register A.
520C
OR C B1
OR Register A with Register C (the low byte of the value): the Z FLAG when the value is 0000H.
520D
If the Z FLAG is set (no value), JUMP to 5226H to display the present top of memory.
520F
LD HL,5200H 21 00 52
Point Register Pair HL to 5200H, the lowest top of memory refused: the start of the area where the library members and programs run.
5212
XOR A AF
Set Register A to 00H (XOR A), which also clears the CARRY FLAG for the subtraction.
5213
SBC HL,BC ED 42
SUBtract Register Pair BC (the new value) from Register Pair HL (5200H): the NC FLAG when the value is 5200H or below.
5215
If the NC FLAG is set (the value is not above 5200H), JUMP to 5252H to display RANGE ERROR and abort.
5217
LD HL,(4049H) 2A 49 40
Fetch the present top of memory from 4049H-404AH into Register Pair HL.
521A
XOR A AF
Set Register A to 00H (XOR A), which also clears the CARRY FLAG for the subtraction.
521B
SBC HL,BC ED 42
SUBtract Register Pair BC (the new value) from Register Pair HL (the present top of memory): the CARRY FLAG when the value is above it.
521D
If the CARRY FLAG is set (the value would raise the top of memory), JUMP to 5252H to display RANGE ERROR and abort.
521F
LD (4049H),BC ED 43 49 40
Store Register Pair BC (the new value, above 5200H and not above the old one) to 4049H-404AH, the top of memory that the system and the programs that honour it keep below.
5223
JUMP to 402DH, the normal exit of the system: VTOS READY.
5226
LD DE,(4049H) ED 5B 49 40
Fetch the top of memory from 4049H-404AH into Register Pair DE, to display it.
522A
LD HL,5281H 21 81 52
Point Register Pair HL to 5281H, the four characters XXXX in the message HIGH = X'XXXX', where the digits go.
522D
GOSUB to 4DE7H to write Register Pair DE (the top of memory) as four hex digits at Register Pair HL (5281H-5284H).
5230
LD HL,5278H 21 78 52
Point Register Pair HL to 5278H, the message HIGH = X' with the four digits just written, the closing apostrophe and 0DH.
5233
GOSUB to 447BH to display the text at Register Pair HL (5278H) and write it to the job log.
5236
JUMP to 402DH, the normal exit of the system: VTOS READY.
5239H - The Error Messages
5239H displays PARAMETER ERROR (a bad parameter list), 5252H displays RANGE ERROR (a value not above 5200H, or above the present top of memory); both are written to the job log as well and both take the abort exit.
5239
LD HL,5242H 21 42 52
Point Register Pair HL to 5242H, the message PARAMETER ERROR ended by 0DH.
523C
GOSUB to 447BH to display the text at Register Pair HL (5242H) and write it to the job log.
523F
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
5242-5250
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of a bad parameter list after MEMORY, displayed by 523CH.
5251
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
5252
LD HL,525BH 21 5B 52
Point Register Pair HL to 525BH, the message RANGE ERROR ended by 0DH.
5255
GOSUB to 447BH to display the text at Register Pair HL (525BH) and write it to the job log.
5258
JUMP to 4030H, the abort exit of the system: SYS1/SYS shows VTOS READY again.
525B-5265
DEFM "RANGE ERROR" 52 41 4E 47 45 20 45 52 52 4F 52
The message of a value of HIGH that is not above 5200H or is above the present top of memory, displayed by 5255H.
5266
DEFB 0DH 0D
The carriage return that ends the message RANGE ERROR.
5267H - The Parameter Table and the Display Text
Two entries of 8 bytes for SYS1/SYS's reader (the name filled with spaces to 6 characters, then the address of the word the value goes to), ended by 00H, then the message that shows the top of memory.
5267-526C
DEFM "HIGH " 48 49 47 48 20 20
Parameter table, entry 1: the name HIGH, filled to 6 characters with spaces, for SYS1/SYS's reader (5203H).
526D-526E
DEFW 5209H 09 52
Entry HIGH: its value goes to 5209H, the operand of LD BC,0000H at 5208H.
526F-5274
DEFM "H " 48 20 20 20 20 20
Parameter table, entry 2: the short name H, filled to 6 characters with spaces.
5275-5276
DEFW 5209H 09 52
Entry H: its value goes to 5209H as well, the operand of LD BC at 5208H.
5277
DEFB 00H 00
The 00H in place of a first character that ends the parameter table of MEMORY.
5278-5280
DEFM "HIGH = X'" 48 49 47 48 20 3D 20 58 27
The start of the message that shows the top of memory, displayed from 5278H by 5233H.
5281-5284
DEFM "XXXX" 58 58 58 58
Four characters XXXX in the file, written over at run time: 4DE7H (called at 522DH) stores the four hex digits of the top of memory here before the message is displayed.
5285
DEFM "'" 27
The apostrophe that closes the hex value X'nnnn' in the message.
5286
DEFB 0DH 0D
The carriage return that ends the message that shows the top of memory.
5200H - Member 9 (SYSTEM SYSGEN, Code 1CH): Build or Delete CONFIG/SYS
No command word runs this member: SYSTEM (member 13) requests it with Register B = 1CH, Register A = 88H and RST 28H at its 5622H-5626H when the two bytes of its SYSGEN parameter word (the operand at 561AH-561BH, 0001H in the file when SYSGEN is not given) ORed together do not give 01H (its 561CH-561FH), and passes that word in Register Pair HL. So on entry Register Pair HL = FFFFH for SYSGEN, SYSGEN=Y or SYSGEN=ON, 0000H for SYSGEN=OFF or SYSGEN=N, or any other number or text address given; Register B = 1CH; the stack holds the request handler's return 4C4BH. With 430FH bit 5 set (a CHAIN file of commands is running) the member refuses. Register Pair HL = 0000H deletes CONFIG/SYS and stores C9H in the system information sector's configuration flag; any other value writes CONFIG/SYS as a load module that holds the current system cells, drive code tables, task slots and the memory above the top of memory (4049H), and stores 00H in the flag, so that SYS0/SYS's reset loads it at the next boot. The member never returns: it ends with JP 402DH (VTOS READY), JP 4030H (abort) or JP 4409H.
5200
LD A,(430FH) 3A 0F 43
Fetch the system flags byte from 430FH into Register A, to test whether a CHAIN file of commands is being run.
5203
BIT 5,A CB 6F
Test bit 5 of Register A (the flags from 430FH): bit 5 is set while SYS7/SYS runs the commands of a CHAIN file.
5205
If the NZ FLAG is set (bit 5 of 430FH set: a CHAIN file is running), JUMP to 535DH to show SYSGEN INVALID DURING PROGRAM CHAINING and abort.
5208
LD A,H 7C
Copy Register H (the high byte of SYSTEM's SYSGEN word passed in Register Pair HL) into Register A.
5209
OR L B5
OR Register L (the low byte of the SYSGEN word) into Register A: the Z FLAG is set when Register Pair HL = 0000H, the value of SYSGEN=OFF or SYSGEN=N.
520A
If the Z FLAG is set (Register Pair HL = 0000H: SYSGEN=OFF), JUMP to 5329H to delete CONFIG/SYS.
520D
LD DE,5392H 11 92 53
Point Register Pair DE to 5392H, the control block holding the text CONFIG/SYS.CCC:0 (name CONFIG, extension SYS, password CCC, drive 0).
5210
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the 256 byte sector buffer of the file (5500H-55FFH, above the member).
5213
LD B,00H 06 00
Load Register B with 00H, the record length 256 for the open.
5215
GOSUB to 4420H (SYS2/SYS request A4H): open CONFIG/SYS with the control block at Register Pair DE (5392H), the buffer at Register Pair HL (5500H) and record length Register B (00H), creating the file on drive 0 when it is not there.
5218
If the NZ FLAG is set (the open or the create failed, Register A = the error code), JUMP to 538DH to show the error and abort.
521BH - Write the Header and the First Two Load Blocks
The file is written byte by byte through 53B2H (ROM 001BH with Register Pair DE = 5392H, the open control block). First the header record: type 05H, length 06H and the six letters CONFIG (taken from the text at 53BDH, inside USER CONFIGURATION BUILT). Then a load block of 19 bytes for 3F93H in video memory (the message CONFIGURING between three asterisks on each side, from 5409H), shown on the second line from the bottom of the screen while the file loads, and a load block of 1 byte for 4012H, the byte C9H from 5408H: while the rest of the file loads, the RST 38H vector at 4012H is a RET, so an interrupt does not run the interrupt routine through the vectors and task slots that the later blocks replace. The key held byte 4018H is set to 00H before the device control blocks are saved.
521B
LD A,05H 3E 05
Load Register A with 05H, the record type of a header record that the loader passes over by its length.
521D
GOSUB to 53B2H to write Register A (05H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
5220
LD A,06H 3E 06
Load Register A with 06H, the length of the header record: six bytes of name follow.
5222
GOSUB to 53B2H to write Register A (06H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
5225
LD B,06H 06 06
Load Register B with 06H, the count of the six letters of the name CONFIG.
5227
LD HL,53BDH 21 BD 53
Point Register Pair HL to 53BDH, the word CONFIG inside the text USER CONFIGURATION BUILT at 53B8H.
522A
LD A,(HL) 7E
Loop Start
Fetch the next letter of the name at Register Pair HL (53BDH-53C2H) into Register A.
522B
INC HL 23
Increment Register Pair HL to the next letter of the name CONFIG.
522C
GOSUB to 53B2H to write Register A (the letter) to CONFIG/SYS through the control block at Register Pair DE (5392H); Register Pair HL and Register B are kept.
522F
Decrement Register B (the letters left) and LOOP BACK to 522AH until Register B is 00H: the six letters CONFIG are written.
5231
LD B,13H 06 13
Load Register B with 13H, the 19 bytes of the message CONFIGURING with three asterisks and a space on each side.
5233
LD DE,3F93H 11 93 3F
Point Register Pair DE to 3F93H, the load address of the message in video memory (the line that starts at 3F80H, the second line from the bottom of the screen, column 19).
5236
LD HL,5409H 21 09 54
Point Register Pair HL to 5409H, the message bytes written into the load block.
5239
GOSUB to 5307H to write a load block of Register B (13H) bytes from Register Pair HL (5409H) with the load address in Register Pair DE (3F93H).
523C
LD B,01H 06 01
Load Register B with 01H, the single byte of the next load block.
523E
LD DE,4012H 11 12 40
Point Register Pair DE to 4012H, the RST 38H vector (the interrupt jump JP 4518H), the load address of the block.
5241
LD HL,5408H 21 08 54
Point Register Pair HL to 5408H, the byte C9H (RET) written as the block's data: loading it turns the interrupt vector at 4012H into a RET.
5244
GOSUB to 5307H to write a load block of Register B (01H) byte from Register Pair HL (5408H) with the load address in Register Pair DE (4012H).
5247
XOR A AF
Set Register A to 00H, the value for the key held byte.
5248
LD (4018H),A 32 18 40
Store Register A (00H) to 4018H, the key held byte of the keyboard device control block (4015H +03H), so that the saved block holds no key down.
524B
LD HL,542FH 21 2F 54
Point Register Pair HL to 542FH, the table of the memory areas to save: a count word and an address word an entry, ended by a count of 0000H.
524EH - Save the Areas of the Table at 542FH
Each entry of the table (542FH-5464H) is written as one or more load blocks by 52CEH: the count from the entry's first word in Register Pair BC, the address from its second word in Register Pair DE. The bytes saved are the memory contents now, so CONFIG/SYS reloads the system cells as they are at the moment of the SYSGEN.
524E
LD C,(HL) 4E
Loop Start
Fetch the low byte of the entry's count at Register Pair HL (the table at 542FH) into Register C.
524F
INC HL 23
Increment Register Pair HL to the high byte of the entry's count.
5250
LD B,(HL) 46
Fetch the high byte of the entry's count at Register Pair HL into Register B: Register Pair BC = the number of bytes to save.
5251
INC HL 23
Increment Register Pair HL to the entry's address word.
5252
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
5253
OR C B1
OR Register C (the low byte of the count) into Register A: the Z FLAG is set when the count in Register Pair BC is 0000H, the end of the table at 5463H.
5254
If the Z FLAG is set (count 0000H: the end of the table), JUMP to 5261H to save the memory above the top of memory.
5256
LD E,(HL) 5E
Fetch the low byte of the entry's address at Register Pair HL into Register E.
5257
INC HL 23
Increment Register Pair HL to the high byte of the entry's address.
5258
LD D,(HL) 56
Fetch the high byte of the entry's address at Register Pair HL into Register D: Register Pair DE = the first address of the area to save.
5259
INC HL 23
Increment Register Pair HL to the next entry of the table.
525A
PUSH HL E5
Save Register Pair HL (the pointer to the next table entry) to the stack.
525B
GOSUB to 52CEH to write the Register Pair BC bytes from the address in Register Pair DE as load blocks of at most 254 bytes each.
525E
POP HL E1
Restore Register Pair HL (the pointer to the next table entry) from the stack.
525F
JUMP back to 524EH for the next entry of the table at Register Pair HL.
5261H - Save the Memory Above the Top of Memory
The physical end of memory is found by testing FFFFH and then every 1K lower (FBFFH, F7FFH, ...) for a byte that can be complemented and read back. The bytes from the address after the top of memory in 4049H-404AH up to that end (the area that drivers, filters and other programs reserve by lowering 4049H) are written as load blocks when there are any. Then a load block of 3 bytes for 4012H with the current interrupt vector (JP 4518H) undoes the RET, and a load block of 19 spaces for 3F93H wipes the message off the screen. The transfer record (type 02H, length 02H, address 0000H) ends the file: SYS0/SYS's reset loads CONFIG/SYS with 4430H, which does not run the transfer address.
5261
LD HL,FFFFH 21 FF FF
Point Register Pair HL to FFFFH, the highest address, to look for the end of the memory.
5264
LD A,(HL) 7E
Loop Start
Fetch the byte at Register Pair HL (the last byte of the 1K block under test) into Register A.
5265
LD B,A 47
Copy Register A (the byte found) into Register B to put it back later.
5266
CPL 2F
Complement Register A (the byte found), so that every bit differs from the stored byte.
5267
LD (HL),A 77
Store Register A (the complemented byte) to the address in Register Pair HL; where there is no memory the store changes nothing.
5268
CP (HL) BE
Compare Register A (the complemented byte) against the byte now at Register Pair HL: the Z FLAG is set when the store took, so there is memory at this address.
5269
LD (HL),B 70
Store Register B (the original byte) back to the address in Register Pair HL; LD does not change the flags of the compare.
526A
If the Z FLAG is set (the address at Register Pair HL is memory), JUMP to 5272H with Register Pair HL = the last address of the memory.
526C
LD A,H 7C
Copy Register H (the high byte of the address under test) into Register A.
526D
SUB 04H D6 04
Subtract 04H from Register A (the high byte): the address 1K (0400H) lower.
526F
LD H,A 67
Copy Register A (the new high byte) back into Register H: Register Pair HL = the last byte of the next 1K block down.
5270
JUMP back to 5264H to test the address in Register Pair HL.
5272
LD DE,(4049H) ED 5B 49 40
Fetch the top of memory from 4049H-404AH into Register Pair DE: the highest address that VTOS lets programs use; the bytes above it are reserved.
5276
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5277
SBC HL,DE ED 52
Subtract Register Pair DE (the top of memory from 4049H) from Register Pair HL (the end of the memory): Register Pair HL = the number of reserved bytes above the top of memory; the Z FLAG is set when there are none.
5279
LD B,H 44
Copy Register H (the high byte of the count of reserved bytes) into Register B.
527A
LD C,L 4D
Copy Register L (the low byte of the count) into Register C: Register Pair BC = the number of bytes to save.
527B
INC DE 13
Increment Register Pair DE (the top of memory) to the first reserved byte; INC of a register pair does not change the flags.
527C
If the NZ FLAG is set (there are reserved bytes), GOSUB to 52CEH to write the Register Pair BC bytes from the address in Register Pair DE as load blocks.
527F
LD B,03H 06 03
Load Register B with 03H, the three bytes of the interrupt vector.
5281
LD DE,4012H 11 12 40
Point Register Pair DE to 4012H, the RST 38H vector, the load address of the block.
5284
LD HL,4012H 21 12 40
Point Register Pair HL to 4012H too: the data of the block are the three bytes now at 4012H (the JP 4518H to the interrupt routine), which take the place of the RET loaded by the second block.
5287
GOSUB to 5307H to write a load block of Register B (03H) bytes from Register Pair HL (4012H) with the load address in Register Pair DE (4012H).
528A
LD B,13H 06 13
Load Register B with 13H, the 19 bytes of the block that clears the message.
528C
LD DE,3F93H 11 93 3F
Point Register Pair DE to 3F93H, the place of the message CONFIGURING in video memory.
528F
LD HL,541CH 21 1C 54
Point Register Pair HL to 541CH, the 19 spaces written as the block's data.
5292
GOSUB to 5307H to write a load block of Register B (13H) spaces from Register Pair HL (541CH) with the load address in Register Pair DE (3F93H).
5295
LD A,02H 3E 02
Load Register A with 02H, the record type of the transfer record.
5297
GOSUB to 53B2H to write Register A (02H) to CONFIG/SYS through the control block at Register Pair DE (5392H, set by 5307H).
529A
LD A,02H 3E 02
Load Register A with 02H, the length of the transfer record: two address bytes follow.
529C
GOSUB to 53B2H to write Register A (02H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
529F
XOR A AF
Set Register A to 00H, the low byte of the transfer address 0000H.
52A0
GOSUB to 53B2H to write Register A (00H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52A3
XOR A AF
Set Register A to 00H, the high byte of the transfer address 0000H.
52A4
GOSUB to 53B2H to write Register A (00H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52A7H - Close CONFIG/SYS and Set the Configuration Flag
The file is closed, then cylinder 0 sector 2 of drive 0, the system information sector, is read into 4200H, its byte +01H (4201H, the configuration flag) is set to 00H and the sector is written back: SYS0/SYS's reset stores that byte as an opcode at 4FE1H, and 00H (NOP) lets it go on to load CONFIG/SYS. Then USER CONFIGURATION BUILT is shown and the command ends at VTOS READY.
52A7
GOSUB to 4428H (SYS3/SYS request 95H) to close CONFIG/SYS, the control block at Register Pair DE (5392H): the last sector is written and the directory record updated.
52AA
If the NZ FLAG is set (the close failed, Register A = the error code), JUMP to 538DH to show the error and abort.
52AD
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, for the system information sector.
52B0
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 00H, Register E = sector 02H, the system information sector.
52B3
LD C,00H 0E 00
Load Register C with 00H, drive 0, the drive whose system information sector is changed.
52B5
GOSUB to 4777H (driver function 09H) to read cylinder Register D (00H) sector Register E (02H) of drive Register C (0) into the buffer at Register Pair HL (4200H).
52B8
If the NZ FLAG is set (the read failed, Register A = the error code), JUMP to 538DH to show the error and abort.
52BB
XOR A AF
Set Register A to 00H, the configuration flag value that makes the boot load CONFIG/SYS (a NOP at SYS0/SYS's 4FE1H).
52BC
LD (4201H),A 32 01 42
Store Register A (00H) to 4201H, byte +01H of the system information sector in the buffer at 4200H.
52BF
GOSUB to 4763H (driver function 0DH) to write the buffer at Register Pair HL (4200H) back to cylinder Register D (00H) sector Register E (02H) of drive Register C (0); the driver calls keep Register Pairs BC, DE and HL.
52C2
If the NZ FLAG is set (the write failed, Register A = the error code), JUMP to 538DH to show the error and abort.
52C5
LD HL,53B8H 21 B8 53
Point Register Pair HL to 53B8H, the text USER CONFIGURATION BUILT ended by 0DH.
52C8
GOSUB to 447BH to display the text at Register Pair HL (53B8H) and write it to the job log.
52CB
JUMP to 402DH: VTOS READY, the end of the command.
52CEH - Write an Area as Load Blocks
Entry: Register Pair DE = the first address of the area, Register Pair BC = its length (not 0000H). The area is cut into load blocks of 254 (00FEH) bytes, the last one shorter; each block is written as type 01H, length (count + 2), load address low and high byte, then the bytes, to CONFIG/SYS (control block 5392H). The load address of each block is the address the bytes come from, so loading the file puts every byte back where it was. Exit: Register Pair DE = 5392H, Register Pair BC = 0000H, Register Pair HL = the address after the area.
52CE
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the first address of the area (the caller's Register Pair DE), Register Pair DE = the caller's Register Pair HL, replaced below.
52CF
LD DE,5392H 11 92 53
Point Register Pair DE to 5392H, the control block of CONFIG/SYS, for the byte writes of 53B2H.
52D2
PUSH HL E5
Loop Start
Save Register Pair HL (the address of this block's first byte) to the stack.
52D3
PUSH BC C5
Save Register Pair BC (the bytes left to write) to the stack.
52D4
LD H,B 60
Copy Register B (the high byte of the bytes left) into Register H.
52D5
LD L,C 69
Copy Register C (the low byte of the bytes left) into Register L: Register Pair HL = the bytes left.
52D6
LD BC,00FEH 01 FE 00
Load Register Pair BC with 00FEH, 254, the most bytes of one load block.
52D9
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
52DA
SBC HL,BC ED 42
Subtract Register Pair BC (00FEH) from Register Pair HL (the bytes left): Register Pair HL = what is left after a full block; the CARRY FLAG is set when fewer than 254 bytes are left.
52DC
If the NC FLAG is set (254 bytes or more left), JUMP to 52E4H with Register Pair BC = 00FEH, the size of this block, and Register Pair HL = the bytes left after it.
52DE
POP BC C1
Restore Register Pair BC from the stack: the bytes left (fewer than 254), the size of this last block.
52DF
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H: no bytes are left after this last block.
52E2
JUMP to 52E5H to write this last block of the area, its size in Register Pair BC.
52E4
POP AF F1
Restore Register Pair AF from the stack to drop the saved bytes left: Register Pair BC already holds 00FEH, the block size, and Register Pair HL the bytes left after it.
52E5
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer, the top of the stack: Register Pair HL = the address of this block's first byte, and the stack holds the bytes left after the block.
52E6
LD B,C 41
Copy Register C (the size of this block, 1 to 254) into Register B, the count of the byte loop.
52E7
LD A,01H 3E 01
Load Register A with 01H, the record type of a load block.
52E9
GOSUB to 53B2H to write Register A (01H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52EC
LD A,B 78
Copy Register B (the size of the block) into Register A.
52ED
ADD A,02H C6 02
Add 02H to Register A: the length byte of a load block counts the two address bytes as well.
52EF
GOSUB to 53B2H to write Register A (the length byte) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52F2
LD A,L 7D
Copy Register L (the low byte of the block's address) into Register A.
52F3
GOSUB to 53B2H to write Register A (the low byte of the load address) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52F6
LD A,H 7C
Copy Register H (the high byte of the block's address) into Register A.
52F7
GOSUB to 53B2H to write Register A (the high byte of the load address) to CONFIG/SYS through the control block at Register Pair DE (5392H).
52FA
LD A,(HL) 7E
Loop Start
Fetch the next byte of the area at Register Pair HL into Register A.
52FB
INC HL 23
Increment Register Pair HL to the following byte of the area.
52FC
GOSUB to 53B2H to write Register A (the byte) to CONFIG/SYS through the control block at Register Pair DE (5392H); Register Pair HL and Register B are kept.
52FF
Decrement Register B (the bytes of the block left) and LOOP BACK to 52FAH until Register B is 00H.
5301
POP BC C1
Restore Register Pair BC from the stack: the bytes of the area left after this block.
5302
LD A,B 78
Copy Register B (the high byte of the bytes left) into Register A.
5303
OR C B1
OR Register C (the low byte of the bytes left) into Register A: the Z FLAG is set when Register Pair BC = 0000H, the whole area written.
5304
If the NZ FLAG is set (bytes are left), JUMP back to 52D2H for the next block from the address in Register Pair HL.
5306
RET C9
RETURN to the caller with the area written; Register Pair HL = the address after the area.
5307H - Write One Load Block
Entry: Register B = the number of bytes (1 to 254), Register Pair HL = where the bytes are taken from, Register Pair DE = the load address put into the block (it may differ from Register Pair HL). Writes type 01H, length Register B + 2, the load address low and high byte and the bytes to CONFIG/SYS. Exit: Register Pair DE = 5392H, Register B = 00H, Register Pair HL past the bytes.
5307
PUSH HL E5
Save Register Pair HL (the address of the block's data) to the stack.
5308
LD H,D 62
Copy Register D (the high byte of the load address) into Register H.
5309
LD L,E 6B
Copy Register E (the low byte of the load address) into Register L: Register Pair HL = the load address of the block.
530A
LD DE,5392H 11 92 53
Point Register Pair DE to 5392H, the control block of CONFIG/SYS, for the byte writes of 53B2H.
530D
LD A,01H 3E 01
Load Register A with 01H, the record type of a load block.
530F
GOSUB to 53B2H to write Register A (01H) to CONFIG/SYS through the control block at Register Pair DE (5392H).
5312
LD A,B 78
Copy Register B (the number of bytes of the block) into Register A.
5313
ADD A,02H C6 02
Add 02H to Register A: the length byte counts the two address bytes as well.
5315
GOSUB to 53B2H to write Register A (the length byte) to CONFIG/SYS through the control block at Register Pair DE (5392H).
5318
LD A,L 7D
Copy Register L (the low byte of the load address) into Register A.
5319
GOSUB to 53B2H to write Register A (the low byte of the load address) to CONFIG/SYS through the control block at Register Pair DE (5392H).
531C
LD A,H 7C
Copy Register H (the high byte of the load address) into Register A.
531D
GOSUB to 53B2H to write Register A (the high byte of the load address) to CONFIG/SYS through the control block at Register Pair DE (5392H).
5320
POP HL E1
Restore Register Pair HL from the stack: the address of the block's data.
5321
LD A,(HL) 7E
Loop Start
Fetch the next data byte at Register Pair HL into Register A.
5322
INC HL 23
Increment Register Pair HL to the following data byte.
5323
GOSUB to 53B2H to write Register A (the data byte) to CONFIG/SYS through the control block at Register Pair DE (5392H); Register Pair HL and Register B are kept.
5326
Decrement Register B (the data bytes left) and LOOP BACK to 5321H until Register B is 00H.
5328
RET C9
RETURN to the caller with the load block written.
5329H - SYSGEN=OFF: Delete CONFIG/SYS
Reached from 520AH when Register Pair HL = 0000H. CONFIG/SYS.CCC:0 is opened; when the open fails (whatever the error) the member shows NO USER CONFIGURATION FOUND and aborts, leaving the configuration flag as it is. Otherwise the file is killed through 442CH (SYS10/SYS request 9CH), the system information sector of drive 0 is read into 4200H, its byte +01H (4201H) is set to C9H (a RET at SYS0/SYS's 4FE1H: the boot loads no CONFIG/SYS) and written back, and USER CONFIGURATION DELETED is shown before VTOS READY.
5329
LD DE,5392H 11 92 53
Point Register Pair DE to 5392H, the control block holding the text CONFIG/SYS.CCC:0.
532C
GOSUB to 4424H (SYS2/SYS request 94H) to open the file named in the control block at Register Pair DE (5392H); Register Pair HL (0000H, the SYSGEN word) is the buffer address and Register B (1CH, the member code) the record length the open stores, but no record is read or written before the kill.
532F
LD HL,53ECH 21 EC 53
Point Register Pair HL to 53ECH, the text NO USER CONFIGURATION FOUND, for the case that the open failed; LD does not change the flags.
5332
If the NZ FLAG is set (the open failed), JUMP to 5360H to display the text at Register Pair HL (53ECH) and abort.
5335
GOSUB to 442CH (SYS10/SYS request 9CH) with the open control block at Register Pair DE (5392H): kill CONFIG/SYS, giving its space back and freeing its directory record.
5338
If the NZ FLAG is set (the kill failed, Register A = the error code), JUMP to 538DH to show the error and abort.
533B
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, for the system information sector.
533E
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 00H, Register E = sector 02H, the system information sector.
5341
LD C,00H 0E 00
Load Register C with 00H, drive 0, the drive whose system information sector is changed.
5343
GOSUB to 4777H (driver function 09H) to read cylinder Register D (00H) sector Register E (02H) of drive Register C (0) into the buffer at Register Pair HL (4200H).
5346
If the NZ FLAG is set (the read failed, Register A = the error code), JUMP to 538DH to show the error and abort.
5349
LD A,C9H 3E C9
Load Register A with C9H, the configuration flag value that makes the boot skip CONFIG/SYS (a RET at SYS0/SYS's 4FE1H).
534B
LD (4201H),A 32 01 42
Store Register A (C9H) to 4201H, byte +01H of the system information sector in the buffer at 4200H.
534E
GOSUB to 4763H (driver function 0DH) to write the buffer at Register Pair HL (4200H) back to cylinder Register D (00H) sector Register E (02H) of drive Register C (0).
5351
If the NZ FLAG is set (the write failed, Register A = the error code), JUMP to 538DH to show the error and abort.
5354
LD HL,53D1H 21 D1 53
Point Register Pair HL to 53D1H, the text USER CONFIGURATION DELETED ended by 0DH.
5357
GOSUB to 447BH to display the text at Register Pair HL (53D1H) and write it to the job log.
535A
JUMP to 402DH: VTOS READY, the end of the command.
535DH - Refuse During a CHAIN File and the Error Exits
535DH shows SYSGEN INVALID DURING PROGRAM CHAINING; 5360H displays the text at Register Pair HL and goes to the abort exit 4030H. 538DH takes an error code in Register A from a failed open, close, kill, sector read or write or byte write and jumps to 4409H with bit 6 set (the text of the message alone) and bit 7 clear (the message routine goes on to the abort exit).
535D
LD HL,5366H 21 66 53
Point Register Pair HL to 5366H, the text SYSGEN INVALID DURING PROGRAM CHAINING ended by 0DH.
5360
GOSUB to 447BH to display the text at Register Pair HL (5366H or 53ECH) and write it to the job log.
5363
JUMP to 4030H, the abort exit: the command ends without changing CONFIG/SYS or the configuration flag.
5366-538B
DEFM "SYSGEN INVALID DURING PROGRAM CHAINING" 53 59 53 47 45 4E 20 49 4E 56 41 4C 49 44 20 44 55 52 49 4E 47 20 50 52 4F 47 52 41 4D 20 43 48 41 49 4E 49 4E 47
The message shown by 535DH when 430FH bit 5 says that a CHAIN file of commands is running.
538C
DEFB 0DH 0D
The carriage return that ends the message at 5366H; 447BH displays it too.
538D
OR 40H F6 40
Set bit 6 of Register A (the error code from the failing request): only the text of the message is to be shown.
538F
JUMP to 4409H to display the message of the error code in Register A; bit 7 is clear, so it goes on to the abort exit 4030H.
5392H - The Control Block of CONFIG/SYS
32 bytes, 5392H-53B1H. The file loads only the text CONFIG/SYS.CCC:0 (16 bytes, with no ending byte); the open (4420H or 4424H) reads the text from here and fills the block in as the open file's control block, which 53B2H, the close and the kill use.
5392-53A1
DEFM "CONFIG/SYS.CCC:0" 43 4F 4E 46 49 47 2F 53 59 53 2E 43 43 43 3A 30
The file specification passed to the open: name CONFIG, extension SYS, password CCC, drive 0. It is the same file that SYS0/SYS's reset loads from its own text at 4338H.
53A2-53B1
DEFS 16
Not in the file: the last 16 bytes of the control block at 5392H, which the open fills in and the byte writes (53B2H), the close (52A7H) and the kill (5335H) use. The text at 5392H has no ending byte, so SYS2/SYS's split of the specification (its 50A5H) fetches the byte at 53A2H after the drive digit, whatever it holds when the open runs, and tests it for an exclamation mark.
53B2H - Write a Byte to CONFIG/SYS
Entry: Register A = the byte, Register Pair DE = 5392H, the open control block. Returns with the Z FLAG when the byte was written; on an error it does not return but goes to 538DH with the error code.
53B2
GOSUB to the ROM's 001BH to send Register A to the device or file whose control block is at Register Pair DE (5392H, an open file: it goes to SYS0/SYS's byte write); the ROM routine keeps Register Pairs BC, DE and HL and returns the Z FLAG on success or the NZ FLAG with Register A = the error code.
53B5
RET Z C8
If the Z FLAG is set (the byte was written), RETURN to the caller.
53B6
JUMP to 538DH with the error code in Register A to show the error and abort; the file stays open and only partly written.
53B8H - Messages, the Byte C9H and the Table of Areas to Save
The texts shown at the end of SYSGEN and SYSGEN=OFF, the message of the first and the last load block of CONFIG/SYS, and the table that 524EH walks.
53B8-53CF
DEFM "USER CONFIGURATION BUILT" 55 53 45 52 20 43 4F 4E 46 49 47 55 52 41 54 49 4F 4E 20 42 55 49 4C 54
The message 52C5H shows after CONFIG/SYS has been written and the flag set; its letters 53BDH-53C2H (CONFIG) also give the header record's name (5227H).
53D0
DEFB 0DH 0D
The carriage return that ends the message at 53B8H.
53D1-53EA
DEFM "USER CONFIGURATION DELETED" 55 53 45 52 20 43 4F 4E 46 49 47 55 52 41 54 49 4F 4E 20 44 45 4C 45 54 45 44
The message 5354H shows after SYSGEN=OFF has killed CONFIG/SYS and set the flag to C9H.
53EB
DEFB 0DH 0D
The carriage return that ends the message at 53D1H.
53EC-5406
DEFM "NO USER CONFIGURATION FOUND" 4E 4F 20 55 53 45 52 20 43 4F 4E 46 49 47 55 52 41 54 49 4F 4E 20 46 4F 55 4E 44
The message 532FH points to for SYSGEN=OFF when CONFIG/SYS cannot be opened.
5407
DEFB 0DH 0D
The carriage return that ends the message at 53ECH.
5408
DEFB C9H C9
The opcode RET, the data of the one byte load block for 4012H (5241H): while CONFIG/SYS loads, the RST 38H vector returns at once.
5409-541B
DEFM "*** CONFIGURING ***" 2A 2A 2A 20 43 4F 4E 46 49 47 55 52 49 4E 47 20 2A 2A 2A
The 19 bytes of the first load block for 3F93H (5236H): the word CONFIGURING with three asterisks and a space on each side, shown on the second line from the bottom of the screen while CONFIG/SYS loads.
541C-542E
DEFB 20H x 19 20 x 19
Nineteen spaces, the data of the last load block for 3F93H (528FH), which wipes the message off the screen at the end of the load.
542F-5432
DEFW 0004H / DEFW 4047H 04 00 47 40
Table entry 1: 4 bytes from 4047H, the word 4047H-4048H (5200H from the reset) and the top of memory 4049H-404AH.
5433-5436
DEFW 0012H / DEFW 404BH 12 00 4B 40
Table entry 2: 18 bytes from 404BH, the copy of the interrupt latch, the served interrupts mask 404CH and the eight interrupt vectors 404DH-405CH.
5437-543A
DEFW 0018H / DEFW 4015H 18 00 15 40
Table entry 3: 24 bytes from 4015H, the KI, DO and PR device control blocks 4015H-402CH (their drivers, cursor and routes).
543B-543E
DEFW 0003H / DEFW 4300H 03 00 00 43
Table entry 4: 3 bytes from 4300H, the keyboard hook that the keyboard driver calls.
543F-5442
DEFW 0001H / DEFW 430FH 01 00 0F 43
Table entry 5: 1 byte, the system flags at 430FH.
5443-5446
DEFW 0002H / DEFW 4310H 02 00 10 43
Table entry 6: 2 bytes from 4310H, where requests below 80H go.
5447-544A
DEFW 0003H / DEFW 4315H 03 00 15 43
Table entry 7: 3 bytes from 4315H, the BREAK vector.
544B-544E
DEFW 0048H / DEFW 43B8H 48 00 B8 43
Table entry 8: 72 bytes from 43B8H, the KI, DO and PR driver addresses at start, the word 43BEH and the device control blocks JL, SI, LO and the five free ones, 43C0H-43FFH.
544F-5452
DEFW 0003H / DEFW 4BC0H 03 00 C0 4B
Table entry 9: 3 bytes from 4BC0H, the CALL 03FAH of the keyboard decode in SYS0/SYS.
5453-5456
DEFW 0003H / DEFW 439CH 03 00 9C 43
Table entry 10: 3 bytes from 439CH, the first instruction of the keyboard driver.
5457-545A
DEFW 0050H / DEFW 4700H 50 00 00 47
Table entry 11: 80 bytes from 4700H, the drive code tables of drives 0-7.
545B-545E
DEFW 0003H / DEFW 4439H 03 00 39 44
Table entry 12: 3 bytes from 4439H, the write record entry point (JP 48C0H, or JP 48DBH while VERIFY is on).
545F-5462
DEFW 0018H / DEFW 4500H 18 00 00 45
Table entry 13: 24 bytes from 4500H, the 12 task slots 4500H-4517H.
5463-5464
DEFW 0000H 00 00
The count 0000H that ends the table (5253H-5254H).
5500-55FF
DEFS 256
Not in the file: the sector buffer of CONFIG/SYS, given to the open at 5210H; the byte writes of 53B2H fill it and the close writes its last sector.
5200H - Member 10 (DIR, Code 21H): Entry
SYS1/SYS's command interpreter runs DIR through request 88H with Register B = 21H, the member code, and Register Pair HL = the text after the word DIR. SYS0/SYS's request handler loads the member at 5200H-5700H and calls 5200H with the return address 4C4BH on the stack. The first three bytes jump over a short routine and a 3 byte work area to the parser at 5213H.
5200
JUMP to 5213H to read the parameters at Register Pair HL (the text after the word DIR), passing over the routine at 5203H and the work bytes 520FH-5211H.
5203H - Fetch the End of File Record Number
Called from 5440H with Register A = the low byte of the address of byte +14H of a directory record (Register H = 42H: the record is in the sector buffer at 4200H). Returns Register Pair DE = the record's end of file record number (bytes +14H-+15H), one less when the end of file offset in 5211H is not 00H, and Register Pair HL = 5211H, the low byte of the work number 520FH-5211H; the Z FLAG is set when the offset is 00H.
5203
LD L,A 6F
Copy Register A (the low byte of the address of the record's byte +14H, from 543EH) into Register L: Register Pair HL = byte +14H of the directory record.
5204
LD E,(HL) 5E
Fetch the low byte of the end of file record number, byte +14H of the record at Register Pair HL, into Register E.
5205
INC L 2C
Increment Register L to byte +15H of the directory record (Register Pair HL).
5206
LD D,(HL) 56
Fetch the high byte of the end of file record number, byte +15H at Register Pair HL, into Register D: Register Pair DE = the end of file record number.
5207
LD HL,5211H 21 11 52
Point Register Pair HL to 5211H, the work byte that 5435H filled with the end of file offset (byte +03H of the record).
520A
LD A,(HL) 7E
Fetch the end of file offset from 5211H (Register Pair HL) into Register A.
520B
OR A B7
OR Register A (the end of file offset) with itself to set the flags: the Z FLAG is set when the file ends on a sector boundary (offset 00H).
520C
RET Z C8
If the Z FLAG is set (offset 00H), RETURN with Register Pair DE = the end of file record number unchanged: every sector before it is full.
520D
DEC DE 1B
Decrement Register Pair DE (the end of file record number): with an offset that is not 00H the last sector is only partly used, so only that many sectors less one are full.
520E
RET C9
RETURN with Register Pair DE = the number of full sectors and Register Pair HL = 5211H.
520FH - The Size of the File in Bytes
Three work bytes, high byte first. 5435H stores the end of file offset (byte +03H of the record) in 5211H; 5443H-5452H then make 520FH-5211H a 24 bit number: the full sectors (Register Pair DE from 5203H) times 256, plus the offset, plus the record length less one; 5455H divides it by the record length to give the number of records shown after EOF=.
520F-5211
DEFB 00H,00H,00H 00 00 00
Work Area
The size of the file in bytes, a 24 bit number with the high byte at 520FH, the middle byte at 5210H and the low byte at 5211H (first the end of file offset alone, from 5435H). Written by 5435H, 5448H, 544DH and 5452H, read by 520AH, 5447H and the division at 55DDH (Register Pair HL = 520FH).
5212
DEFB 00H 00
A byte of 00H after the work area that no instruction of the member reads or writes; 5200H jumps over it to 5213H.
5213H - Read the File Pattern
Register Pair HL = the text after the word DIR. Spaces are passed over; then up to 8 letters and digits of a name go to 56F6H-56FDH and, after a slash, up to 3 of an extension to 56FEH-5700H; both areas hold spaces beforehand, and a space there matches any character (so the listing shows every file whose name and extension start with what was typed). A character from 41H up counts as a letter, so small letters are stored as they are.
5213
LD A,(HL) 7E
Fetch the character at Register Pair HL (the parameters text) into Register A.
5214
INC HL 23
Increment Register Pair HL past the character just fetched.
5215
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
5217
If the Z FLAG is set (a space), JUMP back to 5213H to pass over it. Register A is then the first character that is not a space and Register Pair HL points past it.
5219
LD DE,56F6H 11 F6 56
Point Register Pair DE to 56F6H, the 8 bytes of the name pattern (8 spaces in the file).
521C
LD B,08H 06 08
Load Register B with 08H, the most characters of a name.
521E
CP 41H FE 41
Loop Start
Compare Register A (the character) against 41H, the letter A.
5220
If the NC FLAG is set (41H or above: a letter, or any character from 41H up), JUMP to 522AH to store it.
5222
CP 3AH FE 3A
Compare Register A (the character, below 41H) against 3AH, the colon.
5224
If the NC FLAG is set (3AH-40H: the colon and the characters up to the at sign), JUMP to 5230H: the name ends.
5226
CP 30H FE 30
Compare Register A (the character, below 3AH) against 30H, the digit 0.
5228
If the C FLAG is set (below 30H: a space, a slash, an opening parenthesis, 0DH), JUMP to 5230H: the name ends.
522A
LD (DE),A 12
Store Register A (a letter or digit) to the name pattern at Register Pair DE (56F6H-56FDH).
522B
INC DE 13
Increment Register Pair DE to the next byte of the name pattern.
522C
LD A,(HL) 7E
Fetch the next character of the parameters text at Register Pair HL into Register A.
522D
INC HL 23
Increment Register Pair HL past that character.
522E
Decrement Register B (the characters of the name still allowed) and LOOP BACK to 521EH until Register B is 00H. After the eighth character Register A holds the next character of the text, which goes to the tests below without being checked as a letter.
5230
CP 2FH FE 2F
Compare Register A (the character that ended the name) against 2FH, the slash that starts an extension.
5232
If the NZ FLAG is set (no slash), JUMP to 524DH to look for a colon and a drive number.
5234
LD DE,56FEH 11 FE 56
Point Register Pair DE to 56FEH, the 3 bytes of the extension pattern (3 spaces in the file).
5237
LD B,03H 06 03
Load Register B with 03H, the most characters of an extension.
5239
LD A,(HL) 7E
Fetch the character after the slash at Register Pair HL into Register A.
523A
INC HL 23
Increment Register Pair HL past that character.
523B
CP 41H FE 41
Loop Start
Compare Register A (the character) against 41H, the letter A.
523D
If the NC FLAG is set (41H or above), JUMP to 5247H to store it.
523F
CP 3AH FE 3A
Compare Register A (the character, below 41H) against 3AH, the colon.
5241
If the NC FLAG is set (3AH-40H), JUMP to 524DH: the extension ends.
5243
CP 30H FE 30
Compare Register A (the character, below 3AH) against 30H, the digit 0.
5245
If the C FLAG is set (below 30H), JUMP to 524DH: the extension ends.
5247
LD (DE),A 12
Store Register A (a letter or digit) to the extension pattern at Register Pair DE (56FEH-5700H).
5248
INC DE 13
Increment Register Pair DE to the next byte of the extension pattern.
5249
LD A,(HL) 7E
Fetch the next character of the parameters text at Register Pair HL into Register A.
524A
INC HL 23
Increment Register Pair HL past that character.
524B
Decrement Register B (the characters of the extension still allowed) and LOOP BACK to 523BH until Register B is 00H.
524DH - Read the Drive Number and the Options
A colon and a digit name one drive: the digit less 30H goes to Register C and to 52E7H, which otherwise holds FFH (all drives, from drive 0). The digit is not tested: any character is taken. Then SYS1/SYS's parameter reader (4476H, request E3H) reads an optional list in parentheses against the table at 562FH: A (the allocation line), I (invisible files), P (send the listing to the printer as well) and S (system files). A name given alone stores FFFFH into the operand the table names, a name with =value stores that value. An unknown name gives PARAMETER ERROR.
524D
CP 3AH FE 3A
Compare Register A (the character that ended the name or the extension) against 3AH, the colon that comes before a drive number.
524F
LD C,00H 0E 00
Load Register C with 00H, drive 0, the first drive of the listing when none is named. LD does not change the flags of the compare.
5251
If the NZ FLAG is set (no colon), JUMP to 525CH with Register C = 00H and 52E7H still FFH: every drive is listed.
5253
LD A,(HL) 7E
Fetch the character after the colon at Register Pair HL (the drive digit) into Register A.
5254
INC HL 23
Increment Register Pair HL past the drive digit.
5255
INC HL 23
Increment Register Pair HL once more, past the character after the digit; 525CH steps back onto it.
5256
SUB 30H D6 30
SUBtract 30H from Register A (the drive digit): Register A = the drive number. No test of the range follows, so a character other than 0-7 gives a number above 7.
5258
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive to list.
5259
LD (52E7H),A 32 E7 52
Store Register A (the drive number) to 52E7H, the operand of LD A,FFH at 52E6H: a value other than FFH means one drive was named, and 52E6H and 52F7H stop after it.
525C
DEC HL 2B
Decrement Register Pair HL back onto the character that ended the file pattern or followed the drive digit, where the parameter list can start.
525D
LD DE,562FH 11 2F 56
Point Register Pair DE to 562FH, the table of the parameters A, I, P and S.
5260
PUSH BC C5
Save Register Pair BC (Register C = the first drive to list) to the stack.
5261
GOSUB to 4476H (request E3H, SYS1/SYS's 510FH) to read the parameter list at Register Pair HL against the table at Register Pair DE: a name given stores FFFFH (or its value) into the word the table names. Returns the Z FLAG when the list is good or absent.
5264
POP BC C1
Restore Register Pair BC from the stack: Register C = the first drive to list. POP does not change the flags.
5265
If the NZ FLAG is set (an unknown name or a bad list), JUMP to 5584H to show PARAMETER ERROR and abort.
5268H - List One Drive: the Heading
Register C = the drive. The column counter 53F5H is set to 3 (three files a line), the drive digit goes into the heading at 568AH and 44B8H (request C4H, SYS2/SYS's 5147H, which also replaces the overlay at 4E00H with SYS2/SYS) tests that the drive is there and ready. The allocation table (sector 0 of the directory cylinder) is read into 4200H for the diskette name (42D0H-42D7H) and date (42D8H-42DFH) of the heading line, the sectors of a granule are taken from the drive code table, and the hash index (sector 1) is read into 5800H.
5268
PUSH BC C5
Loop Start
Save Register Pair BC (Register C = the drive to list) to the stack.
5269
LD A,03H 3E 03
Load Register A with 03H, the number of files shown on one line of the listing.
526B
LD (53F5H),A 32 F5 53
Store Register A (03H) to 53F5H, the operand of LD A,03H at 53F4H, the column counter: each drive's listing starts at the beginning of a line.
526E
LD A,C 79
Copy Register C (the drive number) into Register A.
526F
ADD A,30H C6 30
Add 30H to Register A: Register A = the drive digit as a character.
5271
LD (568AH),A 32 8A 56
Store Register A (the drive digit) to 568AH, the X that follows the heading text "FILE DIRECTORY --- DRIVE ".
5274
GOSUB to 44B8H (request C4H, SYS2/SYS's 5147H) to test drive Register C: the Z FLAG and Register A = 00H when the drive is there and ready (for a floppy drive SYS2/SYS has then read its allocation table into 4200H; a drive marked rigid is taken as ready without a read), the NZ FLAG when it is not.
5277
If the NZ FLAG is set (no drive or no diskette), JUMP to 52F6H to go on with the next drive or, for a named drive, to report the error.
527A
LD HL,5670H 21 70 56
Point Register Pair HL to 5670H, the heading text: 0AH (a new line) and "FILE DIRECTORY --- DRIVE " with the drive digit, ended by 03H.
527D
GOSUB to 556CH to display the text at Register Pair HL, and print it too when P was given.
5280
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive.
5281
PUSH BC C5
Save Register Pair BC (Register C = the drive) to the stack again.
5282
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
5285
LD E,00H 1E 00
Load Register E with 00H: sector 0 of the directory cylinder, the allocation table.
5287
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer.
528A
GOSUB to 4B45H to read cylinder Register D, sector Register E of drive Register C into 4200H (Register Pair HL): the Z FLAG when it was read.
528D
If the NZ FLAG is set (the allocation table could not be read), JUMP to 559DH with Register A = the error code of the read, to show its message and abort.
5290
LD HL,42D0H 21 D0 42
Point Register Pair HL to 42D0H, bytes D0H-D7H of the allocation table in 4200H: the diskette name.
5293
LD DE,5691H 11 91 56
Point Register Pair DE to 5691H, the 8 characters NNNNNNNN of the second heading text.
5296
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of the diskette name.
5299
LDIR ED B0
Copy the 8 bytes of the diskette name from Register Pair HL (42D0H) to Register Pair DE (5691H), with Register Pair BC as the count: Register Pair HL ends at 42D8H, the date, Register Pair DE at 5699H and Register Pair BC at 0000H.
529B
LD DE,569DH 11 9D 56
Point Register Pair DE to 569DH, the 8 characters MM/DD/YY of the second heading text.
529E
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of the date.
52A1
LDIR ED B0
Copy the 8 bytes of the diskette's date (bytes D8H-DFH of the allocation table) from Register Pair HL (42D8H) to Register Pair DE (569DH), with Register Pair BC as the count down to 0000H.
52A3
LD HL,5691H 21 91 56
Point Register Pair HL to 5691H, the diskette name, " -- " and the date, ended by 0DH.
52A6
GOSUB to 556CH to display the text at Register Pair HL (and print it when P was given): the heading line ends with the carriage return.
52A9
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, for the empty line under the heading.
52AB
GOSUB to 5577H to display Register A (0DH), and print it when P was given: an empty line after the heading.
52AE
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive.
52AF
PUSH BC C5
Save Register Pair BC (Register C = the drive) to the stack again.
52B0
LD A,08H 3E 08
Load Register A with 08H, the offset of byte +08H of a drive code table (bits 4-0 the sectors of a granule less one).
52B2
GOSUB to 4797H to fetch byte Register A (+08H) of the drive code table of drive Register C into Register A.
52B5
AND 1FH E6 1F
Mask Register A (byte +08H of the drive code table) to bits 4-0: the sectors of a granule less one.
52B7
INC A 3C
Increment Register A: the sectors of a granule (5 with the byte 24H that the drive code tables 4700H-4727H hold in SYS0/SYS's file).
52B8
LD (5466H),A 32 66 54
Store Register A (the sectors of a granule) to 5466H, the operand of LD A,00H at 5465H, which multiplies the granules of a file into sectors.
52BB
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive. The stack is back to the return address of the member.
52BC
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
52BF
LD E,01H 1E 01
Load Register E with 01H: sector 1 of the directory cylinder, the hash index (one byte for each directory record).
52C1
LD HL,5800H 21 00 58
Point Register Pair HL to 5800H, the buffer of the hash index above the member.
52C4
GOSUB to 4B45H to read cylinder Register D, sector Register E of drive Register C into 5800H (Register Pair HL): the Z FLAG when it was read.
52C7
LD A,16H 3E 16
Load Register A with 16H, the error code HIT READ ERROR. LD does not change the flags of the read.
52C9
If the NZ FLAG is set (the hash index could not be read), JUMP to 559DH to show HIT READ ERROR and abort.
52CC
LD HL,5800H 21 00 58
Point Register Pair HL to 5800H, the first byte of the hash index: the byte of directory entry code 00H.
52CF
JUMP to 5308H to look at the first byte of the hash index.
52D2H - Step Through the Hash Index
Byte n of the hash index (5800H + n) belongs to the directory record whose entry code is n: bits 4-0 the directory sector less 2, bits 7-5 the record in that sector. The bytes are taken in the order 00H, 20H, ... E0H, then 01H, 21H, ..., so all the records of one sector come one after the other and each sector is read once. A byte of 00H is a free record. After byte FFH the drive is done: a carriage return ends the last line, and the command ends at once when a drive was named; otherwise the next drive follows, up to drive 7.
52D2
POP BC C1
Restore Register Pair BC from the stack: Register B = the entry code of the record just shown or passed over (pushed at 530DH), Register C = the drive.
52D3
LD H,58H 26 58
Load Register H with 58H, the page of the hash index at 5800H.
52D5
LD L,B 68
Copy Register B (the entry code) into Register L: Register Pair HL = the byte of the record in the hash index.
52D6
LD A,L 7D
Copy Register L (the entry code, the position in the hash index) into Register A.
52D7
ADD A,20H C6 20
Add 20H to Register A: the next record of the same directory sector (bits 7-5); the CARRY FLAG is set after the eighth record, E0H.
52D9
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the next byte of the hash index to look at.
52DA
If the NC FLAG is set (still in the same sector), JUMP to 5308H to look at that byte.
52DC
INC L 2C
Increment Register L (after the carry Register L holds the sector bits alone): the first record of the next directory sector.
52DD
BIT 5,L CB 6D
Test bit 5 of Register L: it becomes 1 when the sector bits pass 1FH, after the last byte of the hash index.
52DF
If the Z FLAG is set (the hash index is not finished), JUMP to 5308H to look at the byte at Register Pair HL.
52E1
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the last line of the drive's listing.
52E3
GOSUB to 5577H to display Register A (0DH), and print it when P was given: the end of the drive's last line.
52E6
LD A,FFH 3E FF
Self-Modifying Code
Load Register A with FFH. The operand at 52E7H is written by 5259H with the drive number when a colon and a drive digit were typed; it stays FFH (from the file) when no drive was named.
52E8
INC A 3C
Increment Register A (the operand of 52E6H): 00H and the Z FLAG for FFH (all drives), the NZ FLAG for a named drive.
52E9
If the NZ FLAG is set (one drive was named), JUMP to 402DH, VTOS READY: the command is done.
52EC
INC C 0C
Increment Register C (the drive just listed) to the next drive.
52ED
LD A,C 79
Copy Register C (the next drive) into Register A.
52EE
CP 08H FE 08
Compare Register A (the next drive) against 08H, one past the last drive 7.
52F0
If the C FLAG is set (drives are left), JUMP back to 5268H to list drive Register C.
52F3
JUMP to 402DH, VTOS READY: every drive was listed.
52F6H - A Drive That Is Not Ready
5277H comes here when 44B8H finds no drive or no diskette in drive Register C. A named drive gives ILLEGAL DRIVE NUMBER (error 20H) and aborts; otherwise the drive is passed over in silence. When the last drive, drive 7, is passed over this way, the member returns to the request handler (4C4BH) instead of jumping to 402DH.
52F6
POP BC C1
Restore Register Pair BC from the stack (pushed at 5268H): Register C = the drive that is not ready.
52F7
LD A,(52E7H) 3A E7 52
Fetch the operand of 52E6H from 52E7H into Register A: FFH when no drive was named, else the drive number.
52FA
INC A 3C
Increment Register A (the byte from 52E7H): the Z FLAG for FFH, all drives.
52FB
LD A,20H 3E 20
Load Register A with 20H, the error code ILLEGAL DRIVE NUMBER. LD does not change the flags of the increment.
52FD
If the NZ FLAG is set (the named drive is not ready), JUMP to 559DH to show ILLEGAL DRIVE NUMBER and abort.
5300
INC C 0C
Increment Register C (the drive that was not ready) to the next drive.
5301
LD A,C 79
Copy Register C (the next drive) into Register A.
5302
CP 08H FE 08
Compare Register A (the next drive) against 08H, one past the last drive 7.
5304
If the C FLAG is set (drives are left), JUMP back to 5268H to list drive Register C.
5307
RET C9
RETURN to 4C4BH, the request handler, which restores the BREAK byte and returns to 402DH (VTOS READY) or to the program that ran the command through 4405H: drive 7 was the last and was not ready.
5308H - Look at One Directory Record
Register Pair HL = a byte of the hash index; Register L is the entry code of its record. A free record (00H) is passed over. Otherwise the record's directory sector is read into 4200H unless 5314H shows it is there already, and the record is passed over when it is not in use (attribute bit 4 clear) or is an extension record (bit 7), when it is a system file (bit 6) and S was not given, or when it is invisible (bit 3) and I was not given. A system file is shown with S whether or not it is also invisible.
5308
LD A,(HL) 7E
Fetch the byte of the hash index at Register Pair HL into Register A: the hash code of the record's name, 00H for a free record.
5309
OR A B7
OR Register A (the hash byte) with itself to set the flags: the Z FLAG for a free record.
530A
If the Z FLAG is set (a free record), JUMP back to 52D6H for the next byte of the hash index.
530C
LD B,L 45
Copy Register L (the position in the hash index: the record's directory entry code) into Register B.
530D
PUSH BC C5
Save Register Pair BC (Register B = the entry code, Register C = the drive) to the stack; 52D2H takes it back.
530E
LD A,L 7D
Copy Register L (the entry code) into Register A.
530F
AND E0H E6 E0
Mask Register A to bits 7-5: the record's number in its sector times 32, its offset in the sector.
5311
LD L,A 6F
Copy Register A (the record's offset) into Register L.
5312
XOR B A8
Exclusive OR Register A with Register B (the entry code): Register A = bits 4-0, the directory sector of the record less 2.
5313
CP FFH FE FF
Self-Modifying Code
Compare Register A (the record's sector code) against FFH. The operand at 5314H is written by 5317H with the sector code last read into 4200H; FFH from the file matches no sector, so the first record of the first drive always reads its sector; the operand is not reset for the next drive.
5315
If the Z FLAG is set (that directory sector is already in 4200H), JUMP to 5320H without reading it.
5317
LD (5314H),A 32 14 53
Store Register A (the sector code) to 5314H, the operand of CP FFH at 5313H, and the sector 5532H compares with: the directory sector about to be read into 4200H.
531A
GOSUB to 4B10H to read the directory sector of entry code Register B on drive Register C into 4200H: Register Pair HL = the record in 4200H, the NZ FLAG with Register A = 11H on an error.
531D
If the NZ FLAG is set (the directory sector could not be read), JUMP to 559DH to show DIRECTORY READ ERROR and abort.
5320
LD H,42H 26 42
Load Register H with 42H: Register Pair HL = 4200H plus the record's offset, the record in the buffer.
5322
LD A,(HL) 7E
Fetch the attribute byte, byte +00H of the directory record at Register Pair HL, into Register A.
5323
BIT 4,A CB 67
Test bit 4 of Register A (the attribute byte): set when the record is in use.
5325
If the Z FLAG is set (a free record), JUMP to 52D2H for the next record.
5328
BIT 7,A CB 7F
Test bit 7 of Register A (the attribute byte): set in an extension record, which holds more extents of a file whose own record comes first.
532A
If the NZ FLAG is set (an extension record), JUMP to 52D2H: it is not listed as a file.
532D
BIT 6,A CB 77
Test bit 6 of Register A (the attribute byte): a system file.
532F
If the Z FLAG is set (not a system file), JUMP to 533BH to test for an invisible file.
5331
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with 0000H. The operand at 5332H-5333H is the word of the parameter S: SYS1/SYS's parameter reader (5261H) stores FFFFH there when S was given; 0000H from the file.
5334
LD A,D 7A
Copy Register D (the high byte of the S word) into Register A.
5335
OR E B3
OR Register E (the low byte of the S word) into Register A: the Z FLAG is set when S was not given.
5336
If the Z FLAG is set (no S), JUMP to 52D2H: a system file is not listed.
5339
JUMP to 5347H to compare the name with the pattern: a system file is listed with S even when it is invisible as well.
533B
BIT 3,A CB 5F
Test bit 3 of Register A (the attribute byte): an invisible file.
533D
If the Z FLAG is set (a visible file), JUMP to 5347H to compare the name.
533F
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with 0000H. The operand at 5340H-5341H is the word of the parameter I: SYS1/SYS's parameter reader (5261H) stores FFFFH there when I was given; 0000H from the file.
5342
LD A,D 7A
Copy Register D (the high byte of the I word) into Register A.
5343
OR E B3
OR Register E (the low byte of the I word) into Register A: the Z FLAG is set when I was not given.
5344
If the Z FLAG is set (no I), JUMP to 52D2H: an invisible file is not listed.
5347H - Compare the Name With the Pattern
The 11 bytes of the record's name and extension (+05H-+0FH) are compared with the pattern at 56F6H-5700H; a pattern byte that is a space matches any character, every other byte must be equal.
5347
LD A,L 7D
Copy Register L (the record's offset in 4200H) into Register A.
5348
ADD A,05H C6 05
Add 05H to Register A: the offset of byte +05H of the record, the first character of the name.
534A
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the name in the directory record.
534B
LD DE,56F6H 11 F6 56
Point Register Pair DE to 56F6H, the name pattern followed by the extension pattern.
534E
LD B,0BH 06 0B
Load Register B with 0BH, the 11 characters of the name (8) and the extension (3).
5350
LD A,(DE) 1A
Loop Start
Fetch a character of the pattern at Register Pair DE into Register A.
5351
CP (HL) BE
Compare Register A (the pattern character) against the record's character at Register Pair HL.
5352
If the Z FLAG is set (the same), JUMP to 5359H for the next character.
5354
CP 20H FE 20
Compare Register A (the pattern character) against 20H, a space: a space in the pattern matches any character.
5356
If the NZ FLAG is set (a typed character that differs), JUMP to 52D2H: the file is not listed.
5359
INC HL 23
Increment Register Pair HL to the next character of the record's name or extension.
535A
INC DE 13
Increment Register Pair DE to the next character of the pattern.
535B
Decrement Register B (the characters left to compare) and LOOP BACK to 5350H until Register B is 00H.
535DH - Show the Name and the Attribute Letters
Each file takes a field of 20 columns: the name, a slash and the extension when there is one, a space, then S (system file), I (invisible), P (protected by a password) and a plus sign (written since the last backup), padded with spaces. Register C counts down the columns left in the field. 5577H shows each character and prints it too when P was given.
535D
LD A,L 7D
Copy Register L (the byte after the record's extension, +10H) into Register A.
535E
AND E0H E6 E0
Mask Register A to bits 7-5: the record's offset in 4200H.
5360
ADD A,05H C6 05
Add 05H to Register A: the offset of byte +05H, the name.
5362
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the name in the directory record.
5363
LD C,14H 0E 14
Load Register C with 14H, the 20 columns of a file's field in the listing.
5365
LD B,08H 06 08
Load Register B with 08H, the most characters of a name.
5367
LD A,(HL) 7E
Loop Start
Fetch a character of the name at Register Pair HL into Register A.
5368
INC HL 23
Increment Register Pair HL to the next character of the name.
5369
CP 20H FE 20
Compare Register A (the character of the name) against 20H, a space: the name is padded with spaces.
536B
If the Z FLAG is set (the end of the name), JUMP to 5375H to move Register Pair HL to the extension.
536D
GOSUB to 5577H to display Register A (the character of the name), and print it when P was given.
5370
DEC C 0D
Decrement Register C, the columns left in the field.
5371
Decrement Register B (the characters of the name left) and LOOP BACK to 5367H until Register B is 00H.
5373
JUMP to 5379H: all 8 characters were shown and Register Pair HL is at the extension, byte +0DH.
5375
LD A,L 7D
Copy Register L (one past the space that ended the name) into Register A.
5376
ADD A,B 80
Add Register B (the characters of the name not yet looked at, the space included) to Register A.
5377
DEC A 3D
Decrement Register A: Register A = the offset of byte +0DH of the record, the extension.
5378
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the extension in the directory record.
5379
LD A,(HL) 7E
Fetch the first character of the extension at Register Pair HL into Register A.
537A
CP 20H FE 20
Compare Register A (the first character of the extension) against 20H, a space: the file has no extension.
537C
If the Z FLAG is set (no extension), JUMP to 5392H to show the space after the name.
537E
LD A,2FH 3E 2F
Load Register A with 2FH, the slash that comes before the extension.
5380
GOSUB to 5577H to display Register A (the slash), and print it when P was given.
5383
DEC C 0D
Decrement Register C, the columns left in the field, for the slash.
5384
LD B,03H 06 03
Load Register B with 03H, the most characters of an extension.
5386
LD A,(HL) 7E
Loop Start
Fetch a character of the extension at Register Pair HL into Register A.
5387
INC HL 23
Increment Register Pair HL to the next character of the extension.
5388
CP 20H FE 20
Compare Register A (the character of the extension) against 20H, a space: the end of a shorter extension.
538A
If the Z FLAG is set (the end of the extension), JUMP to 5392H.
538C
GOSUB to 5577H to display Register A (the character of the extension), and print it when P was given.
538F
DEC C 0D
Decrement Register C, the columns left in the field.
5390
Decrement Register B (the characters of the extension left) and LOOP BACK to 5386H until Register B is 00H.
5392
LD A,20H 3E 20
Load Register A with 20H, the space between the name and the attribute letters.
5394
GOSUB to 5577H to display Register A (the space), and print it when P was given.
5397
DEC C 0D
Decrement Register C, the columns left in the field, for the space.
5398
LD A,L 7D
Copy Register L (a byte of the record between +0DH and +10H, where the extension loop stopped) into Register A.
5399
AND E0H E6 E0
Mask Register A to bits 7-5: the record's offset in 4200H.
539B
LD L,A 6F
Copy Register A into Register L: Register Pair HL = byte +00H of the directory record, the attribute byte.
539C
LD B,(HL) 46
Fetch the attribute byte at Register Pair HL into Register B, kept for the tests below.
539D
BIT 6,B CB 70
Test bit 6 of Register B (the attribute byte): a system file.
539F
LD A,53H 3E 53
Load Register A with 53H, the letter S. LD does not change the flags of the test.
53A1
If the NZ FLAG is set (a system file), GOSUB to 5410H to show Register A (S) and count its column in Register C.
53A4
BIT 3,B CB 58
Test bit 3 of Register B (the attribute byte): an invisible file.
53A6
LD A,49H 3E 49
Load Register A with 49H, the letter I. LD does not change the flags of the test.
53A8
If the NZ FLAG is set (an invisible file), GOSUB to 5410H to show Register A (I) and count its column in Register C.
53ABH - The Letter P and the Plus Sign
4296H holds the hash code of 8 spaces, the code of no password. The file counts as protected (P, and 5416H = 50H) when its update password (+10H-+11H) is not blank and either its access level (attribute bits 2-0) is not 0 or its access password (+12H-+13H) is not blank. Otherwise 5416H = 20H and the allocation line shows ALL. A plus sign follows when bit 6 of +01H is set: the record is marked updated, a bit that SYS3/SYS's close sets when the file was written.
53AB
PUSH HL E5
Save Register Pair HL (byte +00H of the directory record) to the stack; 53DAH takes it back.
53AC
LD A,L 7D
Copy Register L (the record's offset) into Register A.
53AD
ADD A,10H C6 10
Add 10H to Register A: the offset of byte +10H, the update password's hash code. No carry can come from it, so the CARRY FLAG is clear for the SBC below.
53AF
LD L,A 6F
Copy Register A into Register L: Register Pair HL = byte +10H of the record.
53B0
LD E,(HL) 5E
Fetch the low byte of the update password's hash code at Register Pair HL into Register E.
53B1
INC L 2C
Increment Register L to byte +11H of the record (Register Pair HL).
53B2
LD D,(HL) 56
Fetch the high byte of the update password's hash code at Register Pair HL into Register D: Register Pair DE = the code.
53B3
PUSH HL E5
Save Register Pair HL (byte +11H of the record) to the stack.
53B4
LD HL,4296H 21 96 42
Load Register Pair HL with 4296H, the hash code of a password of 8 spaces: no password.
53B7
SBC HL,DE ED 52
SUBtract Register Pair DE (the update password's code) from Register Pair HL (4296H), with the CARRY FLAG clear: the Z FLAG is set when the file has no update password.
53B9
POP HL E1
Restore Register Pair HL from the stack: byte +11H of the record. POP does not change the flags.
53BA
If the Z FLAG is set (no update password), JUMP to 53D0H: no P, and the allocation line shows ALL.
53BC
LD A,B 78
Copy Register B (the attribute byte) into Register A.
53BD
AND 07H E6 07
Mask Register A to bits 2-0, the access level of the file (0 full access); AND also clears the CARRY FLAG.
53BF
LD A,50H 3E 50
Load Register A with 50H, the letter P. LD does not change the flags of the mask.
53C1
If the NZ FLAG is set (the access level is not 0), JUMP to 53D2H with Register A = 50H: the file is protected.
53C3
INC L 2C
Increment Register L to byte +12H of the record (Register Pair HL), the access password's hash code.
53C4
LD E,(HL) 5E
Fetch the low byte of the access password's hash code at Register Pair HL into Register E.
53C5
INC L 2C
Increment Register L to byte +13H of the record (Register Pair HL).
53C6
LD D,(HL) 56
Fetch the high byte of the access password's hash code at Register Pair HL into Register D: Register Pair DE = the code.
53C7
LD HL,4296H 21 96 42
Load Register Pair HL with 4296H, the hash code of a password of 8 spaces.
53CA
SBC HL,DE ED 52
SUBtract Register Pair DE (the access password's code) from Register Pair HL (4296H), with the CARRY FLAG still clear from the AND at 53BDH: the Z FLAG is set when the file has no access password.
53CC
LD A,50H 3E 50
Load Register A with 50H, the letter P. LD does not change the flags of the subtraction.
53CE
If the NZ FLAG is set (an access password), JUMP to 53D2H with Register A = 50H: the file is protected.
53D0
LD A,20H 3E 20
Load Register A with 20H, a space: the file is not protected by a password.
53D2
LD (5416H),A 32 16 54
Store Register A (50H for P, 20H for none) to 5416H, the operand of LD A,00H at 5415H: 5414H shows ALL for 20H and the access level's name for 50H.
53D5
CP 20H FE 20
Compare Register A (50H or 20H) against 20H, a space.
53D7
If the NZ FLAG is set (Register A = 50H), GOSUB to 5410H to show Register A (P) and count its column in Register C.
53DA
POP HL E1
Restore Register Pair HL from the stack: byte +00H of the directory record, pushed at 53ABH.
53DB
INC HL 23
Increment Register Pair HL to byte +01H of the record.
53DC
BIT 6,(HL) CB 76
Test bit 6 of byte +01H at Register Pair HL: set by SYS3/SYS's close when the file was written (the record is marked as updated).
53DE
LD A,2BH 3E 2B
Load Register A with 2BH, the plus sign. LD does not change the flags of the test.
53E0
If the NZ FLAG is set (written since the last backup), GOSUB to 5410H to show Register A (the plus sign) and count its column in Register C.
53E3
DEC HL 2B
Decrement Register Pair HL back to byte +00H of the directory record.
53E4
LD A,20H 3E 20
Loop Start
Load Register A with 20H, a space, to fill the rest of the 20 column field.
53E6
GOSUB to 5577H to display Register A (the space), and print it when P was given.
53E9
DEC C 0D
Decrement Register C, the columns left in the field.
53EA
If the NZ FLAG is set (columns are left), LOOP BACK to 53E4H for another space.
53ECH - End of One File
With A the allocation line follows (5414H), which sets the column counter so that the line ends at once. Otherwise three files share a line. At the end of a line 5603H lets SHIFT and @ hold the listing and BREAK abort it.
53EC
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with 0000H. The operand at 53EDH-53EEH is the word of the parameter A: SYS1/SYS's parameter reader (5261H) stores FFFFH there when A was given; 0000H from the file.
53EF
LD A,D 7A
Copy Register D (the high byte of the A word) into Register A.
53F0
OR E B3
OR Register E (the low byte of the A word) into Register A: the NZ FLAG is set when A was given.
53F1
If the NZ FLAG is set (A), GOSUB to 5414H to show the access level, the number of records, the size and the date of the file at Register Pair HL; it stores 01H at 53F5H.
53F4
LD A,03H 3E 03
Self-Modifying Code
Load Register A with 03H, the column counter. The operand at 53F5H is written by 526BH and 53FFH (03H, three files a line), by 53F7H with each file, and by 5506H (01H after the allocation line).
53F6
DEC A 3D
Decrement Register A, the files still to come on this line.
53F7
LD (53F5H),A 32 F5 53
Store Register A (the files still to come on this line) back to 53F5H, the operand of 53F4H.
53FA
If the NZ FLAG is set (room is left on the line), JUMP to 52D2H for the next record.
53FD
LD A,03H 3E 03
Load Register A with 03H, three files to a line.
53FF
LD (53F5H),A 32 F5 53
Store Register A (03H) to 53F5H, the operand of 53F4H: the next line starts with three places.
5402
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the line of the listing.
5404
GOSUB to 5577H to display Register A (0DH), and print it when P was given.
5407
GOSUB to 5603H to test the keys: the NZ FLAG when BREAK is pressed; SHIFT and @ hold the listing until another key is pressed.
540A
If the NZ FLAG is set (BREAK), JUMP to 4030H, the abort exit.
540D
JUMP to 52D2H for the next record, which starts the new line of the listing.
5410H - Show an Attribute Letter
Register A = the letter; Register C, the columns left in the field, is counted down and the letter goes to 5577H, which returns to the caller.
5410
DEC C 0D
Decrement Register C, the columns left in the 20 column field, for the letter in Register A.
5411
JUMP to 5577H to display Register A (the letter), and print it when P was given; its RET returns to the caller of 5410H.
5414H - A: the Allocation Line
Register Pair HL = byte +00H of the directory record. The text at 56A6H is filled in and shown: the access level's name (ALL when the file has no password, see 53ABH), EOF= the number of records up to the end of file, SIZ= (SIZ: when bit 7 of +01H keeps the space) the space the file holds in K to one digit (.0, .2, .5, .8), and the date of +01H-+02H as DD-MMM-YY with the separators made plus signs when bit 4 of +01H is set. The column counter 53F5H is set to 01H so that the line ends after this file.
5414
PUSH HL E5
Save Register Pair HL (byte +00H of the directory record) to the stack.
5415
LD A,00H 3E 00
Self-Modifying Code
Load Register A with 00H. The operand at 5416H is written by 53D2H for each file: 20H when it has no password (or no access restriction), 50H when it is protected.
5417
SUB 20H D6 20
SUBtract 20H from Register A (the operand of 5415H): the Z FLAG and Register A = 00H when the file is not protected.
5419
If the Z FLAG is set (not protected), JUMP to 541EH with Register A = 00H, the place of ALL in the table.
541B
LD A,(HL) 7E
Fetch the attribute byte, byte +00H at Register Pair HL, into Register A.
541C
AND 07H E6 07
Mask Register A to bits 2-0, the access level of the file (0-7).
541E
RLCA 07
Rotate Register A (the access level) left: the level times 2.
541F
RLCA 07
Rotate Register A left again: the level times 4, the offset of its 4 character name in the table at 5650H.
5420
LD C,A 4F
Copy Register A (the offset of the name) into Register C.
5421
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset of the name.
5423
LD HL,5650H 21 50 56
Point Register Pair HL to 5650H, the table of the 8 names of the access levels.
5426
ADD HL,BC 09
Add Register Pair BC (the offset) to Register Pair HL: Register Pair HL = the name of the level.
5427
LD DE,56A6H 11 A6 56
Point Register Pair DE to 56A6H, the first 4 characters of the allocation line (PROT in the file).
542A
LD BC,0004H 01 04 00
Load Register Pair BC with 0004H, the 4 characters of a level's name.
542D
LDIR ED B0
Copy the 4 characters of the level's name from Register Pair HL to Register Pair DE (56A6H), with Register Pair BC as the count down to 0000H.
542F
POP HL E1
Restore Register Pair HL from the stack: byte +00H of the directory record.
5430
PUSH HL E5
Save Register Pair HL (byte +00H of the record) to the stack again.
5431
INC L 2C
Increment Register L to byte +01H of the record (Register Pair HL).
5432
INC L 2C
Increment Register L to byte +02H of the record (Register Pair HL).
5433
INC L 2C
Increment Register L to byte +03H of the record (Register Pair HL), the end of file offset.
5434
LD A,(HL) 7E
Fetch the end of file offset at Register Pair HL (+03H, the bytes used in the last sector, 00H for a full one) into Register A.
5435
LD (5211H),A 32 11 52
Store Register A (the end of file offset) to 5211H, the low byte of the work number 520FH-5211H, which 5203H tests.
5438
INC L 2C
Increment Register L to byte +04H of the record (Register Pair HL), the record length (00H = 256).
5439
LD A,(HL) 7E
Fetch the record length at Register Pair HL into Register A.
543A
LD (5454H),A 32 54 54
Store Register A (the record length) to 5454H, the operand of LD C,00H at 5453H, the divisor of the size.
543D
LD A,L 7D
Copy Register L (the offset of byte +04H) into Register A.
543E
ADD A,10H C6 10
Add 10H to Register A: the offset of byte +14H of the record, the end of file record number.
5440
GOSUB to 5203H with Register A = the low byte of byte +14H: Register Pair DE = the full sectors of the file, Register Pair HL = 5211H.
5443
LD A,(5454H) 3A 54 54
Fetch the record length from 5454H into Register A.
5446
DEC A 3D
Decrement Register A: the record length less one (FFH for 256), added so that the division below rounds up.
5447
ADD A,(HL) 86
Add the end of file offset at Register Pair HL (5211H) to Register A: the CARRY FLAG goes into the middle byte.
5448
LD (HL),A 77
Store Register A (the low byte of the size plus the record length less one) to 5211H (Register Pair HL).
5449
DEC HL 2B
Decrement Register Pair HL to 5210H, the middle byte of the work number.
544A
LD A,E 7B
Copy Register E (the low byte of the full sectors) into Register A.
544B
ADC A,00H CE 00
Add the CARRY FLAG to Register A (ADC 00H): the middle byte of the 24 bit number.
544D
LD (HL),A 77
Store Register A (the middle byte) to 5210H (Register Pair HL).
544E
DEC HL 2B
Decrement Register Pair HL to 520FH, the high byte of the work number.
544F
LD A,D 7A
Copy Register D (the high byte of the full sectors) into Register A.
5450
ADC A,00H CE 00
Add the CARRY FLAG to Register A (ADC 00H): the high byte of the 24 bit number.
5452
LD (HL),A 77
Store Register A (the high byte) to 520FH (Register Pair HL): 520FH-5211H = the full sectors times 256 plus the offset plus the record length less one.
5453
LD C,00H 0E 00
Self-Modifying Code
Load Register C with 00H. The operand at 5454H is written by 543AH with the file's record length (byte +04H of the record), the divisor; 00H stands for 256.
5455
GOSUB to 55DDH to divide the 24 bit number at Register Pair HL (520FH) by Register C (the record length): Register Pair DE = the number of records up to the end of file.
5458
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the number of records.
5459
LD DE,56B1H 11 B1 56
Point Register Pair DE to 56B1H, the 5 places after EOF= in the allocation line.
545C
GOSUB to 55A2H to write Register Pair HL (the records) as 5 decimal digits at Register Pair DE (56B1H), with spaces for the leading zeros.
545F
POP HL E1
Restore Register Pair HL from the stack: byte +00H of the directory record.
5460
PUSH HL E5
Save Register Pair HL (byte +00H of the record) to the stack again.
5461
GOSUB to 550AH to count the granules of the file over all its extents and extension records: Register Pair DE = the granules.
5464
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the granules of the file.
5465
LD A,00H 3E 00
Self-Modifying Code
Load Register A with 00H. The operand at 5466H is written by 52B8H for each drive with the sectors of a granule, from byte +08H of the drive code table.
5467
GOSUB to 4B8FH to multiply Register Pair HL (the granules) by Register A (the sectors of a granule): Register A = bits 7-0 of the sectors, Register Pair HL = bits 23-8.
546A
PUSH AF F5
Save Register Pair AF (Register A = the low byte of the sectors) to the stack, for the fraction below.
546B
LD H,L 65
Copy Register L (bits 15-8 of the sectors) into Register H.
546C
LD L,A 6F
Copy Register A (bits 7-0 of the sectors) into Register L: Register Pair HL = the sectors of the file.
546D
SRL H CB 3C
Shift Register H right: bit 0 of the sectors' high byte goes into the CARRY FLAG.
546F
RR L CB 1D
Rotate Register L right through the carry: Register Pair HL = the sectors divided by 2.
5471
SRL H CB 3C
Shift Register H right again, into the CARRY FLAG.
5473
RR L CB 1D
Rotate Register L right through the carry: Register Pair HL = the sectors divided by 4, the whole K (4 sectors of 256 bytes).
5475
LD DE,56BDH 11 BD 56
Point Register Pair DE to 56BDH, the 5 places after SIZ= in the allocation line.
5478
GOSUB to 55A2H to write Register Pair HL (the K) as 5 decimal digits at Register Pair DE (56BDH), with spaces for the leading zeros.
547B
POP AF F1
Restore Register Pair AF from the stack: Register A = the low byte of the sectors.
547C
AND 03H E6 03
Mask Register A to bits 1-0: the sectors past the whole K (0-3 quarters of a K).
547E
LD B,A 47
Copy Register A (the quarters) into Register B, for the counting down below.
547F
LD A,30H 3E 30
Load Register A with 30H, the digit 0. LD does not change the flags of the mask.
5481
If the Z FLAG is set (no quarter), JUMP to 548FH with Register A = the digit 0.
5483
DEC B 05
Decrement Register B (the quarters): the Z FLAG for one quarter.
5484
LD A,32H 3E 32
Load Register A with 32H, the digit 2 (one quarter, .25 shown as .2).
5486
If the Z FLAG is set (one quarter), JUMP to 548FH with Register A = the digit 2.
5488
DEC B 05
Decrement Register B (the quarters): the Z FLAG for two quarters.
5489
LD A,35H 3E 35
Load Register A with 35H, the digit 5 (two quarters, .5).
548B
If the Z FLAG is set (two quarters), JUMP to 548FH with Register A = the digit 5.
548D
LD A,38H 3E 38
Load Register A with 38H, the digit 8 (three quarters, .75 shown as .8).
548F
LD (56C3H),A 32 C3 56
Store Register A (the tenths digit) to 56C3H, after the point of the size in the allocation line.
5492
LD HL,56C7H 21 C7 56
Point Register Pair HL to 56C7H, the space before the date field of the allocation line.
5495
LD DE,56C8H 11 C8 56
Point Register Pair DE to 56C8H, the date field DD-MMM-YY.
5498
LD BC,0009H 01 09 00
Load Register Pair BC with 0009H, the 9 characters of the date field.
549B
LDIR ED B0
Copy 9 bytes from Register Pair HL to Register Pair DE, one place on, with Register Pair BC as the count: the space at 56C7H is carried over 56C8H-56D0H and the date field is blank.
549D
POP HL E1
Restore Register Pair HL from the stack: byte +00H of the directory record.
549E
LD DE,56C8H 11 C8 56
Point Register Pair DE to 56C8H, the day of the date field.
54A1
INC HL 23
Increment Register Pair HL to byte +01H of the record.
54A2
BIT 7,(HL) CB 7E
Test bit 7 of byte +01H at Register Pair HL: set when the space of the file is kept (ALLOC), so that a close does not give granules back.
54A4
LD A,3DH 3E 3D
Load Register A with 3DH, the equals sign. LD does not change the flags of the test.
54A6
If the Z FLAG is set (bit 7 clear), JUMP to 54AAH with Register A = the equals sign.
54A8
LD A,3AH 3E 3A
Load Register A with 3AH, the colon, for a file whose space is kept.
54AA
LD (56BCH),A 32 BC 56
Store Register A (the equals sign or the colon) to 56BCH, the character after SIZ in the allocation line.
54AD
INC HL 23
Increment Register Pair HL to byte +02H of the record: the day in bits 7-3 and the year less 80 in bits 2-0.
54AE
LD A,(HL) 7E
Fetch byte +02H at Register Pair HL into Register A.
54AF
OR A B7
OR Register A with itself to set the flags: the Z FLAG when the record holds no date.
54B0
If the Z FLAG is set (no date), JUMP to 54FEH: the date field stays blank.
54B2
RRCA 0F
Rotate Register A (byte +02H) right: the day moves towards bit 0.
54B3
RRCA 0F
Rotate Register A (byte +02H, turned once) right a second time.
54B4
RRCA 0F
Rotate Register A right a third time: the day is in bits 4-0.
54B5
AND 1FH E6 1F
Mask Register A to bits 4-0: the day of the month (1-31).
54B7
LD B,FFH 06 FF
Load Register B with FFH, the tens digit less one.
54B9
INC B 04
Loop Start
Increment Register B, the tens of the day.
54BA
SUB 0AH D6 0A
SUBtract 0AH from Register A (the day): one ten less.
54BC
If the NC FLAG is set (the day held another ten), LOOP BACK to 54B9H.
54BE
ADD A,0AH C6 0A
Add 0AH back to Register A: Register A = the units of the day.
54C0
PUSH AF F5
Save Register Pair AF (Register A = the units of the day) to the stack.
54C1
LD A,B 78
Copy Register B (the tens of the day) into Register A.
54C2
ADD A,30H C6 30
Add 30H to Register A: the tens digit as a character.
54C4
LD (DE),A 12
Store Register A (the tens digit) to the date field at Register Pair DE (56C8H).
54C5
INC DE 13
Increment Register Pair DE to 56C9H, the units of the day.
54C6
POP AF F1
Restore Register Pair AF from the stack: Register A = the units of the day.
54C7
ADD A,30H C6 30
Add 30H to Register A: the units digit as a character.
54C9
LD (DE),A 12
Store Register A (the units digit) to the date field at Register Pair DE (56C9H).
54CA
INC DE 13
Increment Register Pair DE to 56CAH, the separator after the day.
54CB
INC DE 13
Increment Register Pair DE past the separator to 56CBH, the month.
54CC
PUSH HL E5
Save Register Pair HL (byte +02H of the record) to the stack.
54CD
DEC HL 2B
Decrement Register Pair HL to byte +01H of the record, the month in bits 3-0.
54CE
LD A,(HL) 7E
Fetch byte +01H at Register Pair HL into Register A.
54CF
AND 0FH E6 0F
Mask Register A to bits 3-0: the month (1-12).
54D1
DEC A 3D
Decrement Register A: the month less one (0-11).
54D2
LD C,A 4F
Copy Register A (the month less one) into Register C.
54D3
RLCA 07
Rotate Register A left: the month less one times 2.
54D4
ADD A,C 81
Add Register C (the month less one) to Register A: the month less one times 3, the offset of its name.
54D5
LD C,A 4F
Copy Register A (the offset of the month's name) into Register C.
54D6
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset of the month's name.
54D8
LD HL,56D2H 21 D2 56
Point Register Pair HL to 56D2H, the 12 names of the months, 3 letters each.
54DB
ADD HL,BC 09
Add Register Pair BC (the offset) to Register Pair HL: Register Pair HL = the name of the month.
54DC
LD BC,0003H 01 03 00
Load Register Pair BC with 0003H, the 3 letters of a month's name.
54DF
LDIR ED B0
Copy the 3 letters from Register Pair HL to the date field at Register Pair DE (56CBH-56CDH), with Register Pair BC as the count down to 0000H: Register Pair DE ends at 56CEH, the second separator.
54E1
INC DE 13
Increment Register Pair DE past the separator to 56CFH, the year.
54E2
LD A,38H 3E 38
Load Register A with 38H, the digit 8: every year is shown as 80-87.
54E4
LD (DE),A 12
Store Register A (the digit 8) to the date field at Register Pair DE (56CFH).
54E5
INC DE 13
Increment Register Pair DE to 56D0H, the last digit of the year.
54E6
POP HL E1
Restore Register Pair HL from the stack: byte +02H of the record.
54E7
PUSH HL E5
Save Register Pair HL (byte +02H of the record) to the stack again.
54E8
LD A,(HL) 7E
Fetch byte +02H at Register Pair HL into Register A.
54E9
AND 07H E6 07
Mask Register A to bits 2-0: the year less 80.
54EB
ADD A,30H C6 30
Add 30H to Register A: the last digit of the year as a character.
54ED
LD (DE),A 12
Store Register A (the last digit of the year) to the date field at Register Pair DE (56D0H).
54EE
POP HL E1
Restore Register Pair HL from the stack: byte +02H of the record.
54EF
DEC HL 2B
Decrement Register Pair HL to byte +01H of the record.
54F0
BIT 4,(HL) CB 66
Test bit 4 of byte +01H at Register Pair HL: SYS3/SYS's close leaves it set when it wrote the file while no date was set, so the date shown is that of an earlier close.
54F2
LD A,2DH 3E 2D
Load Register A with 2DH, the minus sign. LD does not change the flags of the test.
54F4
If the Z FLAG is set (bit 4 clear), JUMP to 54F8H with Register A = the minus sign.
54F6
LD A,2BH 3E 2B
Load Register A with 2BH, the plus sign, for a date that is older than the file's last write.
54F8
LD (56CAH),A 32 CA 56
Store Register A (the minus or plus sign) to 56CAH, the separator after the day.
54FB
LD (56CEH),A 32 CE 56
Store Register A (the minus or plus sign) to 56CEH, the separator after the month.
54FE
LD HL,56A6H 21 A6 56
Point Register Pair HL to 56A6H, the allocation line, ended by 03H.
5501
GOSUB to 556CH to display the text at Register Pair HL, and print it when P was given.
5504
LD A,01H 3E 01
Load Register A with 01H, the column counter that ends the line after this file.
5506
LD (53F5H),A 32 F5 53
Store Register A (01H) to 53F5H, the operand of 53F4H: the DEC A there gives 00H and the line ends with a carriage return.
5509
RET C9
RETURN to 53F4H with the allocation line shown.
550AH - Count the Granules of a File
Register Pair HL = byte +00H of the directory record (in 4200H). The extents from +16H are added up: each is a cylinder byte and a granule byte whose bits 4-0 are the granules less one. A cylinder byte of FFH ends the list; FEH means that the next byte is the entry code of an extension record holding more extents. That record is taken from 4200H when it is in the sector there (5314H), from 5900H when it is in the sector last read there (553CH), and is otherwise read into 5900H. Returns Register Pair DE = the granules and Register Pair BC = the extents.
550A
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the count of granules.
550D
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the count of extents.
5510
LD A,L 7D
Copy Register L (the offset of the record, +00H) into Register A.
5511
ADD A,16H C6 16
Add 16H to Register A: the offset of byte +16H, the first extent of the record.
5513
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the first extent of the record.
5514
LD A,(HL) 7E
Loop Start
Fetch the cylinder byte of the extent at Register Pair HL into Register A.
5515
INC L 2C
Increment Register L to the extent's granule byte (Register Pair HL).
5516
CP FEH FE FE
Compare Register A (the cylinder byte) against FEH: FEH links to an extension record, FFH ends the extents.
5518
If the NC FLAG is set (FEH or FFH), JUMP to 5527H.
551A
INC BC 03
Increment Register Pair BC, the count of extents.
551B
LD A,(HL) 7E
Fetch the granule byte of the extent at Register Pair HL into Register A: bits 7-5 the first granule, bits 4-0 the granules less one.
551C
INC L 2C
Increment Register L to the next extent of the record (Register Pair HL).
551D
AND 1FH E6 1F
Mask Register A (the granule byte) to bits 4-0: the granules of the extent less one.
551F
INC A 3C
Increment Register A: the granules of the extent.
5520
ADD A,E 83
Add Register E (the low byte of the count of granules) to Register A.
5521
LD E,A 5F
Copy Register A into Register E, the low byte of the count of granules.
5522
If the NC FLAG is set (no carry into the high byte), JUMP back to 5514H for the next extent.
5524
INC D 14
Increment Register D, the high byte of the count of granules.
5525
JUMP back to 5514H for the next extent, with the carry counted in Register D.
5527
RET NZ C0
If the NZ FLAG is set (FFH, the end of the extents), RETURN with Register Pair DE = the granules and Register Pair BC = the extents.
5528
LD A,(HL) 7E
Fetch the byte after FEH at Register Pair HL (byte +1FH of the record) into Register A: the entry code of the extension record.
5529
AND 1FH E6 1F
Mask Register A (the entry code) to bits 4-0: the directory sector of the extension record less 2.
552B
PUSH AF F5
Save Register Pair AF (Register A = the sector code) to the stack.
552C
XOR (HL) AE
Exclusive OR Register A with the entry code at Register Pair HL: Register A = bits 7-5 of the entry code, the offset of the extension record in its sector.
552D
NOP 00
No operation: Register A (the extension record's offset) is not changed by this byte.
552E
NOP 00
No operation: Register A (the extension record's offset) is not changed by this byte either.
552F
LD L,A 6F
Copy Register A (the offset of the extension record) into Register L.
5530
POP AF F1
Restore Register Pair AF from the stack: Register A = the sector code of the extension record.
5531
PUSH HL E5
Save Register Pair HL (Register L = the offset of the extension record) to the stack.
5532
LD HL,5314H 21 14 53
Point Register Pair HL to 5314H, the sector code of the directory sector in 4200H.
5535
CP (HL) BE
Compare Register A (the extension record's sector code) against the byte at Register Pair HL (5314H): the Z FLAG when the record is in 4200H.
5536
POP HL E1
Restore Register Pair HL from the stack: Register L = the offset of the extension record. POP does not change the flags.
5537
LD H,42H 26 42
Load Register H with 42H: Register Pair HL = the extension record in 4200H, in case it is there.
5539
If the Z FLAG is set (the sector is in 4200H), JUMP to 5510H to go on with the extents of the extension record.
553B
CP 00H FE 00
Self-Modifying Code
Compare Register A (the extension record's sector code) against 00H. The operand at 553CH is written by 5541H with the sector code last read into 5900H; it is 00H from the file, so sector code 00H is taken as being in 5900H before anything has been read there.
553D
LD H,59H 26 59
Load Register H with 59H: Register Pair HL = the extension record in 5900H, in case it is there. LD does not change the flags.
553F
If the Z FLAG is set (the sector is taken as being in 5900H), JUMP to 5510H to go on with the extents of the extension record.
5541
LD (553CH),A 32 3C 55
Store Register A (the sector code) to 553CH, the operand of CP 00H at 553BH: the sector about to be read into 5900H.
5544
PUSH BC C5
Save Register Pair BC (the count of extents) to the stack.
5545
PUSH DE D5
Save Register Pair DE (the count of granules) to the stack.
5546
OR L B5
OR Register L (the record's offset, bits 7-5) into Register A (the sector code): Register A = the full entry code of the extension record.
5547
LD B,A 47
Copy Register A (the entry code) into Register B.
5548
LD A,(568AH) 3A 8A 56
Fetch the drive digit of the heading from 568AH into Register A.
554B
SUB 30H D6 30
SUBtract 30H from Register A (the drive digit): the drive number.
554D
LD C,A 4F
Copy Register A (the drive number) into Register C.
554E
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
5551
LD A,B 78
Copy Register B (the entry code of the extension record) into Register A.
5552
AND 1FH E6 1F
Mask Register A to bits 4-0: the sector code of the extension record.
5554
ADD A,02H C6 02
Add 02H to Register A: the directory records start in sector 2 of the directory cylinder.
5556
LD E,A 5F
Copy Register A (the directory sector) into Register E.
5557
LD HL,5900H 21 00 59
Point Register Pair HL to 5900H, the buffer of extension records above the member.
555A
GOSUB to 4B45H to read cylinder Register D, sector Register E of drive Register C into 5900H (Register Pair HL): the Z FLAG when it was read.
555D
LD A,11H 3E 11
Load Register A with 11H, the error code DIRECTORY READ ERROR. LD does not change the flags of the read.
555F
If the NZ FLAG is set (the sector could not be read), JUMP to 559DH to show DIRECTORY READ ERROR and abort.
5562
LD A,B 78
Copy Register B (the entry code of the extension record) into Register A.
5563
AND E0H E6 E0
Mask Register A to bits 7-5: the offset of the extension record in its sector.
5565
ADD A,16H C6 16
Add 16H to Register A: the offset of its first extent, byte +16H.
5567
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the first extent of the extension record in 5900H.
5568
POP DE D1
Restore Register Pair DE from the stack: the count of granules.
5569
POP BC C1
Restore Register Pair BC from the stack: the count of extents.
556A
JUMP back to 5514H to add the extents of the extension record.
556CH - Show a Text, and Print It With P
Register Pair HL = a text ended by 03H or 0DH. It is displayed through 4467H and, when the low byte of the P word (557DH) is not 00H, printed through 446AH as well.
556C
GOSUB to 4467H to display the text at Register Pair HL (Register Pair DE is left at 401DH, the display's control block).
556F
LD A,(557DH) 3A 7D 55
Fetch the low byte of the word of the parameter P from 557DH into Register A: FFH when P was given, 00H when not.
5572
OR A B7
OR Register A with itself to set the flags: the NZ FLAG when P was given.
5573
If the NZ FLAG is set (P), JUMP to 446AH to print the text at Register Pair HL on the PR device; it returns to the caller of 556CH.
5576
RET C9
RETURN to the caller with the text displayed and not printed.
5577H - Show a Character, and Print It With P
Register A = the character. It is displayed through the ROM's 0033H and, when the low byte of the P word is FFH, printed through the ROM's 003BH as well. Register A is kept across the display; Register Pair DE is changed.
5577
PUSH AF F5
Save Register Pair AF (Register A = the character) to the stack.
5578
GOSUB to the ROM's 0033H to display the character in Register A at the cursor.
557B
POP AF F1
Restore Register Pair AF from the stack: Register A = the character again.
557C
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with 0000H. The operand at 557DH-557EH is the word of the parameter P: SYS1/SYS's parameter reader (5261H) stores FFFFH there when P was given; 0000H from the file.
557F
INC E 1C
Increment Register E (the low byte of the P word): FFH becomes 00H and sets the Z FLAG.
5580
If the Z FLAG is set (P), JUMP to the ROM's 003BH to print the character in Register A on the PR device; it returns to the caller of 5577H.
5583
RET C9
RETURN to the caller with the character in Register A displayed.
5584H - Parameter Error
5265H comes here when SYS1/SYS's parameter reader refuses the list in parentheses. The message is displayed and written to the job log, then the command aborts.
5584
LD HL,558DH 21 8D 55
Point Register Pair HL to 558DH, the text "PARAMETER ERROR" ended by 0DH.
5587
GOSUB to 447BH to display the text at Register Pair HL and write it to the job log.
558A
JUMP to 4030H, the abort exit: the listing is not made.
558D-559B
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of 5584H for a parameter list that SYS1/SYS's reader refuses.
559C
DEFB 0DH 0D
The carriage return that ends the text "PARAMETER ERROR" and its line on the display.
559DH - Error Exit
Register A = an error code. Bit 6 is set so that 4409H shows the text of the message alone; bit 7 stays clear, so SYS4/SYS goes on to the abort exit 4030H after it.
559D
OR 40H F6 40
OR Register A (the error code) with 40H: bit 6 set, the text of the message without the error number.
559F
JUMP to 4409H to display the error message of the code in Register A and abort.
55A2H - Write a Number in Decimal
Register Pair HL = the number (0-65535), Register Pair DE = the place for 5 characters. The digits for 10000, 1000, 100 and 10 come from 55C2H, with spaces in place of the leading zeros; the units digit is always written. Returns Register Pair DE past the fifth character.
55A2
LD A,20H 3E 20
Load Register A with 20H, a space: the character written for a leading zero.
55A4
LD BC,2710H 01 10 27
Load Register Pair BC with 2710H (10000), the value of the first digit.
55A7
GOSUB to 55C2H to write the ten thousands of Register Pair HL at Register Pair DE: Register A = the character for a zero from now on.
55AA
LD BC,03E8H 01 E8 03
Load Register Pair BC with 03E8H (1000), the value of the second digit.
55AD
GOSUB to 55C2H to write the thousands of Register Pair HL at Register Pair DE.
55B0
LD BC,0064H 01 64 00
Load Register Pair BC with 0064H (100), the value of the third digit.
55B3
GOSUB to 55C2H to write the hundreds of Register Pair HL at Register Pair DE.
55B6
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH (10), the value of the fourth digit.
55B9
GOSUB to 55C2H to write the tens of Register Pair HL at Register Pair DE: Register Pair HL is left with the units (0-9).
55BC
LD A,L 7D
Copy Register L (the units left in Register Pair HL, 0-9) into Register A.
55BD
ADD A,30H C6 30
Add 30H to Register A: the units digit as a character.
55BF
LD (DE),A 12
Store Register A (the units digit) to Register Pair DE, the fifth place.
55C0
INC DE 13
Increment Register Pair DE past the fifth place.
55C1
RET C9
RETURN with the number written as 5 characters.
55C2H - Write One Decimal Digit
Register Pair HL = the number, Register Pair BC = the value of the digit, Register A = the character for a zero (a space until the first digit that is not zero, then the digit 0), Register Pair DE = the place. Returns Register Pair HL = the rest, Register Pair DE one place on, Register A = the character for a zero from now on.
55C2
PUSH DE D5
Save Register Pair DE (the place of the digit) to the stack.
55C3
LD E,A 5F
Copy Register A (the character for a zero) into Register E.
55C4
LD D,FFH 16 FF
Load Register D with FFH, the digit less one.
55C6
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the first subtraction.
55C7
INC D 14
Loop Start
Increment Register D, the digit counted so far.
55C8
SBC HL,BC ED 42
SUBtract Register Pair BC (the value of the digit) from Register Pair HL (the number); the CARRY FLAG is set when it went below 0.
55CA
If the NC FLAG is set (it did not go below 0), LOOP BACK to 55C7H.
55CC
ADD HL,BC 09
Add Register Pair BC (the value of the digit) back to Register Pair HL: Register Pair HL = the rest of the number, below the value of the digit.
55CD
LD A,E 7B
Copy Register E (the character for a zero, saved at 55C3H) into Register A.
55CE
LD B,D 42
Copy Register D (the digit, 0-9) into Register B.
55CF
POP DE D1
Restore Register Pair DE from the stack: the place of the digit.
55D0
LD (DE),A 12
Store Register A (the character for a zero) to the place at Register Pair DE, where it stays when the digit is 0.
55D1
INC B 04
Increment Register B (the digit), so that the decrement below sets the flags by the digit.
55D2
DEC B 05
Decrement Register B back to the digit: the Z FLAG is set when it is 0.
55D3
If the Z FLAG is set (the digit is 0), JUMP to 55DBH with Register A = the character for a zero unchanged.
55D5
LD A,B 78
Copy Register B (the digit, 1-9) into Register A.
55D6
ADD A,30H C6 30
Add 30H to Register A: the digit as a character.
55D8
LD (DE),A 12
Store Register A (the digit) to the place at Register Pair DE, over the character stored at 55D0H.
55D9
LD A,30H 3E 30
Load Register A with 30H, the digit 0: after a digit that is not zero, zeros are written as 0.
55DB
INC DE 13
Increment Register Pair DE (the place of the digit) to the next place of the number.
55DC
RET C9
RETURN with Register A = the character for a zero from now on and Register Pair HL = the rest of the number.
55DDH - Divide the Size by the Record Length
Register Pair HL = 520FH, a 24 bit number with the high byte first; Register C = the record length (00H = 256). For 256 the number is divided by taking its two high bytes. Otherwise the 24 bits are shifted one at a time into the remainder in Register A, which is compared with Register C. Returns Register Pair DE = the quotient (16 bits) and, for a record length below 256, Register A = the remainder. The shift at 55F1H (RLA) drops bit 7 of the remainder, and the compare that follows does not see it: with a record length of 129-255 a remainder of 128 or more doubles past 255 and the quotient comes out wrong.
55DD
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the quotient.
55E0
LD A,C 79
Copy Register C (the record length) into Register A.
55E1
OR A B7
OR Register A (the record length) with itself to set the flags: the Z FLAG for 00H, a record length of 256.
55E2
If the Z FLAG is set (256), JUMP to 55FFH to take the two high bytes at Register Pair HL as the quotient.
55E4
XOR A AF
Set Register A, the remainder, to 00H (XOR A).
55E5
LD B,03H 06 03
Load Register B with 03H, the 3 bytes of the number.
55E7
PUSH BC C5
Loop Start
Save Register Pair BC (Register B = the bytes left, Register C = the record length) to the stack.
55E8
PUSH HL E5
Save Register Pair HL (the byte of the number) to the stack.
55E9
LD H,(HL) 66
Fetch the byte of the number at Register Pair HL into Register H.
55EA
LD B,08H 06 08
Load Register B with 08H, the bits of the byte.
55EC
EX DE,HL EB
Loop Start
Exchange Register Pairs DE and HL: Register Pair HL = the quotient, Register D = the byte of the number.
55ED
ADD HL,HL 29
Add Register Pair HL (the quotient) to itself: the quotient moves one bit left.
55EE
EX DE,HL EB
Exchange Register Pairs DE and HL back: Register Pair DE = the quotient, Register H = the byte of the number.
55EF
RLC H CB 04
Rotate Register H (the byte of the number) left: its top bit goes into the CARRY FLAG.
55F1
RLA 17
Rotate Register A (the remainder) left through the carry: it takes that bit. Bit 7 of the remainder goes into the CARRY FLAG, which the compare below does not use.
55F2
CP C B9
Compare Register A (the remainder) against Register C (the record length).
55F3
If the C FLAG is set (the remainder is below the record length), JUMP to 55F7H.
55F5
SUB C 91
SUBtract Register C (the record length) from Register A (the remainder).
55F6
INC DE 13
Increment Register Pair DE (the quotient): a 1 bit.
55F7
Decrement Register B (the bits of the byte left) and LOOP BACK to 55ECH until Register B is 00H.
55F9
POP HL E1
Restore Register Pair HL from the stack: the byte of the number just done.
55FA
INC HL 23
Increment Register Pair HL to the next byte of the number.
55FB
POP BC C1
Restore Register Pair BC from the stack: Register B = the bytes left, Register C = the record length.
55FC
Decrement Register B (the bytes left) and LOOP BACK to 55E7H until Register B is 00H.
55FE
RET C9
RETURN with Register Pair DE = the quotient, the number of records, and Register A = the remainder.
55FF
LD D,(HL) 56
Fetch the high byte of the number at Register Pair HL (520FH) into Register D.
5600
INC HL 23
Increment Register Pair HL to the middle byte of the number (5210H).
5601
LD E,(HL) 5E
Fetch the middle byte at Register Pair HL into Register E: Register Pair DE = the number divided by 256.
5602
RET C9
RETURN with Register Pair DE = the number of records of 256 bytes.
5603H - Hold or Break the Listing
Called at the end of each line of the listing. While a file of DO commands is being run (430FH bit 5 set) the keys are not tested. Otherwise BREAK returns the NZ FLAG (abort), and SHIFT and @ held together stop the listing until a key other than SHIFT and @ is pressed (BREAK still aborts). Returns the Z FLAG to go on.
5603
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
5606
AND 20H E6 20
Mask Register A (the system flags) to bit 5, set while SYS7/SYS runs a file of DO commands.
5608
XOR 20H EE 20
Exclusive OR Register A with 20H: Register A = 00H and the Z FLAG when bit 5 was set.
560A
RET Z C8
If the Z FLAG is set (DO commands are running), RETURN with the Z FLAG: go on without testing the keys.
560B
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A: bit 2 is the BREAK key.
560E
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
5610
RET NZ C0
If the NZ FLAG is set (BREAK is pressed), RETURN with the NZ FLAG: abort the listing.
5611
LD A,(3801H) 3A 01 38
Fetch keyboard row 0 from 3801H into Register A: bit 0 is the @ key.
5614
AND 01H E6 01
Mask Register A (keyboard row 0) to bit 0, the @ key.
5616
RET Z C8
If the Z FLAG is set (@ is not pressed), RETURN with the Z FLAG: go on.
5617
LD A,(3880H) 3A 80 38
Fetch keyboard row 7 from 3880H into Register A: bit 0 is the SHIFT key.
561A
AND 01H E6 01
Mask Register A (keyboard row 7) to bit 0, the SHIFT key.
561C
RET Z C8
If the Z FLAG is set (SHIFT is not pressed), RETURN with the Z FLAG: go on.
561D
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A, to test the BREAK key while the listing is held.
5620
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
5622
RET NZ C0
If the NZ FLAG is set (BREAK is pressed), RETURN with the NZ FLAG: abort the listing.
5623
GOSUB to the ROM's 002BH to scan the keyboard through the KI device: Register A = the key pressed, 00H for none.
5626
OR A B7
OR Register A (the key) with itself to set the flags: the Z FLAG for no key.
5627
If the Z FLAG is set (no key), JUMP back to 561DH to go on waiting.
5629
CP 60H FE 60
Compare Register A (the key) against 60H, the code of @ with SHIFT, the keys that stopped the listing.
562B
If the Z FLAG is set (SHIFT and @ again), JUMP back to 561DH to go on waiting.
562D
XOR A AF
Set Register A to 00H and set the Z FLAG (XOR A): any other key lets the listing go on.
562E
RET C9
RETURN with the Z FLAG: go on with the listing.
562FH - The Parameter Table
Read by SYS1/SYS's parameter reader (5261H, request E3H): 8 bytes an entry, a name of 6 characters padded with spaces and the address of the word that a name given in the list sets (FFFFH for a name alone). Each word is the operand of a LD DE instruction of the member. A 00H ends the table.
562F-5636
DEFM "A " / DEFW 53EDH 41 20 20 20 20 20 ED 53
Entry 1, the parameter A: the word 53EDH-53EEH, the operand of LD DE,0000H at 53ECH, which makes 5414H add the allocation line to every file.
5637-563E
DEFM "I " / DEFW 5340H 49 20 20 20 20 20 40 53
Entry 2, the parameter I: the word 5340H-5341H, the operand of LD DE,0000H at 533FH, which lets invisible files (attribute bit 3) be listed.
563F-5646
DEFM "P " / DEFW 557DH 50 20 20 20 20 20 7D 55
Entry 3, the parameter P: the word 557DH-557EH, the operand of LD DE,0000H at 557CH, whose low byte FFH makes 5577H and 556CH print every character and text as well as display it.
5647-564E
DEFM "S " / DEFW 5332H 53 20 20 20 20 20 32 53
Entry 4, the parameter S: the word 5332H-5333H, the operand of LD DE,0000H at 5331H, which lets system files (attribute bit 6) be listed.
564F
DEFB 00H 00
The 00H that ends the parameter table at 562FH, where SYS1/SYS's table search 50BCH stops.
5650H - Names of the Access Levels
4 characters for each access level 0-7 (bits 2-0 of the attribute byte), copied by 542DH to the start of the allocation line; level 0 is also shown for a file without a password (5419H).
5650-5653
DEFM "ALL " 41 4C 4C 20
Level 0, full access, and the name shown for every file that has no password: "ALL ".
5654-5657
DEFM "KILL" 4B 49 4C 4C
Level 1: the name "KILL" in the allocation line.
5658-565B
DEFM "NAME" 4E 41 4D 45
Level 2: the name "NAME" in the allocation line.
565C-565F
DEFM "~~~~" 7E 7E 7E 7E
Level 3: four 7EH characters, shown as they are in the allocation line for a file of access level 3.
5660-5663
DEFM "WRIT" 57 52 49 54
Level 4: the name "WRIT" in the allocation line.
5664-5667
DEFM "READ" 52 45 41 44
Level 5: the name "READ" in the allocation line.
5668-566B
DEFM "EXEC" 45 58 45 43
Level 6: the name "EXEC" in the allocation line.
566C-566F
DEFM "NO " 4E 4F 20 20
Level 7, no access: the name "NO " in the allocation line.
5670H - The Heading Texts
Shown by 527DH and 52A6H at the start of each drive's listing, both on one line: the drive digit is stored at 568AH, the diskette name at 5691H-5698H and the date at 569DH-56A4H from the allocation table.
5670
DEFB 0AH 0A
The line feed that starts the heading of each drive on a new line of the display.
5671-5689
DEFM "FILE DIRECTORY --- DRIVE " 46 49 4C 45 20 44 49 52 45 43 54 4F 52 59 20 2D 2D 2D 20 44 52 49 56 45 20
The text of the heading before the drive digit.
568A
DEFM "X" 58
Work Area
The drive digit of the heading: 5271H stores the drive number plus 30H here for each drive, and 5548H takes the drive back from it to read extension records.
568B-568F
DEFM " " 20 20 20 20 20
Five spaces between the drive digit and the diskette name in the heading line.
5690
DEFB 03H 03
The 03H that ends the first heading text without a carriage return: the name and date follow on the same line.
5691-5698
DEFM "NNNNNNNN" 4E 4E 4E 4E 4E 4E 4E 4E
Work Area
The diskette name: 5299H copies bytes D0H-D7H of the allocation table here for each drive.
5699-569C
DEFM " -- " 20 2D 2D 20
The text between the diskette name and the date in the heading line.
569D-56A4
DEFM "MM/DD/YY" 4D 4D 2F 44 44 2F 59 59
Work Area
The diskette's date: 52A1H copies bytes D8H-DFH of the allocation table here for each drive.
56A5
DEFB 0DH 0D
The carriage return that ends the heading line.
56A6H - The Allocation Line
Filled in by 5414H for each file when A was given, shown by 5501H after the file's 20 column field and ended by 03H. Its 43 characters after the 20 column field take 63 of the 64 columns of a display line.
56A6-56A9
DEFM "PROT" 50 52 4F 54
Work Area
The name of the access level, 4 characters copied here from 5650H by 542DH.
56AA-56B0
DEFM " /" / DEFM " EOF=" 20 2F 20 45 4F 46 3D
The text (a space, a slash, a space and EOF=) before the number of records up to the end of file.
56B1-56B5
DEFM " " 20 20 20 20 20
Work Area
The 5 places of the number of records, written by 55A2H from 545CH.
56B6-56BB
DEFM " /" / DEFM " SIZ" 20 2F 20 53 49 5A
The text (a space, a slash, a space and SIZ) before the size of the file in K.
56BC
DEFM "?" 3F
Work Area
54AAH stores the equals sign here, or the colon when bit 7 of the record's +01H keeps the file's space.
56BD-56C1
DEFM " " 20 20 20 20 20
Work Area
The 5 places of the whole K of the size, written by 55A2H from 5478H.
56C2
DEFM "." 2E
The decimal point between the whole K and the tenths digit of the size.
56C3
DEFM " " 20
Work Area
The tenths digit of the size (0, 2, 5 or 8), stored by 548FH.
56C4-56C7
DEFM " K " 20 4B 20 20
The unit K and two spaces; the space at 56C7H is the byte that 549BH carries over the date field to blank it.
56C8-56C9
DEFM "DD" 44 44
Work Area
The day, two digits stored by 54C4H and 54C9H (spaces from 549BH when the record holds no date).
56CA
DEFM "-" 2D
Work Area
The separator after the day: 54F8H stores a minus sign, or a plus sign when bit 4 of the record's +01H is set.
56CB-56CD
DEFM "MMM" 4D 4D 4D
Work Area
The month, three letters copied from 56D2H by 54DFH.
56CE
DEFM "-" 2D
Work Area
The separator after the month: 54FBH stores a minus sign, or a plus sign when bit 4 of the record's +01H is set.
56CF-56D0
DEFM "YY" 59 59
Work Area
The year: the digit 8 from 54E4H and the year less 80 from 54EDH.
56D1
DEFB 03H 03
The 03H that ends the allocation line without a carriage return; 53F4H-5404H end the line.
56D2H - Names of the Months
Three letters a month, January first, copied by 54DFH from 56D2H plus 3 times the month less one.
56D2-56D4
DEFM "JAN" 4A 41 4E
Month 1, "JAN". The name of the first month in the date of the allocation line.
56D5-56D7
DEFM "FEB" 46 45 42
Month 2, "FEB", the second three letters of the table of month names.
56D8-56DA
DEFM "MAR" 4D 41 52
Month 3, "MAR", the third three letters of the table of month names.
56DB-56DD
DEFM "APR" 41 50 52
Month 4, "APR", the fourth three letters of the table of month names.
56DE-56E0
DEFM "MAY" 4D 41 59
Month 5, "MAY", the fifth three letters of the table of month names.
56E1-56E3
DEFM "JUN" 4A 55 4E
Month 6, "JUN", the sixth three letters of the table of month names.
56E4-56E6
DEFM "JUL" 4A 55 4C
Month 7, "JUL", the seventh three letters of the table of month names.
56E7-56E9
DEFM "AUG" 41 55 47
Month 8, "AUG", the eighth three letters of the table of month names.
56EA-56EC
DEFM "SEP" 53 45 50
Month 9, "SEP", the ninth three letters of the table of month names.
56ED-56EF
DEFM "OCT" 4F 43 54
Month 10, "OCT", the tenth three letters of the table of month names.
56F0-56F2
DEFM "NOV" 4E 4F 56
Month 11, "NOV", the eleventh three letters of the table of month names.
56F3-56F5
DEFM "DEC" 44 45 43
Month 12, "DEC", the last three letters of the table of month names.
56F6H - The File Pattern
11 bytes, spaces in the file: 5213H-524BH store the name and extension typed after DIR here, and 5350H compares them with each record's +05H-+0FH, a space matching any character.
56F6-56FD
DEFM " " 20 20 20 20 20 20 20 20
Work Area
The name pattern, 8 characters: written by 522AH, read by 5350H.
56FE-5700
DEFM " " 20 20 20
Work Area
The extension pattern, 3 characters: written by 5247H, read by 5350H after the name pattern.
5701-57FF
DEFS 255
Not in the file and not written by the member: the member's last byte is 5700H and its buffers start at 5800H. Only a record date with month 0 makes 54DFH copy the 3 bytes at 57D0H-57D2H into the allocation line as the month's name.
5800-58FF
DEFS 256
Not in the file: the buffer of the hash index. 52C4H reads sector 1 of the directory cylinder of each drive here; 5308H takes byte n as the hash code of the record of entry code n (00H for a free record), stepped through by 52D2H-52DFH.
5900-59FF
DEFS 256
Not in the file: the buffer of extension records. 555AH reads the directory sector of an extension record here when it is not the sector in 4200H; 553CH holds its sector code, and 5514H-5525H read the extents from it.
5200H - Member 11 (FREE, Code 22H): Read the Parameter List
SYS1/SYS's command interpreter runs this member for the word FREE (member code 22H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL at the rest of the command line. FREE shows one line for each drive 0-7 that is there and ready: the drive number, the diskette name and date from the granule allocation table, the free and the total directory records, and the free and the total space in K. The one parameter is P (the parameter table at 5389H): P alone also prints each line on the printer. The flags of the entry (NZ after a load error of the member) are not tested.
5200
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the value the parameter P has when it is not given.
5203
LD (5312H),BC ED 43 12 53
Store Register Pair BC (0000H) to 5312H-5313H, the operand of LD DE,0000H at 5311H, the cell of the parameter P. The load of the member has put 0000H there already (request 88H loads the member afresh for every FREE), so the store leaves the cell as it is.
5207
LD DE,5389H 11 89 53
Point Register Pair DE to 5389H, the parameter table of FREE: the one entry P, whose value goes to 5312H.
520A
GOSUB to 4476H (SYS1/SYS function 6, its 510FH) to read the parameter list in parentheses from the text at Register Pair HL against the table at Register Pair DE. P alone stores FFFFH at 5312H, P=n stores the value n; no list stores nothing. It returns the Z FLAG when the list was good or absent.
520D
If the NZ FLAG is set (an unknown word or a bad value), JUMP to 5319H to display PARAMETER ERROR and abort.
5210
LD C,00H 0E 00
Load Register C with 00H, drive 0, the first drive of the loop.
5212
LD A,(5312H) 3A 12 53
Fetch the low byte of the parameter P from 5312H into Register A: FFH for P alone, the low byte of n for P=n, 00H without P.
5215
OR A B7
OR Register A (the low byte of P) with itself: the Z FLAG is set when it is 00H.
5216
If the Z FLAG is set (no P, or a value whose low byte is 00H), JUMP to 5222H to go through the drives without the printer.
5218
LD A,20H 3E 20
Load Register A with 20H, a space, the first character sent to the printer before the drive lines.
521A
GOSUB to the ROM's 003BH to send Register A (the space) to the printer, the PR device control block 4025H.
521D
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, the end of that first printer line.
521F
GOSUB to the ROM's 003BH to send Register A (0DH) to the printer: the printer gets one line holding a space before the drive lines.
5222H - The Drive Loop: Test the Drive and Read Its Allocation Table
Each pass works on the drive in Register C (0-7). A drive whose drive code table is not there, or which is not ready, is passed over without a line (5303H). Otherwise the drive digit is put into the line and the granule allocation table (sector 0 of the directory cylinder) is read into 4200H.
5222
PUSH BC C5
Save Register Pair BC (Register C = the drive of this pass) to the stack; it is restored at 5303H, or at 52D0H for the hash index read.
5223
GOSUB to 44B8H (request C4H, SYS2/SYS's 5147H, which replaces the overlay at 4E00H) to test drive Register C: the Z FLAG when the drive code table starts with C3H and either bit 3 of its byte +03H marks a rigid disk (taken as ready with no read) or a diskette turns in the drive (its allocation table read, the last cylinder and the two sides bit of the table set from it); the NZ FLAG when not.
5226
If the NZ FLAG is set (no drive, or not ready), JUMP to 5303H to go on with the next drive and show nothing for this one.
5229
LD A,C 79
Copy Register C (the drive, 0-7) into Register A.
522A
ADD A,30H C6 30
Add 30H to Register A: the drive digit 0-7 as a character.
522C
LD (5398H),A 32 98 53
Store Register A (the drive digit) to 5398H, the place of X in DRIVE X of the line template.
522F
GOSUB to 5376H to read sector 0 of the directory cylinder of drive Register C, the granule allocation table, into 4200H: the Z FLAG when read, else the NZ FLAG with Register A = 14H.
5232
If the NZ FLAG is set (the table could not be read), JUMP to 5332H to show error 14H (GAT READ ERROR) in Register A and abort.
5235H - Directory Records and Total Space
The geometry comes from the drive code table of the drive (Index Register IY): +08H bits 4-0 the sectors of a granule less one, bits 7-5 the granules of a cylinder less one, +04H bit 5 two sides, +06H the last cylinder. The directory cylinder holds the allocation table, the hash index and then 8 records a sector: (sectors of a cylinder less 2) x 8 records, at most 256; the code takes 256 as soon as there are 30 record sectors (5260H), where 240 or 248 would be right. The total space is cylinders x sectors of a cylinder, in K of 4 sectors, rounded to the nearest K.
5235
GOSUB to 478FH (SYS0/SYS) to point Index Register IY at the drive code table of drive Register C.
5238
LD H,00H 26 00
Load Register H with 00H, the high byte of the count of cylinders in Register Pair HL.
523A
LD L,(IY+06H) FD 6E 06
Fetch byte +06H of the drive code table at Index Register IY (the last cylinder, set by the drive test at 5223H) into Register L.
523D
INC HL 23
Increment Register Pair HL: Register Pair HL = the number of cylinders of the diskette (the last cylinder plus one).
523E
LD A,(IY+08H) FD 7E 08
Fetch byte +08H of the drive code table at Index Register IY into Register A: bits 4-0 the sectors of a granule less one, bits 7-5 the granules of a cylinder less one.
5241
AND 1FH E6 1F
Mask Register A to bits 4-0 (AND 1FH): the sectors of a granule less one.
5243
INC A 3C
Increment Register A: the sectors of a granule.
5244
LD E,A 5F
Copy Register A (the sectors of a granule) into Register E, the multiplier for 4B6CH at 524FH.
5245
PUSH AF F5
Save Register Pair AF (Register A = the sectors of a granule) to the stack; it is restored at 52BAH for the free space.
5246
LD A,(IY+08H) FD 7E 08
Fetch byte +08H of the drive code table at Index Register IY into Register A again, for the granules of a cylinder.
5249
AND E0H E6 E0
Mask Register A to bits 7-5 (AND E0H): the granules of a cylinder less one, times 32.
524B
RLCA 07
Rotate Register A left (RLCA), the first of three: bits 7-5 move towards bits 2-0.
524C
RLCA 07
Rotate Register A left (RLCA) a second time: the field is now in bits 1-0 and bit 7.
524D
RLCA 07
Rotate Register A left (RLCA) a third time: Register A = the granules of a cylinder less one, in bits 2-0.
524E
INC A 3C
Increment Register A: the granules of a cylinder.
524F
GOSUB to 4B6CH (SYS0/SYS) to multiply Register A (the granules of a cylinder) by Register E (the sectors of a granule): Register A = the sectors of a cylinder on one side.
5252
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of byte +04H of the drive code table at Index Register IY: set for a diskette with two sides (set by the drive test from the allocation table's byte CDH).
5256
If the Z FLAG is set (one side), JUMP to 5259H with Register A as it is.
5258
ADD A,A 87
Add Register A to itself: two sides double the sectors of a cylinder in Register A.
5259
PUSH AF F5
Save Register Pair AF (Register A = the sectors of a cylinder) to the stack, for the total space at 5277H.
525A
PUSH HL E5
Save Register Pair HL (the number of cylinders) to the stack, for the total space at 5276H.
525B
LD HL,0100H 21 00 01
Load Register Pair HL with 0100H, 256, the most directory records there can be (the hash index has 256 bytes).
525E
SUB 02H D6 02
SUBtract 02H from Register A (the sectors of a cylinder): the allocation table and the hash index are not record sectors, so Register A = the directory record sectors.
5260
CP 1EH FE 1E
Compare Register A (the record sectors) against 1EH, 30: the C FLAG is set below 30.
5262
If the NC FLAG is set (30 record sectors or more), JUMP to 526DH with Register Pair HL = 256 records.
5264
SLA A CB 27
Shift Register A left (SLA A), the first of three: Register A = the record sectors times 2.
5266
SLA A CB 27
Shift Register A left (SLA A) a second time: Register A = the record sectors times 4.
5268
SLA A CB 27
Shift Register A left (SLA A) a third time: Register A = the record sectors times 8, the records of the directory (8 a sector).
526A
LD L,A 6F
Copy Register A (the number of records) into Register L.
526B
LD H,00H 26 00
Load Register H with 00H: Register Pair HL = the number of directory records, below 256.
526D
LD (52E6H),HL 22 E6 52
Store Register Pair HL (the number of directory records) to 52E6H-52E7H, the operand of LD DE,0000H at 52E5H, the start of the count of the free records.
5270
LD DE,53B9H 11 B9 53
Point Register Pair DE to 53B9H, the second XXX of FILES=XXX/XXX in the line: the total number of records.
5273
GOSUB to 5337H to write Register Pair HL (the number of directory records) as 3 decimal digits at Register Pair DE (53B9H-53BBH), leading zeros shown as spaces.
5276
POP HL E1
Restore Register Pair HL from the stack: the number of cylinders, saved at 525AH.
5277
POP AF F1
Restore Register Pair AF from the stack: Register A = the sectors of a cylinder, saved at 5259H.
5278
GOSUB to 4B8FH (SYS0/SYS) to multiply Register Pair HL (the cylinders) by Register A (the sectors of a cylinder): Register A = bits 7-0 and Register Pair HL = bits 23-8 of the number of sectors of the diskette.
527B
LD H,L 65
Copy Register L (bits 15-8 of the number of sectors) into Register H.
527C
LD L,A 6F
Copy Register A (bits 7-0 of the number of sectors) into Register L: Register Pair HL = the number of sectors of the diskette.
527D
INC HL 23
Increment Register Pair HL: one of the two added before the division by 4, which rounds to the nearest K.
527E
INC HL 23
Increment Register Pair HL again: Register Pair HL = the sectors plus 2.
527F
SRL H CB 3C
Shift Register H right (SRL H): its bit 0 goes into the CARRY FLAG, the first half of a division of Register Pair HL by 2.
5281
RR L CB 1D
Rotate Register L right through the carry (RR L): Register Pair HL = (the sectors plus 2) / 2.
5283
SRL H CB 3C
Shift Register H right (SRL H) again, the first half of the second division of Register Pair HL by 2.
5285
RR L CB 1D
Rotate Register L right through the carry (RR L) again: Register Pair HL = (the sectors plus 2) / 4, the total space in K (a sector holds 256 bytes, 4 a K).
5287
LD DE,53CAH 11 CA 53
Point Register Pair DE to 53CAH, the place after the slash of SPACE= in the line: the total space.
528A
GOSUB to 533BH to write Register Pair HL (the total K) as 5 decimal digits at Register Pair DE (53CAH-53CEH), leading zeros shown as spaces.
528DH - Diskette Name and Date
Bytes D0H-D7H (the diskette name) and D8H-DFH (the date MM/DD/YY) of the allocation table in 4200H are copied into the line.
528D
LD HL,42D0H 21 D0 42
Point Register Pair HL to 42D0H, byte D0H of the allocation table in 4200H: the 8 characters of the diskette name.
5290
LD DE,539CH 11 9C 53
Point Register Pair DE to 539CH, the place of NNNNNNNN in the line.
5293
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of the name.
5296
LDIR ED B0
Copy the 8 bytes of the diskette name from 42D0H at Register Pair HL to 539CH at Register Pair DE (LDIR). Register Pair HL ends at 42D8H, the date; Register Pair DE at 53A4H; Register Pair BC at 0000H.
5298
LD DE,53A5H 11 A5 53
Point Register Pair DE to 53A5H, the place of MM/DD/YY in the line.
529B
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of the date.
529E
LDIR ED B0
Copy the 8 bytes of the date MM/DD/YY from 42D8H at Register Pair HL to 53A5H at Register Pair DE (LDIR). Register Pair HL ends at 42E0H, Register Pair DE at 53ADH, Register Pair BC at 0000H.
52A0H - Count the Free Granules
The allocation bytes start at 4200H, one a cylinder, bit n set for granule n in use. Each 0 bit of the first 35 + (42CCH) bytes is counted as a free granule; the code does not limit the count to the granules a cylinder has, so it relies on the bits of granules that do not exist being 1 (FCH for a cylinder of 2 granules, as the table of this diskette has). The count is multiplied by the sectors of a granule and turned into K.
52A0
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, the first allocation byte of the table (cylinder 0).
52A3
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the count of free granules.
52A6
LD A,(42CCH) 3A CC 42
Fetch byte CCH of the allocation table from 42CCH into Register A: the cylinders past 35.
52A9
ADD A,23H C6 23
Add 23H (35) to Register A: Register A = the number of cylinders the table counts.
52AB
LD B,A 47
Copy Register A (the number of cylinders) into Register B, the count of the loop at 52B7H.
52AC
LD A,(HL) 7E
Loop Start
Fetch the allocation byte of a cylinder from Register Pair HL into Register A.
52AD
SCF 37
Set the CARRY FLAG: the RRA below shifts a 1 bit into bit 7 of Register A, so that Register A becomes FFH once its 8 bits are passed.
52AE
RRA 1F
Rotate Register A right through the carry (RRA): bit 0, one granule, goes into the CARRY FLAG and a 1 comes into bit 7.
52AF
If the C FLAG is set (the granule is in use), JUMP to 52B2H without counting it.
52B1
INC DE 13
Increment Register Pair DE, the count of free granules: the bit was 0.
52B2
CP FFH FE FF
Compare Register A against FFH: the Z FLAG is set when no 0 bit is left in Register A.
52B4
If the NZ FLAG is set (0 bits left), JUMP back to 52ADH to take the next bit of Register A.
52B6
INC L 2C
Increment Register L to the allocation byte of the next cylinder (4200H-42FFH, the high byte stays 42H).
52B7
Decrement Register B (the cylinders left) and LOOP BACK to 52ACH until Register B is 00H.
52B9
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the number of free granules.
52BA
POP AF F1
Restore Register Pair AF from the stack: Register A = the sectors of a granule, saved at 5245H.
52BB
GOSUB to 4B8FH (SYS0/SYS) to multiply Register Pair HL (the free granules) by Register A (the sectors of a granule): Register A = bits 7-0 and Register Pair HL = bits 23-8 of the free sectors.
52BE
LD H,L 65
Copy Register L (bits 15-8 of the free sectors) into Register H.
52BF
LD L,A 6F
Copy Register A (bits 7-0 of the free sectors) into Register L: Register Pair HL = the number of free sectors.
52C0
INC HL 23
Increment Register Pair HL: one of the two added before the division by 4, which rounds to the nearest K.
52C1
INC HL 23
Increment Register Pair HL again: Register Pair HL = the free sectors plus 2.
52C2
SRL H CB 3C
Shift Register H right (SRL H): its bit 0 goes into the CARRY FLAG, the first half of a division of Register Pair HL by 2.
52C4
RR L CB 1D
Rotate Register L right through the carry (RR L): Register Pair HL = (the free sectors plus 2) / 2.
52C6
SRL H CB 3C
Shift Register H right (SRL H) again, the first half of the second division of Register Pair HL by 2.
52C8
RR L CB 1D
Rotate Register L right through the carry (RR L) again: Register Pair HL = (the free sectors plus 2) / 4, the free space in K.
52CA
LD DE,53C4H 11 C4 53
Point Register Pair DE to 53C4H, the place after SPACE= in the line: the free space.
52CD
GOSUB to 533BH to write Register Pair HL (the free K) as 5 decimal digits at Register Pair DE (53C4H-53C8H), leading zeros shown as spaces.
52D0H - Count the Free Directory Records
The hash index (sector 1 of the directory cylinder) has one byte for each directory record, at the record's entry code: 00H free. Starting from the number of records (the operand at 52E6H), the count is lowered by one for every byte that is not 00H and for every one of the 16 bytes kept for the system files (entry codes 00H-07H and 20H-27H, whose bits 7, 6, 4 and 3 are all 0), so it ends at the free records ordinary files can take. Bytes of records the directory does not have are 00H in the index and leave the count as it is.
52D0
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive of this pass, saved at 5222H.
52D1
PUSH BC C5
Save Register Pair BC (the drive) to the stack again, for 5303H.
52D2
GOSUB to 4B65H (SYS0/SYS) to fetch the directory cylinder of drive Register C into Register D.
52D5
LD E,01H 1E 01
Load Register E with 01H, sector 1 of the directory cylinder, the hash index.
52D7
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, the buffer the hash index is read into.
52DA
GOSUB to 4B45H (SYS0/SYS) to read cylinder Register D, sector Register E of drive Register C into 4200H: the Z FLAG when read (with the directory data mark).
52DD
LD A,16H 3E 16
Load Register A with 16H, the error code HIT READ ERROR; LD does not change the flags of the read.
52DF
If the NZ FLAG is set (the hash index could not be read), JUMP to 5332H to show error 16H in Register A and abort.
52E2
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, the first byte of the hash index.
52E5
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the number of directory records of the drive. The operand at 52E6H-52E7H is 0000H in the file; 526DH stores the number of records there in each pass (256 at most), and the loop below lowers it to the free records.
52E8
DEC DE 1B
Loop Start
Decrement Register Pair DE, the count: one record taken, given back at 52F2H when the byte is free.
52E9
LD A,L 7D
Copy Register L (the entry code of the byte at Register Pair HL) into Register A.
52EA
AND D8H E6 D8
Mask Register A with D8H (bits 7, 6, 4 and 3): the Z FLAG is set for the entry codes 00H-07H and 20H-27H, the records kept for the system files.
52EC
If the Z FLAG is set (a record of the system files), JUMP to 52F3H: it stays counted as taken.
52EE
LD A,(HL) 7E
Fetch the hash index byte at Register Pair HL into Register A: 00H for a free record.
52EF
OR A B7
OR Register A with itself: the Z FLAG is set when the byte is 00H.
52F0
If the NZ FLAG is set (the record is in use), JUMP to 52F3H: it stays counted as taken.
52F2
INC DE 13
Increment Register Pair DE, the count: the free record is given back.
52F3
INC L 2C
Increment Register L to the next byte of the hash index: Register L becomes 00H after the 256th.
52F4
If the NZ FLAG is set (bytes left), JUMP back to 52E8H for the next byte at Register Pair HL.
52F6
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the free records.
52F7
LD DE,53B5H 11 B5 53
Point Register Pair DE to 53B5H, the first XXX of FILES=XXX/XXX in the line: the free records.
52FA
GOSUB to 5337H to write Register Pair HL (the free records) as 3 decimal digits at Register Pair DE (53B5H-53B7H), leading zeros shown as spaces.
52FDH - Show the Line and Go On
The line of the drive is displayed (and printed with P alone); then the next drive, until drive 7 is done; then VTOS READY.
52FD
LD HL,5392H 21 92 53
Point Register Pair HL to 5392H, the line of the drive, now filled in.
5300
GOSUB to 530EH to display the line at Register Pair HL, and print it too when P was given alone.
5303
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive of this pass, saved at 5222H (or again at 52D1H). 5226H comes here for a drive that is not there.
5304
INC C 0C
Increment Register C (the drive just done) to the next drive number.
5305
LD A,C 79
Copy Register C (the next drive) into Register A.
5306
CP 08H FE 08
Compare Register A (the next drive) against 08H: the Z FLAG is set after drive 7.
5308
If the NZ FLAG is set (drives left), JUMP back to 5222H for drive Register C.
530B
JUMP to 402DH, VTOS READY: the command is done.
530EH - Display and Print the Line
Register Pair HL = the line. It is displayed, and printed when the low byte of P is FFH (P alone stores FFFFH).
530E
GOSUB to 4467H (SYS0/SYS, its 44DDH) to display the line at Register Pair HL up to and including its 0DH; Register Pair HL comes back unchanged.
5311
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the value of the parameter P. The operand at 5312H-5313H is 0000H in the file; 5203H stores 0000H there and SYS1/SYS's parameter reader (called at 520AH) stores FFFFH for P alone or n for P=n.
5314
INC E 1C
Increment Register E (the low byte of P): the Z FLAG is set when it was FFH.
5315
If the Z FLAG is set (P alone, or a value whose low byte is FFH), JUMP to 446AH (SYS0/SYS, its 44F2H) to print the line at Register Pair HL on the printer; its RET returns to 5303H.
5318
RET C9
RETURN to 5303H with the line displayed only, not printed (no P, or P=n).
5319H - Parameter Error
Reached from 520DH when the parameter list is not good.
5319
LD HL,5322H 21 22 53
Point Register Pair HL to 5322H, the text PARAMETER ERROR.
531C
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
531F
JUMP to 4030H, the abort exit of VTOS: the command ends here.
5322-5330
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message shown by 5319H when the parameter list cannot be read.
5331
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
5332H - Error Exit
Register A = an error code: 14H (GAT READ ERROR) from 5232H or 16H (HIT READ ERROR) from 52DFH.
5332
OR 40H F6 40
OR 40H into Register A (the error code): bit 6 asks for the text of the error alone, without the error number; bit 7 stays clear, so the error message is followed by the abort exit.
5334
JUMP to 4409H to display the error message of Register A (request 86H, SYS4/SYS), then the abort exit 4030H.
5337H - Write a Number in Decimal
Register Pair HL = the number, Register Pair DE = the place in the line. 5337H writes 3 digits (hundreds, tens, units), 533BH writes 5 (ten thousands down). Leading zeros are written as spaces; the units digit is always written. Register Pair DE ends past the last digit.
5337
LD A,20H 3E 20
Load Register A with 20H, a space, the character written for a leading zero.
5339
JUMP to 5349H to write the hundreds, tens and units of Register Pair HL.
533B
LD A,20H 3E 20
Load Register A with 20H, a space, the character written for a leading zero.
533D
LD BC,2710H 01 10 27
Load Register Pair BC with 2710H, 10000, the value of the first digit.
5340
GOSUB to 535BH to write the ten thousands digit of Register Pair HL at Register Pair DE; Register A comes back as the character for a zero from now on.
5343
LD BC,03E8H 01 E8 03
Load Register Pair BC with 03E8H, 1000, the value of the next digit.
5346
GOSUB to 535BH to write the thousands digit of Register Pair HL at Register Pair DE.
5349
LD BC,0064H 01 64 00
Load Register Pair BC with 0064H, 100, the value of the next digit. 5339H joins here with Register A = 20H.
534C
GOSUB to 535BH to write the hundreds digit of Register Pair HL at Register Pair DE.
534F
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, 10, the value of the next digit.
5352
GOSUB to 535BH to write the tens digit of Register Pair HL at Register Pair DE; Register Pair HL is left with the units.
5355
LD A,L 7D
Copy Register L (the units, 0-9) into Register A.
5356
ADD A,30H C6 30
Add 30H to Register A: the units digit as a character, written even when it is 0.
5358
LD (DE),A 12
Store Register A (the units digit) to the line at Register Pair DE.
5359
INC DE 13
Increment Register Pair DE past the last digit.
535A
RET C9
RETURN to the caller with the number written.
535BH - Write One Digit
Register Pair HL = what is left of the number, Register Pair BC = the value of the digit (10000, 1000, 100 or 10), Register A = the character for a zero (20H while no digit other than 0 has been written, then 30H). The digit is found by subtraction; Register Pair HL keeps the rest. Returns Register A = the character for a zero from now on, Register Pair DE one place on.
535B
PUSH DE D5
Save Register Pair DE (the place of the digit) to the stack: Register Pair DE is used for the count.
535C
LD E,A 5F
Copy Register A (the character for a zero) into Register E.
535D
LD D,FFH 16 FF
Load Register D with FFH, the count of subtractions less one: the INC D below makes it 00H for the first.
535F
XOR A AF
Set Register A to 00H (XOR A), which also clears the CARRY FLAG for the first SBC.
5360
INC D 14
Loop Start
Increment Register D, the digit counted so far.
5361
SBC HL,BC ED 42
SUBtract Register Pair BC (the value of the digit) and the carry from Register Pair HL.
5363
If the NC FLAG is set (Register Pair HL did not go below zero), JUMP back to 5360H to count one more.
5365
ADD HL,BC 09
Add Register Pair BC back to Register Pair HL: the subtraction that went below zero is undone, Register Pair HL = the rest of the number.
5366
LD A,E 7B
Copy Register E (the character for a zero) into Register A.
5367
LD B,D 42
Copy Register D (the digit, 0-9) into Register B.
5368
POP DE D1
Restore Register Pair DE from the stack: the place of the digit in the line.
5369
LD (DE),A 12
Store Register A (the character for a zero) to the place at Register Pair DE; it stays when the digit is 0.
536A
INC B 04
Increment Register B (the digit), the first half of a test of Register B for zero.
536B
DEC B 05
Decrement Register B again: the Z FLAG is set when the digit is 0.
536C
If the Z FLAG is set (the digit is 0), JUMP to 5374H: the space or 0 just stored stays and Register A keeps the character for a zero.
536E
LD A,B 78
Copy Register B (the digit, 1-9) into Register A.
536F
ADD A,30H C6 30
Add 30H to Register A: the digit as a character.
5371
LD (DE),A 12
Store Register A (the digit) to the place at Register Pair DE, over the character for a zero.
5372
LD A,30H 3E 30
Load Register A with 30H, the digit 0: after a digit other than 0 every later zero is written as 0.
5374
INC DE 13
Increment Register Pair DE to the place of the next digit.
5375
RET C9
RETURN to the caller with Register A = the character for a zero and Register Pair HL = the rest of the number.
5376H - Read the Allocation Table
Register C = the drive. Reads sector 0 of the directory cylinder into 4200H. Returns the Z FLAG when it was read; otherwise the NZ FLAG with Register A = 14H, GAT READ ERROR. Register Pairs DE and HL are kept.
5376
PUSH DE D5
Save Register Pair DE (the caller's) to the stack.
5377
PUSH HL E5
Save Register Pair HL (the caller's, the number of cylinders) to the stack.
5378
GOSUB to 4B65H (SYS0/SYS) to fetch the directory cylinder of drive Register C into Register D.
537B
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder, the granule allocation table.
537D
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, the buffer the table is read into.
5380
GOSUB to 4B45H (SYS0/SYS) to read cylinder Register D, sector Register E of drive Register C into 4200H: the Z FLAG when read (with the directory data mark).
5383
POP HL E1
Restore Register Pair HL from the stack: the caller's value. POP does not change the flags.
5384
POP DE D1
Restore Register Pair DE from the stack: the caller's value.
5385
RET Z C8
If the Z FLAG is set (the table was read), RETURN to 5232H with the Z FLAG.
5386
LD A,14H 3E 14
Load Register A with 14H, the error code GAT READ ERROR.
5388
RET C9
RETURN to 5232H with the NZ FLAG of the read and Register A = 14H.
5389H - The Parameter Table
One entry of 8 bytes for SYS1/SYS's parameter reader (510FH): the name padded with spaces to 6 characters and the address of the word where its value is stored; 00H ends the table.
5389-538E
DEFM "P " 50 20 20 20 20 20
The name of the parameter P, padded with five spaces to 6 characters.
538F-5390
DEFW 5312H 12 53
The word where the value of P is stored: 5312H-5313H, the operand of LD DE,0000H at 5311H (FFFFH for P alone, n for P=n).
5391
DEFB 00H 00
The end of the parameter table: the reader stops at 00H.
5392H - The Line Template
The line shown for each drive. The member writes the drive digit, the diskette name, the date and the four numbers over the placeholders in every pass; the rest stays as it is.
5392-5397
DEFM "DRIVE " 44 52 49 56 45 20
The word DRIVE and a space, the start of the line.
5398
DEFM "X" 58
The place of the drive digit, written by 522CH in each pass.
5399-539B
DEFM " - " 20 2D 20
A space, a minus sign and a space between the drive and the diskette name.
539C-53A3
DEFM "NNNNNNNN" 4E 4E 4E 4E 4E 4E 4E 4E
The place of the diskette name, 8 characters copied from bytes D0H-D7H of the allocation table by the LDIR at 5296H.
53A4
DEFM " " 20
The space between the diskette name and the date.
53A5-53AC
DEFM "MM/DD/YY" 4D 4D 2F 44 44 2F 59 59
The place of the diskette date, 8 characters copied from bytes D8H-DFH of the allocation table by the LDIR at 529EH.
53AD-53B4
DEFM " FILES=" 20 20 46 49 4C 45 53 3D
Two spaces and the word FILES with an equals sign: the directory records follow.
53B5-53B7
DEFM "XXX" 58 58 58
The place of the free directory records, 3 digits written by 52FAH.
53B8
DEFM "/" 2F
The slash between the free and the total directory records.
53B9-53BB
DEFM "XXX" 58 58 58
The place of the total directory records, 3 digits written by 5273H.
53BC-53C3
DEFM ", SPACE=" 2C 20 53 50 41 43 45 3D
A comma, a space and the word SPACE with an equals sign: the space in K follows.
53C4-53C8
DEFM " " 20 20 20 20 20
The place of the free space in K, 5 digits written by 52CDH.
53C9
DEFM "/" 2F
The slash between the free and the total space.
53CA-53CE
DEFM " " 20 20 20 20 20
The place of the total space in K, 5 digits written by 528AH.
53CF-53D0
DEFM " K" 20 4B
A space and the letter K, the unit of the space (1024 bytes, 4 sectors).
53D1
DEFB 0DH 0D
The carriage return that ends the line: 4467H and 446AH send it as the end of the text.
5200H - Member 12 (CHAIN, Code 91H): Read the Options and Open the Files
SYS1/SYS runs this member for the command word CHAIN and for a command line that starts with an exclamation mark (its 4E65H-4E6BH load Register Pair DE with 8091H, the table word of CHAIN, and go on at 4E97H). On entry Register Pair HL points at the text after the command word (or after the exclamation mark), Register B = 91H, Register Pair DE = 8091H (the request handler keeps Register Pairs BC and DE, 4C6DH-4CA3H) and Register A = the code from 430EH. The first character picks the mode: an asterisk runs SYSTEM/JCL again (52D7H), an equals sign executes a JCL file at once without the compile (52BFH), a dollar sign compiles only (it is stored as the operand 52A9H). Otherwise the JCL file is opened with the control block 56D2H and the sector buffer 5A00H, SYSTEM/JCL is opened or created with the control block 4358H and the buffer 5B00H, and the parameters are read at 5251H.
5200
LD A,(HL) 7E
Fetch the first character after the command word from Register Pair HL into Register A: it may be one of the three option characters.
5201
CP 2AH FE 2A
Compare Register A (the first character) against 2AH, an asterisk: CHAIN followed by an asterisk is meant to run the last SYSTEM/JCL file again.
5203
If the Z FLAG is set (an asterisk), JUMP to 52D7H, which is meant to run SYSTEM/JCL again without a compile.
5206
CP 3DH FE 3D
Compare Register A (the first character) against 3DH, an equals sign: the named JCL file is executed directly, without the compile.
5208
If the Z FLAG is set (an equals sign), JUMP to 52BFH to open the named file as the file of commands.
520B
CP 24H FE 24
Compare Register A (the first character) against 24H, a dollar sign: the file is compiled into SYSTEM/JCL and not executed.
520D
If the NZ FLAG is set (no dollar sign), JUMP to 5219H with Register Pair HL still at the first character, the start of the file specification.
520F
LD (52A9H),A 32 A9 52
Self-Modifying Code
Store Register A (24H, the dollar sign) to 52A9H, the operand of LD A,00H at 52A8H: after the compile that instruction loads 24H, and the OR A at 52AAH then sends CHAIN to 402DH instead of the execution.
5212
INC HL 23
Increment Register Pair HL past the dollar sign.
5213
LD A,(HL) 7E
Fetch the character after the dollar sign from Register Pair HL into Register A.
5214
CP 20H FE 20
Compare Register A (the character after the dollar sign) against 20H, a space.
5216
If the NZ FLAG is set (no space), JUMP to 5219H with Register Pair HL at that character, the start of the file specification.
5218
INC HL 23
Increment Register Pair HL past the one space that may follow the dollar sign.
5219
LD DE,56D2H 11 D2 56
Point Register Pair DE to 56D2H, the control block of the JCL file being read (the main file, and later each included file).
521C
GOSUB to 441CH (SYS1/SYS function 4) to copy the file specification at Register Pair HL into the control block at Register Pair DE (56D2H) as text; it returns the Z FLAG when a specification was read and Register Pair HL past it.
521F
If the NZ FLAG is set (no file specification), JUMP to 56AEH to display FILE SPEC REQUIRED! and abort.
5222
PUSH HL E5
Save Register Pair HL (the text after the file specification: the parameters) to the stack until both files are open.
5223
LD DE,56D2H 11 D2 56
Point Register Pair DE to 56D2H, the control block holding the specification of the JCL file.
5226
LD HL,5722H 21 22 57
Point Register Pair HL to 5722H, the three letters JCL (the end of the text SYSTEM/JCL at 571BH), the default extension.
5229
GOSUB to 4473H (SYS1/SYS function 5) to put /JCL into the specification at Register Pair DE (56D2H) when it has no extension of its own.
522C
LD B,00H 06 00
Load Register B with 00H, the record length for the open: 256 byte records, so that each byte is read through the sector buffer.
522E
LD HL,5A00H 21 00 5A
Point Register Pair HL to 5A00H, the sector buffer of the JCL file being read.
5231
GOSUB to 4424H (the open, SYS2/SYS function 1) for the JCL file: Register Pair DE = its control block 56D2H, Register Pair HL = its buffer 5A00H, Register B = 00H. Register A = the error code when the NZ FLAG is set.
5234
If the NZ FLAG is set (the JCL file cannot be opened, for example error 18H FILE NOT IN DIRECTORY in Register A), JUMP to 56A9H to display the error and abort.
5237
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands that SYS7/SYS reads in the execution phase.
523A
LD HL,571BH 21 1B 57
Point Register Pair HL to 571BH, the specification SYSTEM/JCL ended by 03H.
523D
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
5240
LDIR ED B0
Copy 32 bytes from Register Pair HL (571BH) to Register Pair DE (4358H-4377H), counted by Register Pair BC: the control block 4358H now holds the text SYSTEM/JCL and 03H; the message bytes copied after the 03H are not read by the open.
5242
LD B,00H 06 00
Load Register B with 00H, the record length for SYSTEM/JCL: 256 byte records, written a byte at a time.
5244
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block holding SYSTEM/JCL.
5247
LD HL,5B00H 21 00 5B
Point Register Pair HL to 5B00H, the sector buffer of SYSTEM/JCL during the compile.
524A
GOSUB to 4420H (SYS2/SYS function 2) to open SYSTEM/JCL with the control block at Register Pair DE (4358H) and the buffer at Register Pair HL (5B00H), or to create it when it is not on a diskette.
524D
If the NZ FLAG is set (SYSTEM/JCL can be neither opened nor created), JUMP to 56B7H to display the message at 573AH and abort.
5250
POP HL E1
Restore Register Pair HL from the stack: the text after the file specification, where the parameters are.
5251H - Read the Parameters of the Command Line
Register Pair HL = the text after the file specification. Spaces and commas are passed over; a parenthesis starts a list of parameters (52E1H); a semicolon asks for one more line of parameters, after a question mark, into the command line buffer 4318H; the carriage return starts the compile at 5312H. Any other character gives PARAMETER ERROR. A closing parenthesis returns here, so several lists may follow one another.
5251
LD A,(HL) 7E
Fetch the next character of the parameter text from Register Pair HL into Register A. 525AH, 525EH, 527CH and 52FFH come back here.
5252
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the carriage return that ends the command line.
5254
If the Z FLAG is set (the end of the line), JUMP to 5312H to start the compile with the first line of the JCL file.
5257
INC HL 23
Increment Register Pair HL past the character in Register A.
5258
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
525A
If the Z FLAG is set (a space), LOOP BACK to 5251H for the next character.
525C
CP 2CH FE 2C
Compare Register A (the character) against 2CH, a comma.
525E
If the Z FLAG is set (a comma), LOOP BACK to 5251H for the next character.
5260
CP 28H FE 28
Compare Register A (the character) against 28H, an opening parenthesis: a list of parameters follows.
5262
If the Z FLAG is set (an opening parenthesis), JUMP to 52E1H with Register Pair HL past it, to read the parameters.
5264
CP 3BH FE 3B
Compare Register A (the character) against 3BH, a semicolon: the parameters go on in another line typed at the keyboard.
5266
If the NZ FLAG is set (any other character), JUMP to 56C0H to display PARAMETER ERROR and abort.
5269
LD A,3FH 3E 3F
Load Register A with 3FH, a question mark, the prompt for the next line of parameters.
526B
GOSUB to the ROM routine at 0033H to display the character in Register A (the question mark) at the cursor.
526E
LD HL,4318H 21 18 43
Point Register Pair HL to 4318H, the command line buffer of SYS1/SYS, where the new line is typed.
5271
LD B,3FH 06 3F
Load Register B with 3FH, the most characters the line may have (63).
5273
GOSUB to the ROM routine at 0040H to read a line from the keyboard into the buffer at Register Pair HL (4318H), at most Register B characters, ended by the carriage return. Register Pair HL is returned at the start of the buffer, which SYS1/SYS's own 4E4FH-4E5CH rely on too; the CARRY FLAG is set when BREAK ended the line.
5276
If the CARRY FLAG is set (BREAK was pressed), JUMP to 56C0H to display PARAMETER ERROR and abort.
5279
GOSUB to 447EH to write the line at Register Pair HL (4318H) to the job log; Register Pair HL comes back unchanged.
527C
LOOP BACK to 5251H to read the parameters from the new line at Register Pair HL (4318H).
527EH - End of a JCL File: Back to the Including File
5315H comes here when 53E8H meets the end of the JCL file being read. 57B2H-57B3H points just past the last control block saved on the include stack 57B4H up; when it is 57B4H the stack is empty and the main file is finished (52A2H). Otherwise the 32 bytes of the including file's control block are copied back to 56D2H-56F1H, the pointer goes down by 32, and 4454H positions that file back to the sector its buffer had held, since the included file has used the same buffer 5A00H.
527E
LD HL,(57B2H) 2A B2 57
Fetch the include stack pointer from 57B2H-57B3H into Register Pair HL: the address just past the last control block saved by //INCLUDE (57B4H when none is saved).
5281
LD DE,57B4H 11 B4 57
Point Register Pair DE to 57B4H, the bottom of the include stack.
5284
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5285
SBC HL,DE ED 52
Subtract Register Pair DE (57B4H) from Register Pair HL (the include stack pointer): the Z FLAG is set when no control block is saved.
5287
If the Z FLAG is set (the main JCL file has ended), JUMP to 52A2H to finish the compile.
5289
LD HL,(57B2H) 2A B2 57
Fetch the include stack pointer from 57B2H-57B3H into Register Pair HL again: the address just past the last saved control block.
528C
DEC HL 2B
Decrement Register Pair HL to the last byte of the saved control block, the start of a copy downward.
528D
LD DE,56F1H 11 F1 56
Point Register Pair DE to 56F1H, the last byte of the control block 56D2H-56F1H of the JCL file being read.
5290
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
5293
LDDR ED B8
Copy 32 bytes downward from Register Pair HL to Register Pair DE, counted by Register Pair BC: the including file's control block is back in 56D2H-56F1H. Register Pair HL ends one byte below the saved block.
5295
INC HL 23
Increment Register Pair HL to the first byte of the saved block, the new top of the include stack.
5296
LD (57B2H),HL 22 B2 57
Store Register Pair HL (the new include stack pointer, 32 bytes lower) to 57B2H-57B3H.
5299
LD DE,56D2H 11 D2 56
Point Register Pair DE to 56D2H, the control block of the including file, now the file being read again.
529C
GOSUB to 4454H to set the position of the file at Register Pair DE back to the sector its buffer was read from, so that the next byte comes from that sector read again into 5A00H.
529F
JUMP to 5312H to read the next line of the including file and go on with the compile.
52A2H - Finish the Compile and Start the Execution
The main JCL file has ended. SYSTEM/JCL is closed (SYS3/SYS puts its specification back into 4358H as text). With the dollar sign option the command ends at 402DH. Otherwise SYSTEM/JCL is opened again with the sector buffer 4200H (5B00H belongs to the programs the commands will run) and request 99H hands it to SYS7/SYS. The asterisk option (52D7H) and the equals sign option (52C6H) join at 52AEH.
52A2
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of SYSTEM/JCL.
52A5
GOSUB to 4428H (the close, SYS3/SYS function 1) to write the last sector of SYSTEM/JCL and close it; its control block 4358H then holds the text SYSTEM/JCL, a colon and the drive. The result in Register A is not tested.
52A8
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the compile only mark: the operand 52A9H is 00H in the file and 24H (the dollar sign) when 520FH has stored it.
52AA
OR A B7
OR Register A with itself: the NZ FLAG is set when the dollar sign option was given.
52AB
If the NZ FLAG is set (compile only), JUMP to 402DH, the normal exit to VTOS READY: SYSTEM/JCL stays on the diskette for a later CHAIN with an asterisk.
52AE
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands (SYSTEM/JCL, or the file named after an equals sign). 52D5H and 52DFH also come here.
52B1
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, as the buffer of the file of commands during the execution phase.
52B4
LD B,00H 06 00
Load Register B with 00H, the record length: 256 byte records, read a byte at a time.
52B6
GOSUB to 4424H (the open, SYS2/SYS function 1) with the control block at Register Pair DE (4358H), the buffer at Register Pair HL (4200H) and Register B = 00H. Register A = the error code when the NZ FLAG is set.
52B9
If the NZ FLAG is set (the file of commands cannot be opened), JUMP to 56A9H to display the error and abort.
52BC
LD A,99H 3E 99
Load Register A with 99H: request code 99H, SYS7/SYS (bits 3-0 = 9) function 1 (bits 6-4), whose 4E13H starts the execution phase: it sets bit 5 of 430FH and, when that bit was clear, saves the keyboard driver address of 4016H at 43BEH and replaces the exits 402DH and 4030H by its own requests A9H and B9H; then it takes each command line from the file at 4358H.
52BE
RST 28H EF
RST 28H to 400CH and the request handler, which loads SYS7/SYS into 4E00H and runs it with Register A = 99H. SYS7/SYS sets the Stack Pointer to 41E0H itself (its 4E2CH) and does not return here.
52BFH - The Equals Sign: Execute a JCL File Directly
CHAIN with an equals sign skips the compile: the file named (default extension JCL) is put into the control block 4358H and opened at 52AEH as the file of commands, so its lines go to SYS7/SYS as they are, without substitutions, conditions or the other compile keywords. Parameters after the specification are not read.
52BF
INC HL 23
Increment Register Pair HL past the equals sign.
52C0
LD A,(HL) 7E
Fetch the character after the equals sign from Register Pair HL into Register A.
52C1
CP 20H FE 20
Compare Register A (the character after the equals sign) against 20H, a space.
52C3
If the NZ FLAG is set (no space), JUMP to 52C6H with Register Pair HL at the start of the file specification.
52C5
INC HL 23
Increment Register Pair HL past the one space that may follow the equals sign.
52C6
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands, where the specification is copied.
52C9
GOSUB to 441CH (SYS1/SYS function 4) to copy the file specification at Register Pair HL into the control block at Register Pair DE (4358H); the Z FLAG is set when a specification was read, otherwise Register A holds the character that ended the attempt.
52CC
If the NZ FLAG is set (no file specification), JUMP to 56A9H, which takes Register A (the character that stopped the specification, for example 0DH) as an error code: a CHAIN with an equals sign and no name shows the message of that code (for 0DH, DATA RECORD NOT FOUND DURING WRITE) instead of FILE SPEC REQUIRED!.
52CF
LD HL,5722H 21 22 57
Point Register Pair HL to 5722H, the three letters JCL, the default extension.
52D2
GOSUB to 4473H (SYS1/SYS function 5) to put /JCL into the specification at Register Pair DE (4358H) when it has no extension.
52D5
JUMP to 52AEH to open the file at 4358H and hand it to SYS7/SYS.
52D7H - The Asterisk: Run SYSTEM/JCL Again
CHAIN with an asterisk is meant to run the last compiled SYSTEM/JCL again without a compile. The copy of the specification at 571BH goes to Register Pair DE, which still holds 8091H from SYS1/SYS (the table word of CHAIN, 4E67H), not to the control block 4358H: 32 bytes are written at 8091H-80B0H (lost on a 16K machine, over user memory on a larger one), and the open at 52AEH works on whatever 4358H holds. That is the text SYSTEM/JCL with its drive after a close (after CHAIN with a dollar sign, 52A5H, or after //QUIT, 5571H); after an execution phase SYS7/SYS has stored 00H at 4358H (its 4EA8H-4EA9H), and the open then fails with ILLEGAL FILE NAME.
52D7
LD HL,571BH 21 1B 57
Point Register Pair HL to 571BH, the specification SYSTEM/JCL ended by 03H.
52DA
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
52DD
LDIR ED B0
Copy 32 bytes from Register Pair HL (571BH) to Register Pair DE, counted by Register Pair BC. Register Pair DE is not loaded here and still holds 8091H, the table word SYS1/SYS passed on, so the bytes go to 8091H-80B0H and the control block 4358H is not filled.
52DF
JUMP to 52AEH to open the file named in the control block 4358H as it stands and hand it to SYS7/SYS.
52E1H - One Parameter: a Symbol and Its Value
Inside the parentheses each parameter is a name of 1-8 letters and digits (5577H into 56F2H), optionally followed by an equals sign and a value (5582H into 56FAH-571AH). A name already in the symbol table at 5C00H gives MULTIPLY DEFINED PARAMETER!. Each new name becomes a table entry (560BH) with an empty value, then gets the value when there is one (561DH). Spaces and commas separate the parameters, a closing parenthesis returns to 5251H, anything else gives PARAMETER ERROR.
52E1
GOSUB to 5577H to read a name of up to 8 characters from Register Pair HL into 56F2H-56F9H: the Z FLAG is set when the name is not empty, Register A = the character that ended it. 52F7H and 52FBH come back here.
52E4
If the NZ FLAG is set (no name), JUMP to 52F5H to look at the character in Register A that ended the empty field.
52E6
PUSH AF F5
Save Register Pair AF (Register A = the character after the name) to the stack.
52E7
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there; otherwise Register Pair DE = the end of the table, where a new entry goes.
52EA
If the Z FLAG is set (the name is already defined), JUMP to 56C9H to display MULTIPLY DEFINED PARAMETER! and abort.
52ED
GOSUB to 560BH to add the name at 56F2H to the table at Register Pair DE with an empty value; Register Pair DE returns at the length byte of the new entry.
52F0
POP AF F1
Restore Register Pair AF from the stack: Register A = the character after the name.
52F1
CP 3DH FE 3D
Compare Register A (the character after the name) against 3DH, an equals sign: a value follows.
52F3
If the Z FLAG is set (an equals sign), JUMP to 5305H to read the value.
52F5
CP 20H FE 20
Compare Register A (the character that ended the field) against 20H, a space. 52E4H and 530DH come here.
52F7
If the Z FLAG is set (a space), LOOP BACK to 52E1H for the next parameter.
52F9
CP 2CH FE 2C
Compare Register A (the character) against 2CH, a comma.
52FB
If the Z FLAG is set (a comma), LOOP BACK to 52E1H for the next parameter.
52FD
CP 29H FE 29
Compare Register A (the character) against 29H, a closing parenthesis.
52FF
If the Z FLAG is set (the end of the list), JUMP to 5251H to read on in the command line after the parenthesis.
5302
JUMP to 56C0H to display PARAMETER ERROR and abort: the field ended with another character, for example the carriage return inside the parentheses.
5305
GOSUB to 5582H to read the value after the equals sign from Register Pair HL into 56FBH-571AH with its length at 56FAH; Register A = the character that ended it.
5308
PUSH AF F5
Save Register Pair AF (Register A = the character after the value) to the stack.
5309
GOSUB to 561DH to copy the length and the 32 bytes of the value (56FAH-571AH) into the new entry at Register Pair DE.
530C
POP AF F1
Restore Register Pair AF from the stack: Register A = the character after the value.
530D
JUMP to 52F5H to test the character in Register A that ended the value.
530FH - The Compile Loop: Copy Each Line with Its Substitutions
Each line of the JCL file is read into 5919H (53E8H) and copied to the output line at 5959H. A line that starts with the word PAUSE is first made into //PAUSE (5340H); a line that starts with two slashes goes to 53B8H for the compile keywords. In the copy every pound sign starts a substitution (536FH). When the carriage return has been copied, 5406H writes the output line to SYSTEM/JCL (not inside a false conditional block) and the next line is read. The end of the file goes to 527EH.
530F
GOSUB to 5406H to write the output line at 5959H to SYSTEM/JCL, unless the current conditional block is false or the line is a compile comment.
5312
GOSUB to 53E8H to read the next line of the JCL file into 5919H: the Z FLAG is set when a line ending in 0DH was read, the NZ FLAG at the end of the file. Many rows jump here for the next line: 5254H, 529FH, 53CBH, 549FH, 54B7H, 54CDH, 5502H, 550EH, 5517H, 5536H and 5565H.
5315
If the NZ FLAG is set (the end of the JCL file), JUMP to 527EH to go back to the including file or finish the compile.
5318
LD HL,5919H 21 19 59
Point Register Pair HL to 5919H, the start of the line just read.
531B
LD DE,5959H 11 59 59
Point Register Pair DE to 5959H, the start of the output line.
531E
LD A,(HL) 7E
Fetch the first character of the line from Register Pair HL into Register A.
531F
INC HL 23
Increment Register Pair HL to the second character of the line.
5320
CP 50H FE 50
Compare Register A (the first character) against 50H, the letter P.
5322
If the Z FLAG is set (the line starts with P), GOSUB to 5340H, which makes a line starting with PAUSE into //PAUSE and returns Register A = 2FH, or returns Register A = 50H and Register Pair HL unchanged.
5325
CP 2FH FE 2F
Compare Register A (the first character) against 2FH, a slash.
5327
If the NZ FLAG is set (no slash), JUMP to 532DH to copy the line.
5329
CP (HL) BE
Compare Register A (2FH, a slash) against the second character of the line at Register Pair HL.
532A
If the Z FLAG is set (the line starts with two slashes), JUMP to 53B8H to look for a compile keyword.
532D
CP 23H FE 23
Loop Start
Compare Register A (the character to copy) against 23H, a pound sign, the start of a substitution. 5327H, 5339H and the fall through from 532AH come here.
532F
If the Z FLAG is set (a pound sign), JUMP to 533BH for the substitution.
5331
LD (DE),A 12
Store Register A (the character) to the output line at Register Pair DE.
5332
INC DE 13
Increment Register Pair DE to the next byte of the output line.
5333
CP 0DH FE 0D
Compare Register A (the character just copied) against 0DH, the carriage return that ends the line.
5335
If the Z FLAG is set (the whole line is copied), JUMP to 530FH to write it to SYSTEM/JCL and read the next one.
5337
LD A,(HL) 7E
Fetch the next character of the line from Register Pair HL into Register A. 533EH and 53E5H come here.
5338
INC HL 23
Increment Register Pair HL past that character.
5339
LOOP BACK to 532DH to copy the character in Register A.
533B
GOSUB to 536FH with Register A = the pound sign and Register Pair HL past it: a second pound sign is copied as one, or the name between pound signs is replaced by its value in the output line at Register Pair DE.
533E
JUMP to 5337H to go on with the character at Register Pair HL, after the substitution.
5340H - A Line Starting PAUSE Becomes //PAUSE
Called from 5322H with Register Pair HL at the second character of the line at 5919H. When the next four characters are A, U, S and E, the line (5919H-5955H, 61 bytes) moves up by two bytes and two slashes are put in front, so the line goes on as the execution keyword //PAUSE; Register A returns 2FH and Register Pair HL at the second slash. Otherwise 5367H drops the return into this routine and returns from it with Register A = 50H and Register Pair HL unchanged. Nothing is tested after the E, so PAUSED or PAUSE1 are changed as well.
5340
PUSH HL E5
Save Register Pair HL (the address of the second character, 591AH) to the stack: it is given back in either case.
5341
LD A,41H 3E 41
Load Register A with 41H, the letter A, the second letter of PAUSE.
5343
GOSUB to 5367H to compare Register A (A) with the character at Register Pair HL and step Register Pair HL on; a difference returns straight to 5325H.
5346
LD A,55H 3E 55
Load Register A with 55H, the letter U, the third letter of PAUSE.
5348
GOSUB to 5367H to compare Register A (U) with the character at Register Pair HL and step Register Pair HL on.
534B
LD A,53H 3E 53
Load Register A with 53H, the letter S, the fourth letter of PAUSE.
534D
GOSUB to 5367H to compare Register A (S) with the character at Register Pair HL and step Register Pair HL on.
5350
LD A,45H 3E 45
Load Register A with 45H, the letter E, the last letter of PAUSE.
5352
GOSUB to 5367H to compare Register A (E) with the character at Register Pair HL and step Register Pair HL on.
5355
LD HL,5955H 21 55 59
Point Register Pair HL to 5955H, the last byte of the 61 bytes of the line that are moved.
5358
LD DE,5957H 11 57 59
Point Register Pair DE to 5957H, two bytes higher, where that byte goes.
535B
LD BC,003DH 01 3D 00
Load Register Pair BC with 003DH, the 61 bytes 5919H-5955H.
535E
LDDR ED B8
Copy 61 bytes downward from Register Pair HL to Register Pair DE, counted by Register Pair BC: the line moves up by two bytes to 591BH. Register Pair DE ends at 591AH.
5360
LD A,2FH 3E 2F
Load Register A with 2FH, a slash, the character put in front of the moved line twice.
5362
LD (DE),A 12
Store Register A (the slash) to 591AH, the address in Register Pair DE.
5363
DEC DE 1B
Decrement Register Pair DE to 5919H, the first byte of the line.
5364
LD (DE),A 12
Store Register A (the slash) to 5919H, the address in Register Pair DE: the line starts with //PAUSE.
5365
POP HL E1
Restore Register Pair HL from the stack: 591AH, now the second slash.
5366
RET C9
RETURN to 5325H with Register A = 2FH, the slash, as the first character of the line.
5367H - Match One Letter of PAUSE
Register A = the letter expected, Register Pair HL = the character of the line. On a match Register Pair HL steps on and the routine returns to 5340H. On a difference it drops its own return address and the Register Pair HL that 5340H saved, so the RET goes back to 5325H with Register A = 50H (the P) and Register Pair HL at the second character of the line.
5367
CP (HL) BE
Compare Register A (the letter of PAUSE expected) against the character of the line at Register Pair HL.
5368
INC HL 23
Increment Register Pair HL to the next character of the line.
5369
RET Z C8
If the Z FLAG is set (the letter matches), RETURN to 5340H for the next letter.
536A
POP HL E1
Restore Register Pair HL from the stack: the return address into 5340H, which is dropped.
536B
POP HL E1
Restore Register Pair HL from the stack: the address of the second character of the line, which 5340H saved.
536C
LD A,50H 3E 50
Load Register A with 50H, the letter P, the first character of the line, for the tests at 5325H.
536E
RET C9
RETURN to 5325H, the caller of 5340H: the line is not a PAUSE line.
536FH - A Pound Sign: Substitute the Value of a Symbol
Register A = 23H (a pound sign), Register Pair HL past it, Register Pair DE = the place in the output (the output line at 5959H from 533BH, or the value at 56FBH from 55BAH). Two pound signs give one pound sign. Otherwise a name ended by a pound sign must follow (any other end gives INVALID JCL FORMAT at 53A9H); a defined symbol with a value is replaced by the value, and a symbol not defined or without a value is copied as it stands, both pound signs included. Returns Register Pair DE past what was stored and Register Pair HL past the closing pound sign. The name is read into 56F2H, over whatever name was there.
536F
CP (HL) BE
Compare Register A (23H, the pound sign) against the character after it at Register Pair HL.
5370
If the NZ FLAG is set (no second pound sign), JUMP to 5376H to read the name of the symbol.
5372
INC HL 23
Increment Register Pair HL past the second pound sign.
5373
LD (DE),A 12
Store Register A (the pound sign) to the output at Register Pair DE: two pound signs stand for one.
5374
INC DE 13
Increment Register Pair DE to the next byte of the output.
5375
RET C9
RETURN with Register Pair DE past the pound sign and Register Pair HL past the two pound signs.
5376
PUSH HL E5
Save Register Pair HL (the text after the first pound sign) to the stack, to copy the name as it stands when it has no value.
5377
PUSH DE D5
Save Register Pair DE (the place in the output) to the stack.
5378
GOSUB to 5577H to read the name from Register Pair HL into 56F2H-56F9H: Register A = the character that ended it, which is passed over.
537B
CP 23H FE 23
Compare Register A (the character after the name) against 23H, the closing pound sign.
537D
If the NZ FLAG is set (the name does not end with a pound sign), JUMP to 53A9H to display the line and INVALID JCL FORMAT, PROCESSING ABORTED! and abort.
537F
EX (SP),HL E3
Exchange Register Pair HL with the top of the stack (the Stack Pointer's word, the saved place in the output): Register Pair HL = the place in the output, and the text after the closing pound sign is kept on the stack.
5380
PUSH HL E5
Save Register Pair HL (the place in the output) to the stack.
5381
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there, with Register Pair DE at the entry's length byte.
5384
If the NZ FLAG is set (the symbol is not defined), JUMP to 5395H to copy the name as it stands.
5386
LD A,(DE) 1A
Fetch the length of the symbol's value from the entry at Register Pair DE into Register A.
5387
OR A B7
OR Register A with itself: the Z FLAG is set when the symbol has no value (length 00H).
5388
If the Z FLAG is set (no value), JUMP to 5395H to copy the name as it stands.
538A
LD B,00H 06 00
Load Register B with 00H, the high byte of the count.
538C
LD C,A 4F
Copy Register A (the length of the value) into Register C: Register Pair BC = the length.
538D
INC DE 13
Increment Register Pair DE to the first byte of the value in the entry.
538E
POP HL E1
Restore Register Pair HL from the stack: the place in the output.
538F
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair DE = the place in the output, Register Pair HL = the value in the table.
5390
LDIR ED B0
Copy the value from Register Pair HL to the output at Register Pair DE, Register Pair BC bytes: Register Pair DE ends past the value.
5392
POP HL E1
Restore Register Pair HL from the stack: the text after the closing pound sign.
5393
POP AF F1
Restore Register Pair AF from the stack: this takes off the saved address of the text after the first pound sign, which is not needed; Register A gets its high byte and is not used by the callers.
5394
RET C9
RETURN with Register Pair DE past the value and Register Pair HL past the closing pound sign.
5395
POP DE D1
Restore Register Pair DE from the stack: the place in the output. 5384H and 5388H come here.
5396
POP AF F1
Restore Register Pair AF from the stack: this takes off the address of the text after the closing pound sign, which is not used.
5397
POP HL E1
Restore Register Pair HL from the stack: the text after the first pound sign, the start of the name as typed.
5398
LD A,23H 3E 23
Load Register A with 23H, the pound sign, the first byte to copy.
539A
LD (DE),A 12
Loop Start
Store Register A (the pound sign or a character of the name) to the output at Register Pair DE.
539B
INC DE 13
Increment Register Pair DE to the next byte of the output.
539C
LD A,(HL) 7E
Fetch the next character after the pound sign from Register Pair HL into Register A.
539D
INC HL 23
Increment Register Pair HL past that character.
539E
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the end of the line.
53A0
If the Z FLAG is set (no closing pound sign before the end of the line), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
53A2
CP 23H FE 23
Compare Register A (the character) against 23H, the closing pound sign.
53A4
If the NZ FLAG is set (a character of the name), LOOP BACK to 539AH to store it.
53A6
LD (DE),A 12
Store Register A (the closing pound sign) to the output at Register Pair DE.
53A7
INC DE 13
Increment Register Pair DE past the closing pound sign.
53A8
RET C9
RETURN with Register Pair DE past the copied text and Register Pair HL past the closing pound sign.
53A9H - Invalid JCL Format: Abort
Every format error of the compile ends here, and so does a pound sign error in a parameter value of the command line (536FH called from 55BAH through 5305H): the line buffer 5919H has then not been read yet and is displayed with whatever bytes memory holds there up to a 0DH or 03H. In both cases the text at 5916H, an arrow (two minus signs and a greater than sign) followed at once by the line buffer at 5919H, is displayed and logged, then the message INVALID JCL FORMAT, PROCESSING ABORTED!, and the command aborts at 4030H. SYSTEM/JCL is left as it was, not closed.
53A9
LD HL,5916H 21 16 59
Point Register Pair HL to 5916H, the arrow in front of the line buffer: the text displayed runs on into the line at 5919H up to its carriage return. Twelve rows jump here: 537DH, 53A0H, 548EH, 54ABH, 54C3H, 54F9H, 5508H, 551DH, 552AH, 5530H, 5551H and 5562H.
53AC
GOSUB to 447BH to display the text at Register Pair HL (the arrow and the line) and write it to the job log.
53AF
LD HL,578AH 21 8A 57
Point Register Pair HL to 578AH, the message INVALID JCL FORMAT, PROCESSING ABORTED! ended by 0DH.
53B2
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
53B5
JUMP to 4030H, the abort exit to the command level: the compile ends here.
53B8H - A Line Starting with Two Slashes: Compile Keywords
Register Pair HL = the second slash at 591AH. The word after the slashes is read into 56F2H. IF, ELSE and END (table 5435H) are carried out whatever the state of the current conditional block; SET, RESET, ASSIGN, INCLUDE and QUIT (table 544EH) only when the block is true, and in a false block the line is dropped. Each keyword routine is entered by PUSH DE / RET with Register Pair HL past the keyword. A line with no word (two slashes and a period, a space or the end of the line) or another word is an execution phase line: its start is copied as it is to 5959H and the copy loop goes on at 5337H.
53B8
INC HL 23
Increment Register Pair HL past the second slash, to the word that follows.
53B9
GOSUB to 5577H to read the word at Register Pair HL into 56F2H-56F9H (upper case, padded with spaces): the Z FLAG is set when it is not empty, and Register Pair HL is past the character that ended it (but on a carriage return, 03H or an opening parenthesis).
53BC
If the NZ FLAG is set (no word after the slashes), JUMP to 53D5H to pass the line on to the execution phase.
53BE
GOSUB to 563AH to look for the word at 56F2H in the table of IF, ELSE and END (5435H): the Z FLAG is set when it is there, with Register Pair DE = the address of its routine.
53C1
If the NZ FLAG is set (not IF, ELSE or END), JUMP to 53C5H.
53C3
PUSH DE D5
Save Register Pair DE (the address of the keyword's routine: 5481H, 54A2H or 54BAH) to the stack.
53C4
RET C9
RETURN to the address just saved: JUMP to the keyword's routine with Register Pair HL past the keyword.
53C5
LD DE,(58F4H) ED 5B F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair DE: the state byte of the current conditional block (58F6H, 00H, when no //IF is open).
53C9
LD A,(DE) 1A
Fetch the state of the current block from Register Pair DE into Register A: 00H true, FFH false.
53CA
OR A B7
OR Register A with itself: the NZ FLAG is set when the current block is false.
53CB
If the NZ FLAG is set (a false block), JUMP to 5312H: the line is dropped, its keyword not carried out.
53CE
GOSUB to 564DH to look for the word at 56F2H in the table of SET, RESET, ASSIGN, INCLUDE and QUIT (544EH): the Z FLAG is set when it is there, with Register Pair DE = the address of its routine.
53D1
If the NZ FLAG is set (no compile keyword), JUMP to 53D5H to pass the line on to the execution phase.
53D3
PUSH DE D5
Save Register Pair DE (the address of the keyword's routine) to the stack.
53D4
RET C9
RETURN to the address just saved: JUMP to the keyword's routine with Register Pair HL past the keyword.
53D5
LD DE,5919H 11 19 59
Point Register Pair DE to 5919H, the start of the line. 53BCH and 53D1H come here.
53D8
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
53D9
SBC HL,DE ED 52
Subtract Register Pair DE (5919H) from Register Pair HL (the place reached in the line): Register Pair HL = the number of characters already read (the slashes, the word and the character after it, unless that character is the carriage return, which 5577H does not pass over).
53DB
LD B,H 44
Copy Register H (the high byte of the count) into Register B.
53DC
LD C,L 4D
Copy Register L (the low byte of the count) into Register C: Register Pair BC = the characters already read.
53DD
LD HL,5919H 21 19 59
Point Register Pair HL to 5919H, the start of the line.
53E0
LD DE,5959H 11 59 59
Point Register Pair DE to 5959H, the start of the output line.
53E3
LDIR ED B0
Copy Register Pair BC bytes from the line at Register Pair HL to the output line at Register Pair DE as they were typed: Register Pair HL ends at the next character to read, Register Pair DE at the next byte of the output.
53E5
JUMP to 5337H to copy the rest of the line, with its substitutions.
53E8H - Read a Line of the JCL File
The bytes of the file at the control block 56D2H are read through the ROM's 0013H into 5919H up to and including a carriage return; nothing limits the length. Returns the Z FLAG for a line. The end of the file (error 1CH) and a byte 00H both return Register A = 1CH with the NZ FLAG, so a last line without a carriage return is not compiled. Any other read error goes to 56A9H.
53E8
LD HL,5919H 21 19 59
Point Register Pair HL to 5919H, the line buffer.
53EB
LD DE,56D2H 11 D2 56
Point Register Pair DE to 56D2H, the control block of the JCL file being read.
53EE
Loop Start
GOSUB to the ROM routine at 0013H to get the next byte of the file whose control block is at Register Pair DE (56D2H): Register A = the byte with the Z FLAG, or an error code with the NZ FLAG. Register Pairs DE and HL are kept.
53F1
If the NZ FLAG is set (no byte), JUMP to 53FDH to tell the end of the file from an error.
53F3
OR A B7
OR Register A (the byte) with itself: the Z FLAG is set for a byte 00H.
53F4
If the Z FLAG is set (a byte 00H), JUMP to 5402H, which takes it as the end of the file.
53F6
LD (HL),A 77
Store Register A (the byte) to the line buffer at Register Pair HL.
53F7
INC HL 23
Increment Register Pair HL to the next byte of the line buffer.
53F8
CP 0DH FE 0D
Compare Register A (the byte) against 0DH, the carriage return that ends a line.
53FA
If the NZ FLAG is set (not the end of the line), LOOP BACK to 53EEH for the next byte.
53FC
RET C9
RETURN with the Z FLAG set: the line at 5919H ends with 0DH.
53FD
CP 1CH FE 1C
Compare Register A (the error code from 0013H) against 1CH, END OF FILE ENCOUNTERED.
53FF
If the NZ FLAG is set (another error), JUMP to 56A9H to display the error and abort.
5402
LD A,1CH 3E 1C
Load Register A with 1CH, the end of file code. 53F4H comes here for a byte 00H.
5404
OR A B7
OR Register A (1CH) with itself: the NZ FLAG is set.
5405
RET C9
RETURN with the NZ FLAG set and Register A = 1CH: the end of the file.
5406H - Write the Output Line to SYSTEM/JCL
The output line at 5959H, ended by 0DH, is written byte by byte through the ROM's 001BH to the file at the control block 4358H, unless the current conditional block is false (the line is then dropped). A line starting with two slashes and a period, a compile comment, is displayed with 4467H instead and not written; it is not written to the job log either. A write error goes to 56A9H.
5406
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL: the state byte of the current conditional block. Called from 530FH after each copied line.
5409
LD A,(HL) 7E
Fetch the state of the current block from Register Pair HL into Register A: 00H true, FFH false.
540A
OR A B7
OR Register A with itself: the NZ FLAG is set when the current block is false.
540B
RET NZ C0
If the NZ FLAG is set (a false block), RETURN without writing: the line is dropped.
540C
LD HL,5959H 21 59 59
Point Register Pair HL to 5959H, the output line.
540F
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of SYSTEM/JCL.
5412
LD A,(HL) 7E
Fetch the first character of the output line from Register Pair HL into Register A.
5413
CP 2FH FE 2F
Compare Register A (the first character) against 2FH, a slash.
5415
If the NZ FLAG is set (no slash), JUMP to 5427H to write the line.
5417
INC HL 23
Increment Register Pair HL to the second character of the output line.
5418
CP (HL) BE
Compare Register A (2FH, the slash) against the second character at Register Pair HL.
5419
DEC HL 2B
Decrement Register Pair HL back to 5959H, the start of the output line; the flags of the comparison are kept.
541A
If the NZ FLAG is set (the second character is not a slash), JUMP to 5427H to write the line.
541C
LD A,(595BH) 3A 5B 59
Fetch the third character of the output line from 595BH into Register A.
541F
CP 2EH FE 2E
Compare Register A (the third character) against 2EH, a period: two slashes and a period start a compile comment.
5421
If the NZ FLAG is set (no period), JUMP to 5427H to write the line.
5423
GOSUB to 4467H to display the compile comment at Register Pair HL (5959H) up to its carriage return.
5426
RET C9
RETURN: the compile comment is shown and not written to SYSTEM/JCL.
5427
LD A,(HL) 7E
Loop Start
Fetch the next character of the output line from Register Pair HL into Register A. 5415H, 541AH and 5421H come here.
5428
GOSUB to the ROM routine at 001BH to write Register A to the file whose control block is at Register Pair DE (4358H); the NZ FLAG is set on an error, with the error code in Register A.
542B
If the NZ FLAG is set (the byte could not be written, for example error 1BH DISK SPACE FULL), JUMP to 56A9H to display the error and abort.
542E
LD A,(HL) 7E
Fetch the character just written from Register Pair HL into Register A again, for the test of the end of the line below.
542F
INC HL 23
Increment Register Pair HL to the next character of the output line.
5430
CP 0DH FE 0D
Compare Register A (the character written) against 0DH, the carriage return that ends the line.
5432
If the NZ FLAG is set (not the end of the line), LOOP BACK to 5427H for the next character.
5434
RET C9
RETURN: the line, its carriage return included, is in SYSTEM/JCL.
5435H - Keyword Table of IF, ELSE and END
Searched by 563AH (5660H with Register B = 06H, Register C = 08H). 8 bytes an entry: the keyword in 6 characters padded with spaces, then the address of its routine, which 53C3H-53C4H jumps to. These three are carried out even in a false conditional block. A byte 00H ends the table.
5435-543C
DEFM "IF " / DEFW 5481H 49 46 20 20 20 20 81 54
The keyword IF and the address 5481H of its routine: evaluate the expression after it and open a conditional block.
543D-5444
DEFM "ELSE " / DEFW 54A2H 45 4C 53 45 20 20 A2 54
The keyword ELSE and the address 54A2H of its routine: turn the state of the current conditional block over.
5445-544C
DEFM "END " / DEFW 54BAH 45 4E 44 20 20 20 BA 54
The keyword END and the address 54BAH of its routine: close the current conditional block.
544D
DEFB 00H 00
The end of the first keyword table: 5660H stops at a byte 00H in the place of a keyword and returns the NZ FLAG.
544EH - Keyword Table of SET, RESET, ASSIGN, INCLUDE and QUIT
Searched by 564DH (5660H with Register B = 08H, Register C = 0AH) only when the current conditional block is true. 10 bytes an entry: the keyword in 8 characters padded with spaces, then the address of its routine. A byte 00H ends the table. The execution phase keywords (PAUSE, EXIT and the others) are not here: those lines go to SYSTEM/JCL as they are, for SYS7/SYS.
544E-5457
DEFM "SET " / DEFW 54F6H 53 45 54 20 20 20 20 20 F6 54
The keyword SET and the address 54F6H of its routine: define the symbol named after it, with no value.
5458-5461
DEFM "RESET " / DEFW 5505H 52 45 53 45 54 20 20 20 05 55
The keyword RESET and the address 5505H of its routine: make the symbol named after it undefined.
5462-546B
DEFM "ASSIGN " / DEFW 551AH 41 53 53 49 47 4E 20 20 1A 55
The keyword ASSIGN and the address 551AH of its routine: give the symbol named after it the value after the equals sign.
546C-5475
DEFM "INCLUDE " / DEFW 5539H 49 4E 43 4C 55 44 45 20 39 55
The keyword INCLUDE and the address 5539H of its routine: compile the JCL file named after it at this point.
5476-547F
DEFM "QUIT " / DEFW 5568H 51 55 49 54 20 20 20 20 68 55
The keyword QUIT and the address 5568H of its routine: end the compile with no execution.
5480
DEFB 00H 00
The end of the second keyword table: 5660H stops at a byte 00H in the place of a keyword and returns the NZ FLAG.
5481H - //IF: Evaluate the Expression and Open a Block
Register Pair HL = the text after IF. The expression is terms joined by commas (OR); each term is factors joined by periods (AND, 54D0H). 54D0H returns the Z FLAG for a true term, and the first true term makes the whole expression true without reading the rest. A false term must be followed by a comma (the next term) or the carriage return (the expression is false); any other character, a period after a false factor included, gives INVALID JCL FORMAT. The new block's state is 00H (true) or FFH (false), ORed with the state of the enclosing block, and is pushed on the condition stack at 58F6H up; nothing limits its depth.
5481
GOSUB to 54D0H to evaluate one term at Register Pair HL: the Z FLAG is set when it is true; when it is false Register A = the character after the factor that was false. 548CH comes back here.
5484
If the Z FLAG is set (a true term), JUMP to 5491H: the expression is true.
5486
CP 0DH FE 0D
Compare Register A (the character after the false term) against 0DH, the end of the line.
5488
If the Z FLAG is set (the end of the expression), JUMP to 5494H: the expression is false.
548A
CP 2CH FE 2C
Compare Register A (the character after the false term) against 2CH, a comma, the OR of the next term.
548C
If the Z FLAG is set (a comma), LOOP BACK to 5481H to evaluate the next term.
548E
JUMP to 53A9H to display the line and INVALID JCL FORMAT, PROCESSING ABORTED! and abort: the false term ended with another character.
5491
XOR A AF
Set Register A to 00H, the state of a true block.
5492
JUMP to 5496H to push the state in Register A.
5494
LD A,FFH 3E FF
Load Register A with FFH, the state of a false block.
5496
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL: the state byte of the enclosing block.
5499
OR (HL) B6
OR Register A (the state of the expression) with the state of the enclosing block at Register Pair HL: inside a false block the new block is false too.
549A
INC HL 23
Increment Register Pair HL to the next byte of the condition stack, the place of the new block.
549B
LD (HL),A 77
Store Register A (the state of the new block) to the condition stack at Register Pair HL.
549C
LD (58F4H),HL 22 F4 58
Store Register Pair HL (the new top of the condition stack) to 58F4H-58F5H.
549F
JUMP to 5312H to read the next line of the JCL file.
54A2H - //ELSE: Turn the Current Block Over
With no //IF open (the pointer at 58F4H is 58F6H) ELSE gives INVALID JCL FORMAT. Otherwise the state of the current block is complemented and ORed with the state of the enclosing block, so a true block becomes false and a false one true unless the enclosing block is false. The rest of the line is not read.
54A2
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL.
54A5
LD DE,58F6H 11 F6 58
Point Register Pair DE to 58F6H, the bottom of the condition stack (the state of the lines outside every block).
54A8
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
54A9
SBC HL,DE ED 52
Subtract Register Pair DE (58F6H) from Register Pair HL (the condition stack pointer): the Z FLAG is set when no //IF is open.
54AB
If the Z FLAG is set (an ELSE with no IF), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
54AE
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL again: the state of the current block.
54B1
LD A,(HL) 7E
Fetch the state of the current block from Register Pair HL into Register A.
54B2
CPL 2F
Complement Register A (the state): 00H (true) becomes FFH (false) and FFH becomes 00H.
54B3
DEC HL 2B
Decrement Register Pair HL to the state of the enclosing block.
54B4
OR (HL) B6
OR Register A (the turned state) with the state of the enclosing block at Register Pair HL.
54B5
INC HL 23
Increment Register Pair HL back to the place of the current block.
54B6
LD (HL),A 77
Store Register A (the new state) to the current block's byte at Register Pair HL.
54B7
JUMP to 5312H to read the next line of the JCL file.
54BAH - //END: Close the Current Block
With no //IF open END gives INVALID JCL FORMAT. Otherwise the condition stack pointer goes down by one. The rest of the line is not read. A block left open at the end of the file is not reported.
54BA
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL.
54BD
LD DE,58F6H 11 F6 58
Point Register Pair DE to 58F6H, the bottom of the condition stack.
54C0
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
54C1
SBC HL,DE ED 52
Subtract Register Pair DE (58F6H) from Register Pair HL (the condition stack pointer): the Z FLAG is set when no //IF is open.
54C3
If the Z FLAG is set (an END with no IF), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
54C6
LD HL,(58F4H) 2A F4 58
Fetch the condition stack pointer from 58F4H-58F5H into Register Pair HL again.
54C9
DEC HL 2B
Decrement Register Pair HL to the state byte of the enclosing block.
54CA
LD (58F4H),HL 22 F4 58
Store Register Pair HL (the lowered pointer) to 58F4H-58F5H: the enclosing block is current again.
54CD
JUMP to 5312H to read the next line of the JCL file.
54D0H - One Term: Factors Joined by Periods (AND)
Register Pair HL = the text of the term. Each factor is evaluated by 54DAH; a false factor ends the term at once with the NZ FLAG and Register A = the character after it (the period too, which 5481H then rejects). After a true factor a period goes on with the next factor; any other character ends the term true, with the Z FLAG and Register A = 00H, and the rest of the expression is not read.
54D0
GOSUB to 54DAH to evaluate one factor at Register Pair HL: the Z FLAG is set when it is true, and Register A = the character after it. 54D6H comes back here.
54D3
RET NZ C0
If the NZ FLAG is set (a false factor), RETURN with the NZ FLAG and Register A = the character after the factor: the term is false.
54D4
CP 2EH FE 2E
Compare Register A (the character after the true factor) against 2EH, a period, the AND of the next factor.
54D6
If the Z FLAG is set (a period), LOOP BACK to 54D0H to evaluate the next factor.
54D8
XOR A AF
Set Register A to 00H with the Z FLAG set: the term is true.
54D9
RET C9
RETURN with the Z FLAG set and Register A = 00H: the term is true.
54DAH - One Factor: a Symbol, or a Minus Sign and a Symbol (NOT)
Register Pair HL = the factor. A factor without a minus sign goes on at 54E9H: true when the symbol is defined. For a minus sign 54E9H is called with Register Pair HL still at the minus sign, so it reads an empty name (the minus sign ends it and is passed over) and returns the NZ FLAG; the result turned over is then always true, with Register A = 00H, and the symbol after the minus sign is not read. So a factor with a minus sign is true whatever its symbol, and the expression ends there as true.
54DA
LD A,(HL) 7E
Fetch the first character of the factor from Register Pair HL into Register A.
54DB
CP 2DH FE 2D
Compare Register A (the first character) against 2DH, a minus sign, the NOT of the factor.
54DD
If the NZ FLAG is set (no minus sign), JUMP to 54E9H: the factor is a symbol, true when it is defined, and 54E9H returns to the caller of 54DAH.
54DF
GOSUB to 54E9H with Register Pair HL still at the minus sign: the name read is empty, so it returns the NZ FLAG with Register A = 2DH and Register Pair HL past the minus sign.
54E2
If the NZ FLAG is set (54E9H found no defined symbol: always the case here), JUMP to 54E7H: the factor counts as true.
54E4
OR 01H F6 01
OR Register A with 01H to set the NZ FLAG: a defined symbol after the minus sign would make the factor false. This row is not reached.
54E6
RET C9
RETURN with the NZ FLAG set: a false factor. This row is not reached.
54E7
XOR A AF
Set Register A to 00H with the Z FLAG set: the factor is true, and Register A no longer holds the character after it.
54E8
RET C9
RETURN with the Z FLAG set and Register A = 00H.
54E9H - Test Whether a Symbol Is Defined
Register Pair HL = a name. 5577H reads it into 56F2H; an empty name returns the NZ FLAG at once. Otherwise the symbol table is searched: the Z FLAG is set when the symbol is defined, the NZ FLAG when not. Register A = the character that ended the name, Register Pair HL past it.
54E9
GOSUB to 5577H to read the name at Register Pair HL into 56F2H-56F9H: the Z FLAG is set when it is not empty, Register A = the character that ended it. 54DDH jumps here and 54DFH calls it.
54EC
RET NZ C0
If the NZ FLAG is set (an empty name), RETURN with the NZ FLAG: no symbol, so false.
54ED
PUSH AF F5
Save Register Pair AF (Register A = the character after the name) to the stack.
54EE
PUSH HL E5
Save Register Pair HL (the text after the name) to the stack.
54EF
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there.
54F2
POP HL E1
Restore Register Pair HL from the stack: the text after the name.
54F3
POP BC C1
Restore Register Pair BC from the stack: Register B = the character after the name, saved as Register A at 54EDH.
54F4
LD A,B 78
Copy Register B (the character after the name) into Register A; the flags of the search are kept.
54F5
RET C9
RETURN with the Z FLAG set when the symbol is defined (true), the NZ FLAG when it is not (false), and Register A = the character after the name.
54F6H - //SET: Define a Symbol
The name after SET (none gives INVALID JCL FORMAT) is added to the symbol table with no value, when it is not there already. The rest of the line is not read.
54F6
GOSUB to 5577H to read the name after SET from Register Pair HL into 56F2H-56F9H: the Z FLAG is set when it is not empty.
54F9
If the NZ FLAG is set (no name), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
54FC
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there; otherwise Register Pair DE = the end of the table.
54FF
If the NZ FLAG is set (not defined yet), GOSUB to 560BH to add the name to the table at Register Pair DE with an empty value.
5502
JUMP to 5312H to read the next line of the JCL file.
5505H - //RESET: Make a Symbol Undefined
The name after RESET (none gives INVALID JCL FORMAT) is looked up; when it is defined, the first character of its name in the table is replaced by a space, so that no name read by 5577H can match it again. The entry keeps its place in the table.
5505
GOSUB to 5577H to read the name after RESET from Register Pair HL into 56F2H-56F9H: the Z FLAG is set when it is not empty.
5508
If the NZ FLAG is set (no name), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
550B
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there, with Register Pair DE = the entry's length byte, 8 bytes after the start of the entry.
550E
If the NZ FLAG is set (the symbol is not defined), JUMP to 5312H: there is nothing to reset.
5511
LD HL,FFF8H 21 F8 FF
Load Register Pair HL with FFF8H, minus 8, the step back from the length byte to the first character of the name.
5514
ADD HL,DE 19
Add Register Pair DE (the entry's length byte) to Register Pair HL: Register Pair HL = the first character of the entry's name.
5515
LD (HL),20H 36 20
Store 20H, a space, to the first character of the name at Register Pair HL: the symbol is no longer found.
5517
JUMP to 5312H to read the next line of the JCL file.
551AH - //ASSIGN: Give a Symbol a Value
ASSIGN name=value: the name (none gives INVALID JCL FORMAT) is added to the table when it is new; an equals sign must follow, then the value (5582H, with substitutions) replaces the entry's length and value. A symbol defined before gets the new value.
551A
GOSUB to 5577H to read the name after ASSIGN from Register Pair HL into 56F2H-56F9H: the Z FLAG is set when it is not empty, Register A = the character after it.
551D
If the NZ FLAG is set (no name), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
5520
PUSH AF F5
Save Register Pair AF (Register A = the character after the name) to the stack.
5521
GOSUB to 5628H to look for the name at 56F2H in the symbol table: the Z FLAG is set when it is there, with Register Pair DE = the entry's length byte; otherwise Register Pair DE = the end of the table.
5524
If the NZ FLAG is set (a new symbol), GOSUB to 560BH to add the name at Register Pair DE; Register Pair DE returns at the new entry's length byte.
5527
POP AF F1
Restore Register Pair AF from the stack: Register A = the character after the name.
5528
CP 3DH FE 3D
Compare Register A (the character after the name) against 3DH, an equals sign.
552A
If the NZ FLAG is set (no equals sign), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
552D
GOSUB to 5582H to read the value from Register Pair HL into 56FBH-571AH with its length at 56FAH; it returns with the Z FLAG set.
5530
If the NZ FLAG is set, JUMP to 53A9H to report INVALID JCL FORMAT. 5582H always returns the Z FLAG (from its last comparison), so this jump is not taken.
5533
GOSUB to 561DH to copy the length and the 32 bytes of the value (56FAH-571AH) into the entry at Register Pair DE.
5536
JUMP to 5312H to read the next line of the JCL file.
5539H - //INCLUDE: Compile Another JCL File Here
The control block of the file being read (56D2H-56F1H) is pushed on the include stack at the pointer 57B2H (32 bytes a level, from 57B4H up, with no test of the space: the eleventh level reaches the condition stack pointer at 58F4H). Then the file named (default extension JCL) is opened with the same control block 56D2H and the same buffer 5A00H, and the compile reads on from it; 527EH takes the outer file back at its end. Neither file is closed.
5539
PUSH HL E5
Save Register Pair HL (the text after INCLUDE) to the stack.
553A
LD DE,(57B2H) ED 5B B2 57
Fetch the include stack pointer from 57B2H-57B3H into Register Pair DE: the next free place on the include stack.
553E
LD HL,56D2H 21 D2 56
Point Register Pair HL to 56D2H, the control block of the file being read.
5541
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
5544
LDIR ED B0
Copy 32 bytes from Register Pair HL (56D2H-56F1H) to the include stack at Register Pair DE, counted by Register Pair BC: Register Pair DE ends 32 bytes higher.
5546
LD (57B2H),DE ED 53 B2 57
Store Register Pair DE (the raised include stack pointer) to 57B2H-57B3H.
554A
POP HL E1
Restore Register Pair HL from the stack: the text after INCLUDE, the file specification.
554B
LD DE,56D2H 11 D2 56
Point Register Pair DE to 56D2H, the control block that takes the included file.
554E
GOSUB to 441CH (SYS1/SYS function 4) to copy the file specification at Register Pair HL into the control block at Register Pair DE (56D2H): the Z FLAG is set when one was read.
5551
If the NZ FLAG is set (no file specification), JUMP to 53A9H to report INVALID JCL FORMAT and abort.
5554
LD HL,5722H 21 22 57
Point Register Pair HL to 5722H, the three letters JCL, the default extension.
5557
GOSUB to 4473H (SYS1/SYS function 5) to put /JCL into the specification at Register Pair DE (56D2H) when it has no extension.
555A
LD HL,5A00H 21 00 5A
Point Register Pair HL to 5A00H, the sector buffer of the JCL file being read, now for the included file.
555D
LD B,00H 06 00
Load Register B with 00H, the record length: 256 byte records, read a byte at a time.
555F
GOSUB to 4424H (the open, SYS2/SYS function 1) with the control block at Register Pair DE (56D2H), the buffer at Register Pair HL (5A00H) and Register B = 00H.
5562
If the NZ FLAG is set (the included file cannot be opened), JUMP to 53A9H to report INVALID JCL FORMAT and abort; the error code itself is not shown.
5565
JUMP to 5312H to read the first line of the included file.
5568H - //QUIT: End the Compile with No Execution
The //QUIT line itself is displayed and logged, SYSTEM/JCL is closed (with what has been written so far) and the command ends at 402DH, VTOS READY.
5568
LD HL,5919H 21 19 59
Point Register Pair HL to 5919H, the line just read, //QUIT and whatever follows it.
556B
GOSUB to 447BH to display the line at Register Pair HL and write it to the job log.
556E
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of SYSTEM/JCL.
5571
GOSUB to 4428H (the close, SYS3/SYS function 1) to close SYSTEM/JCL; its control block 4358H then holds its specification as text again.
5574
JUMP to 402DH, the normal exit to VTOS READY: nothing is executed.
5577H - Read a Name of up to 8 Characters into 56F2H
Register Pair HL = the text. 55C0H copies the letters and digits (small letters made capital, characters past the eighth passed over) to 56F2H-56F9H and pads the rest with spaces. Returns the Z FLAG when the name is not empty, Register A = the character that ended it and Register Pair HL past that character, except that 03H, 0DH and an opening parenthesis are not passed over. Register Pair DE is kept; Register B returns 00H.
5577
PUSH DE D5
Save Register Pair DE (the caller's place in the output or table) to the stack. Seven rows call this routine: 52E1H, 5378H, 53B9H, 54E9H, 54F6H, 5505H and 551AH.
5578
LD B,08H 06 08
Load Register B with 08H, the most characters a name may have.
557A
LD DE,56F2H 11 F2 56
Point Register Pair DE to 56F2H, the name buffer.
557D
GOSUB to 55C0H to copy the field at Register Pair HL to Register Pair DE (56F2H), at most Register B (8) characters, padded with spaces: the Z FLAG is set when a character was stored, Register A = the character that ended the field.
5580
POP DE D1
Restore Register Pair DE from the stack: the caller's value; the flags and Register A are kept.
5581
RET C9
RETURN with the Z FLAG (a name) or the NZ FLAG (none) and Register A = the character after the name.
5582H - Read a Value of up to 32 Characters into 56FBH
Register Pair HL = the text after the equals sign. 55A1H reads the value into 56FBH-571AH (padded with spaces by its first field), with substitutions of symbols between pound signs, up to a space, a comma, a carriage return, an equals sign or a parenthesis. The length (the bytes stored) goes to 56FAH; more than 32 bytes, which only substitutions can give, jumps to 56A9H with the length as the error code. Returns the Z FLAG and Register A = the character that ended the value. Register Pair DE is kept.
5582
PUSH DE D5
Save Register Pair DE (the caller's entry in the symbol table) to the stack. Called from 5305H and 552DH.
5583
LD B,20H 06 20
Load Register B with 20H, the most characters of the first field of the value (32).
5585
LD DE,56FBH 11 FB 56
Point Register Pair DE to 56FBH, the value buffer.
5588
GOSUB to 55A1H to read the value at Register Pair HL into the buffer at Register Pair DE: Register Pair DE returns past the bytes stored, Register A = the character that ended the value, the Z FLAG set.
558B
PUSH AF F5
Save Register Pair AF (Register A = the character after the value, the Z FLAG) to the stack.
558C
PUSH HL E5
Save Register Pair HL (the text after the value) to the stack.
558D
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair HL = the end of the bytes stored in the value buffer.
558E
LD DE,56FBH 11 FB 56
Point Register Pair DE to 56FBH, the start of the value buffer.
5591
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5592
SBC HL,DE ED 52
Subtract Register Pair DE (56FBH) from Register Pair HL (the end of the value): Register L = the length of the value.
5594
LD A,L 7D
Copy Register L (the length of the value) into Register A.
5595
CP 21H FE 21
Compare Register A (the length) against 21H: the CARRY FLAG is clear for a value longer than 32 bytes.
5597
If the NO CARRY FLAG is set (more than 32 bytes, through substitutions), JUMP to 56A9H, which shows the message of the error code Register A OR 40H (bits 5-0 of the length) and aborts. The bytes past 571AH have already been written over 571BH and up.
559A
LD (56FAH),A 32 FA 56
Store Register A (the length of the value, 00H-20H) to 56FAH, the length byte in front of the value buffer.
559D
POP HL E1
Restore Register Pair HL from the stack: the text after the value.
559E
POP AF F1
Restore Register Pair AF from the stack: Register A = the character after the value, the Z FLAG set.
559F
POP DE D1
Restore Register Pair DE from the stack: the caller's entry in the symbol table.
55A0
RET C9
RETURN with the Z FLAG, Register A = the character after the value and Register Pair HL at or past it.
55A1H - Read the Words of a Value
Register Pair HL = the text, Register Pair DE = where it goes, Register B = the most characters. 55C0H copies the first field; a space, a comma, 0DH, an equals sign or a parenthesis then ends the value with the Z FLAG; a pound sign calls 536FH for a substitution and the test goes on with the character after it, which is not passed over here. Any other character (a period, a slash) was passed over by 55C0H and another field is read, but 55C0H leaves Register B at 00H, so every later field stores nothing: only the first field and the substitutions make the value, and the letters and digits of every later field and the characters between the fields are dropped (MY.#X# gives MY followed by the value of X). After a substitution Register Pair HL stays at the ending character, so a closing parenthesis right after a pound sign is seen again by 5251H, which gives PARAMETER ERROR.
55A1
GOSUB to 55C0H to copy a field of letters and digits from Register Pair HL to Register Pair DE, at most Register B characters: Register A = the character that ended it. 55B8H comes back here.
55A4
CP 20H FE 20
Compare Register A (the character that ended the field) against 20H, a space. 55BEH comes here after a substitution.
55A6
RET Z C8
If the Z FLAG is set (a space), RETURN with the Z FLAG: the value is complete.
55A7
CP 2CH FE 2C
Compare Register A (the character) against 2CH, a comma.
55A9
RET Z C8
If the Z FLAG is set (a comma), RETURN with the Z FLAG: the value is complete.
55AA
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the carriage return.
55AC
RET Z C8
If the Z FLAG is set (the end of the line), RETURN with the Z FLAG: the value is complete.
55AD
CP 3DH FE 3D
Compare Register A (the character) against 3DH, an equals sign.
55AF
RET Z C8
If the Z FLAG is set (an equals sign), RETURN with the Z FLAG: the value is complete.
55B0
CP 28H FE 28
Compare Register A (the character) against 28H, an opening parenthesis.
55B2
RET Z C8
If the Z FLAG is set (an opening parenthesis), RETURN with the Z FLAG: the value is complete.
55B3
CP 29H FE 29
Compare Register A (the character) against 29H, a closing parenthesis.
55B5
RET Z C8
If the Z FLAG is set (a closing parenthesis), RETURN with the Z FLAG: the value is complete.
55B6
CP 23H FE 23
Compare Register A (the character) against 23H, a pound sign, the start of a substitution.
55B8
If the NZ FLAG is set (another character), LOOP BACK to 55A1H to read the next field, which stores nothing since Register B is 00H.
55BA
GOSUB to 536FH with Register A = the pound sign, Register Pair HL past it and Register Pair DE = the place in the value buffer: the value of the symbol (or the name as typed, or one pound sign) is stored there.
55BD
LD A,(HL) 7E
Fetch the character after the substitution from Register Pair HL into Register A, without passing over it.
55BE
JUMP to 55A4H to test the character in Register A.
55C0H - Copy a Field of Letters and Digits
Register Pair HL = the text, Register Pair DE = where it goes, Register B = the most characters. Letters and digits are copied, small letters made capital; characters past the most allowed are passed over. Any other character ends the field and is passed over, except 03H, 0DH and an opening parenthesis. The room left is padded with spaces, Register Pair DE returns past the characters stored (not the spaces), Register B = 00H, Register C and Register A = the character that ended the field, and the Z FLAG is set when at least one character was stored. The operand 5607H holds Register B until the first character is stored, then 00H.
55C0
LD A,B 78
Copy Register B (the most characters of the field) into Register A. Called from 557DH and 55A1H.
55C1
LD (5607H),A 32 07 56
Self-Modifying Code
Store Register A (the most characters) to 5607H, the operand of LD A,00H at 5606H: the NZ FLAG there when nothing is stored (Register B is not 00H; from 55B8H it is, so that call returns the Z FLAG even with nothing stored).
55C4
INC B 04
Increment Register B: the count is one more than the room, for the DEC B below.
55C5
LD A,(HL) 7E
Loop Start
Fetch the next character of the text from Register Pair HL into Register A. 55F6H and 55F9H come back here.
55C6
CP 03H FE 03
Compare Register A (the character) against 03H, the end of a text.
55C8
If the Z FLAG is set (03H), JUMP to 55FBH to end the field without passing over it.
55CA
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the carriage return.
55CC
If the Z FLAG is set (0DH), JUMP to 55FBH to end the field without passing over it.
55CE
CP 28H FE 28
Compare Register A (the character) against 28H, an opening parenthesis.
55D0
If the Z FLAG is set (an opening parenthesis), JUMP to 55FBH to end the field without passing over it.
55D2
INC HL 23
Increment Register Pair HL past the character in Register A.
55D3
CP 30H FE 30
Compare Register A (the character) against 30H, the digit 0.
55D5
If the CARRY FLAG is set (below 0: a space, a comma, a period, a slash, a pound sign), JUMP to 55FBH to end the field.
55D7
CP 3AH FE 3A
Compare Register A (the character) against 3AH, one past the digit 9.
55D9
If the CARRY FLAG is set (a digit 0-9), JUMP to 55EDH to store it.
55DB
CP 41H FE 41
Compare Register A (the character) against 41H, the letter A.
55DD
If the CARRY FLAG is set (3AH-40H: a colon, an equals sign, a question mark), JUMP to 55FBH to end the field.
55DF
CP 5BH FE 5B
Compare Register A (the character) against 5BH, one past the letter Z.
55E1
If the CARRY FLAG is set (a capital letter), JUMP to 55EDH to store it.
55E3
CP 61H FE 61
Compare Register A (the character) against 61H, the small letter a.
55E5
If the CARRY FLAG is set (5BH-60H), JUMP to 55FBH to end the field.
55E7
CP 7BH FE 7B
Compare Register A (the character) against 7BH, one past the small letter z.
55E9
If the NO CARRY FLAG is set (7BH and up), JUMP to 55FBH to end the field.
55EB
SUB 20H D6 20
Subtract 20H from Register A: the small letter becomes a capital.
55ED
DEC B 05
Decrement Register B, the room left plus one. 55D9H and 55E1H come here.
55EE
If the Z FLAG is set (no room left), JUMP to 55F8H to pass over the character without storing it.
55F0
LD (DE),A 12
Store Register A (the letter or digit) to Register Pair DE.
55F1
XOR A AF
Set Register A to 00H, the mark that a character has been stored.
55F2
LD (5607H),A 32 07 56
Self-Modifying Code
Store Register A (00H) to 5607H, the operand of LD A,00H at 5606H: the field is not empty, so the routine will return the Z FLAG.
55F5
INC DE 13
Increment Register Pair DE to the next byte of the field.
55F6
LOOP BACK to 55C5H for the next character of the field at Register Pair HL.
55F8
INC B 04
Increment Register B back to 01H: the field stays full and the extra characters are passed over.
55F9
LOOP BACK to 55C5H for the next character, which is passed over in the same way.
55FB
LD C,A 4F
Copy Register A (the character that ended the field) into Register C. Seven rows come here: 55C8H, 55CCH, 55D0H, 55D5H, 55DDH, 55E5H and 55E9H.
55FC
PUSH DE D5
Save Register Pair DE (the end of the characters stored) to the stack.
55FD
JUMP to 5603H: the first DJNZ drops the extra one of Register B.
55FF
LD A,20H 3E 20
Load Register A with 20H, a space, for the room left in the field.
5601
LD (DE),A 12
Store Register A (a space) to Register Pair DE.
5602
INC DE 13
Increment Register Pair DE to the next byte of the field.
5603
Decrement Register B and LOOP BACK to 55FFH while room is left: the field is padded with spaces and Register B ends at 00H.
5605
POP DE D1
Restore Register Pair DE from the stack: the end of the characters stored, before the spaces.
5606
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand 5607H: the most characters (written by 55C1H) when nothing was stored, 00H (written by 55F2H) when something was.
5608
OR A B7
OR Register A with itself: the Z FLAG is set when a character was stored (or when Register B was 00H on entry).
5609
LD A,C 79
Copy Register C (the character that ended the field) into Register A; the flags are kept.
560A
RET C9
RETURN with Register A = the character that ended the field, the Z FLAG for a field that is not empty.
560BH - Add a Symbol to the Table
Register Pair DE = the end marker of the symbol table (a byte 00H). An entry is 41 bytes: the name in 8 characters, the length of the value, then 32 bytes of value. The name at 56F2H is copied in, the length is set to 00H (no value) and a new end marker 00H is put 41 bytes after the start of the entry. Returns Register Pair DE at the entry's length byte. Nothing limits the growth of the table from 5C00H up.
560B
PUSH HL E5
Save Register Pair HL (the caller's place in the text) to the stack. Called from 52EDH, 54FFH and 5524H.
560C
LD HL,56F2H 21 F2 56
Point Register Pair HL to 56F2H, the name just read.
560F
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of a name.
5612
LDIR ED B0
Copy the 8 characters from Register Pair HL (56F2H) to the new entry at Register Pair DE, counted by Register Pair BC: Register Pair DE ends at the entry's length byte.
5614
XOR A AF
Set Register A to 00H, the length of an empty value and the end marker of the table.
5615
LD (DE),A 12
Store Register A (00H) to the entry's length byte at Register Pair DE: the symbol is defined with no value.
5616
LD HL,0021H 21 21 00
Load Register Pair HL with 0021H, the 33 bytes from the length byte to the start of the next entry.
5619
ADD HL,DE 19
Add Register Pair DE (the length byte) to Register Pair HL: Register Pair HL = the byte after the entry.
561A
LD (HL),A 77
Store Register A (00H) to the byte at Register Pair HL: the new end marker of the table.
561B
POP HL E1
Restore Register Pair HL from the stack: the caller's place in the text.
561C
RET C9
RETURN with Register Pair DE at the length byte of the new entry.
561DH - Store the Value of a Symbol
Register Pair DE = an entry's length byte. The length at 56FAH and the 32 bytes of the value buffer 56FBH-571AH are copied there.
561D
PUSH HL E5
Save Register Pair HL (the caller's place in the text) to the stack. Called from 5309H and 5533H.
561E
LD HL,56FAH 21 FA 56
Point Register Pair HL to 56FAH, the length of the value just read, followed by the value.
5621
LD BC,0021H 01 21 00
Load Register Pair BC with 0021H, the length byte and the 32 bytes of the value.
5624
LDIR ED B0
Copy 33 bytes from Register Pair HL (56FAH-571AH) to the entry at Register Pair DE, counted by Register Pair BC.
5626
POP HL E1
Restore Register Pair HL from the stack: the caller's place in the text.
5627
RET C9
RETURN with the symbol's length and value stored.
5628H - Find the Symbol Named at 56F2H
Searches the symbol table at 5C00H (5660H with Register B = 08H and Register C = 29H, 41 bytes an entry). Returns the Z FLAG with Register Pair DE at the entry's length byte when the name is there, the NZ FLAG with Register Pair DE at the end marker when it is not. Register Pair HL is kept.
5628
PUSH HL E5
Save Register Pair HL (the caller's place in the text) to the stack. Six rows call this routine: 52E7H, 5381H, 54EFH, 54FCH, 550BH and 5521H.
5629
LD DE,56F2H 11 F2 56
Point Register Pair DE to 56F2H, the name to look for.
562C
LD HL,5C00H 21 00 5C
Point Register Pair HL to 5C00H, the first entry of the symbol table.
562F
LD B,08H 06 08
Load Register B with 08H, the characters of a name.
5631
LD C,29H 0E 29
Load Register C with 29H, the 41 bytes of an entry.
5633
GOSUB to 5660H to search the table at Register Pair HL for the name at Register Pair DE: Register Pair HL returns at the entry's length byte (Z FLAG) or at the end marker (NZ FLAG).
5636
LD D,H 54
Copy Register H into Register D; the flags are kept.
5637
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the entry's length byte, or the end marker.
5638
POP HL E1
Restore Register Pair HL from the stack: the caller's place in the text.
5639
RET C9
RETURN with the Z FLAG when the symbol is defined.
563AH - Find a Keyword of the First Table
Searches the table at 5435H (IF, ELSE, END: 6 characters and an address, 8 bytes an entry) for the word at 56F2H. Returns the Z FLAG with Register Pair DE = the address of the keyword's routine, or the NZ FLAG. Register Pair HL is kept.
563A
PUSH HL E5
Save Register Pair HL (the text after the word) to the stack. Called from 53BEH.
563B
LD DE,56F2H 11 F2 56
Point Register Pair DE to 56F2H, the word after the two slashes.
563E
LD HL,5435H 21 35 54
Point Register Pair HL to 5435H, the table of IF, ELSE and END.
5641
LD B,06H 06 06
Load Register B with 06H, the characters of a keyword in this table.
5643
LD C,08H 0E 08
Load Register C with 08H, the bytes of an entry.
5645
GOSUB to 5660H to search the table at Register Pair HL for the word at Register Pair DE: on a match Register Pair HL returns at the address of the routine with the Z FLAG.
5648
LD E,(HL) 5E
Fetch the low byte of the routine's address from Register Pair HL into Register E (a byte 00H of the end of the table when not found).
5649
INC HL 23
Increment Register Pair HL to the high byte of the routine's address in the entry.
564A
LD D,(HL) 56
Fetch the high byte of the routine's address from Register Pair HL into Register D: Register Pair DE = the routine; the flags of the search are kept.
564B
POP HL E1
Restore Register Pair HL from the stack: the text after the word.
564C
RET C9
RETURN with the Z FLAG and Register Pair DE = the routine when the keyword was found.
564DH - Find a Keyword of the Second Table
Searches the table at 544EH (SET, RESET, ASSIGN, INCLUDE, QUIT: 8 characters and an address, 10 bytes an entry) for the word at 56F2H. Returns the Z FLAG with Register Pair DE = the address of the keyword's routine, or the NZ FLAG. Register Pair HL is kept.
564D
PUSH HL E5
Save Register Pair HL (the text after the word) to the stack. Called from 53CEH.
564E
LD DE,56F2H 11 F2 56
Point Register Pair DE to 56F2H, the word after the two slashes.
5651
LD HL,544EH 21 4E 54
Point Register Pair HL to 544EH, the table of SET, RESET, ASSIGN, INCLUDE and QUIT.
5654
LD B,08H 06 08
Load Register B with 08H, the characters of a keyword in this table.
5656
LD C,0AH 0E 0A
Load Register C with 0AH, the bytes of an entry.
5658
GOSUB to 5660H to search the table at Register Pair HL for the word at Register Pair DE: on a match Register Pair HL returns at the address of the routine with the Z FLAG.
565B
LD E,(HL) 5E
Fetch the low byte of the routine's address from Register Pair HL into Register E (a byte 00H of the end of the table when not found).
565C
INC HL 23
Increment Register Pair HL to the high byte of the routine's address in the entry.
565D
LD D,(HL) 56
Fetch the high byte of the routine's address from Register Pair HL into Register D: Register Pair DE = the routine; the flags of the search are kept.
565E
POP HL E1
Restore Register Pair HL from the stack: the text after the word.
565F
RET C9
RETURN with the Z FLAG and Register Pair DE = the routine when the keyword was found.
5660H - Search a Table of Names
Register Pair HL = the table, Register Pair DE = the word (56F2H, padded with spaces), Register B = the characters of a name in the table, Register C = the bytes of an entry. A byte 00H in the place of a name ends the table: the NZ FLAG and Register A = 01H, Register Pair HL at that byte. An entry matches when its first character equals the word's and the next Register B characters (positions 1 to Register B) agree, except that where the word has a space or a carriage return, or a character that differs and is not a capital letter or a digit, the table's name must have a space there. Then Register Pair HL returns at the entry plus Register B (the address of a keyword's routine, or a symbol's length byte) with the Z FLAG and Register A = 00H. For the symbol table Register B = 08H, so an 8 character name is also compared at position 8: the byte 56FAH (the length of the last value read) against the entry's length byte.
5660
LD A,(HL) 7E
Loop Start
Fetch the first byte of the entry at Register Pair HL into Register A. 566FH comes back here for the next entry.
5661
OR A B7
OR Register A with itself: the Z FLAG is set for a byte 00H, the end of the table.
5662
If the NZ FLAG is set (an entry), JUMP to 5666H to compare it.
5664
INC A 3C
Increment Register A from 00H to 01H: the NZ FLAG is set.
5665
RET C9
RETURN with the NZ FLAG and Register A = 01H: the word is not in the table, and Register Pair HL is at the end marker.
5666
LD A,(DE) 1A
Fetch the first character of the word from Register Pair DE into Register A.
5667
CP (HL) BE
Compare Register A (the word's first character) against the entry's first character at Register Pair HL.
5668
If the Z FLAG is set (the first characters are equal), JUMP to 5671H to compare the rest.
566A
PUSH BC C5
Save Register Pair BC (Register B the name's characters, Register C the entry's bytes) to the stack. 56A7H comes here when the rest did not match.
566B
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the entry's bytes.
566D
ADD HL,BC 09
Add Register Pair BC (the size of an entry) to Register Pair HL: Register Pair HL = the next entry.
566E
POP BC C1
Restore Register Pair BC from the stack: Register B the name's characters again.
566F
LOOP BACK to 5660H to look at the next entry.
5671
PUSH HL E5
Save Register Pair HL (the start of the entry) to the stack.
5672
PUSH DE D5
Save Register Pair DE (the start of the word) to the stack.
5673
PUSH BC C5
Save Register Pair BC (Register B the count, Register C the size) to the stack.
5674
INC DE 13
Loop Start
Increment Register Pair DE to the next character of the word. 5682H comes back here.
5675
INC HL 23
Increment Register Pair HL to the next character of the entry's name.
5676
LD A,(DE) 1A
Fetch the character of the word from Register Pair DE into Register A.
5677
CP 20H FE 20
Compare Register A (the word's character) against 20H, a space: the end of the word.
5679
If the Z FLAG is set (the word has ended), JUMP to 569FH, where the entry's name must have ended too.
567B
CP 0DH FE 0D
Compare Register A (the word's character) against 0DH, a carriage return.
567D
If the Z FLAG is set (a carriage return), JUMP to 569FH, where the entry's name must have ended.
567F
CP (HL) BE
Compare Register A (the word's character) against the entry's character at Register Pair HL.
5680
If the NZ FLAG is set (they differ), JUMP to 568FH.
5682
Decrement Register B and LOOP BACK to 5674H while characters are left to compare.
5684
POP BC C1
Restore Register Pair BC from the stack: Register B the name's characters, Register C the entry's bytes. 56A2H comes here on a match.
5685
POP DE D1
Restore Register Pair DE from the stack: the start of the word.
5686
POP HL E1
Restore Register Pair HL from the stack: the start of the matching entry.
5687
PUSH BC C5
Save Register Pair BC (the count and the size) to the stack.
5688
LD C,B 48
Copy Register B (the name's characters, 06H or 08H) into Register C.
5689
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the name's characters.
568B
ADD HL,BC 09
Add Register Pair BC (the length of the name) to Register Pair HL: Register Pair HL = the byte after the name in the entry.
568C
POP BC C1
Restore Register Pair BC from the stack: the count and the size as given.
568D
XOR A AF
Set Register A to 00H with the Z FLAG set: a match.
568E
RET C9
RETURN with the Z FLAG, Register A = 00H and Register Pair HL past the name in the entry.
568F
CP 30H FE 30
Compare Register A (the word's character, which differs) against 30H, the digit 0. 5680H comes here.
5691
If the CARRY FLAG is set (below 0: not a letter or digit, or a small value such as the length byte 56FAH), JUMP to 569FH, where the entry's name must have a space.
5693
CP 3AH FE 3A
Compare Register A (the word's character) against 3AH, one past the digit 9.
5695
If the CARRY FLAG is set (a digit), JUMP to 56A4H: a different digit, no match.
5697
CP 41H FE 41
Compare Register A (the word's character) against 41H, the letter A.
5699
If the CARRY FLAG is set (3AH-40H), JUMP to 569FH, where the entry's name must have a space.
569B
CP 5BH FE 5B
Compare Register A (the word's character) against 5BH, one past the letter Z.
569D
If the CARRY FLAG is set (a letter), JUMP to 56A4H: a different letter, no match.
569F
LD A,(HL) 7E
Fetch the entry's character from Register Pair HL into Register A. 5679H, 567DH, 5691H and 5699H come here.
56A0
CP 20H FE 20
Compare Register A (the entry's character) against 20H, a space: the entry's name ends here too.
56A2
If the Z FLAG is set (the names end together), JUMP to 5684H: a match.
56A4
POP BC C1
Restore Register Pair BC from the stack: the count and the size. 5695H and 569DH come here.
56A5
POP DE D1
Restore Register Pair DE from the stack: the start of the word.
56A6
POP HL E1
Restore Register Pair HL from the stack: the start of the entry that did not match.
56A7
JUMP to 566AH to step Register Pair HL on to the next entry of the table.
56A9H - Error Exits
56A9H shows the message of the error code in Register A (with bit 6 set: the text alone; bit 7 is clear, so SYS4/SYS goes on to the abort exit 4030H). The other four display one of the member's own messages with 447BH (on the display and in the job log) and abort at 4030H.
56A9
OR 40H F6 40
OR Register A (the error code) with 40H: bit 6 asks for the text of the message alone. Six rows jump here: 5234H, 52B9H, 52CCH, 53FFH, 542BH and 5597H.
56AB
JUMP to 4409H to display the message of the error in Register A; as bit 7 is clear, the command then ends at the abort exit 4030H.
56AE
LD HL,5726H 21 26 57
Point Register Pair HL to 5726H, the message FILE SPEC REQUIRED! ended by 0DH (from 521FH).
56B1
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
56B4
JUMP to 4030H, the abort exit: CHAIN ends without a file specification.
56B7
LD HL,573AH 21 3A 57
Point Register Pair HL to 573AH, the message CANT CREATE SYSTEM, seven bytes 01H and /JCL FILE! ended by 0DH (from 524DH).
56BA
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
56BD
JUMP to 4030H, the abort exit: SYSTEM/JCL could not be opened or created.
56C0
LD HL,575EH 21 5E 57
Point Register Pair HL to 575EH, the message PARAMETER ERROR ended by 0DH (from 5266H, 5276H and 5302H).
56C3
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
56C6
JUMP to 4030H, the abort exit: the parameters of the command line are wrong.
56C9
LD HL,576EH 21 6E 57
Point Register Pair HL to 576EH, the message MULTIPLY DEFINED PARAMETER! ended by 0DH (from 52EAH).
56CC
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
56CF
JUMP to 4030H, the abort exit: a parameter name was given twice.
56D2H - Work Area Between the Load Blocks
56D2H-571AH (73 bytes) is not in the file: the control block of the JCL file being read, then the name buffer, the length of the last value and the value buffer, which 561DH copies as one 33 byte block into a symbol table entry.
56D2-56F1
DEFS 32
Not in the file: the control block of the JCL file being read. 5219H-5231H fill and open it for the main file, 5539H-555FH save it on the include stack and open an included file in it, 5293H copies it back from the include stack, 53EEH reads the bytes through it and 529CH positions it again.
56F2-56F9
DEFS 8
Not in the file: the name buffer. 5577H writes each name or keyword read (upper case, padded with spaces); 5628H, 563AH and 564DH look it up and 560BH copies it into a new symbol table entry.
56FA
DEFS 1
Not in the file: the length of the last value read (00H-20H), written by 559AH and copied with the value by 561DH. 5660H also compares it with an entry's length byte when the symbol name has 8 characters.
56FB-571A
DEFS 32
Not in the file: the value buffer. 5582H reads a value here (padded with spaces by 55C0H), 536FH stores substitutions in it, and 561DH copies it into the symbol table entry.
571BH - Texts
The specification of the compiled file and the member's messages, each ended by 0DH for 447BH.
571B-5721
DEFM "SYSTEM/" 53 59 53 54 45 4D 2F
The start of the file specification SYSTEM/JCL that 5237H-5240H copy into the control block 4358H.
5722-5725
DEFM "JCL" / DEFB 03H 4A 43 4C 03
The extension of SYSTEM/JCL and the 03H that ends the specification. 5226H, 52CFH and 5554H also point here: the three letters JCL are the default extension for 4473H.
5726-5739
DEFM "FILE SPEC REQUIRED!" / DEFB 0DH 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44 21 0D
The message FILE SPEC REQUIRED! that 56AEH displays when no file specification follows CHAIN.
573A-574B
DEFM "CANT CREATE SYSTEM" 43 41 4E 54 20 43 52 45 41 54 45 20 53 59 53 54 45 4D
The first part of the message that 56B7H displays when SYSTEM/JCL can be neither opened nor created.
574C-5752
DEFB 01H,01H,01H,01H,01H,01H,01H 01 01 01 01 01 01 01
Seven bytes 01H, control codes and not printable characters, in the middle of the message; 44E0H sends them on like any byte other than 03H and 0DH. The distributor's manual lists a patch for this message (D14,3B=01 01 01 01 01 01: record 14H byte 3BH of SYS6/SYS, the file offset 143BH, which loads at 574CH) that writes six of them.
5753-575D
DEFM "/JCL FILE!" / DEFB 0DH 2F 4A 43 4C 20 46 49 4C 45 21 0D
The end of the message started at 573AH, /JCL FILE!, and the carriage return that ends it.
575E-576D
DEFM "PARAMETER ERROR" / DEFB 0DH 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52 0D
The message PARAMETER ERROR that 56C0H displays for wrong characters on the command line or BREAK at the question mark.
576E-5789
DEFM "MULTIPLY DEFINED PARAMETER!" / DEFB 0DH 4D 55 4C 54 49 50 4C 59 20 44 45 46 49 4E 45 44 20 50 41 52 41 4D 45 54 45 52 21 0D
The message MULTIPLY DEFINED PARAMETER! that 56C9H displays for a parameter name given twice.
578A-57B1
DEFM "INVALID JCL FORMAT, PROCESSING ABORTED!" / DEFB 0DH 49 4E 56 41 4C 49 44 20 4A 43 4C 20 46 4F 52 4D 41 54 2C 20 50 52 4F 43 45 53 53 49 4E 47 20 41 42 4F 52 54 45 44 21 0D
The message INVALID JCL FORMAT, PROCESSING ABORTED! that 53AFH displays after the line in error.
57B2H - Include Stack
The pointer and the stack where //INCLUDE saves the control block of the file it leaves.
57B2-57B3
DEFW 57B4H B4 57
The include stack pointer, 57B4H in the file (the stack empty): the address just past the last saved control block. 5546H raises it by 32 for each //INCLUDE, 5296H lowers it at the end of an included file, and 527EH compares it with 57B4H.
57B4-58F3
DEFS 320
Not in the file: the include stack, 32 bytes for each level of //INCLUDE (room for ten). 5544H copies the control block 56D2H here, 5293H copies it back. Nothing tests the depth: an eleventh level goes over 58F4H-58F6H.
58F4H - Condition Stack
One state byte for each open //IF block: 00H true, FFH false.
58F4-58F5
DEFW 58F6H F6 58
The condition stack pointer, 58F6H in the file: the address of the current block's state. 549CH raises it for //IF, 54CAH lowers it for //END; 53C5H, 5406H, 54AEH and 5496H read the state it points to.
58F6
DEFB 00H 00
The bottom of the condition stack: the state 00H (true) of the lines outside every //IF block. 54A5H and 54BDH compare the pointer with 58F6H to find an //ELSE or //END with no //IF.
58F7-5915
DEFS 31
Not in the file: the rest of the condition stack, one byte for each open //IF (room for 31 levels). Nothing tests the depth: deeper blocks run on over 5916H and the line buffer.
5916H - Arrow and Line Buffer
The arrow in front of the line buffer, so that 53A9H can display both as one text.
5916-5918
DEFM "-->" 2D 2D 3E
The arrow, two minus signs and a greater than sign, that 53A9H displays in front of the line in error; the text runs on into the line at 5919H.
5919-5958
DEFS 64
Not in the file: the line buffer. 53E8H reads each line of the JCL file here up to its 0DH (no length test), 5340H moves it up by two bytes for //PAUSE, 5318H-53E5H read it and 53A9H and 5568H display it.
5959-59FF
DEFS 167
Not in the file: the output line. 531BH-5339H and 536FH build the compiled line here, 53D5H-53E3H copy the start of a line with two slashes, and 5406H writes it to SYSTEM/JCL or displays it.
5A00-5AFF
DEFS 256
Not in the file: the sector buffer of the JCL file being read (the main file and every included one), given to the open at 522EH and 555AH.
5B00-5BFF
DEFS 256
Not in the file: the sector buffer of SYSTEM/JCL during the compile, given to the open at 5247H.
5C00H - Symbol Table
The symbols defined by the parameters, //SET and //ASSIGN: 41 bytes an entry (the name in 8 characters, the length of the value, 32 bytes of value), ended by a byte 00H in the place of a name. The member is loaded again for each CHAIN, so the table starts empty each time.
5C00
DEFB 00H 00
The end marker of the empty symbol table, loaded by the file: 5660H stops at a byte 00H. 560BH writes each new entry over the end marker and puts a new one 41 bytes on.
5C01-5C29
DEFS 41
Not in the file: the rest of the first entry and the end marker after it. Each further symbol takes 41 more bytes; nothing limits the table's growth upward from here.
5200H - Member 13 (SYSTEM, Code A1H): Read the Parameters
SYSTEM is entered at 5200H from SYS0/SYS's request handler (request 88H, member code A1H) with Register Pair HL pointing at the text after the command word, Register B = A1H and Register A = the code from 430EH; the stack holds 4C4BH (the request handler) and then normally 402DH (VTOS READY). SYS1/SYS's 510FH (through 4476H) reads the parameter list against the table at 5679H and stores each given value into the operand of the LD BC or LD HL instruction named by the table: FFFFH for a name alone or Y/ON, 0000H for N/OFF, the number for =n. The options are then taken one after another in the order SLOW, FAST, BASIC2, BREAK, BLINK (with SMALL), TYPE, LOWER, JKL (with GRAPHIC), ALIVE, DRIVE (with DISABLE, ENABLE, STEP, DELAY) and SYSGEN, each test reading the operand that 510FH may have written.
5200
LD DE,5679H 11 79 56
Point Register Pair DE to 5679H, the parameter table of SYSTEM (18 entries of 8 bytes: 6 characters of name, then the address of the operand that takes the value), for the call below. Register Pair HL still points at the parameter text after the command word.
5203
GOSUB to 4476H (request E3H, SYS1/SYS's 510FH): read the list in parentheses from the text at Register Pair HL against the table at Register Pair DE (5679H), storing each value into the operand the table names. The Z FLAG comes back set when the list is good or absent.
5206
If the NZ FLAG is set (an unknown name or a bad value in the list), JUMP to 5660H to display PARAMETER ERROR and abort.
5209H - SLOW and FAST: the Clock Speed
SLOW is tested first: any value other than 0000H clears bit 3 (fast clock) of the system flags 430FH and outputs 00H to port FEH; FAST is then not looked at. Otherwise FAST with a value other than 0000H sets 430FH bit 3 and outputs 01H to port FEH. The port FEH output is the one SYS0/SYS's reset code at 405DH also writes for a fast clock; bit 3 of 430FH makes SYS0/SYS's drive select wait twice as long (462FH).
5209
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of SLOW: the operand 520AH-520BH is 0000H in the file and is written by SYS1/SYS's 510FH during the CALL 4476H at 5203H when SLOW is given (FFFFH for SLOW alone).
520C
LD A,B 78
Copy Register B (the high byte of the SLOW value) into Register A, to test the whole value.
520D
OR C B1
OR Register C (the low byte of the SLOW value) into Register A: the Z FLAG is set only when Register Pair BC is 0000H, SLOW not given or given as N.
520E
If the NZ FLAG is set (SLOW was given), JUMP to 5224H to switch to the standard clock.
5210
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of FAST: the operand 5211H-5212H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when FAST is given.
5213
LD A,B 78
Copy Register B (the high byte of the FAST value) into Register A, to test the whole value.
5214
OR C B1
OR Register C (the low byte of the FAST value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, FAST not given.
5215
If the Z FLAG is set (no FAST), JUMP to 522EH and go on with BASIC2.
5217
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte, whose bit 3 is the fast clock flag.
521A
DI F3
Disable interrupts so that the interrupt routine does not see the flag change before the port is written.
521B
SET 3,(HL) CB DE
Set bit 3 of the system flags at Register Pair HL (430FH): the fast clock is on, which doubles SYS0/SYS's drive select wait (462FH).
521D
LD A,01H 3E 01
Load Register A with 01H, the value for port FEH that selects the fast clock.
521F
EI FB
Enable interrupts again; the EI takes effect after the next instruction, so the OUT below still runs with interrupts off.
5220
OUT (FEH),A D3 FE
Output Register A (01H) to port FEH, switching the processor to the fast clock, the same output the code SYS0/SYS's reset places at 405DH makes.
5222
JUMP to 522EH and go on with the BASIC2 test, the fast clock being switched on.
5224
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte (SLOW given).
5227
DI F3
Disable interrupts while the flag and the port are changed.
5228
RES 3,(HL) CB 9E
Clear bit 3 of the system flags at Register Pair HL (430FH): the fast clock flag is off.
522A
XOR A AF
Set Register A to 00H, the value for port FEH that selects the standard clock.
522B
EI FB
Enable interrupts again; it takes effect after the OUT below.
522C
OUT (FEH),A D3 FE
Output Register A (00H) to port FEH, switching the processor to the standard clock speed.
522EH - BASIC2: Restart the ROM's BASIC
A BASIC2 value other than 0000H does what the ROM's power up code does at 0674H-068AH (copy the 36H bytes at 06D2H to 4000H-4035H and zero the 27H bytes 4036H-405CH) and then jumps to 0075H, where the ROM's power up code goes when BREAK is held (068BH-0690H): the ROM's own BASIC starts and VTOS is left. The options after BASIC2 are not processed.
522E
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of BASIC2: the operand 522FH-5230H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when BASIC2 is given.
5231
LD A,B 78
Copy Register B (the high byte of the BASIC2 value) into Register A, to test the whole value.
5232
OR C B1
OR Register C (the low byte of the BASIC2 value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, BASIC2 not given.
5233
If the Z FLAG is set (no BASIC2), JUMP to 524BH and go on with BREAK.
5235
LD HL,06D2H 21 D2 06
Point Register Pair HL to 06D2H in the ROM, the 36H bytes the ROM's power up code copies to 4000H (its 0676H): the restart vectors and device control blocks of the ROM.
5238
LD DE,4000H 11 00 40
Point Register Pair DE to 4000H, the start of the ROM's communication area, where the copy goes.
523B
LD BC,0036H 01 36 00
Load Register Pair BC with 0036H, the 54 bytes of the ROM's table.
523E
LDIR ED B0
Copy the 54 bytes from Register Pair HL (06D2H) to Register Pair DE (4000H): the VTOS vectors and control blocks at 4000H-4035H become the ROM's. Register Pair DE ends at 4036H and Register Pair BC at 0000H.
5240
XOR A AF
Set Register A to 00H, the byte that clears the area below.
5241
LD B,27H 06 27
Load Register B with 27H, the count of the 39 bytes 4036H-405CH to clear, as the ROM does at 0685H.
5243
LD (DE),A 12
Loop Start
Store Register A (00H) to the byte at Register Pair DE (4036H up to 405CH).
5244
INC DE 13
Increment Register Pair DE to the next byte to clear.
5245
Decrement Register B and LOOP BACK to 5243H until Register B is 00H: 4036H-405CH (the keyboard image, the clock and the interrupt vectors of VTOS) are all 00H.
5247
DI F3
Disable interrupts: the VTOS interrupt routine and its vectors are gone.
5248
JUMP to 0075H in the ROM, the place the ROM's power up code goes when BREAK is held: the ROM's BASIC starts from the beginning and VTOS is no longer in control.
524BH - BREAK: Turn the BREAK Key On or Off
The BREAK value 0001H (the file's) means not given. 0000H (BREAK=N or OFF) stores C8H (RET Z) at 4C2DH, so that a BREAK key code (request 01H) comes back from SYS0/SYS's handler as 00H, and sets 430FH bit 4, so that the interrupt routine (4561H) ignores BREAK. A value whose bytes OR to FFH (BREAK alone, Y or ON) stores 00H (NOP) at 4C2DH and clears 430FH bit 4. Any other number (BREAK=1, BREAK=5) is taken as not given. In the first two cases the routine ends with RET: the command ends there and BLINK, TYPE, LOWER, JKL, ALIVE, DRIVE and SYSGEN in the same list are not processed.
524B
LD BC,0001H 01 01 00
Self-Modifying Code
Load Register Pair BC with the value of BREAK: the operand 524CH-524DH is 0001H in the file (BREAK not given) and is written by 510FH (CALL 4476H at 5203H): FFFFH for BREAK alone or BREAK=Y, 0000H for BREAK=N.
524E
LD A,B 78
Copy Register B (the high byte of the BREAK value) into Register A, to combine both bytes.
524F
OR C B1
OR Register C (the low byte of the BREAK value) into Register A: Register A = 00H with the Z FLAG for BREAK=N, FFH for BREAK=Y, 01H when BREAK was not given.
5250
If the Z FLAG is set (BREAK=N), JUMP to 5262H to turn the BREAK key off.
5252
INC A 3C
Increment Register A: 00H with the Z FLAG only when Register A was FFH (BREAK or BREAK=Y).
5253
If the NZ FLAG is set (BREAK not given, or given as a number whose two bytes OR to neither 00H nor FFH), JUMP to 526FH and go on with BLINK.
5255
LD A,00H 3E 00
Load Register A with 00H, the NOP opcode to put at 4C2DH (BREAK key on).
5257
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte, whose bit 4 makes the interrupt routine ignore BREAK.
525A
DI F3
Disable interrupts while SYS0/SYS's BREAK code is changed.
525B
LD (4C2DH),A 32 2D 4C
Store Register A (00H, NOP) to 4C2DH in SYS0/SYS's handler for requests below 80H: the BREAK request 01H is passed on as 01H again.
525E
EI FB
Enable interrupts again, the BREAK request code at 4C2DH being changed.
525F
RES 4,(HL) CB A6
Clear bit 4 of the system flags at Register Pair HL (430FH): the interrupt routine acts on BREAK again (4561H).
5261
RET C9
RETURN to the request handler (4C4BH), which returns to the caller, normally VTOS READY at 402DH, with Register A = 00H: the command ends here and the options after BREAK are not processed.
5262
LD A,C8H 3E C8
Load Register A with C8H, the opcode RET Z to put at 4C2DH (BREAK key off).
5264
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte, whose bit 4 makes the interrupt routine ignore BREAK.
5267
DI F3
Disable interrupts while SYS0/SYS's BREAK code is changed.
5268
LD (4C2DH),A 32 2D 4C
Store Register A (C8H, RET Z) to 4C2DH: SYS0/SYS's handler now returns a BREAK request 01H as 00H, so the key decoder's BREAK code is dropped.
526B
EI FB
Enable interrupts again, the BREAK request code at 4C2DH being changed.
526C
SET 4,(HL) CB E6
Set bit 4 of the system flags at Register Pair HL (430FH): the interrupt routine ignores the BREAK key (4561H).
526E
RET C9
RETURN to the request handler (4C4BH) and from there to the caller with Register A = C8H: the command ends here and the options after BREAK are not processed.
526FH - BLINK, SMALL and LARGE: Install the Blinking Cursor
The BLINK value 0001H (the file's) means not given; a value whose bytes OR to 01H (BLINK=1) is taken the same way. 0000H (BLINK=N) removes task slot 5. Any other value installs the cursor task: a value whose bytes OR to FFH (BLINK alone or BLINK=Y) uses the graphics block 8FH, or 88H when SMALL is given; any other value BLINK=n uses its low byte (when the high byte is 00H) as the cursor character. The character is put into three operands of the task, then 3EH bytes (52C7H-5304H, the 5 byte task control block and the task) are copied below the top of memory (4049H, lowered by 3EH) and the copy is installed in task slot 5. LARGE is accepted by the table but its value goes to 52C5H, which nothing reads. Nothing checks for a task already installed: each BLINK lowers the top of memory again.
526F
LD BC,0001H 01 01 00
Self-Modifying Code
Load Register Pair BC with the value of BLINK: the operand 5270H-5271H is 0001H in the file (BLINK not given) and is written by 510FH (CALL 4476H at 5203H): FFFFH for BLINK or BLINK=Y, 0000H for BLINK=N, the character for BLINK=n.
5272
LD A,B 78
Copy Register B (the high byte of the BLINK value) into Register A, to combine both bytes.
5273
OR C B1
OR Register C (the low byte of the BLINK value) into Register A: Register A = 01H when BLINK was not given, 00H for BLINK=N, FFH for BLINK=Y, the character for BLINK=n.
5274
DEC A 3D
Decrement Register A: the Z FLAG is set only when Register A was 01H, BLINK not given.
5275
If the Z FLAG is set (no BLINK), JUMP to 5305H and go on with TYPE.
5278
INC A 3C
Increment Register A back to the combined value: the Z FLAG is set when it is 00H (BLINK=N).
5279
If the NZ FLAG is set (BLINK or BLINK=n), JUMP to 5283H to install the cursor.
527B
LD A,05H 3E 05
Load Register A with 05H, the task slot of the blinking cursor.
527D
GOSUB to 4413H to remove the task in slot Register A (05H): the blinking stops. The copy in high memory stays where it is and the top of memory is not raised.
5280
JUMP to 5305H and go on with TYPE, the blinking cursor task being removed.
5283
NOP 00
No operation: the first of three 00H bytes executed here with Register A holding the combined BLINK value.
5284
NOP 00
No operation: the second of the three 00H bytes, Register A still holds the combined BLINK value.
5285
NOP 00
No operation: the third of the three 00H bytes, Register A still holds the combined BLINK value.
5286
CP FFH FE FF
Compare Register A (the combined BLINK value) against FFH, the value of BLINK alone or BLINK=Y.
5288
If the NZ FLAG is set (BLINK=n), JUMP to 5295H with Register A = the character n for the cursor.
528A
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of SMALL: the operand 528BH-528CH is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when SMALL is given.
528D
LD A,B 78
Copy Register B (the high byte of the SMALL value) into Register A, to test the whole value.
528E
OR C B1
OR Register C (the low byte of the SMALL value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, SMALL not given.
528F
LD A,8FH 3E 8F
Load Register A with 8FH, the large cursor: a graphics character with the top four of its six blocks lit. The LD does not change the Z FLAG from the OR above.
5291
If the Z FLAG is set (no SMALL), JUMP to 5295H with Register A = 8FH.
5293
LD A,88H 3E 88
Load Register A with 88H, the small cursor: a graphics character with only the middle right block lit.
5295
LD (52E6H),A 32 E6 52
Store Register A (the cursor character) to 52E6H, the operand of LD A,8FH at 52E5H in the task: the character the task shows at the cursor.
5298
LD (52F3H),A 32 F3 52
Store Register A (the cursor character) to 52F3H, the operand of CP 8FH at 52F2H in the task: the character the task looks for at the cursor before it puts the original back.
529B
LD (52FCH),A 32 FC 52
Store Register A (the cursor character) to 52FCH, the operand of CP 8FH at 52FBH in the task: the same test one line higher, after a scroll.
529E
LD BC,003EH 01 3E 00
Load Register Pair BC with 003EH, the 62 bytes to copy: the task control block 52C7H-52CBH and the task 52CCH-5304H.
52A1
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
52A4
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
52A5
SBC HL,BC ED 42
Subtract Register Pair BC (003EH) from Register Pair HL: Register Pair HL = the new top of memory, 62 bytes lower.
52A7
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top of memory) to 4049H-404AH, so that nothing else uses the 62 bytes above it.
52AA
INC HL 23
Increment Register Pair HL to the first byte above the new top of memory: the address of the copy, which is also its task control block.
52AB
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
52AC
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the copy, the destination of the LDIR.
52AD
LD HL,52C7H 21 C7 52
Point Register Pair HL to 52C7H, the task control block and task to copy (52C7H-52CBH are not loaded by the file; the first two bytes are written below after the copy).
52B0
LDIR ED B0
Copy the 62 bytes from Register Pair HL (52C7H) to Register Pair DE (the copy): Register Pair BC ends at 0000H.
52B2
POP DE D1
Restore Register Pair DE from the stack: the address of the copy (its task control block).
52B3
PUSH DE D5
Save Register Pair DE (the address of the copy) to the stack again for the install below.
52B4
LD HL,0005H 21 05 00
Load Register Pair HL with 0005H, the offset of the task routine (52CCH) from the control block (52C7H).
52B7
ADD HL,DE 19
Add Register Pair DE (the address of the copy) to Register Pair HL: Register Pair HL = the address of the copied task routine.
52B8
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copied task routine, Register Pair HL = the copied task control block.
52B9
LD (HL),E 73
Store Register E (the low byte of the routine's address) to the control block at Register Pair HL, its +00H.
52BA
INC HL 23
Increment Register Pair HL to the control block's +01H.
52BB
LD (HL),D 72
Store Register D (the high byte of the routine's address) to the control block at Register Pair HL: the control block's +00H-+01H now point at the copied task routine.
52BC
LD A,05H 3E 05
Load Register A with 05H, task slot 5, one of the slots the dispatcher runs every eighth tick.
52BE
POP DE D1
Restore Register Pair DE from the stack: the address of the copied task control block.
52BF
GOSUB to 4410H to install the task: slot Register A (05H), control block Register Pair DE.
52C2
JUMP to 5305H and go on with TYPE, the blinking cursor being installed.
52C5H - Bytes Not in the File: LARGE's Word and the Cursor Task's Control Block
The load blocks 5200H-52C4H and 52CCH-53C9H leave 52C5H-52CBH out of the file. 510FH writes the value of LARGE to 52C5H-52C6H, where nothing reads it, so LARGE has no effect of its own (the large cursor 8FH is the default anyway). 52C7H-52CBH are the 5 bytes of the blinking cursor's task control block: the LDIR at 52B0H copies whatever is in memory there together with the task, and only the copy's bytes are given values.
52C5-52C6
DEFS 2
Not in the file: the word into which SYS1/SYS's 510FH stores the value of LARGE (table entry 56A1H points at 52C5H). No instruction of the member reads 52C5H-52C6H, and the LDIR at 52B0H starts at 52C7H, so the value is not copied either.
52C7-52CB
DEFS 5
Not in the file: the task control block of the blinking cursor, copied with the task by the LDIR at 52B0H. In the copy (Index Register IX while the task runs): +00H-+01H the routine address (52B9H-52BBH, then rewritten by 4416H at 52CCH and 52E8H), +02H-+03H the cursor address taken from 4020H (52DBH-52DEH, read at 52EBH-52EEH), +04H the byte the cursor block covers (52D4H, 52E2H, read at 52FFH).
52CCH - The Blinking Cursor Task (Copied to High Memory)
This routine runs from its copy in high memory as the task in slot 5, which the dispatcher calls every eighth clock tick with Index Register IX pointing at the copied control block. It works in turns through 4416H, which makes the next call go on after the CALL: at one turn it saves the byte at the cursor (4020H) and puts the cursor character there (8FH, 88H or the BLINK=n character, put into the operands by 5295H-529BH), at the next turn it puts the saved byte back, either at the same place or one line higher when the screen has scrolled. Nothing is done while 4022H is 00H (no cursor shown by the display driver).
52CC
GOSUB to 4416H: the address after the CALL (the copy of 52CFH) becomes the routine address of this task in its control block (Index Register IX +00H-+01H) and the task returns to the dispatcher; the next call of slot 5 goes on at 52CFH.
52CF
LD A,(4022H) 3A 22 40
Fetch 4022H, byte +05H of the display device control block 401DH, into Register A: 00H when the display driver shows no cursor, else the character the cursor covers (the ROM's display driver keeps it there, 0487H-0490H).
52D2
OR A B7
OR Register A with itself: the Z FLAG is set when Register A (from 4022H) is 00H, no cursor on the screen.
52D3
RET Z C8
If the Z FLAG is set (no cursor), RETURN to the dispatcher; the next call comes back to 52CFH and tests again.
52D4
LD (IX+04H),A DD 77 04
Store Register A (the character under the cursor from 4022H) to +04H of the control block at Index Register IX. The store at 52E2H replaces it before it is read, so this value is never used.
52D7
LD BC,(4020H) ED 4B 20 40
Fetch the cursor address from 4020H-4021H (the display device control block's +03H-+04H) into Register Pair BC.
52DB
LD (IX+02H),C DD 71 02
Store Register C (the low byte of the cursor address) to +02H of the control block at Index Register IX.
52DE
LD (IX+03H),B DD 70 03
Store Register B (the high byte of the cursor address) to +03H of the control block at Index Register IX.
52E1
LD A,(BC) 0A
Fetch the byte on the screen at the cursor address, Register Pair BC, into Register A: the cursor character the display driver put there (5FH from the ROM's driver) or whatever has replaced it.
52E2
LD (IX+04H),A DD 77 04
Store Register A (the byte at the cursor) to +04H of the control block at Index Register IX, to be put back at the next turn.
52E5
LD A,8FH 3E 8F
Self-Modifying Code
Load Register A with the blinking cursor character: the operand 52E6H is 8FH in the file and in the copy holds the value 5295H stored before the copy was made (8FH large, 88H with SMALL, or the BLINK=n character).
52E7
LD (BC),A 02
Store Register A (the cursor character) to the screen at the cursor address in Register Pair BC: the cursor block is shown.
52E8
GOSUB to 4416H: the copy of 52EBH becomes this task's routine address in the control block at Index Register IX and the task returns to the dispatcher; the cursor block stays on the screen until the next call of slot 5.
52EB
LD C,(IX+02H) DD 4E 02
Fetch +02H of the control block at Index Register IX (the low byte of the saved cursor address) into Register C.
52EE
LD B,(IX+03H) DD 46 03
Fetch +03H of the control block at Index Register IX (the high byte of the saved cursor address) into Register B: Register Pair BC = the place the cursor block was put.
52F1
LD A,(BC) 0A
Fetch the byte now on the screen at Register Pair BC into Register A.
52F2
CP 8FH FE 8F
Self-Modifying Code
Compare Register A against the cursor character: the operand 52F3H is 8FH in the file and holds the character 5298H stored, so the Z FLAG is set when the block is still where it was put.
52F4
If the Z FLAG is set (the block is still there), JUMP to 52FFH to put the saved byte back.
52F6
LD A,C 79
Copy Register C (the low byte of the saved cursor address) into Register A.
52F7
SUB 40H D6 40
Subtract 40H (one line of 64 characters) from Register A. No borrow is carried into Register B, so for a cursor in the first 40H bytes of a 256 byte page the address tested is three lines lower, not one line higher.
52F9
LD C,A 4F
Copy Register A back into Register C: Register Pair BC = the same column one line higher, where the block is after a scroll.
52FA
LD A,(BC) 0A
Fetch the byte on the screen at Register Pair BC (one line higher) into Register A.
52FB
CP 8FH FE 8F
Self-Modifying Code
Compare Register A against the cursor character: the operand 52FCH is 8FH in the file and holds the character 529BH stored.
52FD
If the NZ FLAG is set (the block is not there either), JUMP to 52CCH and leave the screen as it is: the block was overwritten.
52FF
LD A,(IX+04H) DD 7E 04
Fetch the saved byte from +04H of the control block at Index Register IX into Register A.
5302
LD (BC),A 02
Store Register A (the saved byte) to the screen at Register Pair BC: the cursor block is taken away.
5303
JUMP to 52CCH, whose CALL 4416H makes the next call of slot 5 start a new turn at 52CFH.
5305H - TYPE: Install the Type-Ahead Keyboard Driver
The TYPE value 0001H (the file's) means not given; 0000H (TYPE=N) only removes task slot 10. Any other value refuses to run under BASIC (5627H), keeps 259 bytes below the top of memory (a busy flag, the put and take indexes and a 256 byte buffer of 128 two byte entries: key and flags) and copies 53A9H-547EH (D6H bytes) below them. The copy holds a new keyboard driver (53A9H), the type-ahead task (53D7H-5425H) and a key decoder without delays (5426H). The keyboard device control block 4015H (or SYS7/SYS's saved driver at 43BEH while a DO file runs) gets the new driver, SYS0/SYS's CALL 03FAH at 4BC0H is pointed at the copied decoder, 439CH is made LD HL,4300H so that SYS0/SYS's own driver no longer calls the keyboard hook, and the task goes into slot 10. TYPE=N leaves all of these changes in place.
5305
LD BC,0001H 01 01 00
Self-Modifying Code
Load Register Pair BC with the value of TYPE: the operand 5306H-5307H is 0001H in the file (TYPE not given) and is written by 510FH (CALL 4476H at 5203H): FFFFH for TYPE alone, 0000H for TYPE=N.
5308
LD A,B 78
Copy Register B (the high byte of the TYPE value) into Register A, to combine both bytes.
5309
OR C B1
OR Register C (the low byte of the TYPE value) into Register A: Register A = 01H when TYPE was not given, 00H for TYPE=N.
530A
DEC A 3D
Decrement Register A: the Z FLAG is set only when Register A was 01H, TYPE not given.
530B
If the Z FLAG is set (no TYPE), JUMP to 547FH and go on with LOWER.
530E
INC A 3C
Increment Register A back to the combined value: the Z FLAG is set when it is 00H (TYPE=N).
530F
If the NZ FLAG is set (TYPE or TYPE=Y), JUMP to 5319H to install the type-ahead.
5311
LD A,0AH 3E 0A
Load Register A with 0AH, the task slot of the type-ahead task.
5313
GOSUB to 4413H to remove the task in slot Register A (0AH). The copied driver, the 4BC1H pointer and the 439CH byte are not put back, so key input still goes through the copy (with an empty buffer).
5316
JUMP to 547FH and go on with LOWER, the type-ahead task being removed.
5319
GOSUB to 5627H: when 402DH holds C3H (a JP put there by BASIC/CMD), CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL is displayed and the command aborts; otherwise it returns.
531C
LD IX,4015H DD 21 15 40
Point Index Register IX to 4015H, the keyboard device control block, whose +00H-+05H are set below.
5320
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
5323
DEC H 25
Decrement Register H: Register Pair HL = the top of memory less 0100H, the take index of the type-ahead buffer; the 256 bytes above it are the buffer.
5324
LD (HL),00H 36 00
Store 00H to the byte at Register Pair HL (top less 0100H): the take index starts at the buffer's first entry.
5326
DEC HL 2B
Decrement Register Pair HL to the top of memory less 0101H, the put index.
5327
LD (HL),00H 36 00
Store 00H to the byte at Register Pair HL (top less 0101H): the put index equals the take index, the buffer is empty.
5329
DEC HL 2B
Decrement Register Pair HL to the top of memory less 0102H, the busy flag.
532A
LD (HL),00H 36 00
Store 00H to the byte at Register Pair HL (top less 0102H): the busy flag is clear, the task may fill the buffer.
532C
LD D,H 54
Copy Register H into Register D, so that Register Pair DE follows Register Pair HL (the busy flag's address).
532D
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the address of the busy flag.
532E
DEC DE 1B
Decrement Register Pair DE to the top of memory less 0103H, the last byte the copy will take.
532F
LD A,21H 3E 21
Load Register A with 21H, the opcode LD HL,nn.
5331
LD (439CH),A 32 9C 43
Store Register A (21H) to 439CH, the CALL 4300H at the start of SYS0/SYS's keyboard driver: it becomes LD HL,4300H, so the driver no longer calls the keyboard hook; the copied driver calls 4300H itself (53A9H).
5334
LD (53ADH),HL 22 AD 53
Store Register Pair HL (the address of the busy flag) to 53ADH, the operand of LD HL at 53ACH in the driver, before the copy is made.
5337
LD (53DAH),HL 22 DA 53
Store Register Pair HL (the address of the busy flag) to 53DAH, the operand of LD HL at 53D9H in the task.
533A
LD HL,(4016H) 2A 16 40
Fetch the current keyboard driver address from 4016H-4017H (the keyboard device control block's +01H-+02H) into Register Pair HL.
533D
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
5340
BIT 5,A CB 6F
Test bit 5 of Register A (430FH bit 5: SYS7/SYS is running a DO file and has replaced the keyboard driver).
5342
If the Z FLAG is set (no DO file), JUMP to 5347H with Register Pair HL = the driver from 4016H.
5344
LD HL,(43BEH) 2A BE 43
Fetch SYS7/SYS's saved keyboard driver from 43BEH-43BFH into Register Pair HL: the driver that is in use when the DO file ends.
5347
LD (53E6H),HL 22 E6 53
Store Register Pair HL (the old keyboard driver) to 53E6H, the operand of CALL 0000H at 53E5H in the task.
534A
LD (53D1H),HL 22 D1 53
Store Register Pair HL (the old keyboard driver) to 53D1H, the operand of CALL 0000H at 53D0H in the driver.
534D
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the top of memory less 0103H, Register Pair DE = the old driver (not used again).
534E
LD BC,00D6H 01 D6 00
Load Register Pair BC with 00D6H, the 214 bytes 53A9H-547EH to copy.
5351
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5352
SBC HL,BC ED 42
Subtract Register Pair BC (00D6H) from Register Pair HL: Register Pair HL = the new top of memory, just below the copy.
5354
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top of memory) to 4049H-404AH: the copy and the buffer are protected.
5357
INC HL 23
Increment Register Pair HL to the address of the copy.
5358
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
5359
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the copy, the destination of the LDIR.
535A
LD HL,53A9H 21 A9 53
Point Register Pair HL to 53A9H, the first byte to copy.
535D
LDIR ED B0
Copy the 214 bytes from Register Pair HL (53A9H-547EH, with the operands set above) to Register Pair DE (the copy): Register Pair DE ends at the busy flag and Register Pair BC at 0000H.
535F
LD (IX+00H),01H DD 36 00 01
Store 01H (an input device) to +00H of the device control block at Index Register IX (4015H), its type byte.
5363
POP HL E1
Restore Register Pair HL from the stack: the address of the copy, which is the new driver's entry (copy of 53A9H).
5364
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack again.
5365
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
5368
BIT 5,A CB 6F
Test bit 5 of Register A (430FH bit 5: a DO file running under SYS7/SYS).
536A
If the NZ FLAG is set (a DO file is running), JUMP to 5374H to give the new driver to SYS7/SYS instead.
536C
LD (IX+01H),L DD 75 01
Store Register L (the low byte of the new driver) to +01H of the device control block at Index Register IX (4016H).
536F
LD (IX+02H),H DD 74 02
Store Register H (the high byte of the new driver) to +02H of the device control block at Index Register IX (4017H): the keyboard device now uses the copied driver.
5372
JUMP to 5377H, the new driver being in the keyboard device control block.
5374
LD (43BEH),HL 22 BE 43
Store Register Pair HL (the new driver) to 43BEH-43BFH, SYS7/SYS's saved keyboard driver, which SYS7/SYS puts back into 4016H when the DO file ends.
5377
LD A,(4018H) 3A 18 40
Fetch 4018H (the key held byte, +03H of the keyboard device control block) into Register A.
537A
LD (IX+03H),A DD 77 03
Store Register A to +03H of the device control block at Index Register IX, which is 4018H itself: the byte is written back unchanged.
537D
LD HL,(4019H) 2A 19 40
Fetch the word at 4019H-401AH (the repeat tick and the unused +05H byte) into Register Pair HL.
5380
LD (IX+04H),L DD 75 04
Store Register L to +04H of the device control block at Index Register IX, which is 4019H itself: unchanged.
5383
LD (IX+05H),H DD 74 05
Store Register H to +05H of the device control block at Index Register IX, which is 401AH itself: unchanged.
5386
POP HL E1
Restore Register Pair HL from the stack: the address of the copy.
5387
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack again.
5388
LD DE,007DH 11 7D 00
Load Register Pair DE with 007DH, the offset of the key decoder 5426H from 53A9H.
538B
ADD HL,DE 19
Add Register Pair DE to Register Pair HL: Register Pair HL = the copied key decoder.
538C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copied key decoder.
538D
LD HL,4BC1H 21 C1 4B
Point Register Pair HL to 4BC1H, the operand of CALL 03FAH at 4BC0H in SYS0/SYS's key decoding.
5390
LD (HL),E 73
Store Register E (the low byte of the copied decoder) to 4BC1H at Register Pair HL.
5391
INC HL 23
Increment Register Pair HL to 4BC2H, the high byte of the CALL operand.
5392
LD (HL),D 72
Store Register D (the high byte) to 4BC2H at Register Pair HL: SYS0/SYS's keyboard driver now calls the copied decoder, which has no delay loops, in place of the ROM's 03FAH.
5393
POP HL E1
Restore Register Pair HL from the stack: the address of the copy.
5394
LD DE,002EH 11 2E 00
Load Register Pair DE with 002EH, the offset of the task control block 53D7H from 53A9H.
5397
ADD HL,DE 19
Add Register Pair DE to Register Pair HL: Register Pair HL = the copied task control block.
5398
LD D,H 54
Copy Register H into Register D, so that Register Pair DE follows Register Pair HL.
5399
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the copied task control block.
539A
INC DE 13
Increment Register Pair DE, one of the two steps from the control block to its routine.
539B
INC DE 13
Increment Register Pair DE again: Register Pair DE = the copied task routine (copy of 53D9H).
539C
LD (HL),E 73
Store Register E (the low byte of the task routine) to +00H of the control block at Register Pair HL.
539D
INC HL 23
Increment Register Pair HL to the control block's +01H.
539E
LD (HL),D 72
Store Register D (the high byte of the task routine) to +01H of the control block at Register Pair HL.
539F
DEC HL 2B
Decrement Register Pair HL back to the copied task control block.
53A0
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copied task control block for the install.
53A1
LD A,0AH 3E 0A
Load Register A with 0AH, task slot 10, one of the slots the dispatcher runs at every clock interrupt.
53A3
GOSUB to 4410H to install the task: slot Register A (0AH), control block Register Pair DE.
53A6
JUMP to 547FH and go on with LOWER, the type-ahead being installed.
53A9H - The Type-Ahead Keyboard Driver (Copied to High Memory)
The copy of this routine is the keyboard device's driver while TYPE is active. It calls the keyboard hook 4300H, sets the busy flag (so the task leaves the buffer alone), and when the buffer holds an entry returns its key in Register A and its saved flags in the flags register; with an empty buffer it calls the old driver itself and returns its result. The busy flag is cleared before every return. The buffer layout (below the original top of memory T): T less 0102H busy flag, T less 0101H put index, T less 0100H take index, then 256 bytes of two byte entries; the indexes count by 2 and wrap at 256.
53A9
GOSUB to 4300H, the keyboard hook (RET in the file; SPOOL places a JP there), which SYS0/SYS's own driver no longer calls since 5331H changed 439CH.
53AC
LD HL,0000H 21 00 00
Self-Modifying Code
Point Register Pair HL to the busy flag: the operand 53ADH-53AEH is 0000H in the file and holds the original top of memory less 0102H, stored by 5334H before the copy was made.
53AF
LD (HL),FFH 36 FF
Store FFH to the busy flag at Register Pair HL: the type-ahead task does not touch the buffer while the driver works.
53B1
PUSH HL E5
Save Register Pair HL (the address of the busy flag) to the stack.
53B2
INC HL 23
Increment Register Pair HL from the busy flag to the put index of the buffer.
53B3
LD A,(HL) 7E
Fetch the put index at Register Pair HL into Register A.
53B4
INC HL 23
Increment Register Pair HL to the take index.
53B5
CP (HL) BE
Compare Register A (the put index) against the take index at Register Pair HL: the Z FLAG is set when they are equal, an empty buffer.
53B6
LD A,00H 3E 00
Load Register A with 00H without changing the flags; both paths below replace Register A, so this value is not used.
53B8
If the Z FLAG is set (the buffer is empty), JUMP to 53CCH to call the old driver.
53BA
PUSH HL E5
Save Register Pair HL (the address of the take index) to the stack.
53BB
LD E,(HL) 5E
Fetch the take index at Register Pair HL into Register E.
53BC
INC HL 23
Increment Register Pair HL to the first byte of the 256 byte buffer.
53BD
LD D,00H 16 00
Load Register D with 00H: Register Pair DE = the take index as an offset.
53BF
ADD HL,DE 19
Add Register Pair DE (the take index) to Register Pair HL: Register Pair HL = the entry to take.
53C0
LD B,(HL) 46
Fetch the entry's first byte (the key) at Register Pair HL into Register B.
53C1
INC HL 23
Increment Register Pair HL to the entry's second byte.
53C2
LD C,(HL) 4E
Fetch the entry's second byte (the flags the old driver returned with the key) at Register Pair HL into Register C.
53C3
POP HL E1
Restore Register Pair HL from the stack: the address of the take index.
53C4
INC (HL) 34
Increment the take index at Register Pair HL.
53C5
INC (HL) 34
Increment the take index at Register Pair HL again: it moves on by one 2 byte entry and wraps from FEH to 00H.
53C6
POP HL E1
Restore Register Pair HL from the stack: the address of the busy flag.
53C7
LD (HL),00H 36 00
Store 00H to the busy flag at Register Pair HL: the task may fill the buffer again.
53C9
PUSH BC C5
Save Register Pair BC (the key in Register B, its flags in Register C) to the stack.
53CA
POP AF F1
Restore Register Pair AF from the stack: Register A = the key, the flags register = the flags saved with it.
53CB
RET C9
RETURN to the caller of the keyboard device with the buffered key in Register A.
53CC
LD IX,4015H DD 21 15 40
Point Index Register IX to 4015H, the keyboard device control block, for the old driver, which keeps its key held byte and repeat tick at +03H-+04H (4018H-4019H).
53D0
CALL 0000H CD 00 00
Self-Modifying Code
GOSUB to the old keyboard driver: the operand 53D1H-53D2H is 0000H in the file and holds the driver from 4016H (or SYS7/SYS's from 43BEH), stored by 534AH before the copy. It scans the keyboard and returns a key in Register A (00H for none).
53D3
POP HL E1
Restore Register Pair HL from the stack: the address of the busy flag.
53D4
LD (HL),00H 36 00
Store 00H to the busy flag at Register Pair HL: the task may fill the buffer again.
53D6
RET C9
RETURN to the caller of the keyboard device with the old driver's Register A and flags.
53D7H - The Type-Ahead Task (Copied to High Memory)
The copy of 53D9H runs as the task in slot 10, at every clock interrupt. Unless the driver is busy it calls the old keyboard driver; a key is put into the buffer with its flags. Key code C0H (CLEAR with @: SYS0/SYS's decoder ORs 80H into the code of a key typed with CLEAR, 4BD0H-4BD9H) empties the buffer and leaves one entry of key 00H with flags 40H. While the buffer is not empty a key that the old driver returned as a repeat (repeat tick 4019H equal to the tick 4040H plus 3) is dropped and the next repeat is put off by 3 more ticks; a full buffer (127 keys) drops the key.
53D7-53D8
DEFS 2
Not in the file (the gap between the load blocks 53CAH-53D6H and 53D9H-54D6H): the task control block of the type-ahead task. The LDIR at 535DH copies whatever is in memory here; 539CH-539EH then store the address of the copied task routine (copy of 53D9H) into the copy's two bytes, and 53A3H installs it in slot 10.
53D9
LD HL,0000H 21 00 00
Self-Modifying Code
Point Register Pair HL to the busy flag: the operand 53DAH-53DBH is 0000H in the file and holds the original top of memory less 0102H, stored by 5337H before the copy.
53DC
LD A,(HL) 7E
Fetch the busy flag at Register Pair HL into Register A.
53DD
OR A B7
OR Register A with itself: the NZ FLAG is set when Register A (the busy flag) is FFH, the driver is using the buffer.
53DE
RET NZ C0
If the NZ FLAG is set (the driver is busy), RETURN to the dispatcher and try at the next interrupt.
53DF
INC HL 23
Increment Register Pair HL from the busy flag to the put index of the buffer.
53E0
PUSH HL E5
Save Register Pair HL (the address of the put index) to the stack.
53E1
LD IX,4015H DD 21 15 40
Point Index Register IX to 4015H, the keyboard device control block, for the old driver.
53E5
CALL 0000H CD 00 00
Self-Modifying Code
GOSUB to the old keyboard driver: the operand 53E6H-53E7H is 0000H in the file and holds the driver from 4016H (or 43BEH), stored by 5347H before the copy. Register A = the key, 00H for none.
53E8
POP HL E1
Restore Register Pair HL from the stack: the address of the put index.
53E9
INC A 3C
Increment Register A, as half of a test of Register A for 00H that keeps the CARRY FLAG.
53EA
DEC A 3D
Decrement Register A back to the key: the Z FLAG is set when Register A is 00H, no key.
53EB
RET Z C8
If the Z FLAG is set (no key), RETURN to the dispatcher.
53EC
PUSH AF F5
Save Register Pair AF (the key and the flags the old driver returned) to the stack.
53ED
POP BC C1
Restore Register Pair BC from the stack: Register B = the key, Register C = its flags.
53EE
CP C0H FE C0
Compare Register A (the key) against C0H, the code of CLEAR with @.
53F0
If the Z FLAG is set (CLEAR with @), JUMP to 541AH to empty the buffer.
53F2
LD E,(HL) 5E
Fetch the put index at Register Pair HL into Register E.
53F3
LD A,E 7B
Copy Register E (the put index) into Register A for the compare below.
53F4
INC HL 23
Increment Register Pair HL to the take index.
53F5
CP (HL) BE
Compare Register A (the put index) against the take index at Register Pair HL: the Z FLAG is set when the buffer is empty.
53F6
If the Z FLAG is set (an empty buffer), JUMP to 540DH and store the key, even a repeat.
53F8
LD A,(4040H) 3A 40 40
Fetch the tick counter from 4040H into Register A.
53FB
ADD A,03H C6 03
Add 03H to Register A: the repeat tick the old driver sets after a repeated key (tick plus 3).
53FD
CP (IX+04H) DD BE 04
Compare Register A against +04H of the device control block at Index Register IX (4019H, the repeat tick): the Z FLAG is set when this key was a repeat.
5400
If the NZ FLAG is set (a new key press), JUMP to 5408H to store it.
5402
ADD A,03H C6 03
Add 03H to Register A again: the tick counter plus 6.
5404
LD (IX+04H),A DD 77 04
Store Register A to +04H of the device control block at Index Register IX (4019H): the next repeat comes 3 ticks later than usual.
5407
RET C9
RETURN to the dispatcher without storing the repeated key: no auto repeat while keys are waiting.
5408
LD A,E 7B
Copy Register E (the put index) into Register A.
5409
INC A 3C
Increment Register A, the first step to the put index after this entry.
540A
INC A 3C
Increment Register A again: Register A = the put index after this entry.
540B
CP (HL) BE
Compare Register A against the take index at Register Pair HL: the Z FLAG is set when the buffer would be full.
540C
RET Z C8
If the Z FLAG is set (the buffer is full), RETURN to the dispatcher and drop the key.
540D
PUSH HL E5
Save Register Pair HL (the address of the take index) to the stack.
540E
INC HL 23
Increment Register Pair HL to the first byte of the 256 byte buffer.
540F
LD D,00H 16 00
Load Register D with 00H: Register Pair DE = the put index as an offset.
5411
ADD HL,DE 19
Add Register Pair DE (the put index) to Register Pair HL: Register Pair HL = the free entry.
5412
LD (HL),B 70
Store Register B (the key) to the entry's first byte at Register Pair HL.
5413
INC HL 23
Increment Register Pair HL to the entry's second byte.
5414
LD (HL),C 71
Store Register C (the key's flags) to the entry's second byte at Register Pair HL.
5415
POP HL E1
Restore Register Pair HL from the stack: the address of the take index.
5416
DEC HL 2B
Decrement Register Pair HL from the take index to the put index of the buffer.
5417
INC (HL) 34
Increment the put index at Register Pair HL, the first of the two steps of an entry.
5418
INC (HL) 34
Increment the put index at Register Pair HL again: it moves on by one 2 byte entry and wraps from FEH to 00H.
5419
RET C9
RETURN to the dispatcher with the key in the buffer.
541A
LD (HL),02H 36 02
Store 02H to the put index at Register Pair HL: one entry will be in the buffer.
541C
INC HL 23
Increment Register Pair HL to the take index.
541D
LD (HL),00H 36 00
Store 00H to the take index at Register Pair HL: the first entry is the next to take.
541F
INC HL 23
Increment Register Pair HL to the first entry's key byte.
5420
LD (HL),00H 36 00
Store 00H to the key byte at Register Pair HL: the entry gives key 00H, no key.
5422
INC HL 23
Increment Register Pair HL to the first entry's flags byte.
5423
LD (HL),40H 36 40
Store 40H to the flags byte at Register Pair HL: the entry returns with the Z FLAG set and the CARRY FLAG clear.
5425
RET C9
RETURN to the dispatcher with the buffer emptied (the CLEAR with @ key itself is not stored).
5426H - The Key Decoder Without Delays (Copied, Reached Through 4BC1H)
The copy of this routine replaces the ROM's 03FAH in SYS0/SYS's keyboard driver (CALL at 4BC0H, operand written by 5390H-5392H). It is entered with Register A = the newly pressed keys of a row, Register D = the row number (0-6) and Register Pair BC = the row's address. It decodes the key as the ROM's 03FEH-0457H does, but without the ROM's 0500H delay and second reading of the row (011CH-0126H) and without its 0DACH delay after decoding (044CH-044FH): the type-ahead task calls the driver at every interrupt. It returns the key code in Register A with the NZ FLAG; BREAK (01H) goes to SYS0/SYS's request handler with RST 28H.
5426
LD E,A 5F
Copy Register A (the newly pressed keys of the row) into Register E.
5427
LD A,D 7A
Copy Register D (the row number, 0-6) into Register A.
5428
RLCA 07
Rotate Register A left: the row number times 2.
5429
RLCA 07
Rotate Register A left again: the row number times 4.
542A
RLCA 07
Rotate Register A left a third time: Register A = the row number times 8, the code of the row's first key.
542B
LD D,A 57
Copy Register A into Register D: Register D counts the key number.
542C
LD C,01H 0E 01
Load Register C with 01H, the mask of the row's first key.
542E
LD A,C 79
Loop Start
Copy Register C (the mask) into Register A.
542F
AND E A3
AND Register A with Register E (the pressed keys): the NZ FLAG is set at the lowest pressed key.
5430
If the NZ FLAG is set (the key is found), JUMP to 5437H with Register D = its number.
5432
INC D 14
Increment Register D to the number of the next key of the row.
5433
RLC C CB 01
Rotate Register C left: the mask of the next key.
5435
LOOP BACK to 542EH to test the next key of the row with the new mask.
5437
LD A,(3880H) 3A 80 38
Fetch keyboard row 7 from 3880H into Register A (bit 0 the SHIFT key).
543A
LD B,A 47
Copy Register A (the SHIFT row) into Register B.
543B
LD A,D 7A
Copy Register D (the key number) into Register A.
543C
ADD A,40H C6 40
Add 40H to Register A: keys 00H-1FH (rows 0-3, @ and the letters) give 40H-5FH.
543E
CP 60H FE 60
Compare Register A against 60H: the CARRY FLAG is set for rows 0-3.
5440
If the NC FLAG is set (rows 4-6), JUMP to 5455H.
5442
RRC B CB 08
Rotate Register B right: the CARRY FLAG = bit 0 of the SHIFT row (SHIFT down).
5444
If the NC FLAG is set (no SHIFT), JUMP to 547AH with Register A = 40H-5FH.
5446
ADD A,20H C6 20
Add 20H to Register A: the shifted code 60H-7FH.
5448
LD D,A 57
Copy Register A (the shifted code) into Register D.
5449
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A.
544C
AND 10H E6 10
AND Register A with 10H, the down arrow key: the Z FLAG is set when it is not held.
544E
If the Z FLAG is set (no down arrow), JUMP to 5479H to return the shifted code from Register D.
5450
LD A,D 7A
Copy Register D (the shifted code) into Register A.
5451
SUB 60H D6 60
Subtract 60H from Register A: SHIFT with the down arrow and a letter give the control codes 00H-1FH.
5453
JUMP to 547AH with Register A = the control code.
5455
SUB 70H D6 70
Subtract 70H from Register A: Register A = the key number less 30H, with the CARRY FLAG for rows 4 and 5.
5457
If the NC FLAG is set (row 6), JUMP to 5469H.
5459
ADD A,40H C6 40
Add 40H to Register A: the key number plus 10H, 30H-3FH for the digits and symbols of rows 4 and 5.
545B
CP 3CH FE 3C
Compare Register A against 3CH: the CARRY FLAG is set for 30H-3BH.
545D
If the CARRY FLAG is set, JUMP to 5461H and keep Register A.
545F
XOR 10H EE 10
Exclusive OR Register A with 10H: 3CH-3FH become 2CH-2FH (comma, minus, period, slash).
5461
RRC B CB 08
Rotate Register B right: the CARRY FLAG = the SHIFT key.
5463
If the NC FLAG is set (no SHIFT), JUMP to 547AH with Register A as it is.
5465
XOR 10H EE 10
Exclusive OR Register A with 10H: the shifted symbol (30H-3BH become 20H-2BH, 2CH-2FH become 3CH-3FH).
5467
JUMP to 547AH with Register A = the shifted symbol.
5469
RLCA 07
Rotate Register A left: Register A = (the key number less 30H) times 2, the offset of the key's pair in the ROM's table.
546A
RRC B CB 08
Rotate Register B right: the CARRY FLAG = the SHIFT key.
546C
If the NC FLAG is set (no SHIFT), JUMP to 546FH.
546E
INC A 3C
Increment Register A to the shifted code of the pair.
546F
LD HL,0050H 21 50 00
Point Register Pair HL to 0050H, the ROM's table of row 6 codes (ENTER, CLEAR, BREAK, the arrows, space; two bytes a key).
5472
LD C,A 4F
Copy Register A (the offset) into Register C.
5473
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset.
5475
ADD HL,BC 09
Add Register Pair BC to Register Pair HL: Register Pair HL = the key's code in the ROM's table.
5476
LD A,(HL) 7E
Fetch the code at Register Pair HL into Register A.
5477
JUMP to 547AH with Register A = the code from the ROM's table.
5479
LD A,D 7A
Copy Register D (the shifted code 60H-7FH) into Register A.
547A
CP 01H FE 01
Compare Register A (the key code) against 01H, the BREAK key.
547C
RET NZ C0
If the NZ FLAG is set (not BREAK), RETURN to SYS0/SYS's keyboard driver (4BC3H) with the key code in Register A.
547D
RST 28H EF
RST 28H with Register A = 01H: a request below 80H, which SYS0/SYS's handler (4C28H) sends through 4310H and returns straight to the caller of this routine (4BC3H) with Register A = 01H, or 00H when 4C2DH holds RET Z (BREAK=N).
547E
RET C9
RETURN to the caller: not reached through the RST 28H above, because SYS0/SYS's handler drops the RST 28H return address for requests below 80H.
547FH - LOWER: Install the Lower Case Display Driver
Any LOWER value other than 0000H (the file's) refuses to run under BASIC (5627H), lowers the top of memory by 1EH, copies the driver 54BFH-54DCH there and makes it the display device's driver (401DH +01H-+02H). The three stores to +03H-+05H of the control block write 4020H-4022H back unchanged. Nothing checks for a driver already installed and LOWER=N does not take it away.
547F
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of LOWER: the operand 5480H-5481H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when LOWER is given.
5482
LD A,B 78
Copy Register B (the high byte of the LOWER value) into Register A, to test the whole value.
5483
OR C B1
OR Register C (the low byte of the LOWER value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, LOWER not given or LOWER=N.
5484
If the Z FLAG is set (no LOWER), JUMP to 54DDH and go on with JKL.
5487
GOSUB to 5627H: when 402DH holds C3H (a JP put there by BASIC/CMD), CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL is displayed and the command aborts; otherwise it returns.
548A
LD IX,401DH DD 21 1D 40
Point Index Register IX to 401DH, the display device control block, whose +00H-+05H are set below.
548E
LD BC,001EH 01 1E 00
Load Register Pair BC with 001EH, the 30 bytes of the driver 54BFH-54DCH.
5491
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
5494
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5495
SBC HL,BC ED 42
Subtract Register Pair BC (001EH) from Register Pair HL: Register Pair HL = the new top of memory.
5497
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top of memory) to 4049H-404AH, so that the copy is protected.
549A
INC HL 23
Increment Register Pair HL to the address of the copy.
549B
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
549C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the copy, the destination of the LDIR.
549D
LD HL,54BFH 21 BF 54
Point Register Pair HL to 54BFH, the driver to copy.
54A0
LDIR ED B0
Copy the 30 bytes from Register Pair HL (54BFH) to Register Pair DE (the copy): Register Pair BC ends at 0000H.
54A2
LD (IX+00H),07H DD 36 00 07
Store 07H (input, output and control) to +00H of the device control block at Index Register IX (401DH), the type byte it has in the file.
54A6
POP HL E1
Restore Register Pair HL from the stack: the address of the copied driver.
54A7
LD (IX+01H),L DD 75 01
Store Register L (the low byte of the copied driver) to +01H of the device control block at Index Register IX (401EH).
54AA
LD (IX+02H),H DD 74 02
Store Register H (the high byte of the copied driver) to +02H of the device control block at Index Register IX (401FH): the display device now uses the copied driver.
54AD
LD A,(4020H) 3A 20 40
Fetch 4020H (the low byte of the cursor address) into Register A.
54B0
LD (IX+03H),A DD 77 03
Store Register A to +03H of the device control block at Index Register IX, which is 4020H itself: the byte is written back unchanged.
54B3
LD HL,(4021H) 2A 21 40
Fetch the word at 4021H-4022H (the high byte of the cursor and the cursor byte) into Register Pair HL.
54B6
LD (IX+04H),L DD 75 04
Store Register L to +04H of the device control block at Index Register IX, which is 4021H itself: unchanged.
54B9
LD (IX+05H),H DD 74 05
Store Register H to +05H of the device control block at Index Register IX, which is 4022H itself: unchanged.
54BC
JUMP to 54DDH and go on with JKL, the work of LOWER being done.
54BFH - The Lower Case Display Driver (Copied to High Memory)
The copy of these 30 bytes is the display device's driver after LOWER. It is the ROM's display driver (0458H-0470H) with the code that folds 40H-7FH into the video codes 00H-3FH (0471H-047CH) left out: control codes below 20H go to the ROM's 0506H, codes 80H and up to its 04A6H, and every character 20H-7FH is stored into video memory as it is by the ROM's 047DH, so small letters reach the screen as small letters. Entered with Index Register IX = 401DH and Register C = the character.
54BF
LD L,(IX+03H) DD 6E 03
Fetch +03H of the device control block at Index Register IX (4020H, the low byte of the cursor address) into Register L.
54C2
LD H,(IX+04H) DD 66 04
Fetch +04H of the device control block at Index Register IX (4021H, the high byte) into Register H: Register Pair HL = the cursor address.
54C5
If the CARRY FLAG is set (a request to read from the display, as the ROM's own driver tests at 045EH), JUMP to 049AH in the ROM, which returns the character at the cursor in Register A.
54C8
LD A,(IX+05H) DD 7E 05
Fetch +05H of the device control block at Index Register IX (4022H) into Register A: the character the cursor covers, 00H when no cursor is shown.
54CB
OR A B7
OR Register A with itself: the Z FLAG is set when Register A (from 4022H) is 00H.
54CC
If the Z FLAG is set (no cursor), JUMP to 54CFH.
54CE
LD (HL),A 77
Store Register A (the covered character) to the screen at Register Pair HL: the cursor is taken away before the character is handled.
54CF
LD A,C 79
Copy Register C (the character to display) into Register A.
54D0
CP 20H FE 20
Compare Register A against 20H: the CARRY FLAG is set for a control code.
54D2
If the CARRY FLAG is set (a control code below 20H), JUMP to 0506H in the ROM, which handles it and returns through 0480H (cursor shown again).
54D5
CP 80H FE 80
Compare Register A against 80H: the NC FLAG is set for a graphics or space compression code.
54D7
If the NC FLAG is set (80H and up), JUMP to 04A6H in the ROM, which stores the graphics codes 80H-BFH and turns the codes from C0H up into runs of spaces (space compression).
54DA
JUMP to 047DH in the ROM with Register A = the character 20H-7FH: the ROM stores it at the cursor (0541H), moves the cursor on and returns through 0480H.
54DDH - JKL and GRAPHIC: Install the Screen Print
Any JKL value other than 0000H (the file's) refuses to run under BASIC (5627H), copies 5524H-5571H (4EH bytes: a two byte task control block, the key test task 5526H and the print routine 553EH) below the top of memory and installs the task in slot 4, then goes on with DRIVE at 55B4H, so ALIVE is not processed when JKL is given. GRAPHIC (looked at only with JKL) replaces the LD A,2EH at 5561H by two NOPs before the copy, so that graphics codes go to the printer as they are instead of as periods.
54DD
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of JKL: the operand 54DEH-54DFH is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when JKL is given.
54E0
LD A,B 78
Copy Register B (the high byte of the JKL value) into Register A, to test the whole value.
54E1
OR C B1
OR Register C (the low byte of the JKL value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, JKL not given or JKL=N.
54E2
If the Z FLAG is set (no JKL), JUMP to 5572H and go on with ALIVE.
54E5
GOSUB to 5627H: when 402DH holds C3H (a JP put there by BASIC/CMD), CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL is displayed and the command aborts; otherwise it returns.
54E8
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of GRAPHIC: the operand 54E9H-54EAH is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when GRAPHIC (table name GRAPHI) is given.
54EB
LD A,B 78
Copy Register B (the high byte of the GRAPHIC value) into Register A, to test the whole value.
54EC
OR C B1
OR Register C (the low byte of the GRAPHIC value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, GRAPHIC not given.
54ED
If the Z FLAG is set (no GRAPHIC), JUMP to 54F5H and keep the period for graphics codes.
54EF
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, two NOP opcodes.
54F2
LD (5561H),HL 22 61 55
Store Register Pair HL (00H, 00H) to 5561H-5562H, over the LD A,2EH of the print routine: graphics codes are printed as they are.
54F5
LD BC,004EH 01 4E 00
Load Register Pair BC with 004EH, the 78 bytes 5524H-5571H to copy.
54F8
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
54FB
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
54FC
SBC HL,BC ED 42
Subtract Register Pair BC (004EH) from Register Pair HL: Register Pair HL = the new top of memory.
54FE
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top of memory) to 4049H-404AH, so that the copy is protected.
5501
INC HL 23
Increment Register Pair HL to the address of the copy, which starts with the task control block.
5502
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
5503
LD D,H 54
Copy Register H into Register D, so that Register Pair DE follows Register Pair HL.
5504
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the address of the copy.
5505
INC HL 23
Increment Register Pair HL, the first of two steps past the task control block.
5506
INC HL 23
Increment Register Pair HL again: Register Pair HL = the copied key test task (copy of 5526H).
5507
LD (5524H),HL 22 24 55
Store Register Pair HL (the copied task routine) to 5524H-5525H, the task control block before the copy is made (these two bytes are not loaded by the file).
550A
LD HL,001AH 21 1A 00
Load Register Pair HL with 001AH, the offset of the print routine 553EH from 5524H.
550D
ADD HL,DE 19
Add Register Pair DE (the address of the copy) to Register Pair HL: Register Pair HL = the copied print routine.
550E
LD (5533H),HL 22 33 55
Store Register Pair HL (the copied print routine) to 5533H, the operand of LD HL at 5532H in the task, before the copy.
5511
POP DE D1
Restore Register Pair DE from the stack: the address of the copy, the destination of the LDIR.
5512
PUSH DE D5
Save Register Pair DE (the address of the copy) to the stack again for the install below.
5513
LD HL,5524H 21 24 55
Point Register Pair HL to 5524H, the first byte to copy (the task control block).
5516
LD BC,004EH 01 4E 00
Load Register Pair BC with 004EH, the 78 bytes to copy.
5519
LDIR ED B0
Copy the 78 bytes from Register Pair HL (5524H-5571H) to Register Pair DE (the copy): Register Pair BC ends at 0000H.
551B
POP DE D1
Restore Register Pair DE from the stack: the copied task control block.
551C
LD A,04H 3E 04
Load Register A with 04H, task slot 4, one of the slots the dispatcher runs every eighth tick.
551E
GOSUB to 4410H to install the task: slot Register A (04H), control block Register Pair DE.
5521
JUMP to 55B4H and go on with DRIVE (ALIVE is not looked at when JKL is given).
5524H - The Screen Print Task (Copied to High Memory)
The copy of 5526H runs as the task in slot 4. When J, K and L (and no other key of row 1) are held, and the call at SYS0/SYS's 4536H is not already armed, it stores the address of the copied print routine into 4537H-4538H and then CCH into 4536H, turning SYS0/SYS's CALL NZ,0000H into CALL Z to the print routine. The task runs from the clock vector, the last latch bit served, so the same interrupt goes on from 454CH through 452BH to the BREAK test at 452FH-4534H: with BREAK up the AND 04H leaves the Z FLAG set and the CALL Z at 4536H is taken at once (with BREAK down 4534H jumps past it, and the first later interrupt with BREAK up makes the call).
5524-5525
DEFS 2
Not in the file (the gap between the load blocks 54D7H-5523H and 5526H-5623H): the task control block of the screen print task. 5507H stores the address of the copied task routine (copy of 5526H) here before the LDIR at 5519H copies it as the first two bytes of the copy, which 551EH installs in slot 4.
5526
LD A,(3802H) 3A 02 38
Fetch keyboard row 1 from 3802H into Register A (bits 0-7 the keys H, I, J, K, L, M, N, O).
5529
CP 1CH FE 1C
Compare Register A against 1CH (bits 2, 3 and 4: the keys J, K and L): the Z FLAG is set only when these three keys and no other of the row are down.
552B
RET NZ C0
If the NZ FLAG is set (not J, K and L), RETURN to the dispatcher.
552C
LD HL,(4537H) 2A 37 45
Fetch the operand of SYS0/SYS's CALL at 4536H from 4537H-4538H into Register Pair HL: 0000H when no print is pending.
552F
LD A,H 7C
Copy Register H (the high byte from 4537H) into Register A.
5530
OR L B5
OR Register L (the low byte) into Register A: the NZ FLAG is set when a print is already pending or running.
5531
RET NZ C0
If the NZ FLAG is set (a print is pending), RETURN to the dispatcher.
5532
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the address of the print routine: the operand 5533H-5534H is 0000H in the file and holds the copy of 553EH, stored by 550EH before the copy was made.
5535
LD (4537H),HL 22 37 45
Store Register Pair HL (the copied print routine) to 4537H-4538H, the operand of SYS0/SYS's CALL at 4536H.
5538
LD A,CCH 3E CC
Load Register A with CCH, the opcode CALL Z,nn.
553A
LD (4536H),A 32 36 45
Store Register A (CCH) to 4536H: the instruction is now CALL Z to the copied print routine, and the Z FLAG is always set when the interrupt routine reaches 4536H with BREAK up.
553D
RET C9
RETURN to the dispatcher (and through 454CH back to the latch loop at 452BH): in this same interrupt the BREAK test at 452FH follows and, with BREAK up, the CALL Z at 4536H calls the print routine.
553EH - The Screen Print Routine (Called From the Interrupt Routine)
Called from SYS0/SYS's interrupt routine at 4536H (only Register Pairs AF and HL of the interrupted program are saved there, interrupts are off). It puts 4536H back to CALL NZ, then sends the 1024 bytes of video memory 3C00H-3FFFH to the printer through the ROM's 003BH, a carriage return before each line of 64 and one after the last; codes 80H and up are sent as periods unless GRAPHIC was given. BREAK stops the print. At the end 4537H-4538H are set to 0000H so that J, K and L can start another print.
553E
LD A,C4H 3E C4
Load Register A with C4H, the opcode CALL NZ,nn.
5540
LD (4536H),A 32 36 45
Store Register A (C4H) to 4536H: the interrupt routine does not call this routine again (the Z FLAG is always set there). 4537H-4538H keep the address, so that the task does not start a second print meanwhile.
5543
PUSH BC C5
Save Register Pair BC of the interrupted program to the stack: SYS0/SYS's interrupt routine saved only Register Pairs AF and HL.
5544
PUSH DE D5
Save Register Pair DE of the interrupted program to the stack: the ROM's 003BH loads Register Pair DE with 4025H.
5545
LD HL,3C00H 21 00 3C
Point Register Pair HL to 3C00H, the first byte of video memory.
5548
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A (bit 2 the BREAK key).
554B
AND 04H E6 04
AND Register A with 04H, the BREAK key: the NZ FLAG is set when it is down.
554D
If the NZ FLAG is set (BREAK), JUMP to 5568H to stop the print.
554F
LD A,L 7D
Copy Register L (the low byte of the video address) into Register A.
5550
AND 3FH E6 3F
AND Register A with 3FH, the column: the Z FLAG is set at the start of a line of 64 characters.
5552
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return, without changing the Z FLAG.
5554
If the Z FLAG is set (the start of a line), GOSUB to 003BH in the ROM to send Register A (0DH) to the printer device control block 4025H.
5557
BIT 6,H CB 74
Test bit 6 of Register H: it is set when Register Pair HL has reached 4000H, past the last byte of video memory.
5559
If the NZ FLAG is set (the whole screen is printed), JUMP to 5568H.
555B
LD A,(HL) 7E
Fetch the byte at Register Pair HL (video memory) into Register A.
555C
INC HL 23
Increment Register Pair HL to the next byte of video memory.
555D
CP 80H FE 80
Compare Register A against 80H: the CARRY FLAG is set for a character below 80H.
555F
If the CARRY FLAG is set (an ordinary character), JUMP to 5563H to print it.
5561
LD A,2EH 3E 2E
Self-Modifying Code
Load Register A with 2EH, a period, in place of the graphics code. When GRAPHIC is given, 54EFH-54F2H store 00H, 00H here before the copy, the two bytes become NOPs and Register A keeps the graphics code.
5563
GOSUB to 003BH in the ROM to send Register A (the character) to the printer device control block 4025H.
5566
LOOP BACK to 5548H for the next byte of video memory.
5568
POP DE D1
Restore Register Pair DE of the interrupted program from the stack.
5569
POP BC C1
Restore Register Pair BC of the interrupted program from the stack.
556A
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the value that marks no print pending.
556D
DI F3
Disable interrupts, so that the store below and the return into SYS0/SYS's interrupt routine run with interrupts off whatever the printer path did.
556E
LD (4537H),HL 22 37 45
Store Register Pair HL (0000H) to 4537H-4538H: the operand of 4536H is cleared and the task may arm another print.
5571
RET C9
RETURN to SYS0/SYS's interrupt routine (4539H), which restores Register Pairs AF and HL and returns to the interrupted program.
5572H - ALIVE: Install the Alive Indicator
Reached only when JKL is not given. Any ALIVE value other than 0000H refuses to run under BASIC (5627H), copies 55A3H-55B3H (11H bytes: a two byte task control block and the task) below the top of memory and installs it in task slot 3. The task changes the graphics character at 3C3FH, the top right corner of the screen, between 86H and 89H each time it runs.
5572
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of ALIVE: the operand 5573H-5574H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when ALIVE is given.
5575
LD A,B 78
Copy Register B (the high byte of the ALIVE value) into Register A, to test the whole value.
5576
OR C B1
OR Register C (the low byte of the ALIVE value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, ALIVE not given.
5577
If the Z FLAG is set (no ALIVE), JUMP to 55B4H and go on with DRIVE.
557A
GOSUB to 5627H: when 402DH holds C3H (a JP put there by BASIC/CMD), CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL is displayed and the command aborts; otherwise it returns.
557D
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
5580
LD BC,0011H 01 11 00
Load Register Pair BC with 0011H, the 17 bytes 55A3H-55B3H to copy.
5583
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the subtraction below.
5584
SBC HL,BC ED 42
Subtract Register Pair BC (0011H) from Register Pair HL: Register Pair HL = the new top of memory.
5586
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top of memory) to 4049H-404AH, so that the copy is protected.
5589
INC HL 23
Increment Register Pair HL to the address of the copy, its task control block.
558A
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
558B
INC HL 23
Increment Register Pair HL, the first of two steps past the task control block.
558C
INC HL 23
Increment Register Pair HL again: Register Pair HL = the copied task routine (copy of 55A5H).
558D
LD (55A3H),HL 22 A3 55
Store Register Pair HL (the copied task routine) to 55A3H-55A4H, the task control block, before the copy is made.
5590
POP DE D1
Restore Register Pair DE from the stack: the address of the copy, the destination of the LDIR.
5591
PUSH DE D5
Save Register Pair DE (the address of the copy) to the stack again for the install below.
5592
LD HL,55A3H 21 A3 55
Point Register Pair HL to 55A3H, the first byte to copy.
5595
LD BC,0011H 01 11 00
Load Register Pair BC with 0011H, the 17 bytes to copy.
5598
LDIR ED B0
Copy the 17 bytes from Register Pair HL (55A3H-55B3H) to Register Pair DE (the copy): Register Pair BC ends at 0000H.
559A
POP DE D1
Restore Register Pair DE from the stack: the copied task control block.
559B
LD A,03H 3E 03
Load Register A with 03H, task slot 3, one of the slots the dispatcher runs every eighth tick.
559D
GOSUB to 4410H to install the task: slot Register A (03H), control block Register Pair DE.
55A0
JUMP to 55B4H and go on with DRIVE, the alive indicator being installed.
55A3H - The Alive Indicator Task (Copied to High Memory)
The copy of 55A5H runs as the task in slot 3, five times a second at the 40 ticks a second of the clock. Each call puts 89H at 3C3FH when 86H is there and 86H otherwise: two graphics characters of two blocks each that make the corner of the screen move while the interrupts and the task dispatcher work.
55A3-55A4
DEFW 0000H 00 00
Self-Modifying Code
The task control block of the alive indicator: 0000H in the file; 558DH stores the address of the copied task routine (copy of 55A5H) here before the LDIR at 5598H copies it, and 559DH installs the copy in slot 3.
55A5
LD A,(3C3FH) 3A 3F 3C
Fetch the byte at 3C3FH (the top right corner of the screen, line 0 column 63) into Register A.
55A8
CP 86H FE 86
Compare Register A against 86H, the graphics character with the top right and middle left blocks lit.
55AA
LD A,89H 3E 89
Load Register A with 89H, the graphics character with the top left and middle right blocks lit, without changing the Z FLAG.
55AC
If the Z FLAG is set (86H was there), JUMP to 55B0H to put 89H.
55AE
LD A,86H 3E 86
Load Register A with 86H, the other graphics character of the pair.
55B0
LD (3C3FH),A 32 3F 3C
Store Register A (86H or 89H) to 3C3FH, the top right corner of the screen.
55B3
RET C9
RETURN to the dispatcher until the next call of slot 3.
55B4H - DRIVE, DISABLE and ENABLE: Pick a Drive and Turn It Off or On
DRIVE=d picks the drive code table (DCT) that DISABLE, ENABLE, STEP and DELAY change; without DRIVE (the file's FFFFH, also DRIVE alone) none of them is looked at. A drive number of 8 or more gives PARAMETER ERROR. DISABLE stores C9H (no drive) in the table's +00H; otherwise ENABLE stores C3H there, which gives back the JP to the driver only when +01H-+02H still hold the driver's address (drives 4-7 have 0000H there in SYS0/SYS's tables).
55B4
LD BC,FFFFH 01 FF FF
Self-Modifying Code
Load Register Pair BC with the value of DRIVE: the operand 55B5H-55B6H is FFFFH in the file (DRIVE not given) and is written by 510FH (CALL 4476H at 5203H): the drive number for DRIVE=d.
55B7
INC B 04
Increment Register B (the high byte of the DRIVE value): the Z FLAG is set when it was FFH, DRIVE not given or given without a number.
55B8
If the Z FLAG is set (no drive number), JUMP to 5619H and go on with SYSGEN, skipping DISABLE, ENABLE, STEP and DELAY.
55BB
LD A,C 79
Copy Register C (the low byte of the DRIVE value, the drive number) into Register A.
55BC
CP 08H FE 08
Compare Register A (the drive number) against 08H: the NC FLAG is set for 8 or more.
55BE
If the NC FLAG is set (no such drive), JUMP to 5660H to display PARAMETER ERROR and abort.
55C1
GOSUB to 478FH: Index Register IY = the drive code table of drive Register C (4700H plus 10 times the drive number).
55C4
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of DISABLE: the operand 55C5H-55C6H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when DISABLE (table name DISABL) is given.
55C7
LD A,B 78
Copy Register B (the high byte of the DISABLE value) into Register A, to test the whole value.
55C8
OR C B1
OR Register C (the low byte of the DISABLE value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, DISABLE not given.
55C9
If the Z FLAG is set (no DISABLE), JUMP to 55D2H to test ENABLE.
55CB
LD A,C9H 3E C9
Load Register A with C9H, the opcode RET that marks a drive that is not there.
55CD
LD (IY+00H),A FD 77 00
Store Register A (C9H) to +00H of the drive code table at Index Register IY: a call of this drive's driver returns at once with error 20H (477AH), and SYS2/SYS does not use the drive.
55D0
JUMP to 55DEH and go on with STEP; ENABLE is not tested once DISABLE is given.
55D2
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the value of ENABLE: the operand 55D3H-55D4H is 0000H in the file and is written by 510FH (CALL 4476H at 5203H) when ENABLE is given.
55D5
LD A,B 78
Copy Register B (the high byte of the ENABLE value) into Register A, to test the whole value.
55D6
OR C B1
OR Register C (the low byte of the ENABLE value) into Register A: the Z FLAG is set when Register Pair BC is 0000H, ENABLE not given.
55D7
If the Z FLAG is set (no ENABLE), JUMP to 55DEH and go on with STEP.
55D9
LD A,C3H 3E C3
Load Register A with C3H, the opcode JP of a drive that is there.
55DB
LD (IY+00H),A FD 77 00
Store Register A (C3H) to +00H of the drive code table at Index Register IY: the table's JP to the driver at +01H-+02H is in force again.
55DEH - STEP: the Stepping Rate
STEP=n (0-3) puts n into bits 1-0 of +03H of the drive code table picked by DRIVE; the file's FFFFH (also STEP alone) means not given. 4 or more, or a table with +03H bit 3 set (a rigid disk), gives PARAMETER ERROR.
55DE
LD BC,FFFFH 01 FF FF
Self-Modifying Code
Load Register Pair BC with the value of STEP: the operand 55DFH-55E0H is FFFFH in the file (STEP not given) and is written by 510FH (CALL 4476H at 5203H): the rate for STEP=n.
55E1
INC B 04
Increment Register B (the high byte of the STEP value): the Z FLAG is set when it was FFH, STEP not given or given without a number.
55E2
If the Z FLAG is set (no STEP number), JUMP to 55FAH and go on with DELAY.
55E4
LD A,C 79
Copy Register C (the low byte of the STEP value, the rate number) into Register A.
55E5
CP 04H FE 04
Compare Register A (the rate number) against 04H: the NC FLAG is set for 4 or more.
55E7
If the NC FLAG is set (no such rate), JUMP to 5660H to display PARAMETER ERROR and abort.
55EA
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of +03H of the drive code table at Index Register IY, the rigid disk bit.
55EE
If the NZ FLAG is set (a rigid disk), JUMP to 5660H to display PARAMETER ERROR and abort.
55F1
LD A,(IY+03H) FD 7E 03
Fetch +03H of the drive code table at Index Register IY into Register A.
55F4
AND FCH E6 FC
AND Register A with FCH, clearing bits 1-0, the stepping rate.
55F6
OR C B1
OR Register C (the new rate, 0-3) into Register A.
55F7
LD (IY+03H),A FD 77 03
Store Register A to +03H of the drive code table at Index Register IY: the driver steps this drive at the new rate (6, 12, 20 or 40 ms on a 5 inch drive).
55FAH - DELAY: the Wait for a Drive That Is Not Ready
The DELAY value 0001H (the file's) means not given. DELAY=N (0000H) sets bit 2 of the drive code table's +03H, the shorter wait; any other value clears it, the longer wait of SYS0/SYS's drive select (4637H calls the delay once more when the bit is 0). A rigid disk (+03H bit 3) gives PARAMETER ERROR.
55FA
LD BC,0001H 01 01 00
Self-Modifying Code
Load Register Pair BC with the value of DELAY: the operand 55FBH-55FCH is 0001H in the file (DELAY not given) and is written by 510FH (CALL 4476H at 5203H): FFFFH for DELAY or DELAY=Y, 0000H for DELAY=N.
55FD
LD A,B 78
Copy Register B (the high byte of the DELAY value) into Register A, to combine both bytes.
55FE
OR C B1
OR Register C (the low byte of the DELAY value) into Register A: Register A = 01H when DELAY was not given, 00H for DELAY=N.
55FF
DEC A 3D
Decrement Register A: the Z FLAG is set only when Register A was 01H, DELAY not given.
5600
If the Z FLAG is set (no DELAY), JUMP to 5619H and go on with SYSGEN.
5602
INC A 3C
Increment Register A back to the combined value: the Z FLAG is set when it is 00H (DELAY=N).
5603
LD B,00H 06 00
Load Register B with 00H, the value of bit 2 for the longer wait, without changing the Z FLAG.
5605
If the NZ FLAG is set (DELAY or DELAY=Y), JUMP to 5609H with Register B = 00H.
5607
LD B,04H 06 04
Load Register B with 04H, bit 2 set: the shorter wait for DELAY=N.
5609
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of +03H of the drive code table at Index Register IY, the rigid disk bit.
560D
If the NZ FLAG is set (a rigid disk), JUMP to 5660H to display PARAMETER ERROR and abort.
5610
LD A,(IY+03H) FD 7E 03
Fetch +03H of the drive code table at Index Register IY into Register A.
5613
AND FBH E6 FB
AND Register A with FBH, clearing bit 2, the delay bit.
5615
OR B B0
OR Register B (00H or 04H, the new delay bit) into Register A.
5616
LD (IY+03H),A FD 77 03
Store Register A to +03H of the drive code table at Index Register IY: the drive select wait of this drive is set.
5619H - SYSGEN: Hand Over to Member 9
The SYSGEN value 0001H (the file's) means not given and the command ends at VTOS READY. Any other value (FFFFH for SYSGEN or SYSGEN=Y, 0000H for SYSGEN=OFF or N) is passed in Register Pair HL to member 9 of SYS6/SYS (code 1CH, which has no command word of its own), loaded and entered by RST 28H with Register A = 88H and Register B = 1CH. The request handler drops the RST 28H return address and member 9 does not return: it ends with JP 402DH, JP 4030H or JP 4409H.
5619
LD HL,0001H 21 01 00
Self-Modifying Code
Load Register Pair HL with the value of SYSGEN: the operand 561AH-561BH is 0001H in the file (SYSGEN not given) and is written by 510FH (CALL 4476H at 5203H): FFFFH for SYSGEN or SYSGEN=Y, 0000H for SYSGEN=OFF or N.
561C
LD A,H 7C
Copy Register H (the high byte of the SYSGEN value) into Register A, to combine both bytes.
561D
OR L B5
OR Register L (the low byte of the SYSGEN value) into Register A: Register A = 01H when SYSGEN was not given.
561E
DEC A 3D
Decrement Register A: the Z FLAG is set only when Register A was 01H, SYSGEN not given.
561F
If the Z FLAG is set (no SYSGEN), JUMP to 402DH: VTOS READY, the command is done.
5622
LD B,1CH 06 1C
Load Register B with 1CH, the member code of member 9 of SYS6/SYS, which writes or removes the configuration on the diskette.
5624
LD A,88H 3E 88
Load Register A with 88H, the request that loads a member of SYS6/SYS (always read from the diskette).
5626
RST 28H EF
RST 28H: SYS0/SYS's request handler loads member 1CH and calls its entry 5200H with Register Pair HL = the SYSGEN value; this member is overwritten and nothing after the RST is reached from here.
5627H - Refuse to Run Under BASIC
Called by TYPE, LOWER, JKL and ALIVE before they lower the top of memory. 402DH holds LD A,93H (3EH) in SYS0/SYS's file; BASIC/CMD puts a JP there (C3H, its 66A9H), and then the routine displays CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL and aborts the command through 4030H.
5627
LD A,(402DH) 3A 2D 40
Fetch the first byte of the normal exit at 402DH into Register A: 3EH (LD A,93H) from SYS0/SYS, C3H when BASIC/CMD has put a JP there.
562A
CP C3H FE C3
Compare Register A against C3H, the opcode JP: the Z FLAG is set when a program has taken over the exit at 402DH.
562C
RET NZ C0
If the NZ FLAG is set (the normal exit is in place), RETURN to the caller and go on with the option.
562D
LD HL,5636H 21 36 56
Point Register Pair HL to 5636H, the message CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL ended by 0DH.
5630
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
5633
JUMP to 4030H, the abort exit (request A3H, SYS1/SYS function 2), which ends the command; the options not yet processed are not done.
5636-565E
DEFM "CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL" 43 41 4E 27 54 20 2D 2D 20 4F 4E 4C 59 20 56 41 4C 49 44 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C
The message 5627H displays when 402DH holds a JP, shown with 447BH.
565F
DEFB 0DH 0D
The carriage return that ends the message at 5636H and moves the cursor to the next line.
5660H - PARAMETER ERROR
Reached from 5206H (510FH found an unknown name or a bad value), 55BEH (a drive number of 8 or more), 55E7H and 55EEH (a bad STEP), and 560DH (DELAY on a rigid disk). The options before the failing one have already been done.
5660
LD HL,5669H 21 69 56
Point Register Pair HL to 5669H, the message PARAMETER ERROR ended by 0DH.
5663
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
5666
JUMP to 4030H, the abort exit (request A3H, SYS1/SYS function 2), which ends the command.
5669-5677
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message 5660H displays with 447BH when a parameter is wrong.
5678
DEFB 0DH 0D
The carriage return that ends the message at 5669H.
5679H - The Parameter Table
18 entries of 8 bytes for SYS1/SYS's 510FH (5200H-5203H): 6 characters of name (padded with spaces; a word typed longer is matched on its first 6 characters by 50BCH), then the address of the word that takes the value. The words are the operands of the LD BC (LD HL for SYSGEN) instructions that test each option, except LARGE's, which is in memory the file does not load. A 00H byte ends the table.
5679-5680
DEFM "FAST " / DEFW 5211H 46 41 53 54 20 20 11 52
Entry 1: FAST, its value into 5211H-5212H, the operand of LD BC at 5210H (fast clock).
5681-5688
DEFM "SLOW " / DEFW 520AH 53 4C 4F 57 20 20 0A 52
Entry 2: SLOW, its value into 520AH-520BH, the operand of LD BC at 5209H (standard clock, tested before FAST).
5689-5690
DEFM "BASIC2" / DEFW 522FH 42 41 53 49 43 32 2F 52
Entry 3: BASIC2, its value into 522FH-5230H, the operand of LD BC at 522EH (restart the ROM's BASIC).
5691-5698
DEFM "BREAK " / DEFW 524CH 42 52 45 41 4B 20 4C 52
Entry 4: BREAK, its value into 524CH-524DH, the operand of LD BC at 524BH (BREAK key on or off).
5699-56A0
DEFM "BLINK " / DEFW 5270H 42 4C 49 4E 4B 20 70 52
Entry 5: BLINK, its value into 5270H-5271H, the operand of LD BC at 526FH (the blinking cursor or its character).
56A1-56A8
DEFM "LARGE " / DEFW 52C5H 4C 41 52 47 45 20 C5 52
Entry 6: LARGE, its value into 52C5H-52C6H, in the bytes the file does not load between 52C4H and 52CCH. No instruction reads them, so LARGE does nothing (the large cursor is the default).
56A9-56B0
DEFM "SMALL " / DEFW 528BH 53 4D 41 4C 4C 20 8B 52
Entry 7: SMALL, its value into 528BH-528CH, the operand of LD BC at 528AH (the small cursor 88H).
56B1-56B8
DEFM "TYPE " / DEFW 5306H 54 59 50 45 20 20 06 53
Entry 8: TYPE, its value into 5306H-5307H, the operand of LD BC at 5305H (type-ahead).
56B9-56C0
DEFM "LOWER " / DEFW 5480H 4C 4F 57 45 52 20 80 54
Entry 9: LOWER, its value into 5480H-5481H, the operand of LD BC at 547FH (lower case display driver).
56C1-56C8
DEFM "JKL " / DEFW 54DEH 4A 4B 4C 20 20 20 DE 54
Entry 10: JKL, its value into 54DEH-54DFH, the operand of LD BC at 54DDH (screen print with J, K and L).
56C9-56D0
DEFM "GRAPHI" / DEFW 54E9H 47 52 41 50 48 49 E9 54
Entry 11: GRAPHI (GRAPHIC typed in full matches it), its value into 54E9H-54EAH, the operand of LD BC at 54E8H (print graphics codes as they are).
56D1-56D8
DEFM "ALIVE " / DEFW 5573H 41 4C 49 56 45 20 73 55
Entry 12: ALIVE, its value into 5573H-5574H, the operand of LD BC at 5572H (the alive indicator at 3C3FH).
56D9-56E0
DEFM "DRIVE " / DEFW 55B5H 44 52 49 56 45 20 B5 55
Entry 13: DRIVE, its value into 55B5H-55B6H, the operand of LD BC at 55B4H (the drive for the next four options).
56E1-56E8
DEFM "ENABLE" / DEFW 55D3H 45 4E 41 42 4C 45 D3 55
Entry 14: ENABLE, its value into 55D3H-55D4H, the operand of LD BC at 55D2H (C3H into the drive code table's +00H).
56E9-56F0
DEFM "DISABL" / DEFW 55C5H 44 49 53 41 42 4C C5 55
Entry 15: DISABL (DISABLE typed in full matches it), its value into 55C5H-55C6H, the operand of LD BC at 55C4H (C9H into the drive code table's +00H).
56F1-56F8
DEFM "STEP " / DEFW 55DFH 53 54 45 50 20 20 DF 55
Entry 16: STEP, its value into 55DFH-55E0H, the operand of LD BC at 55DEH (the stepping rate 0-3).
56F9-5700
DEFM "DELAY " / DEFW 55FBH 44 45 4C 41 59 20 FB 55
Entry 17: DELAY, its value into 55FBH-55FCH, the operand of LD BC at 55FAH (the drive select wait).
5701-5708
DEFM "SYSGEN" / DEFW 561AH 53 59 53 47 45 4E 1A 56
Entry 18: SYSGEN, its value into 561AH-561BH, the operand of LD HL at 5619H (passed on to member 9).
5709
DEFB 00H 00
The 00H byte that ends the parameter table at 5679H for 510FH.
5200H - Member 14 (SPOOL, Code A2H): Eight Bytes Before the Entry
SYS6/SYS member 14 is the SPOOL command, entry code A2H, entered at 5208H. It puts a queue in front of the output of a device: the characters sent to the device go into 256 byte memory pages, which a task in slot 9 hands to the device's own driver as fast as it takes them, with records of a disk file as overflow. The member has seven load blocks (5200H-52FDH, 52FEH-53FBH, 53FCH-548AH, 54ABH-5574H, 5577H-55B8H, 55BCH-5629H and 5654H-5655H, 1031 bytes); 54D3H-5629H is the resident part, which 53BAH-53BDH copies to the top of memory, where it runs. The first 8 bytes of the member come before the entry and are not used.
5200-5207
DEFB 00H x 8 00 x 8
Eight 00H bytes at 5200H-5207H, before the entry 5208H of the member header. No row of the member reads, writes or jumps to them; they are loaded and never used.
5208H - SPOOL (Code A2H): Read the Device and the File
Entered from SYS0/SYS's request handler with Register Pair HL at the text after the command word SPOOL. The command takes a device specification (an asterisk and the device name), then an optional file specification, then an optional list (MEM=m,DISK=d). SPOOL is refused when the exit 402DH holds a JP (BASIC/CMD stores C3H there at its 66A9H). The device specification goes into the block at 548BH; the file specification into 562AH, by default the name of the device with the extension SPL ("XX/SPL" at 54ABH with XX replaced); a specification that is only a colon and a drive number gets that drive put after the default name.
5208
LD A,(402DH) 3A 2D 40
Fetch the first byte of the exit at 402DH into Register A: 3EH (LD A,93H) as SYS0/SYS loads it, C3H when a program such as BASIC/CMD has put a JP there.
520B
CP C3H FE C3
Compare Register A (the first byte of 402DH) against C3H, the opcode of JP: the Z FLAG is set when the exit has been taken over.
520D
If the Z FLAG is set (402DH holds a JP), JUMP to 543FH to display CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL and abort.
5210
LD DE,548BH 11 8B 54
Point Register Pair DE to 548BH, the control block the device specification is read into.
5213
GOSUB to 441CH (SYS1/SYS function 4) to read a specification from the command line at Register Pair HL into the block at Register Pair DE (548BH). It returns the Z FLAG when one was read, Register Pair HL past it and Register Pair DE at 548BH.
5216
If the NZ FLAG is set (no specification was read), JUMP to 5421H to display DEVICE SPEC REQUIRED and abort.
5219
LD A,(DE) 1A
Fetch the first character of the specification at Register Pair DE (548BH) into Register A.
521A
CP 2AH FE 2A
Compare Register A (the first character of the specification) against 2AH, an asterisk: a device specification starts with one.
521C
If the NZ FLAG is set (a file name, not a device), JUMP to 5421H to display DEVICE SPEC REQUIRED and abort.
521F
LD DE,(548CH) ED 5B 8C 54
Load Register Pair DE with the two characters after the asterisk at 548CH-548DH: Register E = the first character of the device name, Register D = the second (03H for a name of one character).
5223
LD (54ABH),DE ED 53 AB 54
Store Register Pair DE (the device name) to 54ABH-54ACH, over the XX of the default file specification XX/SPL: a device PR gives the file name PR/SPL.
5227
LD DE,562AH 11 2A 56
Point Register Pair DE to 562AH, the control block of the spool file.
522A
GOSUB to 441CH (SYS1/SYS function 4) to read the next specification from Register Pair HL into the block at Register Pair DE (562AH). The Z FLAG is set and Register A = 00H when a file specification was read; otherwise the NZ FLAG is set and Register A = the character where the reading stopped (3AH, a colon, for a specification that is only a colon and a drive number, with Register Pair HL past the colon).
522D
PUSH AF F5
Save Register Pair AF (Register A and the flags of the file specification read) to the stack, for 523CH.
522E
PUSH HL E5
Save Register Pair HL (the command line, past the file specification when there was one, else past a colon or at an opening parenthesis or 0DH) to the stack, for 523BH.
522F
LD HL,54ABH 21 AB 54
Point Register Pair HL to 54ABH, the default file specification (the device name, then /SPL and 03H).
5232
If the NZ FLAG is set (no file specification was read at 522AH), GOSUB to 441CH to read the default specification at Register Pair HL (54ABH) into the block at Register Pair DE (562AH) instead.
5235
LD HL,54AEH 21 AE 54
Point Register Pair HL to 54AEH, the three letters SPL.
5238
GOSUB to 4473H (SYS1/SYS function 5) to put the default extension at Register Pair HL (SPL) after the name in the block at Register Pair DE (562AH) when it has no extension. Register Pair DE is returned unchanged.
523B
POP HL E1
Restore Register Pair HL from the stack: the command line after the file specification (saved at 522EH).
523C
POP AF F1
Restore Register Pair AF from the stack: Register A and the flags of the file specification read at 522AH.
523D
CP 3AH FE 3A
Compare Register A (the character the file specification read ended on) against 3AH, a colon: the Z FLAG is set when only a drive was given.
523F
If the NZ FLAG is set (a file specification was read, or no colon), JUMP to 525DH to read the parameters.
5241H - Put the Drive After the Default Name
Only a colon and a drive were given: the end of the specification in the block at 562AH is found (03H or 0DH) and replaced by the colon, the character after the colon in the command line and a new 03H. The drive character is not checked here; only 0DH is refused.
5241
LD A,(DE) 1A
Fetch a character of the specification at Register Pair DE (from 562AH up) into Register A. Loop Start
The search for the end of the specification.
5242
CP 0DH FE 0D
Compare Register A (a character of the specification) against 0DH, a carriage return.
5244
If the Z FLAG is set (0DH: the end), JUMP to 524DH to put the drive there.
5246
CP 03H FE 03
Compare Register A (a character of the specification) against 03H, the end of text that 441CH puts after a specification.
5248
If the Z FLAG is set (03H: the end), JUMP to 524DH to put the drive there.
524A
INC DE 13
Increment Register Pair DE to the next character of the specification in the block.
524B
JUMP back to 5241H to test the next character at Register Pair DE.
524D
LD A,3AH 3E 3A
Load Register A with 3AH, a colon, the start of the drive field.
524F
LD (DE),A 12
Store Register A (the colon) to Register Pair DE, over the 03H or 0DH that ended the specification.
5250
INC DE 13
Increment Register Pair DE to the byte after the colon.
5251
LD A,(HL) 7E
Fetch the character after the colon in the command line at Register Pair HL into Register A: the drive.
5252
CP 0DH FE 0D
Compare Register A (the character after the colon) against 0DH, the end of the command line.
5254
If the Z FLAG is set (nothing after the colon), JUMP to 5472H to display PARAMETER ERROR and abort.
5257
INC HL 23
Increment Register Pair HL past the drive character in the command line.
5258
LD (DE),A 12
Store Register A (the drive character) to the block at Register Pair DE, after the colon.
5259
INC DE 13
Increment Register Pair DE to the byte after the drive.
525A
LD A,03H 3E 03
Load Register A with 03H, the end of text of a specification.
525C
LD (DE),A 12
Store Register A (03H) to Register Pair DE, after the drive: the block at 562AH now holds the default name with the drive, for example PR/SPL:1.
525DH - Read the Parameters and Find the Device
The parameter list (MEM=m,DISK=d, or M and D) goes through 4476H with the table at 54B2H, which stores MEM's value at 52C9H and DISK's at 5295H (the operands of LD BC at 52C8H and 5294H, defaults 1 and 4). Then the device control block of the device is found by its name and, when it is routed, the route is followed to the block that has the driver; its address goes to 536FH.
525D
LD DE,54B2H 11 B2 54
Point Register Pair DE to 54B2H, the table of the parameters MEM, M, DISK and D.
5260
GOSUB to 4476H (SYS1/SYS function 6) to read the parameter list in parentheses from the command line at Register Pair HL against the table at Register Pair DE (54B2H): MEM or M stores its value at 52C9H-52CAH, DISK or D at 5295H-5296H. No list leaves the defaults and returns the Z FLAG.
5263
If the NZ FLAG is set (an unknown parameter or a bad value), JUMP to 5472H to display PARAMETER ERROR and abort.
5266
LD DE,(548CH) ED 5B 8C 54
Load Register Pair DE with the device name at 548CH-548DH: Register E = the first character, Register D = the second.
526A
GOSUB to 53F6H to find the device control block whose name is Register Pair DE. It returns the Z FLAG and Register Pair HL = the block, or the NZ FLAG and Register A = 08H.
526D
If the NZ FLAG is set (no device of that name), JUMP to 541CH to display error 08H, DEVICE NOT AVAILABLE, and abort.
5270
BIT 4,(HL) CB 66
Test bit 4 of the type byte at Register Pair HL (the device control block): bit 4 set (10H) means the device is routed to another block. Loop Start
The route is followed until a block that is not routed.
5272
If the Z FLAG is set (bit 4 clear: not routed), JUMP to 527BH: Register Pair HL is the block whose driver is to be spooled.
5274
INC HL 23
Increment Register Pair HL to byte +01H of the routed block, the low byte of the block it is routed to.
5275
LD A,(HL) 7E
Fetch the low byte of the route target from Register Pair HL into Register A.
5276
INC HL 23
Increment Register Pair HL to byte +02H, the high byte of the route target.
5277
LD H,(HL) 66
Fetch the high byte of the route target from Register Pair HL into Register H.
5278
LD L,A 6F
Copy Register A (the low byte of the route target) into Register L: Register Pair HL = the device control block the route goes to.
5279
JUMP back to 5270H to test the type byte of the block at Register Pair HL.
527B
LD (536FH),HL 22 6F 53
Store Register Pair HL (the device control block with the driver) to 536FH-5370H, the operand of LD HL,0000H at 536EH, for 536EH and 53C1H.
527EH - Make the Disk File
When DISK is not 0 the spool file is opened (created when it does not exist) with records of 256 bytes, written out to DISK x 4 records (DISK K), and its directory record gets bit 7 of byte +01H set, the bit that keeps a close (SYS3/SYS 4E91H) from giving space back. The buffer of the open is 4200H; the resident code points the buffer at a memory page before each record it moves.
527E
LD DE,(5295H) ED 5B 95 52
Load Register Pair DE with DISK's value from 5295H-5296H (the operand of LD BC,0004H at 5294H: 0004H unless the parameter list gave another).
5282
LD A,D 7A
Copy Register D (the high byte of DISK's value) into Register A.
5283
OR E B3
OR Register A with Register E (the low byte of DISK's value): the Z FLAG is set when DISK is 0.
5284
If the Z FLAG is set (DISK=0: no disk file), JUMP to 52C8H to check MEM's value.
5286
LD DE,562AH 11 2A 56
Point Register Pair DE to 562AH, the control block of the spool file (its specification as text).
5289
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, as the buffer of the file.
528C
LD B,00H 06 00
Load Register B with 00H, the record length 256.
528E
GOSUB to 4420H (SYS2/SYS function 2) to open the file of the block at Register Pair DE (562AH) with the buffer at Register Pair HL (4200H) and the record length Register B (256), creating it when it does not exist. It returns the Z FLAG when the file is open.
5291
If the NZ FLAG is set (the open failed, Register A = the error), JUMP to 541CH to display the error and abort.
5294
LD BC,0004H 01 04 00
Load Register Pair BC with DISK's value. Self-Modifying Code
The operand 5295H-5296H is DISK's value: 0004H (4K) in the file, written by 4476H (called at 5260H) when the list gives DISK=d or D=d, and read at 527EH, 52DBH and 530FH.
5297
LD A,B 78
Copy Register B (the high byte of DISK's value) into Register A.
5298
AND F0H E6 F0
Mask Register A (the high byte of DISK's value) to bits 7-4: not zero for a value of 1000H (4096) or more.
529A
If the NZ FLAG is set (DISK is 4096 or more), JUMP to 5472H to display PARAMETER ERROR and abort. The file is already open by then.
529D
SLA C CB 21
Shift Register C (the low byte of DISK's value) left one bit, bit 7 into the CARRY FLAG.
529F
RL B CB 10
Rotate Register B left through the CARRY FLAG: Register Pair BC = DISK x 2.
52A1
SLA C CB 21
Shift Register C left one bit again, bit 7 into the CARRY FLAG.
52A3
RL B CB 10
Rotate Register B left through the CARRY FLAG: Register Pair BC = DISK x 4, the records of 256 bytes in DISK K.
52A5
DEC BC 0B
Decrement Register Pair BC: the number of the last record, DISK x 4 less 1 (records are counted from 0).
52A6
GOSUB to 4442H to position the open file at Register Pair DE (562AH) to the record Register Pair BC, the last record the spooler uses.
52A9
GOSUB to 4439H to write a record of the file at Register Pair DE (562AH): the buffer 4200H goes to the last record, so that the file holds DISK x 4 records. It returns the Z FLAG when the write worked.
52AC
If the NZ FLAG is set (the write failed, Register A = the error), JUMP to 541CH to display the error and abort.
52AF
GOSUB to 443FH to rewind the file at Register Pair DE (562AH) to its first record.
52B2
GOSUB to 444EH to write any changed buffer of the file at Register Pair DE (562AH) and store its ending record number in its directory record.
52B5
LD BC,(5630H) ED 4B 30 56
Load Register Pair BC from 5630H-5631H, bytes +06H and +07H of the file's control block: Register C = the drive, Register B = the directory entry code of the file.
52B9
GOSUB to 4B10H to read the directory sector of the entry code Register B on the drive Register C into 4200H; it returns Register Pair HL at the file's directory record and the Z FLAG when the read worked.
52BC
If the NZ FLAG is set (directory read error, Register A = the error), JUMP to 541CH to display the error and abort.
52BF
INC HL 23
Increment Register Pair HL to byte +01H of the directory record at Register Pair HL.
52C0
SET 7,(HL) CB FE
Set bit 7 of byte +01H of the directory record at Register Pair HL: a close of this file (SYS3/SYS 4E91H) will not give back any of its granules.
52C2
GOSUB to 4B1FH to write the directory sector at 4200H back (with read back check); it returns the Z FLAG when the write worked.
52C5
If the NZ FLAG is set (directory write error, Register A = the error), JUMP to 541CH to display the error and abort.
52C8H - Lay Out the Memory: Pages and the Page Table
MEM is checked (1 to 32). The memory pages go just below the top of memory: the top (4049H) plus 1 is rounded down to a page boundary and MEM x 4 pages are taken below it. Below the pages goes the page table, 4 bytes an entry: +00H-+01H the link to the next entry of the queue (0000H free, the entry itself for the last), +02H the page (memory) or the low byte of the record (disk), +03H 00H for a memory page or the high byte of the record OR 80H for a disk record. First MEM x 4 memory entries, then DISK x 4 disk entries, then the end entry 00H 00H FFH FFH. The table is (DISK + MEM) x 16 + 4 bytes.
52C8
LD BC,0001H 01 01 00
Load Register Pair BC with MEM's value. Self-Modifying Code
The operand 52C9H-52CAH is MEM's value: 0001H (1K) in the file, written by 4476H (called at 5260H) when the list gives MEM=m or M=m, and read at 52EBH.
52CB
LD A,B 78
Copy Register B (the high byte of MEM's value) into Register A.
52CC
OR A B7
OR Register A with itself: the NZ FLAG is set when MEM is 256 or more.
52CD
If the NZ FLAG is set (MEM is 256 or more), JUMP to 5472H to display PARAMETER ERROR and abort.
52D0
LD A,C 79
Copy Register C (the low byte of MEM's value) into Register A.
52D1
CP 21H FE 21
Compare Register A (MEM's value) against 21H (33): the NC FLAG is set for 33 or more.
52D3
If the NC FLAG is set (MEM is more than 32), JUMP to 5472H to display PARAMETER ERROR and abort.
52D6
SUB 01H D6 01
SUBtract 01H from Register A (MEM's value): the C FLAG is set when MEM is 0.
52D8
If the C FLAG is set (MEM=0), JUMP to 5472H to display PARAMETER ERROR and abort.
52DB
LD HL,(5295H) 2A 95 52
Load Register Pair HL with DISK's value from 5295H-5296H (0 when no disk file is used).
52DE
ADD HL,BC 09
Add Register Pair BC (MEM's value) to Register Pair HL: Register Pair HL = DISK + MEM, the K of memory and disk together.
52DF
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = (DISK + MEM) x 2.
52E0
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = (DISK + MEM) x 4, the number of 256 byte pages and records.
52E1
INC HL 23
Increment Register Pair HL: one entry more, for the end entry of the table.
52E2
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = the entries x 2.
52E3
ADD HL,HL 29
Add Register Pair HL to itself: Register Pair HL = the entries x 4, the bytes of the page table ((DISK + MEM) x 16 + 4).
52E4
PUSH HL E5
Save Register Pair HL (the size of the page table) to the stack, for 52FCH.
52E5
LD HL,(4049H) 2A 49 40
Load Register Pair HL with the top of memory from 4049H-404AH.
52E8
INC HL 23
Increment Register Pair HL: the first byte above the top of memory.
52E9
LD L,00H 2E 00
Load Register L with 00H: Register Pair HL = that address rounded down to a page boundary (0000H when the top is FFFFH).
52EB
LD A,(52C9H) 3A C9 52
Fetch MEM's value from 52C9H (the low byte of the operand of LD BC at 52C8H) into Register A.
52EE
RLCA 07
Rotate Register A (MEM's value, 1 to 32) left: Register A = MEM x 2.
52EF
RLCA 07
Rotate Register A left again: Register A = MEM x 4, the number of 256 byte memory pages.
52F0
LD B,A 47
Copy Register A (the number of memory pages) into Register B, the count of the loop at 5301H.
52F1
NEG ED 44
Negate Register A: Register A = 0 less the number of pages.
52F3
ADD A,H 84
Add Register H (the page above the top of memory) to Register A: Register A = the first memory page.
52F4
LD H,A 67
Copy Register A (the first memory page) into Register H: Register Pair HL = the start of the memory pages, offset 00H.
52F5
LD (564AH),HL 22 4A 56
Store Register Pair HL (the first memory page, offset 00H) to 564AH-564BH: the write pointer, where the first character goes.
52F8
LD (564CH),HL 22 4C 56
Store Register Pair HL (the first memory page, offset 00H) to 564CH-564DH: the read pointer, where printing starts.
52FB
LD C,H 4C
Copy Register H (the first memory page) into Register C, the page of the first table entry.
52FC
POP DE D1
Restore Register Pair DE from the stack: the size of the page table (pushed at 52E4H).
52FD
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the SBC below.
52FE
SBC HL,DE ED 52
SUBtract Register Pair DE (the size of the table) from Register Pair HL (the start of the memory pages): Register Pair HL = the start of the page table.
5300
PUSH HL E5
Save Register Pair HL (the start of the page table) to the stack, for 533FH.
5301
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL, the low byte of the link of a memory entry: free. Loop Start
One memory entry for each page, Register B times.
5303
INC HL 23
Increment Register Pair HL to byte +01H of the entry.
5304
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL, the high byte of the link: the link is 0000H, the entry is free.
5306
INC HL 23
Increment Register Pair HL to byte +02H of the entry.
5307
LD (HL),C 71
Store Register C (the memory page) to byte +02H of the entry at Register Pair HL.
5308
INC HL 23
Increment Register Pair HL to byte +03H of the entry.
5309
LD (HL),00H 36 00
Store 00H to byte +03H of the entry at Register Pair HL: bit 7 clear, a memory page.
530B
INC HL 23
Increment Register Pair HL to the next entry.
530C
INC C 0C
Increment Register C to the next memory page.
530D
Decrement Register B (the memory pages left) and JUMP back to 5301H while it is not zero.
530F
LD DE,(5295H) ED 5B 95 52
Load Register Pair DE with DISK's value from 5295H-5296H.
5313
LD A,D 7A
Copy Register D (the high byte of DISK's value) into Register A.
5314
OR E B3
OR Register A with Register E (the low byte of DISK's value): the Z FLAG is set when DISK is 0.
5315
If the Z FLAG is set (no disk file), JUMP to 5334H to put the end entry in.
5317
SLA E CB 23
Shift Register E (the low byte of DISK's value) left one bit, bit 7 into the CARRY FLAG.
5319
RL D CB 12
Rotate Register D left through the CARRY FLAG: Register Pair DE = DISK x 2.
531B
SLA E CB 23
Shift Register E left one bit again, bit 7 into the CARRY FLAG.
531D
RL D CB 12
Rotate Register D left through the CARRY FLAG: Register Pair DE = DISK x 4, the number of records, the count of the loop at 5322H.
531F
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the first record number of the file.
5322
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL, the low byte of the link of a disk entry: free. Loop Start
One disk entry for each record, Register Pair DE times.
5324
INC HL 23
Increment Register Pair HL to byte +01H of the entry.
5325
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL, the high byte of the link: the link is 0000H, the entry is free.
5327
INC HL 23
Increment Register Pair HL to byte +02H of the entry.
5328
LD (HL),C 71
Store Register C (the low byte of the record number) to byte +02H of the entry at Register Pair HL.
5329
INC HL 23
Increment Register Pair HL to byte +03H of the entry.
532A
LD (HL),B 70
Store Register B (the high byte of the record number) to byte +03H of the entry at Register Pair HL.
532B
SET 7,(HL) CB FE
Set bit 7 of byte +03H of the entry at Register Pair HL: a disk record.
532D
INC HL 23
Increment Register Pair HL to the next entry.
532E
INC BC 03
Increment Register Pair BC to the next record number.
532F
DEC DE 1B
Decrement Register Pair DE, the records left.
5330
LD A,D 7A
Copy Register D (the high byte of the records left) into Register A.
5331
OR E B3
OR Register A with Register E (the low byte of the records left): the Z FLAG is set when none is left.
5332
If the NZ FLAG is set (records are left), JUMP back to 5322H for the next disk entry.
5334
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL, byte +00H of the end entry.
5336
INC HL 23
Increment Register Pair HL to byte +01H of the end entry.
5337
LD (HL),00H 36 00
Store 00H to the address at Register Pair HL: the end entry's link is 0000H, so the search for a free entry (54F9H) stops at it.
5339
INC HL 23
Increment Register Pair HL to byte +02H of the end entry.
533A
LD (HL),FFH 36 FF
Store FFH to byte +02H of the end entry at Register Pair HL.
533C
INC HL 23
Increment Register Pair HL to byte +03H of the end entry.
533D
LD (HL),FFH 36 FF
Store FFH to byte +03H of the end entry at Register Pair HL: FFH there marks the end of the table (550AH).
533FH - Set Up the Queue Block and the Resident Code
The queue starts with the first memory entry alone, linked to itself: it is the head (the page being printed) and the tail (the page being filled). The queue block, 2CH bytes below the table, is the control block of the spool file (+00H-+1FH, from 562AH) and the pointers +20H-+2BH (from 564AH-5655H). 157H bytes below it go the resident code (54D3H-5629H), whose first byte is called the spooler base below; the top of memory becomes the spooler base less 1. Before the copy, the operands of the resident code are written with the run addresses: the queue block, the queue block + 23H, the spooler base + 09H, + A7H, + E9H, the device's own driver and the three bytes of 4300H.
533F
POP HL E1
Restore Register Pair HL from the stack: the start of the page table (pushed at 5300H).
5340
PUSH HL E5
Save Register Pair HL (the start of the table) to the stack again, for 534EH.
5341
LD (564EH),HL 22 4E 56
Store Register Pair HL (the start of the table) to 564EH-564FH: the place where the search for a free entry starts (queue block +24H).
5344
LD (5650H),HL 22 50 56
Store Register Pair HL (the first entry) to 5650H-5651H: the tail of the queue, the entry of the page being filled (queue block +26H).
5347
LD (5652H),HL 22 52 56
Store Register Pair HL (the first entry) to 5652H-5653H: the head of the queue, the entry of the page being printed (queue block +28H).
534A
LD A,H 7C
Copy Register H (the high byte of the first entry's address) into Register A.
534B
LD (HL),L 75
Store Register L (the low byte of the first entry's address) to the entry's link at Register Pair HL.
534C
INC HL 23
Increment Register Pair HL to the high byte of the link.
534D
LD (HL),A 77
Store Register A (the high byte of the first entry's address) to Register Pair HL: the first entry links to itself, in use and the last of the queue.
534E
POP HL E1
Restore Register Pair HL from the stack: the start of the page table.
534F
LD BC,002CH 01 2C 00
Load Register Pair BC with 002CH, the 44 bytes of the queue block.
5352
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the SBC below.
5353
SBC HL,BC ED 42
SUBtract Register Pair BC (2CH) from Register Pair HL (the start of the table): Register Pair HL = the queue block.
5355
PUSH HL E5
Save Register Pair HL (the queue block) to the stack, for 535CH.
5356
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the queue block, the destination of the copy.
5357
LD HL,562AH 21 2A 56
Point Register Pair HL to 562AH, the control block of the spool file, followed by the pointers 564AH-5655H.
535A
LDIR ED B0
Copy Register Pair BC (2CH) bytes from Register Pair HL (562AH-5655H) to Register Pair DE (the queue block): the file's control block to +00H-+1FH, the write pointer to +20H-+21H, the read pointer to +22H-+23H, the table start to +24H-+25H, the tail to +26H-+27H, the head to +28H-+29H and 0000H to +2AH-+2BH. Register Pair BC ends at 0000H.
535C
POP HL E1
Restore Register Pair HL from the stack: the queue block.
535D
PUSH HL E5
Save Register Pair HL (the queue block) to the stack again, for 5389H.
535E
LD (54DEH),HL 22 DE 54
Store Register Pair HL (the queue block) to 54DEH-54DFH, the operand of LD IX,0000H at 54DCH.
5361
LD (558AH),HL 22 8A 55
Store Register Pair HL (the queue block) to 558AH-558BH, the operand of LD IX,0000H at 5588H.
5364
LD (55CAH),HL 22 CA 55
Store Register Pair HL (the queue block) to 55CAH-55CBH, the operand of LD IX,0000H at 55C8H.
5367
LD BC,0023H 01 23 00
Load Register Pair BC with 0023H, the offset of the read page in the queue block.
536A
ADD HL,BC 09
Add Register Pair BC (23H) to Register Pair HL (the queue block): Register Pair HL = the queue block + 23H, the read page.
536B
LD (55BEH),HL 22 BE 55
Store Register Pair HL (the queue block + 23H) to 55BEH-55BFH, the operand of LD A,(0000H) at 55BDH.
536E
LD HL,0000H 21 00 00
Load Register Pair HL with the device control block that has the driver. Self-Modifying Code
The operand 536FH-5370H is 0000H in the file; 527BH writes the block found by 526AH-5279H there before this row runs, and 53C1H reads it again.
5371
INC HL 23
Increment Register Pair HL to byte +01H of the device control block, the low byte of its driver's address.
5372
LD C,(HL) 4E
Fetch the low byte of the driver's address from Register Pair HL into Register C.
5373
INC HL 23
Increment Register Pair HL to byte +02H, the high byte of the driver's address.
5374
LD B,(HL) 46
Fetch the high byte of the driver's address from Register Pair HL into Register B: Register Pair BC = the device's own driver.
5375
LD (5583H),BC ED 43 83 55
Store Register Pair BC (the device's own driver) to 5583H-5584H, the operand of CALL 0000H at 5582H.
5379
LD (55A9H),BC ED 43 A9 55
Store Register Pair BC (the device's own driver) to 55A9H-55AAH, the operand of CALL 0000H at 55A8H.
537D
LD A,(4300H) 3A 00 43
Fetch the first byte of the keyboard hook at 4300H into Register A (C9H, a RET, as SYS0/SYS loads it).
5380
LD HL,(4301H) 2A 01 43
Load Register Pair HL with the other two bytes of the hook from 4301H-4302H.
5383
LD (55B9H),A 32 B9 55
Store Register A (the first byte of the hook) to 55B9H, after the CALL at 55B6H.
5386
LD (55BAH),HL 22 BA 55
Store Register Pair HL (the other two bytes of the hook) to 55BAH-55BBH: 55B9H-55BBH now hold the old hook, which runs after the spooler's call.
5389
POP HL E1
Restore Register Pair HL from the stack: the queue block.
538A
LD BC,0157H 01 57 01
Load Register Pair BC with 0157H, the 343 bytes of the resident code (54D3H-5629H). Register Pair BC keeps this value for the LDIR at 53BDH.
538D
XOR A AF
Set Register A to 00H and clear the CARRY FLAG for the SBC below.
538E
SBC HL,BC ED 42
SUBtract Register Pair BC (157H) from Register Pair HL (the queue block): Register Pair HL = the spooler base, where the copy of 54D3H goes.
5390
DEC HL 2B
Decrement Register Pair HL: the spooler base less 1, the new top of memory.
5391
LD (4049H),HL 22 49 40
Store Register Pair HL (the spooler base less 1) to 4049H-404AH, the top of memory: the spooler, its queue block, the table and the pages are above it.
5394
INC HL 23
Increment Register Pair HL back to the spooler base.
5395
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack, for 539DH.
5396
LD DE,0009H 11 09 00
Load Register Pair DE with 0009H, the offset of 54DCH in the resident code.
5399
ADD HL,DE 19
Add Register Pair DE (09H) to Register Pair HL: Register Pair HL = the spooler base + 09H, the run address of 54DCH.
539A
LD (54D8H),HL 22 D8 54
Store Register Pair HL (the spooler base + 09H) to 54D8H-54D9H, the operand of CALL 0000H at 54D7H.
539D
POP HL E1
Restore Register Pair HL from the stack: the spooler base.
539E
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack again, for 53A9H.
539F
LD DE,00E9H 11 E9 00
Load Register Pair DE with 00E9H, the offset of 55BCH in the resident code.
53A2
ADD HL,DE 19
Add Register Pair DE (E9H) to Register Pair HL: Register Pair HL = the spooler base + E9H, the run address of 55BCH.
53A3
LD (5514H),HL 22 14 55
Store Register Pair HL (the spooler base + E9H) to 5514H-5515H, the operand of CALL 0000H at 5513H.
53A6
LD (55B7H),HL 22 B7 55
Store Register Pair HL (the spooler base + E9H) to 55B7H-55B8H, the operand of CALL 0000H at 55B6H.
53A9
POP HL E1
Restore Register Pair HL from the stack: the spooler base.
53AA
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack again, for 53B8H.
53AB
LD DE,00A7H 11 A7 00
Load Register Pair DE with 00A7H, the offset of 557AH in the resident code.
53AE
ADD HL,DE 19
Add Register Pair DE (A7H) to Register Pair HL: Register Pair HL = the spooler base + A7H, the run address of 557AH.
53AF
LD (54EEH),HL 22 EE 54
Store Register Pair HL (the spooler base + A7H) to 54EEH-54EFH, the operand of CALL 0000H at 54EDH.
53B2
LD (5510H),HL 22 10 55
Store Register Pair HL (the spooler base + A7H) to 5510H-5511H, the operand of CALL 0000H at 550FH.
53B5
LD (5578H),HL 22 78 55
Store Register Pair HL (the spooler base + A7H) to 5578H-5579H, the operand of CALL 0000H at 5577H.
53B8
POP DE D1
Restore Register Pair DE from the stack: the spooler base, the destination of the copy.
53B9
PUSH DE D5
Save Register Pair DE (the spooler base) to the stack again, for 53BFH.
53BA
LD HL,54D3H 21 D3 54
Point Register Pair HL to 54D3H, the first byte of the resident code.
53BD
LDIR ED B0
Copy Register Pair BC (0157H) bytes from Register Pair HL (54D3H-5629H) to Register Pair DE (the spooler base up to the byte below the queue block). Register Pair HL ends at 562AH, Register Pair DE at the queue block and Register Pair BC at 0000H.
53BF
POP HL E1
Restore Register Pair HL from the stack: the spooler base.
53C0
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack again, for 53CEH.
53C1
LD DE,(536FH) ED 5B 6F 53
Load Register Pair DE with the device control block that has the driver, from 536FH-5370H (written at 527BH).
53C5
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H: the offset of the driver entry 54D3H in the resident code. Nothing writes this operand.
53C8
ADD HL,BC 09
Add Register Pair BC (0000H) to Register Pair HL: Register Pair HL stays the spooler base, the run address of 54D3H.
53C9
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the device control block, Register Pair DE = the spooler base.
53CA
INC HL 23
Increment Register Pair HL to byte +01H of the device control block, the low byte of the driver's address.
53CB
LD (HL),E 73
Store Register E (the low byte of the spooler base) to byte +01H of the device control block at Register Pair HL.
53CC
INC HL 23
Increment Register Pair HL to byte +02H, the high byte of the driver's address.
53CD
LD (HL),D 72
Store Register D (the high byte of the spooler base) to byte +02H at Register Pair HL: from now on output to the device goes to the copy of 54D3H.
53CE
POP HL E1
Restore Register Pair HL from the stack: the spooler base.
53CF
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack again, for 53E5H.
53D0
LD DE,00A2H 11 A2 00
Load Register Pair DE with 00A2H, the offset of 5575H in the resident code.
53D3
ADD HL,DE 19
Add Register Pair DE (A2H) to Register Pair HL: Register Pair HL = the spooler base + A2H, the task control block (the copy of 5575H-5576H).
53D4
LD D,H 54
Copy Register H (the high byte of the task control block's address) into Register D.
53D5
LD E,L 5D
Copy Register L into Register E: Register Pair DE = the spooler base + A2H.
53D6
LD BC,0002H 01 02 00
Load Register Pair BC with 0002H, the size of the task control block.
53D9
ADD HL,BC 09
Add Register Pair BC (2) to Register Pair HL: Register Pair HL = the spooler base + A4H, the run address of the task routine 5577H.
53DA
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the task control block (spooler base + A2H), Register Pair DE = the task routine (spooler base + A4H).
53DB
LD (HL),E 73
Store Register E (the low byte of the task routine) to byte +00H of the task control block at Register Pair HL.
53DC
INC HL 23
Increment Register Pair HL to byte +01H of the task control block.
53DD
LD (HL),D 72
Store Register D (the high byte of the task routine) to byte +01H at Register Pair HL: the task control block names the copy of 5577H.
53DE
DEC HL 2B
Decrement Register Pair HL back to the task control block (spooler base + A2H).
53DF
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the task control block, Register Pair HL = the task routine.
53E0
LD A,09H 3E 09
Load Register A with 09H, task slot 9, one of the slots the dispatcher runs at every clock interrupt (40 times a second).
53E2
GOSUB to 4410H to install the task control block at Register Pair DE in the task slot Register A (9), at 4512H-4513H.
53E5
POP HL E1
Restore Register Pair HL from the stack: the spooler base.
53E6
PUSH HL E5
Save Register Pair HL (the spooler base) to the stack. Nothing takes this word back: 402DH below sets a new Stack Pointer.
53E7
LD DE,00E3H 11 E3 00
Load Register Pair DE with 00E3H, the offset of 55B6H in the resident code.
53EA
ADD HL,DE 19
Add Register Pair DE (E3H) to Register Pair HL: Register Pair HL = the spooler base + E3H, the run address of 55B6H.
53EB
LD (4301H),HL 22 01 43
Store Register Pair HL (the spooler base + E3H) to 4301H-4302H, the address of the keyboard hook's JP.
53EE
LD A,C3H 3E C3
Load Register A with C3H, the opcode of JP, for the first byte of the keyboard hook.
53F0
LD (4300H),A 32 00 43
Store Register A (C3H) to 4300H: the keyboard driver's CALL 4300H (439CH) now reaches the copy of 55B6H at every keyboard scan.
53F3
JUMP to 402DH, the normal exit: VTOS READY. The spooler now runs from the top of memory.
53F6H - Find a Device Control Block by Name
Register Pair DE = the two characters of the name (Register E the first, Register D the second). The blocks are 8 bytes each with the name at +06H-+07H: first 4015H, 401DH and 4025H (KI, DO, PR), then 43C0H-43F8H (JL, SI, LO and the five free blocks). Returns the Z FLAG, Register A = 00H and Register Pair HL = the block; or the NZ FLAG and Register A = 08H (DEVICE NOT AVAILABLE) when no name matches.
53F6
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the first device control block (KI).
53F9
PUSH HL E5
Save Register Pair HL (the start of the block being tested) to the stack. Loop Start
Each block is tested here.
53FA
LD A,L 7D
Copy Register L (the low byte of the block's address) into Register A.
53FB
ADD A,06H C6 06
Add 06H to Register A: the low byte of the block's byte +06H, the first character of its name.
53FD
LD L,A 6F
Copy Register A into Register L: Register Pair HL = byte +06H of the block (the blocks do not cross a page boundary).
53FE
LD A,(HL) 7E
Fetch the first character of the block's name from Register Pair HL into Register A.
53FF
INC L 2C
Increment Register L to byte +07H of the block, the second character of the name.
5400
CP E BB
Compare Register A (the block's first character) against Register E (the first character wanted).
5401
If the NZ FLAG is set (the first characters differ), JUMP to 540AH to go on to the next block.
5403
LD A,(HL) 7E
Fetch the second character of the block's name from Register Pair HL (+07H) into Register A.
5404
CP D BA
Compare Register A (the block's second character) against Register D (the second character wanted).
5405
If the NZ FLAG is set (the second characters differ), JUMP to 540AH to go on to the next block.
5407
POP HL E1
Restore Register Pair HL from the stack: the start of the block that matched.
5408
XOR A AF
Set Register A to 00H and set the Z FLAG (XOR A): found.
5409
RET C9
RETURN to 526DH with the Z FLAG set and Register Pair HL = the device control block.
540A
POP AF F1
Restore Register Pair AF from the stack: the start of the block that did not match is dropped (Register Pair AF gets its address and is not used).
540B
INC L 2C
Increment Register L from byte +07H to the first byte of the next block.
540C
If the NZ FLAG is set (Register L did not wrap to 00H), JUMP to 5412H to see whether the first group of blocks has ended.
540E
LD A,08H 3E 08
Load Register A with 08H, the error DEVICE NOT AVAILABLE: Register L wrapped past 43F8H-43FFH, the last block.
5410
OR A B7
OR Register A (08H) with itself: the NZ FLAG is set.
5411
RET C9
RETURN to 526DH with the NZ FLAG set and Register A = 08H.
5412
LD A,L 7D
Copy Register L (the low byte of the next block's address) into Register A.
5413
CP 2DH FE 2D
Compare Register A against 2DH: Register Pair HL = 402DH after the third block (4025H-402CH), the end of the first group.
5415
If the NZ FLAG is set (not the end of the first group), JUMP back to 53F9H to test the block at Register Pair HL.
5417
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the first block of the second group (JL).
541A
JUMP back to 53F9H to test the block at Register Pair HL (43C0H).
541CH - The Error Exits
541CH displays the message of the error code in Register A as text alone (bit 6 set) through 4409H, which then goes to the abort exit 4030H. 5421H, 543FH and 5472H display one of the member's own messages with 447BH (display and job log) and abort through 4030H.
541C
OR 40H F6 40
OR Register A (the error code from SYS0/SYS, SYS2/SYS or 53F6H) with 40H: bit 6 asks for the text of the message alone.
541E
JUMP to 4409H to display the message of the error code in Register A; with bit 7 clear it ends at the abort exit 4030H.
5421
LD HL,542AH 21 2A 54
Point Register Pair HL to 542AH, the text DEVICE SPEC REQUIRED.
5424
GOSUB to 447BH to display the text at Register Pair HL (542AH) and write it to the job log.
5427
JUMP to 4030H, the abort exit: VTOS READY and the next command.
542A-543D
DEFM "DEVICE SPEC REQUIRED" 44 45 56 49 43 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5421H when no device specification (an asterisk and a name) follows SPOOL.
543E
DEFB 0DH 0D
The carriage return that ends the message DEVICE SPEC REQUIRED.
543F
LD HL,5448H 21 48 54
Point Register Pair HL to 5448H, the text CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL.
5442
GOSUB to 447BH to display the text at Register Pair HL (5448H) and write it to the job log.
5445
JUMP to 4030H, the abort exit: VTOS READY and the next command.
5448-5470
DEFM "CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL" 43 41 4E 27 54 20 2D 2D 20 4F 4E 4C 59 20 56 41 4C 49 44 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C
The message of 543FH when the exit 402DH holds a JP (520DH).
5471
DEFB 0DH 0D
The carriage return that ends the message CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL.
5472
LD HL,547BH 21 7B 54
Point Register Pair HL to 547BH, the text PARAMETER ERROR.
5475
GOSUB to 447BH to display the text at Register Pair HL (547BH) and write it to the job log.
5478
JUMP to 4030H, the abort exit: VTOS READY and the next command.
547B-5489
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of 5472H: a bad parameter list, a colon with no drive, DISK of 4096 or more, MEM of 0 or more than 32.
548A
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
548B-54AA
DEFS 32
Not in the file: the control block 5210H-5213H reads the device specification into (an asterisk at 548BH, the name at 548CH-548DH, then 03H). 5219H tests its first byte; 521FH and 5266H read the name.
54ABH - The Default File Specification and the Parameter Table
54ABH-54B1H is the file specification used when none is given, its first two characters replaced by the device name (5223H). 54B2H-54D2H is the table for 4476H: 8 bytes an entry, the name in 6 characters and the address of the word that gets the value.
54AB-54AC
DEFM "XX" 58 58
The name of the default spool file: 5223H stores the two characters of the device name here (Register E at 54ABH, Register D at 54ACH), so that the name is the device's.
54AD
DEFM "/" 2F
The slash that starts the extension of the default specification.
54AE-54B0
DEFM "SPL" 53 50 4C
The extension SPL of the default specification; 5235H also points 4473H here, to give SPL to a file specification without an extension.
54B1
DEFB 03H 03
The end of text 03H of the default specification (and of the three letters for 4473H).
54B2-54B9
DEFM "MEM " / DEFW 52C9H 4D 45 4D 20 20 20 C9 52
Entry 1: MEM, its value to 52C9H-52CAH, the operand of LD BC at 52C8H: the K of memory pages (1 to 32, default 1).
54BA-54C1
DEFM "M " / DEFW 52C9H 4D 20 20 20 20 20 C9 52
Entry 2: M, the short form of MEM, its value to 52C9H-52CAH as well.
54C2-54C9
DEFM "DISK " / DEFW 5295H 44 49 53 4B 20 20 95 52
Entry 3: DISK, its value to 5295H-5296H, the operand of LD BC at 5294H: the K of the disk file (0 for none, below 4096, default 4).
54CA-54D1
DEFM "D " / DEFW 5295H 44 20 20 20 20 20 95 52
Entry 4: D, the short form of DISK, its value to 5295H-5296H as well.
54D2
DEFB 00H 00
The end of the parameter table: 00H where the next name would start.
54D3H - Resident: the Driver Entry of the Spooled Device
54D3H-5629H is copied by 53BDH to the spooler base (the new top of memory 4049H plus 1) and runs there, each row at the spooler base plus its offset from 54D3H; all its CALLs to its own routines and its pointers are operands written at 535EH-53B5H before the copy. Byte +01H-+02H of the device control block names this entry (53CBH-53CDH), so the ROM's device call 03C2H (or SYS0/SYS's 44C4H for a route) enters here with Register C = the character to output and Index Register IX at the device control block. Character 00H, the status request of the ROM's printer driver, is answered at once with the Z FLAG (ready); any other character is queued by 54DCH and returned in Register A with the NZ FLAG.
54D3
LD A,C 79
Runs at the spooler base + 00H: Copy Register C (the character to output, 00H for a status request) into Register A.
54D4
OR A B7
Runs at the spooler base + 01H: OR Register A (the character) with itself: the Z FLAG is set for 00H, the status request.
54D5
RET Z C8
Runs at the spooler base + 02H: If the Z FLAG is set (a status request), RETURN with Register A = 00H and the Z FLAG: the spooled device always answers ready, whatever its own state.
54D6
PUSH AF F5
Runs at the spooler base + 03H: Save Register Pair AF (Register A the character, the NZ FLAG) to the stack, for 54DAH.
54D7
CALL 0000H CD 00 00
Runs at the spooler base + 04H: GOSUB to the copy of 54DCH to put the character Register C in the queue. Self-Modifying Code
The operand 54D8H-54D9H is 0000H in the file; 539AH writes the spooler base + 09H (the run address of 54DCH) there before the copy, so the copy calls its own 54DCH.
54DA
POP AF F1
Runs at the spooler base + 07H: Restore Register Pair AF from the stack: Register A = the character and the NZ FLAG, as the caller expects from a driver.
54DB
RET C9
Runs at the spooler base + 08H: RETURN to the caller of the driver.
54DCH - Resident: Put a Character in the Queue
The queue block (Index Register IX): +20H the write offset and +21H the write page, +22H the read offset and +23H the read page (00H when the next page is to be fetched), +24H-+25H the start of the page table, +26H-+27H the tail entry (the page being filled), +28H-+29H the head entry (the page being printed), +2AH-+2BH the entry before the tail. The character goes to the write pointer; while the page has room one character is printed and 55BCH is given the chance to fetch the next page to print. When the page is full a free table entry is searched from the start of the table: a memory page becomes the new tail and the write page; when only disk records are free the full page is written to a record, whose entry goes in before the tail, and the page is filled again; when no entry is free the routine waits, printing, until one is.
54DC
LD IX,0000H DD 21 00 00
Runs at the spooler base + 09H: Load Index Register IX with the queue block. Self-Modifying Code
The operand 54DEH-54DFH is 0000H in the file; 535EH writes the address of the queue block (the spooler base + 157H) there before the copy.
54E0
LD L,(IX+20H) DD 6E 20
Runs at the spooler base + 0DH: Load Register L with the write offset from +20H of the queue block at Index Register IX.
54E3
LD H,(IX+21H) DD 66 21
Runs at the spooler base + 10H: Load Register H with the write page from +21H of the queue block at Index Register IX: Register Pair HL = the write pointer.
54E6
LD (HL),C 71
Runs at the spooler base + 13H: Store Register C (the character) to the write pointer at Register Pair HL.
54E7
DI F3
Runs at the spooler base + 14H: Disable interrupts: the task in slot 9 reads the write pointer, and it must not run while the pointer and the table change.
54E8
INC (IX+20H) DD 34 20
Runs at the spooler base + 15H: Increment the write offset at +20H of the queue block (Index Register IX): the Z FLAG is set when it wraps to 00H, the page is full.
54EB
Runs at the spooler base + 18H: If the Z FLAG is set (the page is full), JUMP to 54F3H to take another page.
54ED
CALL 0000H CD 00 00
Runs at the spooler base + 1AH: GOSUB to the copy of 557AH to print one character when the device is ready. Self-Modifying Code
The operand 54EEH-54EFH is 0000H in the file; 53AFH writes the spooler base + A7H (the run address of 557AH) there before the copy.
54F0
EI FB
Runs at the spooler base + 1DH: Enable interrupts again.
54F1
Runs at the spooler base + 1EH: JUMP to 553DH, which jumps on to 55BCH: fetch the next page to print when needed, then return to 54DAH.
54F3
LD L,(IX+24H) DD 6E 24
Runs at the spooler base + 20H: Load Register L with the low byte of the start of the page table from +24H of the queue block at Index Register IX. Loop Start
The search for a free entry, from the start of the table each time.
54F6
LD H,(IX+25H) DD 66 25
Runs at the spooler base + 23H: Load Register H with the high byte from +25H of the queue block at Index Register IX: Register Pair HL = the first entry of the table.
54F9
LD A,(HL) 7E
Runs at the spooler base + 26H: Fetch the low byte of the entry's link from Register Pair HL into Register A. Loop Start
Each entry is tested here.
54FA
INC HL 23
Runs at the spooler base + 27H: Increment Register Pair HL to the high byte of the entry's link.
54FB
OR (HL) B6
Runs at the spooler base + 28H: OR Register A (the low byte of the link) with the high byte at Register Pair HL: the Z FLAG is set when the link is 0000H, a free entry (or the end entry).
54FC
Runs at the spooler base + 29H: If the Z FLAG is set (a free entry), JUMP to 5503H.
54FE
INC HL 23
Runs at the spooler base + 2BH: Increment Register Pair HL to byte +02H of the entry.
54FF
INC HL 23
Runs at the spooler base + 2CH: Increment Register Pair HL to byte +03H of the entry.
5500
INC HL 23
Runs at the spooler base + 2DH: Increment Register Pair HL to byte +00H of the next entry.
5501
Runs at the spooler base + 2EH: JUMP back to 54F9H to test the entry at Register Pair HL.
5503
DEC HL 2B
Runs at the spooler base + 30H: Decrement Register Pair HL back to byte +00H of the free entry.
5504
PUSH HL E5
Runs at the spooler base + 31H: Save Register Pair HL (the free entry) to the stack.
5505
INC HL 23
Runs at the spooler base + 32H: Increment Register Pair HL to byte +01H of the entry.
5506
INC HL 23
Runs at the spooler base + 33H: Increment Register Pair HL to byte +02H of the entry.
5507
LD B,(HL) 46
Runs at the spooler base + 34H: Fetch byte +02H of the entry at Register Pair HL into Register B: the memory page, or the low byte of the record number.
5508
INC HL 23
Runs at the spooler base + 35H: Increment Register Pair HL to byte +03H of the entry.
5509
LD A,(HL) 7E
Runs at the spooler base + 36H: Fetch byte +03H of the entry at Register Pair HL into Register A: 00H for a memory page, the record's high byte OR 80H for a disk record, FFH for the end entry.
550A
CP FFH FE FF
Runs at the spooler base + 37H: Compare Register A (byte +03H of the entry) against FFH, the mark of the end entry.
550C
Runs at the spooler base + 39H: If the NZ FLAG is set (a real entry), JUMP to 5519H to use it.
550E
POP HL E1
Runs at the spooler base + 3BH: Restore Register Pair HL from the stack: the end entry is dropped, no entry is free.
550F
CALL 0000H CD 00 00
Runs at the spooler base + 3CH: GOSUB to the copy of 557AH to print one character when the device is ready. Self-Modifying Code
The operand 5510H-5511H is 0000H in the file; 53B2H writes the spooler base + A7H (the run address of 557AH) there before the copy.
5512
EI FB
Runs at the spooler base + 3FH: Enable interrupts, so the task in slot 9 can print as well while the program waits.
5513
CALL 0000H CD 00 00
Runs at the spooler base + 40H: GOSUB to the copy of 55BCH to fetch the next page to print, which frees the entry of the page printed. Self-Modifying Code
The operand 5514H-5515H is 0000H in the file; 53A3H writes the spooler base + E9H (the run address of 55BCH) there before the copy.
5516
DI F3
Runs at the spooler base + 43H: Disable interrupts again for the search.
5517
Runs at the spooler base + 44H: JUMP back to 54F3H to search the table again from its start.
5519
BIT 7,A CB 7F
Runs at the spooler base + 46H: Test bit 7 of Register A (byte +03H of the free entry): set for a disk record.
551B
Runs at the spooler base + 48H: If the NZ FLAG is set (a disk record), JUMP to 553FH to write the full page to it.
551D
POP HL E1
Runs at the spooler base + 4AH: Restore Register Pair HL from the stack: the free memory entry.
551E
PUSH HL E5
Runs at the spooler base + 4BH: Save Register Pair HL (the free memory entry) to the stack again, for 5532H.
551F
LD (HL),L 75
Runs at the spooler base + 4CH: Store Register L (the low byte of the entry's address) to the low byte of its link at Register Pair HL.
5520
LD A,H 7C
Runs at the spooler base + 4DH: Copy Register H (the high byte of the entry's address) into Register A.
5521
INC HL 23
Runs at the spooler base + 4EH: Increment Register Pair HL to the high byte of the link.
5522
LD (HL),A 77
Runs at the spooler base + 4FH: Store Register A (the high byte of the entry's address) to Register Pair HL: the entry links to itself, in use and the last of the queue.
5523
LD (IX+21H),B DD 70 21
Runs at the spooler base + 50H: Store Register B (the entry's memory page) to the write page at +21H of the queue block (Index Register IX); the write offset +20H is 00H after the wrap.
5526
LD L,(IX+26H) DD 6E 26
Runs at the spooler base + 53H: Load Register L with the low byte of the tail entry from +26H of the queue block at Index Register IX.
5529
LD H,(IX+27H) DD 66 27
Runs at the spooler base + 56H: Load Register H with the high byte from +27H of the queue block at Index Register IX: Register Pair HL = the tail entry, the page just filled.
552C
LD (IX+2AH),L DD 75 2A
Runs at the spooler base + 59H: Store Register L (the low byte of the old tail) to +2AH of the queue block at Index Register IX.
552F
LD (IX+2BH),H DD 74 2B
Runs at the spooler base + 5CH: Store Register H (the high byte of the old tail) to +2BH at Index Register IX: the old tail is now the entry before the tail.
5532
POP BC C1
Runs at the spooler base + 5FH: Restore Register Pair BC from the stack: the new memory entry.
5533
LD (HL),C 71
Runs at the spooler base + 60H: Store Register C (the low byte of the new entry) to the link of the old tail at Register Pair HL.
5534
INC HL 23
Runs at the spooler base + 61H: Increment Register Pair HL to the high byte of the old tail's link.
5535
LD (HL),B 70
Runs at the spooler base + 62H: Store Register B (the high byte of the new entry) to Register Pair HL: the old tail now links to the new entry.
5536
LD (IX+26H),C DD 71 26
Runs at the spooler base + 63H: Store Register C (the low byte of the new entry) to the tail at +26H of the queue block (Index Register IX).
5539
LD (IX+27H),B DD 70 27
Runs at the spooler base + 66H: Store Register B (the high byte of the new entry) to +27H at Index Register IX: the new entry is the tail.
553C
RET C9
Runs at the spooler base + 69H: RETURN to 54DAH. Interrupts stay disabled on this path: no EI follows the DI at 54E7H.
553D
Runs at the spooler base + 6AH: JUMP to 55BCH to fetch the next page to print when the read page is 00H; its RET goes back to 54DAH.
553F
EI FB
Runs at the spooler base + 6CH: Enable interrupts again (disabled at 54E7H) before the full page is written to the disk record.
5540
LD C,B 48
Runs at the spooler base + 6DH: Copy Register B (byte +02H of the disk entry, the low byte of the record) into Register C.
5541
AND 0FH E6 0F
Runs at the spooler base + 6EH: Mask Register A (byte +03H of the disk entry) to bits 3-0: the high byte of the record without the disk mark bit 7.
5543
LD B,A 47
Runs at the spooler base + 70H: Copy Register A (the high byte of the record) into Register B: Register Pair BC = the record number.
5544
PUSH IX DD E5
Runs at the spooler base + 71H: Save Index Register IX (the queue block, whose first 32 bytes are the spool file's control block) to the stack.
5546
POP DE D1
Runs at the spooler base + 73H: Restore Register Pair DE from the stack: Register Pair DE = the spool file's control block.
5547
Runs at the spooler base + 74H: GOSUB to 4442H to position the spool file at Register Pair DE to the record Register Pair BC.
554A
Runs at the spooler base + 77H: If the NZ FLAG is set (the position failed, Register A = the error), JUMP to 4409H to display the error message and go to the abort exit 4030H.
554D
LD C,(IX+26H) DD 4E 26
Runs at the spooler base + 7AH: Load Register C with the low byte of the tail from +26H of the queue block at Index Register IX.
5550
LD B,(IX+27H) DD 46 27
Runs at the spooler base + 7DH: Load Register B with the high byte from +27H at Index Register IX: Register Pair BC = the tail entry, the page that is full.
5553
POP HL E1
Runs at the spooler base + 80H: Restore Register Pair HL from the stack: the free disk entry.
5554
PUSH HL E5
Runs at the spooler base + 81H: Save Register Pair HL (the disk entry) to the stack again, for 5558H.
5555
LD (HL),C 71
Runs at the spooler base + 82H: Store Register C (the low byte of the tail) to the link of the disk entry at Register Pair HL.
5556
INC HL 23
Runs at the spooler base + 83H: Increment Register Pair HL to the high byte of the disk entry's link.
5557
LD (HL),B 70
Runs at the spooler base + 84H: Store Register B (the high byte of the tail) to Register Pair HL: the disk entry links to the tail, it goes in before it.
5558
POP BC C1
Runs at the spooler base + 85H: Restore Register Pair BC from the stack: the disk entry.
5559
LD L,(IX+2AH) DD 6E 2A
Runs at the spooler base + 86H: Load Register L with the low byte of the entry before the tail from +2AH of the queue block at Index Register IX.
555C
LD H,(IX+2BH) DD 66 2B
Runs at the spooler base + 89H: Load Register H with the high byte from +2BH at Index Register IX: Register Pair HL = the entry before the tail (0000H until a second memory page has been taken).
555F
LD (HL),C 71
Runs at the spooler base + 8CH: Store Register C (the low byte of the disk entry) to the link of the entry at Register Pair HL.
5560
INC HL 23
Runs at the spooler base + 8DH: Increment Register Pair HL to the high byte of that link.
5561
LD (HL),B 70
Runs at the spooler base + 8EH: Store Register B (the high byte of the disk entry) to Register Pair HL: the entry before the tail now links to the disk entry.
5562
LD (IX+2AH),C DD 71 2A
Runs at the spooler base + 8FH: Store Register C (the low byte of the disk entry) to +2AH of the queue block (Index Register IX).
5565
LD (IX+2BH),B DD 70 2B
Runs at the spooler base + 92H: Store Register B (the high byte of the disk entry) to +2BH at Index Register IX: the disk entry is now the entry before the tail.
5568
LD B,(IX+21H) DD 46 21
Runs at the spooler base + 95H: Load Register B with the write page from +21H of the queue block at Index Register IX: the page that is full.
556B
LD (IX+04H),B DD 70 04
Runs at the spooler base + 98H: Store Register B (the full page) to +04H of the spool file's control block at Index Register IX, the high byte of its buffer address (+03H is 00H from 4200H): the buffer is the full page.
556E
Runs at the spooler base + 9BH: GOSUB to 4439H to write the buffer of the spool file at Register Pair DE (the full page) to the record positioned. The page stays the write page and is filled again from offset 00H.
5571
Runs at the spooler base + 9EH: If the NZ FLAG is set (the write failed, Register A = the error), JUMP to 4409H to display the error message and go to the abort exit 4030H.
5574
RET C9
Runs at the spooler base + A1H: RETURN to 54DAH with interrupts enabled.
5575-5576
DEFS 2
Not in the file: the task control block of the spooler, two bytes the LDIR at 53BDH copies to the spooler base + A2H. 53DBH-53DDH then write the address of the task routine (the spooler base + A4H, the copy of 5577H) into the copy, and 53E2H installs the copy in task slot 9. Nothing uses these two bytes at their file address.
5577H - Resident: the Task in Slot 9
The dispatcher runs this routine 40 times a second, under the clock interrupt, with Index Register IX at its task control block (the spooler base + A2H). It calls 557AH and then runs on into it, so that up to two characters are printed each time. 557AH asks the device's own driver for its status with character 00H and returns when it is busy; otherwise it prints the next character of the read page when the read pointer is behind the write pointer. At the end of a page it sets the read page to 00H; the next page is fetched by 55BCH, which runs in the foreground (driver calls and the keyboard hook), never in the task. The driver is called with Index Register IX = 4025H, the PR device control block, whichever device was spooled.
5577
CALL 0000H CD 00 00
Runs at the spooler base + A4H: GOSUB to the copy of 557AH to print one character. Self-Modifying Code
The operand 5578H-5579H is 0000H in the file; 53B5H writes the spooler base + A7H (the run address of 557AH) there before the copy. After it returns, the task runs on into 557AH for a second character.
557A
LD C,00H 0E 00
Runs at the spooler base + A7H: Load Register C with 00H, the status request of the ROM's printer driver (058DH): it returns the Z FLAG when the printer is ready.
557C
PUSH IX DD E5
Runs at the spooler base + A9H: Save Index Register IX (the task control block or the queue block of the caller) to the stack, for 5585H.
557E
LD IX,4025H DD 21 25 40
Runs at the spooler base + ABH: Load Index Register IX with 4025H, the PR device control block, the block the ROM's printer driver works with (lines at +03H and +04H).
5582
CALL 0000H CD 00 00
Runs at the spooler base + AFH: GOSUB to the device's own driver with Register C = 00H, the status request. Self-Modifying Code
The operand 5583H-5584H is 0000H in the file; 5375H writes the driver address the device control block had before SPOOL (its +01H-+02H) there before the copy.
5585
POP IX DD E1
Runs at the spooler base + B2H: Restore Index Register IX from the stack: the caller's value.
5587
RET NZ C0
Runs at the spooler base + B4H: If the NZ FLAG is set (the device is busy), RETURN: nothing is printed this time.
5588
LD IX,0000H DD 21 00 00
Runs at the spooler base + B5H: Load Index Register IX with the queue block. Self-Modifying Code
The operand 558AH-558BH is 0000H in the file; 5361H writes the address of the queue block (the spooler base + 157H) there before the copy.
558C
LD A,(IX+23H) DD 7E 23
Runs at the spooler base + B9H: Fetch the read page from +23H of the queue block at Index Register IX into Register A.
558F
OR A B7
Runs at the spooler base + BCH: OR Register A (the read page) with itself: the Z FLAG is set when it is 00H.
5590
RET Z C8
Runs at the spooler base + BDH: If the Z FLAG is set (no read page: the next one has not been fetched), RETURN.
5591
LD H,A 67
Runs at the spooler base + BEH: Copy Register A (the read page) into Register H, the high byte of the read pointer.
5592
CP (IX+21H) DD BE 21
Runs at the spooler base + BFH: Compare Register A (the read page) against the write page at +21H of the queue block (Index Register IX).
5595
Runs at the spooler base + C2H: If the NZ FLAG is set (the pages differ: the read page is full), JUMP to 559EH to print.
5597
LD A,(IX+22H) DD 7E 22
Runs at the spooler base + C4H: Load Register A with the read offset from +22H of the queue block at Index Register IX.
559A
CP (IX+20H) DD BE 20
Runs at the spooler base + C7H: Compare Register A (the read offset) against the write offset at +20H of the queue block (Index Register IX).
559D
RET Z C8
Runs at the spooler base + CAH: If the Z FLAG is set (the read pointer has reached the write pointer: nothing to print), RETURN.
559E
LD L,(IX+22H) DD 6E 22
Runs at the spooler base + CBH: Load Register L with the read offset from +22H of the queue block at Index Register IX: Register Pair HL = the read pointer.
55A1
LD C,(HL) 4E
Runs at the spooler base + CEH: Fetch the character at the read pointer (Register Pair HL) into Register C.
55A2
PUSH IX DD E5
Runs at the spooler base + CFH: Save Index Register IX (the queue block) to the stack, for 55ABH.
55A4
LD IX,4025H DD 21 25 40
Runs at the spooler base + D1H: Load Index Register IX with 4025H, the PR device control block, for the driver.
55A8
CALL 0000H CD 00 00
Runs at the spooler base + D5H: GOSUB to the device's own driver to output the character in Register C. Self-Modifying Code
The operand 55A9H-55AAH is 0000H in the file; 5379H writes the driver address the device control block had before SPOOL there before the copy.
55AB
POP IX DD E1
Runs at the spooler base + D8H: Restore Index Register IX from the stack: the queue block.
55AD
INC (IX+22H) DD 34 22
Runs at the spooler base + DAH: Increment the read offset at +22H of the queue block (Index Register IX): the Z FLAG is set when it wraps to 00H, the page is done.
55B0
RET NZ C0
Runs at the spooler base + DDH: If the NZ FLAG is set (the page has more), RETURN.
55B1
LD (IX+23H),00H DD 36 23 00
Runs at the spooler base + DEH: Store 00H to the read page at +23H of the queue block (Index Register IX): the page is printed and 55BCH is to fetch the next one.
55B5
RET C9
Runs at the spooler base + E2H: RETURN to the caller: to 557AH after the CALL at 5577H, to the dispatcher after the second pass, or to 54F0H or 5512H.
55B6H - Resident: the Keyboard Hook
53EBH-53F0H put JP to the copy of 55B6H at 4300H, which SYS0/SYS's keyboard driver calls at every scan (439CH). The hook calls 55BCH to fetch the next page to print and then runs the three bytes 4300H-4302H held before SPOOL (a RET as SYS0/SYS loads them), copied to 55B9H-55BBH by 5383H-5386H.
55B6
CALL 0000H CD 00 00
Runs at the spooler base + E3H: GOSUB to the copy of 55BCH to fetch the next page to print when needed. Self-Modifying Code
The operand 55B7H-55B8H is 0000H in the file; 53A6H writes the spooler base + E9H (the run address of 55BCH) there before the copy.
55B9-55BB
DEFS 3
Not in the file: 5383H and 5386H store the three bytes of the keyboard hook 4300H-4302H here before the copy (C9H 00H 00H, a RET, as SYS0/SYS loads them; a JP when another program or an earlier SPOOL had hooked the keyboard). The copy runs them after the call at 55B6H.
55BCH - Resident: Fetch the Next Page to Print
Nothing is done unless the read page (+23H) is 00H. Then the entry after the head is taken (the head's link). A memory entry becomes the head and its page the read page; the old head is freed. For a disk entry the record is read into the head's own page, the disk entry is freed and taken out of the queue, and the head's page is the read page again. Every register is kept.
55BC
PUSH AF F5
Runs at the spooler base + E9H: Save Register Pair AF (the caller's) to the stack, for 55F4H.
55BD
LD A,(0000H) 3A 00 00
Runs at the spooler base + EAH: Fetch the read page into Register A. Self-Modifying Code
The operand 55BEH-55BFH is 0000H in the file; 536BH writes the queue block + 23H (the read page) there before the copy.
55C0
OR A B7
Runs at the spooler base + EDH: OR Register A (the read page) with itself: the NZ FLAG is set while a page is being printed.
55C1
Runs at the spooler base + EEH: If the NZ FLAG is set (the read page is in use), JUMP to 55F4H to return.
55C3
PUSH IX DD E5
Runs at the spooler base + F0H: Save Index Register IX (the caller's) to the stack.
55C5
PUSH HL E5
Runs at the spooler base + F2H: Save Register Pair HL (the caller's) to the stack.
55C6
PUSH DE D5
Runs at the spooler base + F3H: Save Register Pair DE (the caller's) to the stack.
55C7
PUSH BC C5
Runs at the spooler base + F4H: Save Register Pair BC (the caller's) to the stack.
55C8
LD IX,0000H DD 21 00 00
Runs at the spooler base + F5H: Load Index Register IX with the queue block. Self-Modifying Code
The operand 55CAH-55CBH is 0000H in the file; 5364H writes the address of the queue block (the spooler base + 157H) there before the copy.
55CC
LD L,(IX+28H) DD 6E 28
Runs at the spooler base + F9H: Load Register L with the low byte of the head entry from +28H of the queue block at Index Register IX.
55CF
LD H,(IX+29H) DD 66 29
Runs at the spooler base + FCH: Load Register H with the high byte from +29H at Index Register IX: Register Pair HL = the head entry, the page just printed.
55D2
PUSH HL E5
Runs at the spooler base + FFH: Save Register Pair HL (the head entry) to the stack.
55D3
LD C,(HL) 4E
Runs at the spooler base + 100H: Fetch the low byte of the head's link from Register Pair HL into Register C.
55D4
INC HL 23
Runs at the spooler base + 101H: Increment Register Pair HL to the high byte of the head's link.
55D5
LD B,(HL) 46
Runs at the spooler base + 102H: Fetch the high byte of the head's link from Register Pair HL into Register B: Register Pair BC = the next entry of the queue (the head itself when it is the last).
55D6
LD HL,0002H 21 02 00
Runs at the spooler base + 103H: Load Register Pair HL with 0002H, the offset of byte +02H in an entry.
55D9
ADD HL,BC 09
Runs at the spooler base + 106H: Add Register Pair BC (the next entry) to Register Pair HL: Register Pair HL = byte +02H of the next entry.
55DA
LD A,(HL) 7E
Runs at the spooler base + 107H: Fetch byte +02H of the next entry at Register Pair HL into Register A: its memory page or the low byte of its record.
55DB
INC HL 23
Runs at the spooler base + 108H: Increment Register Pair HL to byte +03H of the next entry.
55DC
BIT 7,(HL) CB 7E
Runs at the spooler base + 109H: Test bit 7 of byte +03H of the next entry at Register Pair HL: set for a disk record.
55DE
Runs at the spooler base + 10BH: If the NZ FLAG is set (a disk record), JUMP to 55F6H to read it.
55E0
LD (IX+23H),A DD 77 23
Runs at the spooler base + 10DH: Store Register A (the next entry's memory page) to the read page at +23H of the queue block (Index Register IX); the read offset +22H is 00H after the wrap.
55E3
POP HL E1
Runs at the spooler base + 110H: Restore Register Pair HL from the stack: the old head entry.
55E4
LD (HL),00H 36 00
Runs at the spooler base + 111H: Store 00H to the low byte of the old head's link at Register Pair HL.
55E6
INC HL 23
Runs at the spooler base + 113H: Increment Register Pair HL to the high byte of the old head's link.
55E7
LD (HL),00H 36 00
Runs at the spooler base + 114H: Store 00H to the high byte at Register Pair HL: the old head is free.
55E9
LD (IX+28H),C DD 71 28
Runs at the spooler base + 116H: Store Register C (the low byte of the next entry) to the head at +28H of the queue block (Index Register IX).
55EC
LD (IX+29H),B DD 70 29
Runs at the spooler base + 119H: Store Register B (the high byte of the next entry) to +29H at Index Register IX: the next entry is the head.
55EF
POP BC C1
Runs at the spooler base + 11CH: Restore Register Pair BC from the stack: the caller's.
55F0
POP DE D1
Runs at the spooler base + 11DH: Restore Register Pair DE from the stack: the caller's.
55F1
POP HL E1
Runs at the spooler base + 11EH: Restore Register Pair HL from the stack: the caller's.
55F2
POP IX DD E1
Runs at the spooler base + 11FH: Restore Index Register IX from the stack: the caller's.
55F4
POP AF F1
Runs at the spooler base + 121H: Restore Register Pair AF from the stack: the caller's.
55F5
RET C9
Runs at the spooler base + 122H: RETURN to the caller (54DAH, 5516H or the old keyboard hook at 55B9H).
55F6
LD C,A 4F
Runs at the spooler base + 123H: Copy Register A (byte +02H of the disk entry, the low byte of the record) into Register C.
55F7
LD A,(HL) 7E
Runs at the spooler base + 124H: Fetch byte +03H of the disk entry at Register Pair HL into Register A.
55F8
AND 0FH E6 0F
Runs at the spooler base + 125H: Mask Register A (byte +03H) to bits 3-0: the high byte of the record without the disk mark bit 7.
55FA
LD B,A 47
Runs at the spooler base + 127H: Copy Register A (the high byte of the record) into Register B: Register Pair BC = the record number.
55FB
PUSH IX DD E5
Runs at the spooler base + 128H: Save Index Register IX (the queue block, the spool file's control block) to the stack.
55FD
POP DE D1
Runs at the spooler base + 12AH: Restore Register Pair DE from the stack: Register Pair DE = the spool file's control block.
55FE
Runs at the spooler base + 12BH: GOSUB to 4442H to position the spool file at Register Pair DE to the record Register Pair BC.
5601
Runs at the spooler base + 12EH: If the NZ FLAG is set (the position failed, Register A = the error), JUMP to 4409H to display the error message and go to the abort exit 4030H.
5604
POP HL E1
Runs at the spooler base + 131H: Restore Register Pair HL from the stack: the head entry.
5605
PUSH HL E5
Runs at the spooler base + 132H: Save Register Pair HL (the head entry) to the stack again, for 5612H.
5606
INC HL 23
Runs at the spooler base + 133H: Increment Register Pair HL to byte +01H of the head entry.
5607
INC HL 23
Runs at the spooler base + 134H: Increment Register Pair HL to byte +02H of the head entry.
5608
LD B,(HL) 46
Runs at the spooler base + 135H: Fetch byte +02H of the head entry at Register Pair HL into Register B: the head's memory page, the one just printed.
5609
LD (IX+04H),B DD 70 04
Runs at the spooler base + 136H: Store Register B (the head's page) to +04H of the spool file's control block at Index Register IX: the buffer is now that page.
560C
Runs at the spooler base + 139H: GOSUB to 4436H to read the record positioned of the spool file at Register Pair DE into its buffer, the head's page.
560F
Runs at the spooler base + 13CH: If the NZ FLAG is set (the read failed, Register A = the error), JUMP to 4409H to display the error message and go to the abort exit 4030H.
5612
POP HL E1
Runs at the spooler base + 13FH: Restore Register Pair HL from the stack: the head entry.
5613
PUSH HL E5
Runs at the spooler base + 140H: Save Register Pair HL (the head entry) to the stack again, for 561FH.
5614
LD A,(HL) 7E
Runs at the spooler base + 141H: Fetch the low byte of the head's link from Register Pair HL into Register A.
5615
INC HL 23
Runs at the spooler base + 142H: Increment Register Pair HL to the high byte of the head's link.
5616
LD H,(HL) 66
Runs at the spooler base + 143H: Fetch the high byte of the head's link from Register Pair HL into Register H.
5617
LD L,A 6F
Runs at the spooler base + 144H: Copy Register A (the low byte of the link) into Register L: Register Pair HL = the disk entry just read.
5618
LD C,(HL) 4E
Runs at the spooler base + 145H: Fetch the low byte of the disk entry's link from Register Pair HL into Register C.
5619
LD (HL),00H 36 00
Runs at the spooler base + 146H: Store 00H to the low byte of the disk entry's link at Register Pair HL.
561B
INC HL 23
Runs at the spooler base + 148H: Increment Register Pair HL to the high byte of the disk entry's link.
561C
LD B,(HL) 46
Runs at the spooler base + 149H: Fetch the high byte of the disk entry's link from Register Pair HL into Register B: Register Pair BC = the entry after the disk entry.
561D
LD (HL),00H 36 00
Runs at the spooler base + 14AH: Store 00H to the high byte at Register Pair HL: the disk entry is free.
561F
POP HL E1
Runs at the spooler base + 14CH: Restore Register Pair HL from the stack: the head entry.
5620
LD (HL),C 71
Runs at the spooler base + 14DH: Store Register C (the low byte of the entry after the disk entry) to the head's link at Register Pair HL.
5621
INC HL 23
Runs at the spooler base + 14EH: Increment Register Pair HL to the high byte of the head's link.
5622
LD (HL),B 70
Runs at the spooler base + 14FH: Store Register B (the high byte) to Register Pair HL: the head now links past the disk entry.
5623
INC HL 23
Runs at the spooler base + 150H: Increment Register Pair HL to byte +02H of the head entry.
5624
LD B,(HL) 46
Runs at the spooler base + 151H: Fetch byte +02H of the head entry at Register Pair HL into Register B: the head's page, which now holds the record.
5625
LD (IX+23H),B DD 70 23
Runs at the spooler base + 152H: Store Register B (the head's page) to the read page at +23H of the queue block (Index Register IX): it is printed from offset 00H.
5628
Runs at the spooler base + 155H: JUMP to 55EFH to restore the caller's registers and return.
562AH - Work Areas Above the Resident Code
Not in the file except 5654H-5655H: the control block of the spool file and the pointers that 535AH copies, 2CH bytes from 562AH, to the queue block at the spooler base + 157H, where the resident code reaches them through Index Register IX (+00H-+2BH).
562A-5649
DEFS 32
Not in the file: the control block of the spool file. 522AH (or 5232H with the default XX/SPL) reads the file specification into it, 5238H gives it the extension SPL, 5241H-525CH may add the drive; 528EH opens it with the buffer 4200H, 52A6H-52B2H use it, 52B5H reads its drive (+06H) and directory entry code (+07H). 535AH copies it to the queue block +00H-+1FH, where 5544H and 55FBH pass it to 4442H, 4439H and 4436H.
564A-564B
DEFS 2
Not in the file: the write pointer, 52F5H stores the first memory page with offset 00H; it becomes the queue block +20H (offset) and +21H (page), written by 54E8H and 5523H, read by 54E0H, 5568H and 5592H-559AH.
564C-564D
DEFS 2
Not in the file: the read pointer, 52F8H stores the first memory page with offset 00H; it becomes the queue block +22H (offset) and +23H (page, 00H when the next page is to be fetched), written by 55ADH, 55B1H, 55E0H and 5625H, read by 558CH, 5597H, 559EH and 55BDH.
564E-564F
DEFS 2
Not in the file: the start of the page table, 5341H; it becomes the queue block +24H-+25H, where the search for a free entry starts (54F3H). Nothing changes it.
5650-5651
DEFS 2
Not in the file: the tail of the queue, the entry of the page being filled, 5344H stores the first entry; it becomes the queue block +26H-+27H, written by 5536H-5539H, read by 5526H and 554DH.
5652-5653
DEFS 2
Not in the file: the head of the queue, the entry of the page being printed, 5347H stores the first entry; it becomes the queue block +28H-+29H, written by 55E9H-55ECH, read by 55CCH.
5654-5655
DEFW 0000H 00 00
The entry before the tail, 0000H as loaded (the last load block of the member); 535AH copies it to the queue block +2AH-+2BH, written by 552CH-552FH and 5562H-5565H, read by 5559H as the entry whose link gets a new disk entry.
5200H - Member 15 (APPEND and COPY, Codes 31H and 32H): APPEND
SYS1/SYS runs APPEND as member code 31H: the request handler of SYS0/SYS loads this member at 5200H and calls 5200H with Register Pair HL at the text after the command word, Register B = 31H and Register A = the code taken from 430EH; the stack holds 4C4BH (the handler's return) and then 402DH. APPEND reads two file specifications, the source into the control block at 549DH and the destination into the one at 54BDH, fills in the parts the destination leaves out from the source (53CDH) and opens both with 256 byte records. A destination whose end of file offset is 00H (it ends on a sector boundary) is given the source sector by sector (52DCH) after its space has been written ahead (535BH); any other destination is positioned to its end and given the source byte by byte (5391H). A destination that is a device is refused with FILE SPEC REQUIRED.
5200
GOSUB to 5349H to work out the stop page of the sector buffers from the top of memory at 4049H and store it in the three compares at 52F7H, 530CH and 5330H. Register Pair HL (the parameters text) is kept.
5203
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the control block of the source file (32 bytes, not in the file).
5206
GOSUB to 441CH, which has SYS1/SYS (request C3H, its 4FCEH) read the file specification at Register Pair HL into the control block at Register Pair DE (549DH): the Z FLAG when one was read, Register Pair HL moved past it and the character that ended it.
5209
If the NZ FLAG is set (no source specification), JUMP to 5459H to display FILE SPEC REQUIRED and abort.
520C
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the control block of the destination file (32 bytes, not in the file).
520F
GOSUB to 441CH to read the next file specification at Register Pair HL into the control block at Register Pair DE (54BDH): the Z FLAG when one was read.
5212
If the Z FLAG is set (a destination specification was read), JUMP to 521AH.
5214
DEC HL 2B
No specification was read (the word starts with a character that cannot start one, for example the colon of :1, or the line has ended): decrement Register Pair HL back to the character that stopped the read; at the end of the line it is the last character before the 0DH.
5215
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
5218
LDIR ED B0
Copy 32 bytes of the command line from Register Pair HL to the destination control block at Register Pair DE (54BDH) as they stand, ended by the 0DH of the line; 53CDH completes this text from the source. Register Pair BC ends at 0000H, Register Pair HL and Register Pair DE 32 bytes on.
521A
LD A,(54BDH) 3A BD 54
Fetch the first byte of the destination specification at 54BDH into Register A.
521D
CP 2AH FE 2A
Compare Register A (the first character of the destination) against 2AH, an asterisk: the specification of a device.
521F
If the Z FLAG is set (the destination is a device), JUMP to 5459H to display FILE SPEC REQUIRED and abort: APPEND only adds to a file.
5222
LD HL,549DH 21 9D 54
Point Register Pair HL to 549DH, the source specification.
5225
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination specification.
5228
GOSUB to 53CDH to complete the destination at Register Pair DE from the source at Register Pair HL: a missing name, extension or password is copied from the source. Register Pair DE returns 54BDH; Register C holds 03H or 0DH when characters were inserted.
522B
LD B,00H 06 00
Load Register B with 00H, the record length for the open: 00H means 256 byte records, whole sectors.
522D
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the sector buffer for the open.
5230
GOSUB to 4424H to open the file of the control block at Register Pair DE (54BDH, the destination) with the buffer at Register Pair HL (5500H) and the record length in Register B (00H): request 94H, SYS2/SYS. The destination must exist. Register Pairs BC, DE and HL come back unchanged.
5233
If the NZ FLAG is set (the open failed, the error code in Register A), JUMP to 5454H to display the error and abort.
5236
LD B,00H 06 00
Load Register B with 00H, the record length (256 byte records) for the open of the source. Register C keeps the value left by the calls before.
5238
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the source control block.
523B
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the sector buffer: the source shares it with the destination until the copy gives each page its own use.
523E
GOSUB to 4424H to open the source at Register Pair DE (549DH) with the buffer at Register Pair HL (5500H) and 256 byte records (Register B = 00H). Register Pairs BC, DE and HL come back unchanged.
5241
If the NZ FLAG is set (the source could not be opened, the error code in Register A), JUMP to 5454H to display the error and abort.
5244
LD A,(54C5H) 3A C5 54
Fetch the end of file offset of the destination, byte +08H of its control block at 54C5H, into Register A.
5247
OR A B7
OR Register A (the destination's end of file offset) with itself: the Z FLAG is set when it is 00H, a file that ends on a sector boundary.
5248
If the Z FLAG is set (the destination ends on a sector boundary), JUMP to 5259H to add the source sector by sector.
524A
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
524D
GOSUB to 4448H to position the destination at Register Pair DE (54BDH) to its end of file: the sector before its ending record number, at the end of file offset, marked to be read before the next byte.
5250
LD HL,5600H 21 00 56
Load Register Pair HL with 5600H, a buffer page of its own for the destination: the source reads into 5500H.
5253
LD (54C0H),HL 22 C0 54
Store Register Pair HL (5600H) to 54C0H-54C1H, bytes +03H-+04H of the destination control block: its buffer address.
5256
JUMP to 5391H to add the source to the destination one byte at a time.
5259H - APPEND Sector by Sector
The destination ends on a sector boundary, so whole sectors can be added at its end. 535BH first writes a sector of E5H at the record number source ending record number plus Register Pair BC, then the ending record number at 54C9H-54CAH is put back and the destination positioned to its end. Register Pair BC is not loaded here: Register B is 00H (5236H) and Register C is what the calls before left (05H after SYS1/SYS's 4FCEH, 03H or 0DH after an insertion of 53CDH, 00H after the LDIR at 5218H), not the destination's ending record number. When that record number lies inside the destination, its sector there is overwritten with E5H bytes.
5259
LD HL,(54C9H) 2A C9 54
Fetch the ending record number of the destination, bytes +0CH-+0DH of its control block at 54C9H-54CAH, into Register Pair HL: the number of its sectors.
525C
PUSH HL E5
Save Register Pair HL (the destination's ending record number) to the stack, to put it back after 535BH.
525D
LD HL,(54A9H) 2A A9 54
Fetch the ending record number of the source, bytes +0CH-+0DH of its control block at 54A9H-54AAH, into Register Pair HL.
5260
ADD HL,BC 09
Add Register Pair BC to Register Pair HL (the source's ending record number). Register Pair BC holds 00H in Register B (5236H) and in Register C the value the earlier calls left (05H, 03H, 0DH or 00H, see the heading), not the destination's ending record number in the stack.
5261
LD B,H 44
Copy Register H (high byte of the sum) into Register B.
5262
LD C,L 4D
Copy Register L (low byte of the sum) into Register C: Register Pair BC = the record number at which 535BH writes ahead.
5263
GOSUB to 535BH to position the destination to record Register Pair BC and write a sector of E5H bytes there from 5500H.
5266
POP HL E1
Restore Register Pair HL from the stack: the destination's ending record number as it was before the write ahead.
5267
LD (54C9H),HL 22 C9 54
Store Register Pair HL to 54C9H-54CAH, bytes +0CH-+0DH of the destination control block: its ending record number as it was.
526A
GOSUB to 4448H to position the destination at Register Pair DE (54BDH, kept by 535BH) to its end of file: the sector numbered by the ending record number, offset 00H.
526D
JUMP to 52DCH to read the source and write it to the destination sector by sector.
5270H - COPY (Code 32H)
SYS1/SYS runs COPY as member code 32H: the request handler loads this member and calls 5270H with Register Pair HL at the text after the command word, Register B = 32H and Register A = the code taken from 430EH. COPY reads the source and destination specifications as APPEND does. When either one is a device (an asterisk first) both are opened as they stand and the copy goes byte by byte (5375H). Otherwise the destination is completed from the source (53CDH), the source opened and the destination opened or created, both with 256 byte records; when both name the same file (same drive, same directory entry code) DESTINATION FILE SPEC REQUIRED is displayed. The destination's space is written ahead to the source's size (535BH), the destination is emptied and rewound, and the source is copied sector by sector (52DCH).
5270
GOSUB to 5349H to work out the stop page of the sector buffers from the top of memory at 4049H and store it in the compares at 52F7H, 530CH and 5330H. Register Pair HL (the parameters text) is kept.
5273
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the control block of the source (32 bytes, not in the file).
5276
GOSUB to 441CH, which has SYS1/SYS read the file specification at Register Pair HL into the control block at Register Pair DE (549DH): the Z FLAG when one was read, Register Pair HL moved past it.
5279
If the NZ FLAG is set (no source specification), JUMP to 5459H to display FILE SPEC REQUIRED and abort.
527C
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the control block of the destination (32 bytes, not in the file).
527F
GOSUB to 441CH to read the next file specification at Register Pair HL into the control block at Register Pair DE (54BDH): the Z FLAG when one was read.
5282
If the Z FLAG is set (a destination specification was read), JUMP to 528AH.
5284
DEC HL 2B
No destination specification was read: decrement Register Pair HL back to the character that stopped the read (for :1 the colon; at the end of the line the last character before the 0DH).
5285
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
5288
LDIR ED B0
Copy 32 bytes of the command line from Register Pair HL to the destination control block at Register Pair DE (54BDH) as they stand, ended by the 0DH of the line, for 53CDH to complete. Register Pair BC ends at 0000H.
528A
LD A,(549DH) 3A 9D 54
Fetch the first byte of the source specification at 549DH into Register A.
528D
CP 2AH FE 2A
Compare Register A (the first character of the source) against 2AH, an asterisk: a device.
528F
If the Z FLAG is set (the source is a device), JUMP to 5375H to open both as they stand and copy byte by byte.
5292
LD A,(54BDH) 3A BD 54
Fetch the first byte of the destination specification at 54BDH into Register A.
5295
CP 2AH FE 2A
Compare Register A (the first character of the destination) against 2AH, an asterisk: a device.
5297
If the Z FLAG is set (the destination is a device), JUMP to 5375H to copy byte by byte.
529A
LD HL,549DH 21 9D 54
Point Register Pair HL to 549DH, the source specification.
529D
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination specification.
52A0
GOSUB to 53CDH to complete the destination at Register Pair DE from the source at Register Pair HL: a missing name, extension or password is copied from the source. Register Pair DE returns 54BDH.
52A3
LD B,00H 06 00
Load Register B with 00H, the record length for the open: 256 byte records, whole sectors.
52A5
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the source control block.
52A8
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the sector buffer for the open.
52AB
GOSUB to 4424H to open the source at Register Pair DE (549DH) with the buffer at Register Pair HL (5500H) and 256 byte records (Register B = 00H): request 94H, SYS2/SYS. Register Pairs BC, DE and HL come back unchanged.
52AE
If the NZ FLAG is set (the source could not be opened, the error code in Register A), JUMP to 5454H to display the error and abort.
52B1
LD B,00H 06 00
Load Register B with 00H, the record length for the destination: 256 byte records.
52B3
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
52B6
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the sector buffer for the destination as well.
52B9
GOSUB to 4420H to open the destination at Register Pair DE (54BDH), or create it when it is not in the directory (request A4H, SYS2/SYS), with the buffer at Register Pair HL (5500H) and 256 byte records (Register B = 00H).
52BC
If the NZ FLAG is set (the destination could not be opened or created, the error code in Register A), JUMP to 5454H to display the error and abort.
52BF
LD HL,(54A3H) 2A A3 54
Fetch bytes +06H-+07H of the source control block at 54A3H-54A4H into Register Pair HL: Register L = the drive, Register H = the directory entry code of the file's record.
52C2
LD DE,(54C3H) ED 5B C3 54
Fetch bytes +06H-+07H of the destination control block at 54C3H-54C4H into Register Pair DE: Register E = its drive, Register D = its directory entry code.
52C6
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A), so that SBC below is a plain subtraction.
52C7
SBC HL,DE ED 52
SUBtract Register Pair DE (the destination's drive and entry code) from Register Pair HL (the source's): the Z FLAG is set when both control blocks name the same directory record, the same file.
52C9
If the Z FLAG is set (the source and the destination are one file), JUMP to 5475H to display DESTINATION FILE SPEC REQUIRED and abort.
52CC
LD BC,(54A9H) ED 4B A9 54
Fetch the ending record number of the source, bytes +0CH-+0DH of its control block at 54A9H-54AAH, into Register Pair BC: the number of its sectors.
52D0
GOSUB to 535BH to position the destination to record Register Pair BC (the source's sector count) and write a sector of E5H bytes there, so that the destination has the space for the whole copy before it starts.
52D3
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the ending record number of an empty file.
52D6
LD (54C9H),HL 22 C9 54
Store Register Pair HL (0000H) to 54C9H-54CAH, bytes +0CH-+0DH of the destination control block: the destination is empty again, so every sector the copy writes moves its end of file.
52D9
GOSUB to 443FH to rewind the destination at Register Pair DE (54BDH, kept by 535BH): the next write goes to its sector 0.
52DCH - Copy Sector by Sector
The memory from 5500H up to the stop page (5349H) is a row of 256 byte buffer pages. The source's buffer address (+03H-+04H at 54A0H) is set to each page in turn and the next sector read into it until the pages are full; then the destination's buffer address (54C0H) is set to each page in turn and the sectors written, and the round starts again. The reads and writes keep Register Pair HL, so Register H is the page. Error 1CH or 1DH from a read is the end of the source (1DH when its last sector is only partly used, so that the position after it is past the end of file): 5312H writes the pages read so far, gives the destination the source's end of file offset and closes it.
52DC
LD HL,5500H 21 00 55
Load Register Pair HL with 5500H, the first buffer page.
52DF
LD (54A0H),HL 22 A0 54
Store Register Pair HL (the page to read into) to 54A0H-54A1H, bytes +03H-+04H of the source control block: the source's buffer address.
52E2
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the source control block.
52E5
GOSUB to 4436H to read the next record of the source at Register Pair DE: with 256 byte records the next sector goes into the file's buffer, the page in Register Pair HL. Register Pair HL comes back unchanged; the Z FLAG when the sector was read.
52E8
If the Z FLAG is set (the sector was read), JUMP to 52F5H to go on to the next page.
52EA
CP 1CH FE 1C
Compare Register A (the error code) against 1CH, END OF FILE ENCOUNTERED.
52EC
If the Z FLAG is set (the end of the source), JUMP to 5312H to write the pages read and close the destination.
52EE
CP 1DH FE 1D
Compare Register A (the error code) against 1DH, RECORD NUMBER OUT OF RANGE: the position is past the end of a source whose last sector is partly used.
52F0
If the Z FLAG is set (the end of the source), JUMP to 5312H to write the pages read and close the destination.
52F2
Any other error: JUMP to 5454H to display the error in Register A and abort.
52F5
INC H 24
Increment Register H: Register Pair HL = the next buffer page.
52F6
LD A,H 7C
Copy Register H (the next page) into Register A.
52F7
CP 60H FE 60
Self-Modifying Code
Compare Register A (the next page) against the stop page. The operand at 52F8H is 60H in the file; 5350H stores there, at every start of APPEND or COPY, the high byte of the top of memory at 4049H plus one, less one (7FH with the top at 7FFFH, BFH at BFFFH, FFH at FFFFH).
52F9
If the NZ FLAG is set (pages are left), JUMP to 52DFH to read the next sector of the source into the page in Register Pair HL.
52FB
LD HL,5500H 21 00 55
All pages are full: load Register Pair HL with 5500H, the first page, to write them out.
52FE
LD (54C0H),HL 22 C0 54
Store Register Pair HL (the page to write) to 54C0H-54C1H, bytes +03H-+04H of the destination control block: the destination's buffer address.
5301
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
5304
GOSUB to 4439H to write the next record of the destination at Register Pair DE: with 256 byte records the file's buffer, the page in Register Pair HL, is written as the next sector. Register Pair HL comes back unchanged.
5307
If the NZ FLAG is set (the write failed, the error code in Register A), JUMP to 5454H to display the error and abort.
530A
INC H 24
Increment Register H: Register Pair HL = the next page to write.
530B
LD A,H 7C
Copy Register H (the next page) into Register A.
530C
CP 60H FE 60
Self-Modifying Code
Compare Register A (the next page) against the stop page. The operand at 530DH is 60H in the file; 5353H stores the same stop page there as at 52F8H at every start of APPEND or COPY.
530E
If the NZ FLAG is set (pages are left), JUMP to 52FEH to write the next page.
5310
All the pages are written: JUMP to 52DCH to fill them again from the source.
5312
The source has ended: GOSUB to 532CH to write the pages from 5500H up to the one below Register H (Register H is the page the failed read was for, which holds no sector).
5315
LD HL,(54A5H) 2A A5 54
Fetch bytes +08H-+09H of the source control block at 54A5H-54A6H into Register Pair HL: Register L = the source's end of file offset, Register H = its record length (00H, from the open).
5318
LD (54C5H),HL 22 C5 54
Store Register Pair HL to 54C5H-54C6H, bytes +08H-+09H of the destination control block: the destination ends at the same offset in its last sector as the source, and its record length byte stays 00H.
531B
JUMP to 5320H to close the destination, passing over the unused CALL at 531DH.
531D
GOSUB to 532CH to write the pages read. No branch in the member leads to 531DH, so this instruction is never run.
5320
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block. The byte by byte copy comes here at the end of the source and after BREAK.
5323
GOSUB to 4428H to close the file at Register Pair DE (54BDH, the destination): request 95H, SYS3/SYS, which for a file writes its end of file to its directory record and gives back the granules past it (not when bit 7 of the record's byte +01H is set); a device's control block (type 10H, a COPY to a device) is closed by SYS3/SYS's 4FD8H instead.
5326
If the NZ FLAG is set (the close failed, the error code in Register A), JUMP to 5454H to display the error and abort.
5329
JUMP to 402DH, the normal exit: VTOS READY. The source is not closed; it was only read.
532CH - Write the Pages Read
Register H = the page after the last one read (5312H). The pages from 5500H up to it are written to the destination as its next sectors. Nothing is written when Register H is 55H (no sector read in this round). The test for the stop page at 5330H does not fire from 5312H, since 52F9H writes the pages out as soon as Register H reaches it.
532C
LD A,H 7C
Copy Register H (the page after the last one read) into Register A.
532D
CP 55H FE 55
Compare Register A (the page) against 55H, the first page: the Z FLAG when no sector was read in this round.
532F
RET Z C8
If the Z FLAG is set (nothing to write), RETURN.
5330
CP 60H FE 60
Self-Modifying Code
Compare Register A (the page) against the stop page. The operand at 5331H is 60H in the file; 5356H stores the same stop page there as at 52F8H at every start of APPEND or COPY.
5332
RET Z C8
If the Z FLAG is set (Register A is the stop page), RETURN: the pages are already written.
5333
LD B,H 44
Copy Register H (the page after the last one read) into Register B, the page to stop at.
5334
LD HL,5500H 21 00 55
Load Register Pair HL with 5500H, the first page.
5337
LD (54C0H),HL 22 C0 54
Store Register Pair HL (the page to write) to 54C0H-54C1H, bytes +03H-+04H of the destination control block: its buffer address.
533A
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
533D
GOSUB to 4439H to write the page in Register Pair HL as the next sector of the destination at Register Pair DE. Register Pairs BC, DE and HL come back unchanged.
5340
If the NZ FLAG is set (the write failed, the error code in Register A), JUMP to 5454H to display the error and abort.
5343
INC H 24
Increment Register H: Register Pair HL = the next page.
5344
LD A,H 7C
Copy Register H (the next page) into Register A.
5345
CP B B8
Compare Register A (the next page) against Register B (the page after the last one read).
5346
If the NZ FLAG is set (pages are left), JUMP to 5337H to write the next one.
5348
RET C9
RETURN to 5315H with every page read written.
5349H - Set the Stop Page
The sector buffers run from 5500H up to the page below the stop page. The stop page is the high byte of the top of memory (4049H-404AH) plus one, less one: with the top at 7FFFH it is 7FH, so the pages 55H-7EH (42 sectors) are used. The value is stored as the operand of the three compares that test for it. Register Pair HL is kept.
5349
PUSH HL E5
Save Register Pair HL (the parameters text) to the stack.
534A
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL: the highest address the reset found in RAM (7FFFH, BFFFH or FFFFH), or lower when a program or driver has taken memory at the top.
534D
INC HL 23
Increment Register Pair HL: the first address above the top of memory (FFFFH gives 0000H).
534E
DEC H 25
Decrement Register H: Register H = the page below the one that holds that address, the stop page.
534F
LD A,H 7C
Copy Register H (the stop page) into Register A.
5350
LD (52F8H),A 32 F8 52
Store Register A (the stop page) to 52F8H, the operand of CP 60H at 52F7H, the end of the reading round.
5353
LD (530DH),A 32 0D 53
Store Register A (the stop page) to 530DH, the operand of CP 60H at 530CH, the end of the writing round.
5356
LD (5331H),A 32 31 53
Store Register A (the stop page) to 5331H, the operand of CP 60H at 5330H in 532CH.
5359
POP HL E1
Restore Register Pair HL (the parameters text) from the stack.
535A
RET C9
RETURN to 5203H (APPEND) or 5273H (COPY) with the stop page stored in all three compares.
535BH - Write the Destination Ahead
Register Pair BC = a record number. The destination is positioned to that sector and a sector of E5H bytes is written there from 5500H, its buffer at that moment: the space of the file reaches that sector before the copy starts, and the close later gives back what the copy did not use. The result of the position (error 1DH when the record is past the end of file) and of the write is not tested. Register Pair DE returns 54BDH.
535B
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
535E
GOSUB to 4442H to position the destination at Register Pair DE to the record number in Register Pair BC (whole sectors: the sector Register Pair BC at offset 00H). It also sets bit 6 of byte +01H, the mark of a positioned file. Register Pair BC comes back unchanged; the flags are not tested.
5361
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the destination's buffer page.
5364
LD DE,5501H 11 01 55
Point Register Pair DE to 5501H, the second byte of the page.
5367
LD BC,00FFH 01 FF 00
Load Register Pair BC with 00FFH, the 255 bytes after the first.
536A
LD (HL),E5H 36 E5
Store E5H to 5500H, the byte at Register Pair HL: the value a freshly formatted sector holds.
536C
LDIR ED B0
Copy 255 bytes from Register Pair HL to Register Pair DE, one byte on each time: E5H spreads over the whole page 5500H-55FFH. Register Pair HL ends at 55FFH, Register Pair DE at 5600H, Register Pair BC at 0000H.
536E
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
5371
GOSUB to 4439H to write the destination's buffer (5500H, the E5H page) to the sector at its position, Register Pair DE = 54BDH. The ending record number moves past it when the sector is at or past the end of file. The flags are not tested.
5374
RET C9
RETURN to 5266H (APPEND) or 52D3H (COPY) with Register Pair DE = 54BDH.
5375H - COPY With a Device
The source or the destination begins with an asterisk. Neither specification is completed. The source is opened with the buffer 5500H, the destination opened or created with the buffer 5600H, both with 256 byte records, and the copy goes one byte at a time from 5391H.
5375
LD B,00H 06 00
Load Register B with 00H, the record length for the open: 256 byte records.
5377
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the source control block.
537A
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the source's buffer.
537D
GOSUB to 4424H to open the source at Register Pair DE (549DH), a file or a device, with the buffer at Register Pair HL (5500H) and Register B = 00H. A device's control block gets the type 10H and the address of the device's control block.
5380
If the NZ FLAG is set (the open failed, the error code in Register A), JUMP to 5454H to display the error and abort.
5383
LD B,00H 06 00
Load Register B with 00H, the record length for the destination: 256 byte records.
5385
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block.
5388
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the destination's own buffer page.
538B
GOSUB to 4420H to open the destination at Register Pair DE (54BDH), or create it when it is a file that is not in the directory, with the buffer at Register Pair HL (5600H) and Register B = 00H.
538E
If the NZ FLAG is set (the open failed, the error code in Register A), JUMP to 5454H to display the error and abort.
5391H - Copy Byte by Byte
Each byte is read with the ROM's 0013H and written with the ROM's 001BH, Register Pair DE pointing at the control block. For an open file (bit 7 of byte +00H set) the ROM reaches SYS0/SYS's 48E1H through 4033H and 44C4H, so a file is read and written one byte at a time through its buffer; for a device the control block (type 10H) leads to the device's driver. A file source ends at error 1CH. A device source is read until it gives a byte; 00H (nothing yet) waits with the BREAK test of 5428H, and 01H (the BREAK key) ends the copy. A write error ends the command when the destination is a file and is passed over when it is a device. After each byte written 5428H tests BREAK and the pause. Each end goes to 5320H, which closes the destination.
5391
LD DE,549DH 11 9D 54
Point Register Pair DE to 549DH, the source control block.
5394
LD A,(DE) 1A
Fetch byte +00H of the source control block at Register Pair DE (549DH) into Register A: 80H and up for an open file, 10H for a device.
5395
BIT 7,A CB 7F
Test bit 7 of Register A: set for an open file, clear for a device.
5397
If the Z FLAG is set (the source is a device), JUMP to 53ACH to wait for a byte from it.
5399
GOSUB to the ROM's 0013H to take a byte from the control block at Register Pair DE (the source file): Register A = the byte with the Z FLAG, or the error code with the NZ FLAG. Register Pairs BC, DE and HL are kept.
539C
If the Z FLAG is set (a byte in Register A), JUMP to 53B7H to write it to the destination.
539E
CP 1CH FE 1C
Compare Register A (the error code) against 1CH, END OF FILE ENCOUNTERED.
53A0
If the Z FLAG is set (the whole source has been copied), JUMP to 5320H to close the destination and end.
53A3
JUMP to 5454H to display the error in Register A and abort (a read error of the source, or from 53C3H a write error of a destination file).
53A6
GOSUB to 5428H to test BREAK and the pause while a device source has no byte: the NZ FLAG when BREAK is held.
53A9
If the NZ FLAG is set (BREAK), JUMP to 5320H to close the destination and end.
53AC
GOSUB to the ROM's 0013H to take a byte from the device of the control block at Register Pair DE (549DH): Register A = the byte, 00H when the device has none. Register Pairs BC, DE and HL are kept.
53AF
OR A B7
OR Register A (the byte) with itself: the Z FLAG is set for 00H, no byte.
53B0
If the Z FLAG is set (no byte yet), JUMP to 53A6H to test BREAK and ask again.
53B2
CP 01H FE 01
Compare Register A (the byte) against 01H, the code the keyboard gives for the BREAK key.
53B4
If the Z FLAG is set (BREAK), JUMP to 5320H to close the destination and end.
53B7
LD DE,54BDH 11 BD 54
Point Register Pair DE to 54BDH, the destination control block. Register A holds the byte to write.
53BA
GOSUB to the ROM's 001BH to send Register A (the byte) to the control block at Register Pair DE (54BDH): a file puts it at its position (48E1H), a device passes it to its driver. The Z FLAG for success; Register Pairs BC, DE and HL are kept.
53BD
If the Z FLAG is set (the byte was written), JUMP to 53C5H.
53BF
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair HL = 54BDH, the destination control block.
53C0
BIT 7,(HL) CB 7E
Test bit 7 of byte +00H of the destination control block at Register Pair HL (54BDH): set for an open file.
53C2
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL again: Register Pair DE = 54BDH, Register Pair HL as it was. EX does not change the flags.
53C3
If the NZ FLAG is set (the destination is a file: a real write error, its code in Register A), JUMP to 53A3H to display it and abort. A device's result is passed over.
53C5
GOSUB to 5428H to test BREAK and the pause after the byte: the NZ FLAG when BREAK is held.
53C8
If the NZ FLAG is set (BREAK), JUMP to 5320H to close the destination and end.
53CB
JUMP to 5391H to copy the next byte from the source to the destination.
53CDH - Complete the Destination From the Source
Register Pair HL = the source specification (549DH), Register Pair DE = the destination (54BDH), both as text. When the destination does not start with a letter (for example :1 or /OLD), the source's name, its letters and digits up to its first other character, is put in front (5408H). Then the destination is searched for a slash and for a period: a part that is missing (the search meets another character that ends a field first) is taken from the source, its slash or period and the letters and digits after it inserted at that place (53F5H). The drive is never copied. Each insertion moves the rest of the destination text, up to and with its 03H or 0DH, one place on. Register Pair DE returns the start of the destination; Register C is the last end byte moved (03H or 0DH) when anything was inserted.
53CD
PUSH DE D5
Save Register Pair DE (54BDH, the start of the destination) to the stack.
53CE
LD A,(DE) 1A
Fetch the first character of the destination at Register Pair DE into Register A.
53CF
CP 41H FE 41
Compare Register A (the first character of the destination) against 41H, the letter A: the CARRY FLAG is set for a digit, a colon, a slash or a period, a destination without a name.
53D1
If the C FLAG is set (no name), GOSUB to 5408H to insert the source's name at Register Pair DE. Register Pair HL comes back after the source's name, Register Pair DE after the inserted name.
53D4
LD B,2FH 06 2F
Load Register B with 2FH, a slash: look for the extension.
53D6
GOSUB to 53E1H to find the slash in the destination at Register Pair DE, or insert the source's extension there.
53D9
LD B,2EH 06 2E
Load Register B with 2EH, a period: look for the password.
53DB
GOSUB to 53E1H to find the period in the destination at Register Pair DE, or insert the source's password there.
53DE
POP DE D1
Restore Register Pair DE from the stack: 54BDH, the start of the destination.
53DF
RET C9
RETURN to 522BH (APPEND) or 52A3H (COPY) with the destination complete.
53E0
INC DE 13
Increment Register Pair DE to the next character of the destination.
53E1
LD A,(DE) 1A
Fetch the character of the destination at Register Pair DE into Register A.
53E2
CP B B8
Compare Register A (the character of the destination) against Register B, the separator looked for (2FH a slash or 2EH a period).
53E3
If the Z FLAG is set (the destination has this part), JUMP to 53F3H.
53E5
CP 41H FE 41
Compare Register A (the character of the destination) against 41H, the letter A.
53E7
If the NC FLAG is set (41H and up, a letter of the field), JUMP to 53E0H for the next character.
53E9
CP 30H FE 30
Compare Register A (the character of the destination) against 30H, the digit 0.
53EB
If the C FLAG is set (below 30H: the other separator, an exclamation mark, 03H or 0DH), JUMP to 53F5H: the part is missing and goes in here.
53ED
CP 3AH FE 3A
Compare Register A (the character of the destination) against 3AH, the character after 9.
53EF
If the C FLAG is set (a digit, a character of the field), JUMP to 53E0H for the next character.
53F1
JUMP to 53F5H: Register A is 3AH-40H (the colon of the drive), so the part is missing and goes in before it.
53F3
INC DE 13
Increment Register Pair DE past the separator found in the destination.
53F4
RET C9
RETURN with Register Pair DE after the separator, where the search for the next part starts.
53F5
PUSH HL E5
Save Register Pair HL (the place in the source) to the stack.
53F6
LD A,(HL) 7E
Fetch the character of the source at Register Pair HL into Register A.
53F7
INC HL 23
Increment Register Pair HL to the next character of the source.
53F8
CP 03H FE 03
Compare Register A (the character of the source) against 03H, the end of the source specification.
53FA
If the Z FLAG is set (the source has no such part either), JUMP to 5406H.
53FC
CP 0DH FE 0D
Compare Register A (the character of the source) against 0DH, an end of line.
53FE
If the Z FLAG is set (the end of the source), JUMP to 5406H.
5400
CP B B8
Compare Register A (the character of the source) against Register B, the separator looked for.
5401
If the NZ FLAG is set (not yet), JUMP to 53F6H for the next character of the source.
5403
The source has the part: GOSUB to 5414H with Register A = the separator (Register B) to insert it at Register Pair DE, then the letters and digits after it from Register Pair HL.
5406
POP HL E1
Restore Register Pair HL from the stack: the place in the source as it was at 53F5H.
5407
RET C9
RETURN to 53D9H or 53DEH with Register Pair HL back at the place in the source where the search began.
5408H - Insert Letters and Digits
Register Pair HL = the source text, Register Pair DE = the place in the destination. Each letter or digit of the source (and any character from 5BH up) is inserted at Register Pair DE until a character below 30H or 3AH-40H; Register Pair HL is left on that character. 5414H inserts the character in Register A first (the separator from 5403H).
5408
LD A,(HL) 7E
Fetch the character of the source at Register Pair HL into Register A.
5409
CP 30H FE 30
Compare Register A (the character of the source) against 30H, the digit 0.
540B
RET C D8
If the C FLAG is set (below 30H: a slash, a period, an exclamation mark, 03H or 0DH), RETURN: the field has ended.
540C
CP 3AH FE 3A
Compare Register A (the character of the source) against 3AH, the character after 9.
540E
If the C FLAG is set (a digit), JUMP to 5413H to insert it.
5410
CP 41H FE 41
Compare Register A (the character of the source) against 41H, the letter A.
5412
RET C D8
If the C FLAG is set (3AH-40H, the colon of the drive), RETURN: the field has ended.
5413
INC HL 23
Increment Register Pair HL past the character of the source in Register A.
5414
PUSH HL E5
Save Register Pair HL (the place in the source) to the stack.
5415
LD H,D 62
Copy Register D (high byte of the place in the destination) into Register H.
5416
LD L,E 6B
Copy Register E into Register L: Register Pair HL = the place in the destination.
5417
LD C,(HL) 4E
Fetch the character of the destination at Register Pair HL into Register C, the one that has to move on.
5418
LD (HL),A 77
Store Register A (the character to insert, or the one moved from the place before) to the destination at Register Pair HL.
5419
INC HL 23
Increment Register Pair HL to the next place of the destination.
541A
LD A,C 79
Copy Register C (the character taken out) into Register A, to go into the next place.
541B
CP 03H FE 03
Compare Register A (the character moved) against 03H, the end of the destination text.
541D
If the Z FLAG is set (the end byte), JUMP to 5423H to store it.
541F
CP 0DH FE 0D
Compare Register A (the character moved) against 0DH, the end of a destination copied from the line at 5218H or 5288H.
5421
If the NZ FLAG is set (not the end), JUMP to 5417H to move the next character on.
5423
LD (HL),A 77
Store Register A (the end byte, 03H or 0DH) to Register Pair HL, one place after where it was.
5424
POP HL E1
Restore Register Pair HL from the stack: the place in the source.
5425
INC DE 13
Increment Register Pair DE past the character inserted in the destination.
5426
JUMP to 5408H to take the next character of the source.
5428H - Test BREAK and the Pause
Returns the NZ FLAG when BREAK is held, the Z FLAG to go on. While a file of DO commands runs (bit 5 of 430FH) nothing is tested. SHIFT and @ held together stop the copy until another key is typed (the key itself is dropped) or BREAK is pressed. The keys are read in the keyboard matrix: 3840H row 6 (bit 2 BREAK), 3801H row 0 (bit 0 @), 3880H row 7 (bit 0 SHIFT).
5428
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
542B
AND 20H E6 20
Mask Register A (the system flags) to bit 5, set while SYS7/SYS runs a file of DO commands.
542D
XOR 20H EE 20
Exclusive OR Register A with 20H: Register A = 00H and the Z FLAG when bit 5 was set.
542F
RET Z C8
If the Z FLAG is set (DO commands are running), RETURN with the Z FLAG: go on without a test.
5430
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A (bit 0 ENTER, 1 CLEAR, 2 BREAK, 3-6 the arrows, 7 the space bar).
5433
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
5435
RET NZ C0
If the NZ FLAG is set (BREAK held), RETURN with the NZ FLAG and Register A = 04H.
5436
LD A,(3801H) 3A 01 38
Fetch keyboard row 0 from 3801H into Register A (bit 0 the key @, bits 1-7 the letters A-G).
5439
AND 01H E6 01
Mask Register A (keyboard row 0) to bit 0, the key @.
543B
RET Z C8
If the Z FLAG is set (@ not held), RETURN with the Z FLAG: go on.
543C
LD A,(3880H) 3A 80 38
Fetch keyboard row 7 from 3880H into Register A (bit 0 SHIFT).
543F
AND 01H E6 01
Mask Register A (keyboard row 7) to bit 0, the SHIFT key.
5441
RET Z C8
If the Z FLAG is set (SHIFT not held), RETURN with the Z FLAG: go on.
5442
LD A,(3840H) 3A 40 38
The pause: fetch keyboard row 6 from 3840H into Register A.
5445
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
5447
RET NZ C0
If the NZ FLAG is set (BREAK held), RETURN with the NZ FLAG: the copy ends.
5448
GOSUB to the ROM's 002BH to scan the keyboard through the keyboard's control block 4015H: Register A = the key typed, 00H for none.
544B
OR A B7
OR Register A (the key) with itself: the Z FLAG is set for 00H, no key.
544C
If the Z FLAG is set (no key), JUMP to 5442H to keep waiting.
544E
CP 60H FE 60
Compare Register A (the key) against 60H, the code of @ with SHIFT, the keys that began the pause.
5450
If the Z FLAG is set (the pause keys again), JUMP to 5442H to keep waiting.
5452
XOR A AF
Set Register A to 00H and the Z FLAG (XOR A): another key ends the pause.
5453
RET C9
RETURN with the Z FLAG and Register A = 00H: the copy goes on with the next byte.
5454H - Error Exits
5454H displays the message of the error code in Register A (bit 6 set: the text alone) through 4409H, which then goes to the abort exit 4030H since bit 7 is clear. 5459H and 5475H display the member's own messages through 447BH (the display and the job log) and abort.
5454
OR 40H F6 40
Set bit 6 of Register A (the error code from a request): OR 40H asks for the text of the message alone.
5456
JUMP to 4409H to display the message of the error in Register A; with bit 7 clear it then goes to the abort exit 4030H.
5459
LD HL,5462H 21 62 54
Point Register Pair HL to 5462H, the message FILE SPEC REQUIRED.
545C
GOSUB to 447BH to display the text at Register Pair HL (5462H) up to its 0DH and write it to the job log.
545F
JUMP to 4030H, the abort exit: request A3H, the command ends and VTOS READY is displayed.
5462-5473
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5459H, displayed when a specification is missing or the destination of APPEND is a device.
5474
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED at 5462H, for 447BH.
5475
LD HL,547EH 21 7E 54
Point Register Pair HL to 547EH, the message DESTINATION FILE SPEC REQUIRED.
5478
GOSUB to 447BH to display the text at Register Pair HL (547EH) up to its 0DH and write it to the job log.
547B
JUMP to 4030H, the abort exit: request A3H, the command ends and VTOS READY is displayed.
547E-549B
DEFM "DESTINATION FILE SPEC REQUIRED" 44 45 53 54 49 4E 41 54 49 4F 4E 20 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5475H, displayed by COPY when the source and the destination are the same file.
549C
DEFB 0DH 0D
The carriage return that ends the message DESTINATION FILE SPEC REQUIRED at 547EH, for 447BH.
549DH - Work Areas Above the Member
Not in the file: the two control blocks follow the member's last byte (549CH), and the sector buffers start at 5500H.
549D-54BC
DEFS 32
Not in the file: the control block of the source, filled with the specification as text by 441CH (5206H, 5276H) and by the open (523EH, 52ABH, 537DH). Used: +00H 549DH (5394H), +03H-+04H 54A0H (the buffer, 52DFH), +06H-+07H 54A3H (52BFH), +08H-+09H 54A5H (5315H), +0CH-+0DH 54A9H (525DH, 52CCH).
54BD-54DC
DEFS 32
Not in the file: the control block of the destination, filled by 441CH or the LDIR (520FH, 5218H, 527FH, 5288H), completed by 53CDH and opened at 5230H, 52B9H or 538BH. Used: +00H 54BDH (521AH, 5292H, 53C0H), +03H-+04H 54C0H (the buffer, 5253H, 52FEH, 5337H), +06H-+07H 54C3H (52C2H), +08H-+09H 54C5H (5244H, 5318H), +0CH-+0DH 54C9H (5259H, 5267H, 52D6H).
54DD-54FF
DEFS 35
Not in the file: the bytes between the destination control block and the first buffer page 5500H. No instruction addresses them, but an insertion by 53CDH into a destination copied from the line by the LDIR (5218H, 5288H) moves that text on up to its first 03H or 0DH, which can lie past 54DCH, and then shifts bytes into this area.
5500-55FF
DEFS 256
Not in the file: the first buffer page. Both files are opened with it (522DH, 523BH, 52A8H, 52B6H, 537AH); 535BH fills it with E5H for the write ahead; the sector copy reads into it and writes from it as its first page (52DCH, 52FBH, 5334H); the byte by byte copy uses it as the source's buffer.
5600-56FF
DEFS 256
Not in the file: the second buffer page, the destination's buffer in the byte by byte copy (5250H, 5388H), and the second page of the sector copy, which goes on through the pages above it up to the page below the stop page (5349H): 7EFFH with the top of memory at 7FFFH, FEFFH at FFFFH.
5200H - Member 16 (BUILD, Code 33H): Read the File Specification
BUILD filespec. Entered from SYS1/SYS's command interpreter (request 88H with Register B = 33H) with Register Pair HL pointing at the text after the command word. The file specification is copied into the control block at 52CCH by 441CH; when there is none the member shows FILE SPEC REQUIRED and aborts. When the extension in the copied text is KSM, the operand at 523EH is set to FFH and every line is prompted with its letter (A=> up to Z=>). The file is created with 4420H; a file that already exists is refused with FILE ALREADY EXISTS. The lines typed are kept in memory from 5400H on and written to the file only after the last one.
5200
LD DE,52CCH 11 CC 52
Point Register Pair DE to 52CCH, the 32 byte control block (not in the file) that receives the file specification.
5203
GOSUB to 441CH (SYS1/SYS's 4FCEH) to copy the file specification from the command text at Register Pair HL into the control block at Register Pair DE (52CCH), upper case and ended by 03H: the Z FLAG is set when it is a good specification.
5206
If the NZ FLAG is set (no file specification, or a bad one), JUMP to 5293H to show FILE SPEC REQUIRED and abort.
5209
LD HL,52CCH 21 CC 52
Point Register Pair HL to 52CCH, the copied text of the file specification, to look for its extension.
520C
LD A,(HL) 7E
Loop Start
Fetch the next character of the text at Register Pair HL (from 52CCH) into Register A.
520D
INC HL 23
Increment Register Pair HL to the following character.
520E
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the carriage return; the 03H that ends the copied text is not tested.
5210
If the Z FLAG is set (Register A = 0DH), JUMP to 522CH: no KSM extension.
5212
CP 2FH FE 2F
Compare Register A (the character) against 2FH, the slash that starts the extension.
5214
If the NZ FLAG is set (not a slash), LOOP BACK to 520CH for the next character at Register Pair HL.
5216
LD A,(HL) 7E
Fetch the first character of the extension at Register Pair HL into Register A.
5217
INC HL 23
Increment Register Pair HL to the second character of the extension.
5218
CP 4BH FE 4B
Compare Register A (the first character of the extension) against 4BH, the letter K.
521A
If the NZ FLAG is set (not K), JUMP to 522CH: not a KSM file.
521C
LD A,(HL) 7E
Fetch the second character of the extension at Register Pair HL into Register A.
521D
INC HL 23
Increment Register Pair HL to the third character of the extension.
521E
CP 53H FE 53
Compare Register A (the second character of the extension) against 53H, the letter S.
5220
If the NZ FLAG is set (not S), JUMP to 522CH: not a KSM file.
5222
LD A,(HL) 7E
Fetch the third character of the extension at Register Pair HL into Register A.
5223
CP 4DH FE 4D
Compare Register A (the third character of the extension) against 4DH, the letter M.
5225
If the NZ FLAG is set (not M), JUMP to 522CH: not a KSM file.
5227
LD A,FFH 3E FF
Load Register A with FFH, the value that turns on the letter prompts of a KSM file.
5229
LD (523EH),A 32 3E 52
Store Register A (FFH) to 523EH, the operand of LD A,00H at 523DH: every line is now prompted with its letter.
522CH - Create the File
The file is opened with SYS2/SYS's request A4H (4420H), which creates it when it is not there: the Z FLAG with the CARRY FLAG means a new file, the Z FLAG with the NC FLAG a file that was there already (refused), the NZ FLAG an error.
522C
LD HL,5300H 21 00 53
Point Register Pair HL to 5300H, the 256 byte sector buffer of the file (5300H-53FFH, not in the file).
522F
LD B,00H 06 00
Load Register B with 00H, the record length 256 for the open.
5231
GOSUB to 4420H (SYS2/SYS request A4H) to open or create the file named in the control block at Register Pair DE (52CCH) with the buffer at Register Pair HL (5300H) and record length Register B (00H): the CARRY FLAG is set when the file was created.
5234
If the NZ FLAG is set (the open or the create failed, Register A = the error code), JUMP to 528EH to show the error and abort.
5237
If the NC FLAG is set (the file was there already and has been opened, not created), JUMP to 52AFH to show FILE ALREADY EXISTS and abort.
523A
LD HL,5400H 21 00 54
Point Register Pair HL to 5400H, the start of the memory that keeps the lines typed.
523DH - Read the Lines
Loop Start
Each pass reads one line with the ROM's 0040H into memory at Register Pair HL: up to 255 characters, ended by the 0DH that the ROM stores. In KSM mode (523EH = FFH) the line counter at 5243H counts 1 to 26 and the prompt is the letter (40H + count), the sign =, the sign > and a space; after the line for Z the input ends by itself. BREAK typed on an empty line ends the input; BREAK after some characters keeps the line (the ROM ends it with 0DH as well) and the input goes on.
523D
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the KSM flag: the operand at 523EH is 00H as loaded, and 5229H writes FFH there when the extension of the file is KSM, before the first line is read.
523F
OR A B7
OR Register A (the KSM flag) with itself: the Z FLAG is set when it is 00H, an ordinary file.
5240
If the Z FLAG is set (not a KSM file), JUMP to 5260H to read the line with no prompt.
5242
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the line counter: the operand at 5243H is 00H as loaded (the member is loaded afresh for each BUILD) and 5245H writes the new count there for each line, 01H for A up to 1AH for Z.
5244
INC A 3C
Increment Register A (the line counter): the number of this line, 01H to 1BH.
5245
LD (5243H),A 32 43 52
Store Register A (the new line number) to 5243H, the operand of LD A,00H at 5242H, for the next line.
5248
CP 1BH FE 1B
Compare Register A (the line number) against 1BH, one past the 26 letters.
524A
If the Z FLAG is set (the 26 lines A to Z have been read), JUMP to 5272H to end the input and write the file.
524C
ADD A,40H C6 40
Add 40H to Register A (the line number 01H to 1AH): Register A = the letter of the line, A (41H) to Z (5AH).
524E
GOSUB to the ROM's 0033H to display Register A, the letter of the line.
5251
LD A,3DH 3E 3D
Load Register A with 3DH, the equals sign of the prompt.
5253
GOSUB to the ROM's 0033H to display Register A, the equals sign.
5256
LD A,3EH 3E 3E
Load Register A with 3EH, the greater than sign of the prompt.
5258
GOSUB to the ROM's 0033H to display Register A, the greater than sign.
525B
LD A,20H 3E 20
Load Register A with 20H, the space that ends the prompt.
525D
GOSUB to the ROM's 0033H to display Register A, the space; the ROM's display routine keeps Register Pair HL, the line's place in memory.
5260
LD B,FFH 06 FF
Load Register B with FFH, the most characters of a line, 255, for any file.
5262
GOSUB to the ROM's 0040H to read a line into memory at Register Pair HL, at most Register B (FFH) characters, ended by 0DH: Register B returns the number of characters typed, Register Pair HL the start of the line, and the CARRY FLAG is set when the line was ended by BREAK.
5265
If the CARRY FLAG is set (the line was ended by BREAK), JUMP to 526EH to see whether anything was typed.
5267
LD C,B 48
Copy Register B (the number of characters of the line) into Register C.
5268
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the length of the line.
526A
ADD HL,BC 09
Add Register Pair BC (the length of the line) to Register Pair HL (its start): Register Pair HL points at the 0DH that ends the line.
526B
INC HL 23
Increment Register Pair HL past the 0DH, to the place of the next line.
526C
JUMP back to 523DH to read the next line at Register Pair HL.
526E
LD A,B 78
Copy Register B (the number of characters typed before BREAK) into Register A.
526F
OR A B7
OR Register A (the number of characters) with itself: the Z FLAG is set when BREAK was the first key of the line.
5270
If the NZ FLAG is set (characters were typed before BREAK), JUMP back to 5267H to keep the line, which the ROM ended with 0DH, and go on.
5272H - Write the Lines to the File
The 03H stored after the last line ends the text; every byte from 5400H up to it (the lines and their 0DH bytes) is written to the file through the ROM's 001BH, then the file is closed. The member ends at VTOS READY, or with the error message of a failed write or close.
5272
LD (HL),03H 36 03
Store 03H at Register Pair HL (the place of the next line, or the start of the empty line ended by BREAK): the end of the text; the 0DH that the ROM stored there for an empty line is replaced.
5274
LD HL,5400H 21 00 54
Point Register Pair HL to 5400H, the first line typed.
5277
LD DE,52CCH 11 CC 52
Point Register Pair DE to 52CCH, the open control block of the file, for the ROM's byte output.
527A
LD A,(HL) 7E
Loop Start
Fetch the next byte of the text at Register Pair HL (from 5400H) into Register A.
527B
INC HL 23
Increment Register Pair HL to the following byte of the text.
527C
CP 03H FE 03
Compare Register A (the byte) against 03H, the end of the text stored at 5272H.
527E
If the Z FLAG is set (Register A = 03H), JUMP to 5287H to close the file; the 03H is not written.
5280
GOSUB to the ROM's 001BH to send Register A (the byte) to the file whose control block is at Register Pair DE (52CCH); the ROM routine keeps Register Pairs BC, DE and HL and returns the Z FLAG on success or the NZ FLAG with Register A = the error code.
5283
If the NZ FLAG is set (the write failed, Register A = the error code), JUMP to 528EH to show the error and abort.
5285
JUMP back to 527AH for the next byte at Register Pair HL.
5287
GOSUB to 4428H (SYS3/SYS request 95H) to close the file whose control block is at Register Pair DE (52CCH): the last sector is written and the directory record updated.
528A
If the Z FLAG is set (the file was closed), JUMP to 402DH: VTOS READY, the end of the command.
528D
NOP 00
No operation: with the NZ FLAG from the close, the member runs on into 528EH with the error code in Register A.
528EH - The Error Exits and the Messages
528EH takes an error code in Register A and jumps to 4409H with bit 6 set (the text of the message alone) and bit 7 clear (the message routine goes on to the abort exit). 5293H and 52AFH display FILE SPEC REQUIRED or FILE ALREADY EXISTS and jump to the abort exit 4030H.
528E
OR 40H F6 40
Set bit 6 of Register A (the error code from the open, the byte write or the close): only the text of the message is to be shown.
5290
JUMP to 4409H to display the message of the error code in Register A; bit 7 is clear, so it goes on to the abort exit 4030H.
5293
LD HL,529CH 21 9C 52
Point Register Pair HL to 529CH, the text FILE SPEC REQUIRED ended by 0DH.
5296
GOSUB to 447BH to display the text at Register Pair HL (529CH) and write it to the job log.
5299
JUMP to 4030H, the abort exit: no file is opened.
529C-52AD
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message 5293H shows when the command text holds no good file specification.
52AE
DEFB 0DH 0D
The carriage return that ends the message at 529CH.
52AF
LD HL,52B8H 21 B8 52
Point Register Pair HL to 52B8H, the text FILE ALREADY EXISTS ended by 0DH.
52B2
GOSUB to 447BH to display the text at Register Pair HL (52B8H) and write it to the job log.
52B5
JUMP to 4030H, the abort exit: the file that was there is left as it was, open but not written.
52B8-52CA
DEFM "FILE ALREADY EXISTS" 46 49 4C 45 20 41 4C 52 45 41 44 59 20 45 58 49 53 54 53
The message 52AFH shows when the open at 5231H found the file already there (the NC FLAG).
52CB
DEFB 0DH 0D
The carriage return that ends the message at 52B8H.
52CC-52EB
DEFS 32
Not in the file: the control block of the file. 441CH (5203H) copies the file specification here as text ended by 03H, 5209H-5225H look for the extension KSM in it, the open at 5231H fills it in, and the byte writes (5280H) and the close (5287H) use it.
5300-53FF
DEFS 256
Not in the file: the sector buffer of the file, given to the open at 522CH; the byte writes of 5280H fill it and the close writes its last sector.
5400-6E00
DEFS 6657
Not in the file: the text typed, from 5400H up, each line ended by 0DH and the whole ended by the 03H that 5272H stores; read by 527AH-5285H. The size shown is the most a KSM file can use (26 lines of 255 characters and 0DH, then 03H); without the extension KSM there is no limit and the lines go on up through memory.
5200H - Member 17 (LIST, PRINT, Codes 41H, 42H): LIST Entry, Code 41H
SYS1/SYS's command interpreter runs this member for the word LIST (member code 41H, entry 5200H) and for the word PRINT (member code 42H, entry 5206H): the request handler of SYS0/SYS loads it at 5200H-5517H and CALLs the entry with Register Pair HL pointing at the rest of the command line, a file specification and an optional parameter list (NUM, LINE=, HEX, REC=, LRL=). LIST sends the listing to the DO device control block at 401DH (the display), PRINT to the PR device control block at 4025H (the printer); the two entries differ only in that address and in the flag stored at 5380H (00H LIST, FFH PRINT), which picks the layout of a HEX listing. Without HEX the file is listed as text, line by line, from line LINE (default 1), with five digit line numbers when NUM is given; with HEX it is listed in hex and as characters, 16 bytes a line, from record REC (default 0) with records of LRL bytes (default 0, 256). Normal ends go to 402DH (VTOS READY), BREAK to 4030H (the abort exit), errors to 4409H.
5200
XOR A AF
Set Register A to 00H with XOR A: the layout flag of LIST (00H: the characters of a HEX line are shown on a second line under the hex bytes), stored at 5380H below.
5201
LD DE,401DH 11 1D 40
Point Register Pair DE to 401DH, the DO device control block (the display): LIST sends every character of its listing there.
5204
JUMP to 520BH, the part common to LIST and PRINT, with Register A = 00H and Register Pair DE = 401DH.
5206H - PRINT Entry, Code 42H
The entry of PRINT (member code 42H): the same work as LIST, but every character goes to the PR device control block at 4025H (the printer) and a HEX line carries its characters on the same line after the hex bytes. It falls into the common setup at 520BH, which keeps the device control block address on the stack, clears the parameter words and reads the file specification and the parameters.
5206
LD A,FFH 3E FF
Load Register A with FFH, the layout flag of PRINT (not 00H: the characters of a HEX line follow the hex bytes on the same line), stored at 5380H below.
5208
LD DE,4025H 11 25 40
Point Register Pair DE to 4025H, the PR device control block (the printer): PRINT sends every character of its listing there.
520BH - Common Setup: File Specification, Parameters and Open
Register A holds the layout flag (00H LIST, FFH PRINT) and Register Pair DE the device control block of the listing (401DH or 4025H). The flag is stored at 5380H and the device control block address is pushed: it stays on the stack for the whole command and is fetched with POP DE / PUSH DE wherever a character is sent. The parameter words NUM (52ADH), HEX (527AH) and LRL (5329H) are cleared and LINE (5282H) is set to 1; REC (530FH) keeps the 0000H of the file. The file specification is read into the control block at 5528H (an asterisk, a device, is refused with FILE SPEC REQUIRED), the parameters through the table at 54EFH, and the file is opened with the buffer at 5600H and the record length LRL: first with the default extension TXT, and when that fails with the specification as typed.
520B
LD (5380H),A 32 80 53
Store Register A (00H for LIST, FFH for PRINT) to 5380H, the operand of LD A,00H at 537FH, which picks the layout of a HEX line.
520E
PUSH DE D5
Save Register Pair DE (401DH for LIST, 4025H for PRINT, the device control block of the listing) to the stack, where it stays until the command ends.
520F
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the value of a parameter that is not given (off).
5212
LD (52ADH),BC ED 43 AD 52
Store Register Pair BC (0000H) to 52ADH-52AEH, the word of the parameter NUM (the operand of LD BC,0000H at 52ACH): no line numbers unless NUM is given.
5216
LD (527AH),BC ED 43 7A 52
Store Register Pair BC (0000H) to 527AH-527BH, the word of the parameter HEX (the operand of LD BC,0000H at 5279H): a text listing unless HEX is given.
521A
LD (5329H),BC ED 43 29 53
Store Register Pair BC (0000H) to 5329H-532AH, the word of the parameter LRL (the operand of LD BC,0000H at 5328H): record length 00H, 256 bytes, unless LRL is given.
521E
LD BC,0001H 01 01 00
Load Register Pair BC with 0001H, the default of the parameter LINE: the listing starts at the first line.
5221
LD (5282H),BC ED 43 82 52
Store Register Pair BC (0001H) to 5282H-5283H, the word of the parameter LINE (the operand of LD BC,0000H at 5281H).
5225
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the file control block of the member (32 bytes above the member, not in the file), which takes the file specification.
5228
GOSUB to 441CH, SYS1/SYS function 4: copy the file specification from the text at Register Pair HL (the rest of the command line) into the control block at Register Pair DE (5528H). It returns the Z FLAG when good, Register Pair HL past the specification and Register Pair DE = 5528H.
522B
If the NZ FLAG is set (no valid file specification), JUMP to 54A3H to display FILE SPEC REQUIRED and abort.
522E
LD A,(DE) 1A
Fetch the first byte of the specification from the control block at Register Pair DE (5528H) into Register A.
522F
CP 2AH FE 2A
Compare Register A (the first byte of the specification) against 2AH, an asterisk, which starts a device name.
5231
If the Z FLAG is set (a device was named, not a file), JUMP to 54A3H to display FILE SPEC REQUIRED and abort: the member lists files only.
5234
LD DE,54EFH 11 EF 54
Point Register Pair DE to 54EFH, the parameter table of the member (LINE, NUM, HEX, REC, LRL, each with the address of its word).
5237
GOSUB to 4476H, SYS1/SYS function 6: read the parameter list in parentheses from the text at Register Pair HL against the table at Register Pair DE (54EFH), storing each value in its word. No list (0DH or no parenthesis) gives the Z FLAG with nothing stored.
523A
If the NZ FLAG is set (an unknown name or a bad value in the list), JUMP to 54BFH to display PARAMETER ERROR and abort.
523D
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a file control block, for the copy below.
5240
LD DE,5548H 11 48 55
Point Register Pair DE to 5548H, the save area for the specification as typed (32 bytes above the member, not in the file).
5243
LD HL,5528H 21 28 55
Point Register Pair HL to 5528H, the control block that holds the specification as typed.
5246
LDIR ED B0
Copy the 32 bytes of the control block at Register Pair HL (5528H) to the save area at Register Pair DE (5548H): the specification is kept for the second open below. Register Pair HL ends at 5548H, Register Pair DE at 5568H and Register Pair BC at 0000H.
5248
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the control block with the file specification.
524B
LD HL,54ECH 21 EC 54
Point Register Pair HL to 54ECH, the three letters TXT, the default extension of the member.
524E
GOSUB to 4473H, SYS1/SYS function 5: add "/TXT" to the specification in the control block at Register Pair DE (5528H) when it has no extension; one that has an extension is not changed.
5251
LD A,(5329H) 3A 29 53
Fetch the low byte of the parameter word LRL from 5329H (00H unless LRL was given) into Register A.
5254
LD B,A 47
Copy Register A (the record length, 00H for 256) into Register B, the record length the open takes.
5255
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the 256 byte sector buffer of the file (above the member, not in the file).
5258
GOSUB to 4424H, request 94H: SYS2/SYS opens the file named by the control block at Register Pair DE (5528H) with the buffer at Register Pair HL (5600H) and the record length in Register B. It returns the Z FLAG when the file is open.
525B
If the Z FLAG is set (the file with the extension TXT, or with its own extension, is open), JUMP to 5279H to start the listing.
525E
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of the saved specification, for the copy below.
5261
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the control block, where the specification as typed is put back.
5264
LD HL,5548H 21 48 55
Point Register Pair HL to 5548H, the save area holding the specification as typed.
5267
LDIR ED B0
Copy the 32 bytes from the save area at Register Pair HL (5548H) back to the control block at Register Pair DE (5528H): the specification without the added /TXT. Register Pair HL ends at 5568H, Register Pair DE at 5548H and Register Pair BC at 0000H.
5269
LD A,(5329H) 3A 29 53
Fetch the low byte of the parameter word LRL from 5329H (the record length, 00H for 256) into Register A again for the second open.
526C
LD B,A 47
Copy Register A (the record length) into Register B, the record length the open takes.
526D
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the control block with the specification as typed.
5270
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the sector buffer of the file.
5273
GOSUB to 4424H, request 94H: SYS2/SYS opens the file named by the control block at Register Pair DE (5528H, the specification as typed) with the buffer at Register Pair HL (5600H) and the record length in Register B.
5276
If the NZ FLAG is set (this open failed too), JUMP to 549EH to display the error in Register A and abort.
5279H - Text or HEX Listing; Skip to Line LINE
The file is open in the control block at 5528H. A HEX word other than 0000H sends the listing to 530EH. A text listing passes over the first LINE less one lines of the file: each line ends with a carriage return (0DH). LINE=0 makes the count 0000H less one, FFFFH, and LINE alone (FFFFH) FFFEH, so both read on to the end of any file of fewer lines, and that end of file is shown as an error here. Then the line number text at 54D8H is set to the value of LINE.
5279
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the word of the parameter HEX. 5216H stores 0000H here at each start and 4476H (from 5237H) stores the value given: FFFFH for HEX alone, 0000H for HEX=N or HEX=OFF, the number for HEX=n.
527C
LD A,B 78
Copy Register B (the high byte of the HEX word) into Register A.
527D
OR C B1
OR Register C (the low byte of the HEX word) into Register A: the Z FLAG is set when the word is 0000H, HEX not given.
527E
If the NZ FLAG is set (HEX given), JUMP to 530EH for the HEX listing.
5281
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the word of the parameter LINE, the first line to list (0000H in the file). 5221H stores 0001H here at each start and 4476H (from 5237H) stores the value given (FFFFH for LINE alone).
5284
DEC BC 0B
Decrement Register Pair BC (the line LINE) to the count of lines to pass over: LINE less one (0000H for line 1, FFFFH for LINE=0).
5285
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
5286
OR C B1
OR Register C (the low byte of the count) into Register A: the Z FLAG is set when there are no lines to pass over.
5287
If the Z FLAG is set (the listing starts at line 1), JUMP to 5298H to set up the line number.
5289
Loop Start
GOSUB to the ROM's 0013H to read the next byte from the device control block at Register Pair DE, here the file control block 5528H (its type byte 80H sends the request through 4033H to SYS0/SYS's 48F1H): Register A = the byte with the Z FLAG, or an error code (1CH at the end of the file) with the NZ FLAG.
528C
If the NZ FLAG is set (the end of the file or a read error while passing over lines), JUMP to 549EH to display the error in Register A and abort.
528F
CP 0DH FE 0D
Compare Register A (the byte read) against 0DH, the carriage return that ends a line.
5291
If the NZ FLAG is set (not the end of a line), JUMP back to 5289H for the next byte of the same line.
5293
DEC BC 0B
Decrement Register Pair BC, the count of lines still to pass over.
5294
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
5295
OR C B1
OR Register C (the low byte of the count) into Register A: the Z FLAG is set when all the lines before line LINE are passed over.
5296
If the NZ FLAG is set (lines left to pass over), JUMP back to 5289H to read the next line.
5298
LD HL,(5282H) 2A 82 52
Fetch the word of the parameter LINE from 5282H-5283H (the operand at 5281H) into Register Pair HL: the number of the first line listed.
529B
LD BC,54D8H 01 D8 54
Point Register Pair BC to 54D8H, the five digits of the line number text " . " ended by 03H.
529E
GOSUB to 542BH to write Register Pair HL (the line number LINE) as five decimal digits at Register Pair BC (54D8H-54DCH).
52A1H - Text Listing: One Line
Each pass lists one line of the file. The first byte is read and kept at 52C2H; with NUM the line number text 54D8H ("nnnnn. ") is sent first and then counted on by one. The bytes up to the carriage return are sent to the device with bit 7 cleared; after a byte that had bit 7 set, and after each line, 5472H tests the keyboard (BREAK ends the listing, SHIFT and @ pause it). The end of the file (1CH) or a record number out of range (1DH) ends the listing normally at 52F6H.
52A1
LD DE,5528H 11 28 55
Loop Start
Point Register Pair DE to 5528H, the file control block of the open file.
52A4
GOSUB to the ROM's 0013H to read the next byte from the file whose control block is at Register Pair DE (5528H): Register A = the byte with the Z FLAG, or an error code with the NZ FLAG.
52A7
If the NZ FLAG is set (the end of the file, or a read error, before the first byte of a line), JUMP to 52F6H to end the listing.
52A9
LD (52C2H),A 32 C2 52
Store Register A (the first byte of the line) to 52C2H, the operand of LD A,00H at 52C1H, to keep it while the line number is sent.
52AC
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the word of the parameter NUM. 5212H stores 0000H here at each start and 4476H (from 5237H) stores the value given: FFFFH for NUM alone.
52AF
LD A,B 78
Copy Register B (the high byte of the NUM word) into Register A.
52B0
OR C B1
OR Register C (the low byte of the NUM word) into Register A: the Z FLAG is set when the word is 0000H, no line numbers.
52B1
If the Z FLAG is set (NUM not given), JUMP to 52C1H to send the line without a number.
52B3
LD HL,54D8H 21 D8 54
Point Register Pair HL to 54D8H, the line number text "nnnnn. " ended by 03H.
52B6
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH LIST, 4025H PRINT) pushed at 520EH.
52B7
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again, for the next use.
52B8
GOSUB to 4479H to send the text at Register Pair HL (54D8H, the five digits, the period and a space; the 03H ends it unsent) to the device at Register Pair DE.
52BB
LD HL,54D8H 21 D8 54
Point Register Pair HL to 54D8H, the line number text, to count it on.
52BE
GOSUB to 5461H to add one to the five digit number at Register Pair HL (54D8H-54DCH): the number of the next line.
52C1
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the first byte of the line. 52A9H stores the byte read from the file here at each line before this row runs.
52C3
CP 0DH FE 0D
Compare Register A (the first byte of the line) against 0DH, the carriage return of an empty line.
52C5
If the Z FLAG is set (an empty line), JUMP to 52E3H to send the carriage return alone.
52C7
POP DE D1
Loop Start
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
52C8
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again.
52C9
PUSH AF F5
Save Register Pair AF (Register A the byte of the line) to the stack, to keep bit 7 of the byte for the test below.
52CA
AND 7FH E6 7F
Mask Register A (the byte of the line) with 7FH: bit 7 is cleared before the byte is sent.
52CC
GOSUB to the ROM's 001BH to send Register A (the byte with bit 7 clear) to the device whose control block is at Register Pair DE.
52CF
POP AF F1
Restore Register Pair AF from the stack: Register A = the byte as read from the file, bit 7 included.
52D0
BIT 7,A CB 7F
Test bit 7 of Register A (the byte as read): the NZ FLAG is set when bit 7 is set.
52D2
If the NZ FLAG is set (the byte had bit 7 set), GOSUB to 5472H to test the keyboard: it returns the NZ FLAG for BREAK, else the Z FLAG (after a pause with SHIFT and @). With bit 7 clear the Z FLAG of the test stays.
52D5
If the NZ FLAG is set (BREAK was pressed in 5472H), JUMP to 52EDH to end the listing with the abort exit.
52D7
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the file control block of the open file.
52DA
GOSUB to the ROM's 0013H to read the next byte of the line from the file whose control block is at Register Pair DE (5528H): Register A = the byte with the Z FLAG, or an error code with the NZ FLAG.
52DD
If the NZ FLAG is set (the end of the file or a read error inside a line), JUMP to 52F6H to end the listing.
52DF
CP 0DH FE 0D
Compare Register A (the byte read) against 0DH, the carriage return that ends the line.
52E1
If the NZ FLAG is set (not the end of the line), JUMP back to 52C7H to send the byte.
52E3
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
52E4
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again.
52E5
GOSUB to the ROM's 001BH to send Register A (0DH, the carriage return that ends the line) to the device at Register Pair DE.
52E8
GOSUB to 5472H to test the keyboard after the line: the NZ FLAG for BREAK, else the Z FLAG (after a pause when SHIFT and @ are held).
52EB
If the Z FLAG is set (no BREAK), JUMP back to 52A1H for the next line; with the NZ FLAG (BREAK) the code falls into 52EDH.
52EDH - BREAK: End With the Abort Exit
Reached from the text listing (52D5H after a byte with bit 7 set, and by falling through from 52EBH after a line) and from the HEX listing (53E5H) when 5472H finds BREAK pressed. A carriage return is sent to the device to end the line, then the command ends through 4030H, the abort exit. The file is only read, so it is not closed.
52ED
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
52EE
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return to end the line on the device.
52F0
GOSUB to the ROM's 001BH to send Register A (0DH) to the device whose control block is at Register Pair DE.
52F3
JUMP to 4030H, the abort exit of the system (request A3H): the listing stopped by BREAK.
52F6H - End of the Listing
Reached when a read gives the NZ FLAG (52A7H, 52DDH) and from the HEX listing at its end (53DFH, Register A = 1CH). A carriage return is sent to the device. Error 1CH (END OF FILE ENCOUNTERED) or 1DH (RECORD NUMBER OUT OF RANGE) is the normal end: JP 402DH, VTOS READY; any other code is shown as an error at 549EH.
52F6
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
52F7
PUSH AF F5
Save Register Pair AF (Register A the error code of the read, or 1CH from 53DDH) to the stack while the carriage return is sent.
52F8
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return to end the last line on the device.
52FA
GOSUB to the ROM's 001BH to send Register A (0DH) to the device whose control block is at Register Pair DE.
52FD
POP AF F1
Restore Register Pair AF from the stack: Register A = the error code of the read (or 1CH).
52FE
CP 1CH FE 1C
Compare Register A (the code) against 1CH, END OF FILE ENCOUNTERED.
5300
If the Z FLAG is set (the end of the file), JUMP to 530BH: the listing is complete.
5303
CP 1DH FE 1D
Compare Register A (the code) against 1DH, RECORD NUMBER OUT OF RANGE (the position past the end of the file).
5305
If the Z FLAG is set (past the end of the file), JUMP to 530BH: the listing is complete.
5308
JUMP to 549EH to display the error in Register A (a read error) and abort.
530B
JUMP to 402DH, the normal exit of the system: VTOS READY after a complete listing.
530EH - HEX Listing: Position to Record REC
The file is positioned to record REC (default 0000H) with 4442H, which counts in records of the record length the file was opened with (LRL, 00H = 256 bytes). The record number is written as five decimal digits into the line head text at 54E0H ("nnnnn:XX = " ended by 03H).
530E
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the word of the parameter REC, the first record to list. The member never clears it: it holds the 0000H of the file, or the value 4476H (from 5237H) stored, FFFFH for REC alone.
5311
LD DE,5528H 11 28 55
Point Register Pair DE to 5528H, the file control block of the open file.
5314
GOSUB to 4442H to position the file whose control block is at Register Pair DE (5528H) to the record number in Register Pair BC (REC). It returns the Z FLAG before the end of the file, else the NZ FLAG with 1CH (at the end) or 1DH (past it) in Register A.
5317
If the NZ FLAG is set (record REC is at or past the end of the file), JUMP to 549EH to display the error in Register A and abort.
531A
NOP 00
No operation: this byte does nothing, and the code goes on at 531BH.
531B
LD HL,(530FH) 2A 0F 53
Fetch the word of the parameter REC from 530FH-5310H (the operand at 530EH) into Register Pair HL: the number of the first record listed.
531E
LD BC,54E0H 01 E0 54
Point Register Pair BC to 54E0H, the five digits of the line head text of a HEX line.
5321
GOSUB to 542BH to write Register Pair HL (the record number REC) as five decimal digits at Register Pair BC (54E0H-54E4H).
5324H - HEX Listing: Start of a Record
Each record starts here: the offset in the record (the operand at 532CH) is set to 00H and Register C is loaded with the record length (the low byte of LRL, 00H for 256), the count of the bytes of the record still to list.
5324
XOR A AF
Loop Start
Set Register A to 00H with XOR A, the offset of the first line of a record.
5325
LD (532CH),A 32 2C 53
Store Register A (00H) to 532CH, the operand of LD A,00H at 532BH: the offset in the record shown at the head of the line.
5328
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the word of the parameter LRL. 521AH stores 0000H here at each start and 4476H (from 5237H) stores the value given. Register C (its low byte, 00H for 256) is the count of the bytes of the record; Register B is loaded again at 5343H.
532BH - HEX Listing: One Line of Up to 16 Bytes
The line head "nnnnn:oo = " is sent: the record number at 54E0H-54E4H and the offset in the record as two hex digits at 54E6H-54E7H, then the offset is moved on by 10H. Up to 16 bytes are read: each is kept in the buffer 5518H-5527H and sent as two hex digits and a space, with one more space after the eighth byte. The line ends after 16 bytes, at the end of the record (Register C counted down to 00H) or at the end of the file. Register B counts the places of the line from 10H down.
532B
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the offset in the record of this line. 5325H stores 00H here at the start of each record and 5340H adds 10H after each line head.
532D
LD HL,54E6H 21 E6 54
Point Register Pair HL to 54E6H, the two characters XX of the line head text, where the offset is written.
5330
GOSUB to 4DECH to write Register A (the offset) as two hex digits at Register Pair HL (54E6H-54E7H).
5333
LD HL,54E0H 21 E0 54
Point Register Pair HL to 54E0H, the line head text "nnnnn:oo = " ended by 03H.
5336
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
5337
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again.
5338
GOSUB to 4479H to send the text at Register Pair HL (54E0H, the line head; the 03H ends it unsent) to the device at Register Pair DE.
533B
LD A,(532CH) 3A 2C 53
Fetch the offset of this line from 532CH (the operand at 532BH) into Register A.
533E
ADD A,10H C6 10
Add 10H to Register A (the offset): the offset of the next line, 16 bytes on.
5340
LD (532CH),A 32 2C 53
Store Register A (the offset of the next line) to 532CH, the operand of LD A,00H at 532BH.
5343
LD B,10H 06 10
Load Register B with 10H, the 16 places of a line, counted down as the bytes are sent.
5345
LD HL,5518H 21 18 55
Point Register Pair HL to 5518H, the buffer that keeps the bytes of the line for the characters after the hex.
5348
LD DE,5528H 11 28 55
Loop Start
Point Register Pair DE to 5528H, the file control block of the open file.
534B
GOSUB to the ROM's 0013H to read the next byte from the file whose control block is at Register Pair DE (5528H): Register A = the byte with the Z FLAG, or an error code with the NZ FLAG.
534E
If the Z FLAG is set (a byte was read), JUMP to 535BH to show it.
5350
PUSH AF F5
Save Register Pair AF (Register A the error code and the NZ FLAG) to the stack while the code is tested.
5351
CP 1CH FE 1C
Compare Register A (the error code) against 1CH, END OF FILE ENCOUNTERED.
5353
If the Z FLAG is set (the end of the file), JUMP to 535AH to end the line.
5355
CP 1DH FE 1D
Compare Register A (the error code) against 1DH, RECORD NUMBER OUT OF RANGE.
5357
If the NZ FLAG is set (a read error, not the end of the file), JUMP to 549EH to display the error in Register A and abort.
535A
POP AF F1
Restore Register Pair AF from the stack: Register A = 1CH or 1DH with the NZ FLAG of the read again.
535B
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH. POP does not change the flags.
535C
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again.
535D
If the NZ FLAG is set (the end of the file was reached), JUMP to 5379H to end the line with the bytes read so far.
535F
LD (HL),A 77
Store Register A (the byte read) into the line buffer at Register Pair HL (5518H up), for the characters shown after the hex.
5360
INC HL 23
Increment Register Pair HL to the next place of the line buffer.
5361
GOSUB to 5417H to send Register A (the byte) as two hex digits to the device at Register Pair DE.
5364
LD A,20H 3E 20
Load Register A with 20H, the space after the two hex digits.
5366
GOSUB to the ROM's 001BH to send Register A (20H, a space) to the device at Register Pair DE.
5369
LD A,B 78
Copy Register B (the places left on the line, 10H for the first byte) into Register A.
536A
CP 09H FE 09
Compare Register A (the places left) against 09H: equal after the eighth byte of the line.
536C
LD A,20H 3E 20
Load Register A with 20H, a space. LD does not change the flags of the compare.
536E
If the Z FLAG is set (the eighth byte was just sent), GOSUB to the ROM's 001BH to send Register A (20H) to the device at Register Pair DE: one more space between the two halves of the line.
5371
DEC B 05
Decrement Register B, the places left on the line.
5372
DEC C 0D
Decrement Register C, the bytes of the record left: the Z FLAG is set when the record is complete (from 00H, a 256 byte record, it goes to FFH).
5373
If the Z FLAG is set (the last byte of the record was sent), JUMP to 5379H to end the line with the Z FLAG.
5375
LD A,B 78
Copy Register B (the places left on the line) into Register A.
5376
OR A B7
OR Register A (the places left) with itself: the Z FLAG is set when the 16 places are used.
5377
If the NZ FLAG is set (places left on the line), JUMP back to 5348H for the next byte.
5379H - HEX Listing: The Characters of the Line
The flags say how the line ended: the Z FLAG for a full line or the end of the record, the NZ FLAG for the end of the file; they are kept on the stack until 53DCH. Register B holds the places of the line left unused; a line with no byte goes straight to its carriage return. The characters of the bytes kept at 5518H are then sent (5402H shows a period for a byte that is not a letter, a digit or a sign): for LIST (flag 00H at 5380H) on a new line, under the hex bytes; for PRINT (FFH) on the same line after the hex, from 53B5H.
5379
PUSH AF F5
Save Register Pair AF to the stack: the Z FLAG (line full or record complete) or the NZ FLAG with Register A = 1CH or 1DH (end of the file).
537A
LD A,B 78
Copy Register B (the places left unused on the line) into Register A.
537B
CP 10H FE 10
Compare Register A (the places left) against 10H: equal when the line holds no byte.
537D
If the Z FLAG is set (no byte on the line: the file ended at the start of it), JUMP to 53D7H to send the carriage return alone.
537F
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the layout flag. 520BH stores it at the start: 00H for LIST (from 5200H), FFH for PRINT (from 5206H).
5381
OR A B7
OR Register A (the layout flag) with itself: the NZ FLAG is set for PRINT.
5382
If the NZ FLAG is set (PRINT), JUMP to 53B5H to put the characters on the same line.
5384
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the hex line of LIST.
5386
GOSUB to the ROM's 001BH to send Register A (0DH) to the device at Register Pair DE (401DH).
5389
PUSH BC C5
Save Register Pair BC (Register B the places left unused, Register C the bytes of the record left) to the stack.
538A
LD B,0CH 06 0C
Load Register B with 0CH, the 12 spaces that put the characters under the hex bytes (the line head "nnnnn:oo = " is 11 characters).
538C
LD A,20H 3E 20
Load Register A with 20H, a space, the character the loop below sends 12 times.
538E
Loop Start
GOSUB to the ROM's 001BH to send Register A (20H, a space) to the device at Register Pair DE. The loop relies on Register A still holding 20H afterwards.
5391
Decrement Register B and LOOP BACK to 538EH until Register B is 00H: 12 spaces.
5393
POP BC C1
Restore Register Pair BC from the stack: Register B the places left unused, Register C the bytes of the record left.
5394
LD A,10H 3E 10
Load Register A with 10H, the 16 places of a line.
5396
SUB B 90
SUBtract Register B (the places left unused) from Register A: Register A = the bytes on the line.
5397
LD B,A 47
Copy Register A (the bytes on the line) into Register B, the count of the characters to send.
5398
LD HL,5518H 21 18 55
Point Register Pair HL to 5518H, the bytes of the line kept in the buffer.
539B
LD A,(HL) 7E
Loop Start
Fetch the next byte of the line from the buffer at Register Pair HL into Register A.
539C
INC HL 23
Increment Register Pair HL to the next byte of the buffer.
539D
GOSUB to 5402H to send Register A to the device at Register Pair DE as itself, or as a period when it is not printable.
53A0
LD A,20H 3E 20
Load Register A with 20H, a space after the character.
53A2
GOSUB to the ROM's 001BH to send Register A (20H) to the device at Register Pair DE.
53A5
GOSUB to the ROM's 001BH to send Register A to the device at Register Pair DE again, relying on it still being 20H: two spaces, so that each character takes the three places of its hex byte.
53A8
LD A,B 78
Copy Register B (the characters left to send) into Register A.
53A9
CP 09H FE 09
Compare Register A (the characters left) against 09H, the place of the extra space of the hex line.
53AB
LD A,20H 3E 20
Load Register A with 20H, a space. LD does not change the flags of the compare.
53AD
If the Z FLAG is set (Register B was 09H), GOSUB to the ROM's 001BH to send Register A (20H) to the device at Register Pair DE: the extra space. Register B counts the characters of this line, not the places of a full line, so on a last line of 9 to 15 bytes this space falls after byte 1 to 7 instead of after byte 8.
53B0
Decrement Register B and LOOP BACK to 539BH until Register B is 00H: every byte of the line shown.
53B2
JUMP to 53D7H to end the line of characters of LIST with its carriage return.
53B5
PUSH BC C5
Save Register Pair BC (Register B the places left unused, Register C the bytes of the record left) to the stack.
53B6
LD A,B 78
Copy Register B (the places left unused on the line) into Register A.
53B7
RLCA 07
Rotate Register A left: Register A = twice the places left (at most 1EH, so bit 7 stays clear).
53B8
ADD A,B 80
Add Register B to Register A: Register A = three times the places left, the places of the hex bytes not sent.
53B9
LD B,A 47
Copy Register A (three times the places left) into Register B.
53BA
CP 18H FE 18
Compare Register A (three times the places left) against 18H: the CARRY FLAG is set when it is below 18H (fewer than 8 places left).
53BC
CCF 3F
Complement the CARRY FLAG: set when 8 or more places are left, the case where the code takes the extra space after the eighth byte as not sent. With exactly 8 places left that space was sent, so the line gets one space too many.
53BD
LD A,03H 3E 03
Load Register A with 03H, three spaces between the hex bytes and the characters.
53BF
ADC A,B 88
Add Register B (three times the places left) and the CARRY FLAG to Register A: Register A = the spaces to send.
53C0
LD B,A 47
Copy Register A (the spaces to send) into Register B, the count of the loop below.
53C1
LD A,20H 3E 20
Load Register A with 20H, a space, the character the loop below sends Register B times.
53C3
Loop Start
GOSUB to the ROM's 001BH to send Register A (20H, a space) to the device at Register Pair DE (4025H), relying on Register A still holding 20H afterwards.
53C6
Decrement Register B and LOOP BACK to 53C3H until Register B is 00H: the characters start in the same column on every line.
53C8
POP BC C1
Restore Register Pair BC from the stack: Register B the places left unused, Register C the bytes of the record left.
53C9
LD A,10H 3E 10
Load Register A with 10H, the 16 places of a line.
53CB
SUB B 90
SUBtract Register B (the places left unused) from Register A: Register A = the bytes on the line.
53CC
LD B,A 47
Copy Register A (the bytes on the line) into Register B, the count of the characters to send.
53CD
LD HL,5518H 21 18 55
Point Register Pair HL to 5518H, the bytes of the line kept in the buffer.
53D0
LD A,(HL) 7E
Loop Start
Fetch the next byte of the line from the buffer at Register Pair HL into Register A.
53D1
INC HL 23
Increment Register Pair HL to the next byte of the buffer.
53D2
GOSUB to 5402H to send Register A to the device at Register Pair DE as itself, or as a period when it is not printable.
53D5
Decrement Register B and LOOP BACK to 53D0H until Register B is 00H: the characters follow one another with no space.
53D7H - HEX Listing: End of the Line
The line ends with a carriage return. The flags saved at 5379H decide: the end of the file ends the listing (52F6H with Register A = 1CH, the normal end); otherwise the keyboard is tested (BREAK ends with the abort exit), and the next line follows, of the same record while Register C is not 00H. After a complete record a line with a space alone is sent (a blank line), the record number at 54E0H is counted on by one, and the next record starts at 5324H.
53D7
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the line.
53D9
GOSUB to the ROM's 001BH to send Register A (0DH) to the device at Register Pair DE.
53DC
POP AF F1
Restore Register Pair AF from the stack (saved at 5379H): the NZ FLAG when the file ended, the Z FLAG otherwise.
53DD
LD A,1CH 3E 1C
Load Register A with 1CH, the code END OF FILE ENCOUNTERED that 52F6H takes as the normal end. LD does not change the flags.
53DF
If the NZ FLAG is set (the file ended), JUMP to 52F6H to end the listing with Register A = 1CH.
53E2
GOSUB to 5472H to test the keyboard after the line: the NZ FLAG for BREAK, else the Z FLAG (after a pause when SHIFT and @ are held).
53E5
If the NZ FLAG is set (BREAK), JUMP to 52EDH to end with the abort exit.
53E8
LD A,C 79
Copy Register C (the bytes of the record left) into Register A.
53E9
OR A B7
OR Register A (the bytes of the record left) with itself: the Z FLAG is set when the record is complete.
53EA
If the NZ FLAG is set (bytes of the record left), JUMP back to 532BH for the next line of the same record.
53ED
POP DE D1
Restore Register Pair DE from the stack: the device control block of the listing (401DH or 4025H), pushed at 520EH.
53EE
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again.
53EF
LD A,20H 3E 20
Load Register A with 20H, a space, the only character of the line between two records.
53F1
GOSUB to the ROM's 001BH to send Register A (20H) to the device at Register Pair DE.
53F4
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the blank line.
53F6
GOSUB to the ROM's 001BH to send Register A (0DH) to the device at Register Pair DE.
53F9
LD HL,54E0H 21 E0 54
Point Register Pair HL to 54E0H, the record number of the line head text.
53FC
GOSUB to 5461H to add one to the five digit number at Register Pair HL (54E0H-54E4H): the number of the next record.
53FF
JUMP to 5324H to start the next record with its offset 00H and a new count of bytes.
5402H - Send a Byte as a Character
Register A = a byte of the file, Register Pair DE = the device control block. Bytes 20H-5AH (space, signs, digits, capital letters) and 61H-7AH (small letters) are sent as they are; every other byte (below 20H, 5BH-60H, 7BH and up, bit 7 set) is sent as a period, 2EH. Ends with a JP into the ROM's 001BH, whose RET returns to the caller.
5402
CP 20H FE 20
Compare Register A (the byte) against 20H, the first printable character, the space.
5404
If the CARRY FLAG is set (a control byte below 20H), JUMP to 5412H to send a period.
5406
CP 5BH FE 5B
Compare Register A (the byte) against 5BH, the character after Z.
5408
If the CARRY FLAG is set (20H-5AH: a space, a sign, a digit or a capital letter), JUMP to 5414H to send the byte itself.
540A
CP 61H FE 61
Compare Register A (the byte) against 61H, the small letter a.
540C
If the CARRY FLAG is set (5BH-60H, the six codes between the capital letters and the small letters), JUMP to 5412H to send a period.
540E
CP 7BH FE 7B
Compare Register A (the byte) against 7BH, the character after the small letter z.
5410
If the CARRY FLAG is set (61H-7AH, a small letter), JUMP to 5414H to send the byte itself.
5412
LD A,2EH 3E 2E
Load Register A with 2EH, a period, shown in place of a byte that is not printable.
5414
JUMP to the ROM's 001BH to send Register A to the device whose control block is at Register Pair DE; its RET returns to the caller of 5402H.
5417H - Send a Byte as Two Hex Digits
Register A = the byte, Register Pair DE = the device control block. The high digit is sent first through 5420H, then the routine falls into 5420H for the low digit; 5420H turns bits 3-0 of Register A into the ASCII digit 0-9 or A-F with the 90H/DAA/40H/DAA sequence and sends it through the ROM's 001BH.
5417
PUSH AF F5
Save Register Pair AF (Register A the byte) to the stack, for the low digit.
5418
RRCA 0F
Rotate Register A (the byte) right, the first of four rotations that move the high digit into bits 3-0.
5419
RRCA 0F
Rotate Register A right, the second of four rotations of the byte.
541A
RRCA 0F
Rotate Register A right, the third of four rotations of the byte.
541B
RRCA 0F
Rotate Register A right, the fourth: the high digit of the byte is now in bits 3-0 of Register A.
541C
GOSUB to 5420H to send bits 3-0 of Register A (the high digit) as a hex digit to the device at Register Pair DE.
541F
POP AF F1
Restore Register Pair AF from the stack: Register A = the byte again, and fall into 5420H for its low digit.
5420
AND 0FH E6 0F
Mask Register A to bits 3-0, one hex digit, 00H-0FH.
5422
ADD A,90H C6 90
Add 90H to Register A (the digit), the first step of turning it into ASCII.
5424
DAA 27
Decimal adjust Register A: 90H-99H for the digits 0-9, 00H-05H with the CARRY FLAG for A-F.
5425
ADC A,40H CE 40
Add 40H and the CARRY FLAG to Register A (from the DAA above).
5427
DAA 27
Decimal adjust Register A: the ASCII character of the digit, 30H-39H or 41H-46H.
5428
JUMP to the ROM's 001BH to send Register A (the hex digit) to the device whose control block is at Register Pair DE; its RET returns to the caller.
542BH - Write a Number as Five Decimal Digits
Register Pair HL = the number (0-65535), Register Pair BC = where the five digits go (54D8H or 54E0H). 5446H finds each digit by subtracting the power of ten in Register Pair DE (10000, 1000, 100, 10, 1) until the CARRY FLAG, stores it at Register Pair BC and moves Register Pair BC on. A 0 is to be stored as a space when the character before it is a space, but the byte before each field is never a space (54D7H holds 0DH, 54DFH holds 03H), so every digit, leading zeros included, is stored as written: 00001 for 1. Register Pair BC ends after the fifth digit.
542B
LD DE,2710H 11 10 27
Load Register Pair DE with 2710H, 10000, the place of the first digit.
542E
GOSUB to 5446H to store the ten thousands digit of Register Pair HL at Register Pair BC.
5431
LD DE,03E8H 11 E8 03
Load Register Pair DE with 03E8H, 1000, the place of the second digit.
5434
GOSUB to 5446H to store the thousands digit of Register Pair HL at Register Pair BC.
5437
LD DE,0064H 11 64 00
Load Register Pair DE with 0064H, 100, the place of the third digit.
543A
GOSUB to 5446H to store the hundreds digit of Register Pair HL at Register Pair BC.
543D
LD DE,000AH 11 0A 00
Load Register Pair DE with 000AH, 10, the place of the fourth digit.
5440
GOSUB to 5446H to store the tens digit of Register Pair HL at Register Pair BC.
5443
LD DE,0001H 11 01 00
Load Register Pair DE with 0001H, 1, the place of the last digit, and fall into 5446H, whose RET then returns to the caller of 542BH.
5446
XOR A AF
Set Register A to 00H with XOR A, the digit counter; the CARRY FLAG is cleared for the first subtraction.
5447
SBC HL,DE ED 52
Loop Start
SUBtract Register Pair DE (the power of ten) and the CARRY FLAG from Register Pair HL (what is left of the number).
5449
If the CARRY FLAG is set (Register Pair HL went below 0), JUMP to 544EH: Register A holds the digit.
544B
INC A 3C
Increment Register A, the digit counter: one more power of ten taken away.
544C
JUMP back to 5447H to subtract the power of ten again (the CARRY FLAG is clear there).
544E
ADD HL,DE 19
Add Register Pair DE (the power of ten) back to Register Pair HL: the rest of the number for the lower digits.
544F
ADD A,30H C6 30
Add 30H to Register A (the digit 0-9): the ASCII character of the digit.
5451
CP 30H FE 30
Compare Register A (the digit character) against 30H, the character 0.
5453
If the NZ FLAG is set (not a 0), JUMP to 545EH to store the digit.
5455
DEC BC 0B
Decrement Register Pair BC to the character before the place of this digit.
5456
LD A,(BC) 0A
Fetch the character before the place of the digit from Register Pair BC into Register A (0DH at 54D7H, 03H at 54DFH, or the digit stored before).
5457
INC BC 03
Increment Register Pair BC back to the place of this digit.
5458
CP 20H FE 20
Compare Register A (the character before) against 20H, a space.
545A
If the Z FLAG is set (the character before is a space), JUMP to 545EH to store Register A, the space, in place of the 0. The fields at 54D8H and 54E0H never have a space before them, so this jump is not taken.
545C
LD A,30H 3E 30
Load Register A with 30H, the character 0, to store it.
545E
LD (BC),A 02
Store Register A (the digit, or a space) at Register Pair BC, the place of the digit.
545F
INC BC 03
Increment Register Pair BC to the place of the next digit.
5460
RET C9
RETURN to the caller with Register Pair HL the rest of the number and Register Pair BC after the digit.
5461H - Add One to a Five Digit Number
Register Pair HL = the first of five ASCII digits (54D8H the line number, 54E0H the record number). The last digit is counted on by one; a digit that passes 9 becomes 0 and the carry goes to the digit before it. OR 30H makes a space count as 0. There is no stop after the first digit: past 99999 the carry goes on into the bytes before the field (the 0DH at 54D7H and the text PARAMETER ERROR, or the 03H at 54DFH) and the field shows 00000.
5461
INC HL 23
Increment Register Pair HL (the first digit), the first of four steps to the last digit.
5462
INC HL 23
Increment Register Pair HL, the second step to the last digit of the number.
5463
INC HL 23
Increment Register Pair HL, the third step to the last digit of the number.
5464
INC HL 23
Increment Register Pair HL: Register Pair HL now points at the fifth and last digit.
5465
LD A,(HL) 7E
Loop Start
Fetch the digit at Register Pair HL into Register A.
5466
OR 30H F6 30
OR Register A (the digit) with 30H: a digit stays as it is, a space becomes the character 0.
5468
INC A 3C
Increment Register A, the digit plus one (3AH when the digit was 9).
5469
LD (HL),A 77
Store Register A (the digit plus one) at Register Pair HL.
546A
SUB 3AH D6 3A
SUBtract 3AH from Register A (the new digit): the CARRY FLAG is set when it is 0-9, below 3AH.
546C
RET C D8
If the CARRY FLAG is set (no carry to the digit before), RETURN to the caller.
546D
LD (HL),30H 36 30
Store 30H, the character 0, at Register Pair HL: the digit went past 9.
546F
DEC HL 2B
Decrement Register Pair HL to the digit before, which takes the carry.
5470
JUMP back to 5465H to add the carry to the digit at Register Pair HL.
5472H - Test the Keyboard: BREAK and Pause
Returns the Z FLAG to go on, the NZ FLAG to stop. While a file of commands runs (bit 5 of 430FH set) nothing is tested and the Z FLAG returns. Otherwise the keyboard rows are read directly (the BREAK vector 4315H holds C9H while a member runs): BREAK (3840H bit 2) returns the NZ FLAG. SHIFT (3880H bit 0) with @ (3801H bit 0) held pauses the listing: the routine waits until BREAK (NZ FLAG) or another key read through the ROM's 002BH, other than 60H, the code of SHIFT and @ themselves; then it returns the Z FLAG.
5472
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
5475
AND 20H E6 20
Mask Register A (the system flags) to bit 5, set while a file of commands (DO) is being run.
5477
XOR 20H EE 20
Exclusive OR Register A with 20H: Register A = 00H and the Z FLAG set when bit 5 of 430FH was set.
5479
RET Z C8
If the Z FLAG is set (a file of commands is running), RETURN with the Z FLAG and Register A = 00H: the keyboard is not tested.
547A
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A (bit 0 ENTER, bit 1 CLEAR, bit 2 BREAK).
547D
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
547F
RET NZ C0
If the NZ FLAG is set (BREAK is pressed), RETURN with the NZ FLAG and Register A = 04H: stop the listing.
5480
LD A,(3801H) 3A 01 38
Fetch keyboard row 0 from 3801H into Register A (bit 0 the @ key).
5483
AND 01H E6 01
Mask Register A (keyboard row 0) to bit 0, the @ key.
5485
RET Z C8
If the Z FLAG is set (@ is not pressed), RETURN with the Z FLAG and Register A = 00H: go on.
5486
LD A,(3880H) 3A 80 38
Fetch keyboard row 7 from 3880H into Register A (bit 0 the SHIFT key).
5489
AND 01H E6 01
Mask Register A (keyboard row 7) to bit 0, the SHIFT key.
548B
RET Z C8
If the Z FLAG is set (@ without SHIFT), RETURN with the Z FLAG and Register A = 00H: go on.
548C
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A: the listing is paused by SHIFT and @.
548F
AND 04H E6 04
Mask Register A (keyboard row 6) to bit 2, the BREAK key.
5491
RET NZ C0
If the NZ FLAG is set (BREAK is pressed during the pause), RETURN with the NZ FLAG and Register A = 04H: stop the listing.
5492
GOSUB to the ROM's 002BH to scan the keyboard through the KI device: Register A = the key typed, or 00H for none.
5495
OR A B7
OR Register A (the key) with itself: the Z FLAG is set for 00H, no key.
5496
If the Z FLAG is set (no key), JUMP back to 548CH to go on waiting.
5498
CP 60H FE 60
Compare Register A (the key) against 60H, the code of the @ key with SHIFT, the keys of the pause.
549A
If the Z FLAG is set (SHIFT and @ again), JUMP back to 548CH to go on waiting.
549C
XOR A AF
Set Register A to 00H with XOR A and the Z FLAG: another key ends the pause.
549D
RET C9
RETURN to the caller with the Z FLAG and Register A = 00H: the listing goes on.
549EH - Error Exit
Register A = an error code from the open, the positioning or a read. 4409H shows the text of the error alone (bit 6) and then, bit 7 being clear, takes the abort exit 4030H.
549E
OR 40H F6 40
OR Register A (the error code) with 40H: bit 6 set asks 4409H for the text of the error alone; bit 7 clear means 4409H does not return.
54A0
JUMP to 4409H to display the error message of the code in Register A (for example 58H, FILE NOT IN DIRECTORY) and take the abort exit.
54A3H - FILE SPEC REQUIRED
Reached when the command line holds no valid file specification, or names a device (an asterisk first): the message is displayed and logged through 447BH and the command ends with the abort exit 4030H.
54A3
LD HL,54ACH 21 AC 54
Point Register Pair HL to 54ACH, the message FILE SPEC REQUIRED ended by a carriage return.
54A6
GOSUB to 447BH to display the text at Register Pair HL (54ACH) up to its carriage return and write it to the job log.
54A9
JUMP to 4030H, the abort exit of the system (request A3H).
54AC-54BD
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 54A3H, displayed when no file specification is given or a device is named.
54BE
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED: 447BH sends it and stops there.
54BFH - PARAMETER ERROR
Reached when 4476H rejects the parameter list (an unknown name or a bad value): the message is displayed and logged through 447BH and the command ends with the abort exit 4030H.
54BF
LD HL,54C8H 21 C8 54
Point Register Pair HL to 54C8H, the message PARAMETER ERROR ended by a carriage return.
54C2
GOSUB to 447BH to display the text at Register Pair HL (54C8H) up to its carriage return and write it to the job log.
54C5
JUMP to 4030H, the abort exit of the system (request A3H).
54C8-54D6
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of 54BFH, displayed when the parameter list cannot be read.
54D7
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR. It is also the byte before the line number field: 5455H-545AH read it (not a space, so no 0 is turned into a space).
54D8H - Texts, Default Extension and Parameter Table
The line number text of NUM, the line head text of HEX, the default extension TXT and the parameter table that 4476H reads with the names LINE, NUM, HEX, REC and LRL (6 characters each, then the address of the word to store, the operand of a LD BC instruction). The table ends with 00H.
54D8-54DE
DEFM " . " 20 20 20 20 20 2E 20
The line number text of NUM: 54D8H-54DCH the five digits written by 542BH (from 5298H) and counted on by 5461H (from 52BEH), then a period and a space; 52B8H sends it before each line.
54DF
DEFB 03H 03
The 03H that ends the line number text: 44E0H (through 4479H) stops there without sending it. It is also the byte before the record number field at 54E0H (read by 5456H).
54E0-54EA
DEFM " :XX = " 20 20 20 20 20 3A 58 58 20 3D 20
The line head text of a HEX line: 54E0H-54E4H the record number written by 542BH (from 5321H) and counted on by 5461H (from 53FCH), a colon, 54E6H-54E7H the offset in the record written in hex by 4DECH (from 5330H), then " = "; 5338H sends it.
54EB
DEFB 03H 03
The 03H that ends the line head text of a HEX line: 44E0H (through 4479H) stops there without sending it.
54EC-54EE
DEFM "TXT" 54 58 54
The default extension of the member: 524EH passes it to 4473H, which adds /TXT to a specification with no extension.
54EF-54F6
DEFM "LINE " / DEFW 5282H 4C 49 4E 45 20 20 82 52
Parameter table entry 1: LINE, the first line of a text listing, stored at 5282H-5283H, the operand of LD BC at 5281H (1 when not given).
54F7-54FE
DEFM "NUM " / DEFW 52ADH 4E 55 4D 20 20 20 AD 52
Parameter table entry 2: NUM, line numbers, stored at 52ADH-52AEH, the operand of LD BC at 52ACH (0000H when not given).
54FF-5506
DEFM "HEX " / DEFW 527AH 48 45 58 20 20 20 7A 52
Parameter table entry 3: HEX, the hex listing, stored at 527AH-527BH, the operand of LD BC at 5279H (0000H when not given).
5507-550E
DEFM "REC " / DEFW 530FH 52 45 43 20 20 20 0F 53
Parameter table entry 4: REC, the first record of a HEX listing, stored at 530FH-5310H, the operand of LD BC at 530EH (the 0000H of the file when not given).
550F-5516
DEFM "LRL " / DEFW 5329H 4C 52 4C 20 20 20 29 53
Parameter table entry 5: LRL, the record length for the open and the HEX listing, stored at 5329H-532AH, the operand of LD BC at 5328H (0000H, 256 bytes, when not given).
5517
DEFB 00H 00
The 00H that ends the parameter table: 4476H finds no entry after it.
5518-5527
DEFS 16
Not in the file: the line buffer of a HEX line. 535FH stores each byte read there (from 5345H, Register Pair HL), and 539BH (LIST) or 53D0H (PRINT) read the bytes back to show them as characters.
5528-5547
DEFS 32
Not in the file: the file control block of the member. 441CH (from 5228H) puts the file specification there, 4473H (from 524EH) adds /TXT, 4424H (from 5258H or 5273H) opens it, and every read (ROM 0013H at 5289H, 52A4H, 52DAH, 534BH) and the positioning at 5314H use it.
5548-5567
DEFS 32
Not in the file: the copy of the file specification as typed, saved by the LDIR at 5246H and copied back into 5528H by the LDIR at 5267H for the second open.
5568-55FF
DEFS 152
Not in the file and not used by the member: the bytes between the saved specification and the sector buffer.
5600-56FF
DEFS 256
Not in the file: the sector buffer of the open file, given to 4424H at 5255H and 5270H; SYS0/SYS reads the sectors of the file into it.
5200H - Member 18 (ATTRIB, Code 51H): Open the File
SYS1/SYS runs ATTRIB as member code 51H: the request handler of SYS0/SYS loads this member at 5200H and calls 5200H with Register Pair HL at the text after the command word, Register B = 51H and Register A = the code taken from 430EH; the stack holds 4C4BH and then 402DH. ATTRIB reads a file specification into the control block at 53DBH and opens the file; it goes on only when the open gave access level 0 (the update password, a blank password when the update password is blank, the code CAD2H that opens every file, or the access password of a file whose protection level is 0), else error 25H. The rest of the line is made upper case (53BDH) and must be a list in parentheses: INV, VIS, ACC=password, UPD=password, PROT=level, parted by commas. Each parameter sets a bit of the change mask (the operand at 532FH); after the closing parenthesis the file's directory record is read, changed and written back (5323H).
5200
LD DE,53DBH 11 DB 53
Point Register Pair DE to 53DBH, the control block of the file (32 bytes, not in the file).
5203
GOSUB to 441CH, which has SYS1/SYS (request C3H, its 4FCEH) read the file specification at Register Pair HL into the control block at Register Pair DE (53DBH): the Z FLAG when one was read, Register Pair HL past it (an opening parenthesis is left where it is).
5206
If the NZ FLAG is set (no file specification), JUMP to 5370H to display FILE SPEC REQUIRED and abort.
5209
LD A,(DE) 1A
Fetch the first byte of the specification at Register Pair DE (53DBH) into Register A.
520A
CP 2AH FE 2A
Compare Register A (the first character of the specification) against 2AH, an asterisk: a device.
520C
If the Z FLAG is set (a device has no attributes), JUMP to 5370H to display FILE SPEC REQUIRED and abort.
520F
PUSH HL E5
Save Register Pair HL (the text after the specification) to the stack.
5210
LD B,00H 06 00
Load Register B with 00H, the record length for the open (256 byte records).
5212
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer, as the file's buffer: ATTRIB reads no record of the file.
5215
GOSUB to 4424H to open the file of the control block at Register Pair DE (53DBH) with the buffer at Register Pair HL (4200H) and Register B = 00H: request 94H, which loads SYS2/SYS at 4E00H. The password typed decides the access level in byte +01H.
5218
If the NZ FLAG is set (the open failed, or from 5223H error 25H), JUMP to 536BH to display the error in Register A and abort.
521B
POP HL E1
Restore Register Pair HL from the stack: the text after the specification.
521C
LD A,(53DCH) 3A DC 53
Fetch byte +01H of the control block at 53DCH into Register A: bits 2-0 hold the access level the open granted.
521F
AND 07H E6 07
Mask Register A (byte +01H of the control block) to bits 2-0, the access level: the NZ FLAG for any level other than 0, full access.
5221
LD A,25H 3E 25
Load Register A with 25H, the error code ILLEGAL ACCESS ATTEMPTED TO PROTECTED FILE. LD does not change the flags of the AND.
5223
If the NZ FLAG is set (the access level is not 0, the full access that the update password gives), JUMP to 5218H, which goes on to 536BH with Register A = 25H.
5225
PUSH HL E5
Save Register Pair HL (the text after the specification) to the stack.
5226
GOSUB to 53BDH to make the small letters of the rest of the command line at Register Pair HL capital letters, in place.
5229
POP HL E1
Restore Register Pair HL from the stack: the text after the specification.
522AH - Read the Parameter List
Spaces are passed over up to an opening parenthesis; anything else (the end of the line included) ends the command with -NOTHING DONE-. Then each parameter is told by its first letter: I (INV), V (VIS), A (ACC), U (UPD) and P (PROT); the rest of the word up to an equal sign, a comma, a closing parenthesis or 0DH is passed over (52F7H). A space after the parenthesis or a comma, or any other letter, gives PARAMETER ERROR.
522A
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
522B
CP 28H FE 28
Compare Register A (the character) against 28H, an opening parenthesis: the start of the parameter list.
522D
If the Z FLAG is set (the opening parenthesis), JUMP to 5237H to read the first parameter.
522F
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
5231
If the NZ FLAG is set (neither a space nor the opening parenthesis, the end of the line too), JUMP to 538CH to display -NOTHING DONE- and abort.
5234
INC HL 23
Increment Register Pair HL past the space before the parameter list.
5235
JUMP to 522AH to look at the next character at Register Pair HL.
5237
INC HL 23
Increment Register Pair HL past the opening parenthesis or the comma (from 52A1H), to the first letter of the parameter.
5238
LD A,(HL) 7E
Fetch the first letter of the parameter at Register Pair HL into Register A.
5239
CP 49H FE 49
Compare Register A (the first letter of the parameter) against 49H, the letter I: INV.
523B
If the Z FLAG is set (INV), JUMP to 52A6H to make the file invisible.
523D
CP 56H FE 56
Compare Register A (the first letter of the parameter) against 56H, the letter V: VIS.
523F
If the Z FLAG is set (VIS), JUMP to 52B8H to make the file visible.
5241
CP 41H FE 41
Compare Register A (the first letter of the parameter) against 41H, the letter A: ACC.
5243
If the Z FLAG is set (ACC), JUMP to 52CAH to take the access password.
5246
CP 55H FE 55
Compare Register A (the first letter of the parameter) against 55H, the letter U: UPD.
5248
If the Z FLAG is set (UPD), JUMP to 52DFH to take the update password.
524B
CP 50H FE 50
Compare Register A (the first letter of the parameter) against 50H, the letter P: PROT.
524D
If the NZ FLAG is set (no parameter starts with this character), JUMP to 53A4H to display PARAMETER ERROR and abort.
5250H - PROT: the Protection Level
The value after the equal sign (a letter, then letters and digits, at most 8, copied to 51E0H by 52F7H) is looked up by its first two characters in the table at 53CBH. The entry number gives the level stored in bits 2-0 of the attribute byte: AL 0, EX 6, RE 5, WR 4, the unusable entry 3, NA 2, KI 1, FU 0; a value starting RE whose third character is N (RENAME) gives 2. The level goes to the operand at 5337H and bit 0 is set in the change mask.
5250
GOSUB to 52F7H to find the value of the parameter: the NZ FLAG when an equal sign was found and the value copied to 51E0H-51E7H; Register Pair HL at the character after the value.
5253
If the Z FLAG is set (PROT without a value), JUMP to 53A4H to display PARAMETER ERROR and abort.
5256
PUSH HL E5
Save Register Pair HL (the place after the value) to the stack.
5257
LD B,08H 06 08
Load Register B with 08H, the 8 entries of the table of levels.
5259
LD DE,(51E0H) ED 5B E0 51
Fetch the first two characters of the value from 51E0H-51E1H (SYS2/SYS's work area) into Register Pair DE: Register E = the first character, Register D = the second (a space for a value of one character).
525D
LD HL,53CBH 21 CB 53
Point Register Pair HL to 53CBH, the table of levels, two characters an entry.
5260
LD A,(HL) 7E
Fetch the first character of the table entry at Register Pair HL into Register A.
5261
INC HL 23
Increment Register Pair HL to the second character of the entry.
5262
CP E BB
Compare Register A (the first character of the entry) against Register E (the first character of the value).
5263
If the Z FLAG is set (the first characters match), GOSUB to 526CH to compare the second ones; on a match it does not return here.
5266
INC HL 23
Increment Register Pair HL to the next entry of the table.
5267
Decrement Register B and JUMP to 5260H while entries are left.
5269
No entry matched: JUMP to 53A4H to display PARAMETER ERROR and abort (the place pushed at 5256H stays on the stack).
526C
LD A,(HL) 7E
Fetch the second character of the table entry at Register Pair HL into Register A.
526D
CP D BA
Compare Register A (the second character of the entry) against Register D (the second character of the value).
526E
RET NZ C0
If the NZ FLAG is set (they differ), RETURN to 5266H to try the next entry.
526F
POP AF F1
Restore Register Pair AF from the stack: the return address 5266H is dropped, so the table loop ends here.
5270
LD A,B 78
Copy Register B (8 for the first entry down to 1 for the last) into Register A.
5271
SUB 08H D6 08
SUBtract 08H from Register A: 00H and the Z FLAG for the first entry, AL.
5273
If the Z FLAG is set (AL), JUMP to 5286H with Register A = 00H, level 0.
5275
ADD A,07H C6 07
Add 07H to Register A: Register A = Register B less 1, the level of entries 2-8 (EX 6, RE 5, WR 4, the unusable entry 3, NA 2, KI 1, FU 0).
5277
CP 05H FE 05
Compare Register A (the level) against 05H, the level of RE.
5279
If the NZ FLAG is set (not RE), JUMP to 5286H to store the level in Register A.
527B
LD A,(51E2H) 3A E2 51
Fetch the third character of the value from 51E2H into Register A.
527E
CP 4EH FE 4E
Compare Register A (the third character of the value) against 4EH, the letter N: RENA or RENAME.
5280
LD A,05H 3E 05
Load Register A with 05H, the level of READ. LD does not change the flags.
5282
If the NZ FLAG is set (READ), JUMP to 5286H to store Register A = 05H.
5284
LD A,02H 3E 02
Load Register A with 02H, the level of RENAME, which NAME also gives.
5286
LD (5337H),A 32 37 53
Store Register A (the level) to 5337H, the operand of OR 00H at 5336H, which puts it into bits 2-0 of the attribute byte.
5289
POP HL E1
Restore Register Pair HL from the stack: the place after the value of PROT.
528A
LD B,01H 06 01
Load Register B with 01H, bit 0 of the change mask: the protection level.
528CH - Mark the Parameter and Go On
Register B = the bit of the change mask: 01H PROT, 02H ACC, 04H UPD, 08H INV or VIS. A closing quote after a value is passed over (528CH); then a closing parenthesis ends the list and goes to 5323H, a comma takes the next parameter, anything else is PARAMETER ERROR.
528C
LD A,(HL) 7E
Fetch the character after the value at Register Pair HL into Register A.
528D
CP 22H FE 22
Compare Register A (the character after the value) against 22H, a quotation mark: the end of a quoted value.
528F
If the NZ FLAG is set (no quotation mark), JUMP to 5292H.
5291
INC HL 23
Increment Register Pair HL past the closing quotation mark.
5292
LD A,(532FH) 3A 2F 53
Fetch the change mask from 532FH, the operand of LD D,00H at 532EH, into Register A.
5295
OR B B0
OR Register B (the bit of this parameter) into Register A, the change mask.
5296
LD (532FH),A 32 2F 53
Store Register A (the change mask) back to 532FH, the operand of LD D,00H at 532EH.
5299
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A: what follows the parameter.
529A
CP 29H FE 29
Compare Register A (the character after the parameter) against 29H, a closing parenthesis: the end of the list.
529C
If the Z FLAG is set (the end of the list), JUMP to 5323H to change the directory record.
529F
CP 2CH FE 2C
Compare Register A (the character after the parameter) against 2CH, a comma: another parameter follows.
52A1
If the Z FLAG is set (a comma), JUMP to 5237H to read the next parameter.
52A3
Anything else (0DH when the closing parenthesis is missing): JUMP to 53A4H to display PARAMETER ERROR and abort.
52A6H - INV and VIS
INV and VIS take no value. INV sets bit 3 of the operand at 533FH, VIS clears it; either one marks bit 3 of the change mask, and 5338H then copies that bit into bit 3 of the attribute byte, the invisible bit.
52A6
INV: GOSUB to 52F7H to pass over the rest of the word: the Z FLAG when it ends without an equal sign.
52A9
If the NZ FLAG is set (INV with a value), JUMP to 53A4H to display PARAMETER ERROR and abort.
52AC
LD A,(533FH) 3A 3F 53
Fetch the invisible bit from 533FH, the operand of OR 00H at 533EH, into Register A.
52AF
OR 08H F6 08
Set bit 3 of Register A: OR 08H, the file is to be invisible.
52B1
LD (533FH),A 32 3F 53
Store Register A to 533FH, the operand of OR 00H at 533EH.
52B4
LD B,08H 06 08
Load Register B with 08H, bit 3 of the change mask: the invisible bit.
52B6
JUMP to 5292H to mark the change and go on after the word.
52B8
VIS: GOSUB to 52F7H to pass over the rest of the word: the Z FLAG when it ends without an equal sign.
52BB
If the NZ FLAG is set (VIS with a value), JUMP to 53A4H to display PARAMETER ERROR and abort.
52BE
LD A,(533FH) 3A 3F 53
Fetch the invisible bit from 533FH, the operand of OR 00H at 533EH, into Register A.
52C1
AND F7H E6 F7
Clear bit 3 of Register A: AND F7H, the file is to be visible.
52C3
LD (533FH),A 32 3F 53
Store Register A to 533FH, the operand of OR 00H at 533EH.
52C6
LD B,08H 06 08
Load Register B with 08H, bit 3 of the change mask: the invisible bit.
52C8
JUMP to 5292H to mark the change and go on after the word.
52CAH - ACC and UPD: the Passwords
The value (at most 8 letters and digits, the first a letter, padded with spaces at 51E0H-51E7H) is turned into its hash code by SYS2/SYS (request E4H, its 511EH), still in memory from the open. ACC stores the code at 51F5H-51F6H and marks bit 1, UPD at 51F3H-51F4H and marks bit 2; 5349H and 5359H copy them into the directory record. An empty value gives the code of 8 spaces, no password.
52CA
ACC: GOSUB to 52F7H to find the value: the NZ FLAG when an equal sign was found and the value copied to 51E0H-51E7H.
52CD
If the Z FLAG is set (ACC without a value), JUMP to 53A4H to display PARAMETER ERROR and abort.
52D0
PUSH HL E5
Save Register Pair HL (the place after the value) to the stack.
52D1
LD DE,51E0H 11 E0 51
Point Register Pair DE to 51E0H, the value padded to 8 characters with spaces.
52D4
GOSUB to 52F4H, which has SYS2/SYS work out the hash code of the 8 characters at Register Pair DE (51E0H): Register Pair HL = the code.
52D7
LD (51F5H),HL 22 F5 51
Store Register Pair HL (the hash code) to 51F5H-51F6H, SYS2/SYS's cell of the access password code, for 5359H.
52DA
POP HL E1
Restore Register Pair HL from the stack: the place after the value.
52DB
LD B,02H 06 02
Load Register B with 02H, bit 1 of the change mask: the access password.
52DD
JUMP to 528CH to pass over a closing quote, mark the change and go on.
52DF
UPD: GOSUB to 52F7H to find the value: the NZ FLAG when an equal sign was found and the value copied to 51E0H-51E7H.
52E2
If the Z FLAG is set (UPD without a value), JUMP to 53A4H to display PARAMETER ERROR and abort.
52E5
PUSH HL E5
Save Register Pair HL (the place after the value) to the stack.
52E6
LD DE,51E0H 11 E0 51
Point Register Pair DE to 51E0H, the value padded to 8 characters with spaces.
52E9
GOSUB to 52F4H, which has SYS2/SYS work out the hash code of the 8 characters at Register Pair DE (51E0H): Register Pair HL = the code.
52EC
LD (51F3H),HL 22 F3 51
Store Register Pair HL (the hash code) to 51F3H-51F4H, SYS2/SYS's cell of the update password code, for 5349H.
52EF
POP HL E1
Restore Register Pair HL from the stack: the place after the value.
52F0
LD B,04H 06 04
Load Register B with 04H, bit 2 of the change mask: the update password.
52F2
JUMP to 528CH to pass over a closing quote, mark the change and go on.
52F4H - Hash Code of a Password
Register Pair DE = 8 characters. Request E4H goes to SYS2/SYS's 511EH, which is in memory since the open at 5215H, so nothing is loaded over 51E0H; RST 28H's return address is dropped by the request handler, which returns to the caller of 52F4H with Register Pair HL = the hash code.
52F4
LD A,E4H 3E E4
Load Register A with E4H, the request code of SYS2/SYS function 6 (its 511EH): the hash code of a password.
52F6
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H with Register A = E4H: SYS2/SYS hashes the 8 characters at Register Pair DE into Register Pair HL and the handler returns to the caller of 52F4H (52D7H or 52ECH).
52F7H - Find the Value of a Parameter
Register Pair HL = the first letter of the parameter. The word is passed over up to 0DH, a closing parenthesis or a comma (the Z FLAG, Register Pair HL on that character) or an equal sign. After an equal sign an opening quote is passed over, 51E0H-51E7H is filled with spaces and SYS2/SYS's 50B1H copies the value there (the first character must be a letter, then up to 8 letters and digits in all); Register Pair HL is left on the character that ended it and the NZ FLAG is returned.
52F7
INC HL 23
Increment Register Pair HL to the next character of the parameter word.
52F8
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
52F9
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the end of the line.
52FB
RET Z C8
If the Z FLAG is set (the end of the line), RETURN with the Z FLAG: no value.
52FC
CP 29H FE 29
Compare Register A (the character) against 29H, a closing parenthesis.
52FE
RET Z C8
If the Z FLAG is set (the end of the list), RETURN with the Z FLAG: no value.
52FF
CP 2CH FE 2C
Compare Register A (the character) against 2CH, a comma.
5301
RET Z C8
If the Z FLAG is set (the next parameter follows), RETURN with the Z FLAG: no value.
5302
CP 3DH FE 3D
Compare Register A (the character) against 3DH, an equal sign.
5304
If the NZ FLAG is set (a letter of the word), JUMP to 52F7H for the next character.
5306
INC HL 23
Increment Register Pair HL past the equal sign, to the value.
5307
LD A,(HL) 7E
Fetch the first character of the value at Register Pair HL into Register A.
5308
CP 22H FE 22
Compare Register A (the first character of the value) against 22H, a quotation mark.
530A
If the NZ FLAG is set (no quotation mark), JUMP to 530DH.
530C
INC HL 23
Increment Register Pair HL past the opening quotation mark.
530D
LD DE,51E0H 11 E0 51
Point Register Pair DE to 51E0H, SYS2/SYS's 8 byte work area of a password, where the value goes.
5310
LD B,08H 06 08
Load Register B with 08H, the 8 characters of the field.
5312
PUSH DE D5
Save Register Pair DE (51E0H, the start of the field) to the stack.
5313
PUSH BC C5
Save Register Pair BC (Register B = 08H) to the stack.
5314
LD A,20H 3E 20
Load Register A with 20H, a space, to clear the field.
5316
LD (DE),A 12
Store Register A (a space) to the field at Register Pair DE.
5317
INC DE 13
Increment Register Pair DE to the next byte of the field.
5318
Decrement Register B and JUMP to 5316H until the 8 bytes 51E0H-51E7H hold spaces.
531A
POP BC C1
Restore Register Pair BC from the stack: Register B = 08H, the most characters to copy.
531B
POP DE D1
Restore Register Pair DE from the stack: 51E0H.
531C
GOSUB to 50B1H in SYS2/SYS (in memory since the open) to copy the value from Register Pair HL to Register Pair DE (51E0H), at most Register B (8) characters, a letter first: Register A = the character that ended it, Register Pair HL past that character.
531F
DEC HL 2B
Decrement Register Pair HL back to the character that ended the value.
5320
OR 01H F6 01
OR Register A with 01H: the NZ FLAG is set whatever the character, the sign that a value was given.
5322
RET C9
RETURN with the NZ FLAG and Register Pair HL on the character after the value.
5323H - Change the Directory Record
The file's directory record is read (4B10H with the entry code and drive of the open), the attribute byte changed by bits 0 and 3 of the change mask, the update password code stored at +10H-+11H (bit 2) and the access password code at +12H-+13H (bit 1), and the sector written back (4B1FH). The level is stored with AND F0H, which clears bit 3 as well: PROT without INV or VIS makes an invisible file visible.
5323
LD BC,(53E1H) ED 4B E1 53
Fetch bytes +06H-+07H of the control block at 53E1H-53E2H into Register Pair BC: Register C = the drive, Register B = the directory entry code of the file's record.
5327
GOSUB to 4B10H to read the directory sector of entry Register B on drive Register C into 4200H: Register Pair HL = the file's record in 4200H-42FFH, the Z FLAG when read.
532A
If the NZ FLAG is set (error 11H, DIRECTORY READ ERROR, in Register A), JUMP to 536BH to display it and abort.
532D
LD A,(HL) 7E
Fetch the attribute byte, byte +00H of the record at Register Pair HL, into Register A.
532E
LD D,00H 16 00
Self-Modifying Code
Load Register D with the change mask: the operand at 532FH is 00H in the file (the member is loaded afresh for each command) and 5296H ORs in bit 0 for PROT, bit 1 for ACC, bit 2 for UPD and bit 3 for INV or VIS.
5330
BIT 0,D CB 42
Test bit 0 of Register D (the change mask): PROT was given.
5332
If the Z FLAG is set (no PROT), JUMP to 5338H.
5334
AND F0H E6 F0
Mask Register A (the attribute byte) with F0H: bits 2-0, the old level, are cleared and bit 3, the invisible bit, with them.
5336
OR 00H F6 00
Self-Modifying Code
OR the level into Register A (the attribute byte): the operand at 5337H is 00H in the file; 5286H stores the level of PROT there.
5338
BIT 3,D CB 5A
Test bit 3 of Register D (the change mask): INV or VIS was given.
533A
If the Z FLAG is set (neither INV nor VIS), JUMP to 5340H.
533C
AND F7H E6 F7
Mask Register A (the attribute byte) with F7H to clear bit 3, the invisible bit.
533E
OR 00H F6 00
Self-Modifying Code
OR the invisible bit into Register A (the attribute byte): the operand at 533FH is 00H in the file; 52B1H stores 08H there for INV, 52C3H 00H for VIS.
5340
LD (HL),A 77
Store Register A (the new attribute byte) to byte +00H of the record at Register Pair HL.
5341
LD A,L 7D
Copy Register L (the low byte of the record's address) into Register A.
5342
ADD A,10H C6 10
Add 10H to Register A: the low byte of record byte +10H. The record starts at a multiple of 20H, so no carry goes to Register H.
5344
LD L,A 6F
Copy Register A into Register L: Register Pair HL = byte +10H of the record, the update password code.
5345
BIT 2,D CB 52
Test bit 2 of Register D (the change mask): UPD was given.
5347
If the Z FLAG is set (no UPD), JUMP to 5353H.
5349
LD A,(51F3H) 3A F3 51
Fetch the low byte of the update password code from 51F3H into Register A.
534C
LD (HL),A 77
Store Register A to byte +10H of the record at Register Pair HL.
534D
LD A,(51F4H) 3A F4 51
Fetch the high byte of the update password code from 51F4H into Register A.
5350
INC HL 23
Increment Register Pair HL to byte +11H of the record.
5351
LD (HL),A 77
Store Register A (the high byte of the code) to byte +11H at Register Pair HL.
5352
DEC HL 2B
Decrement Register Pair HL back to byte +10H of the record.
5353
INC HL 23
Increment Register Pair HL to byte +11H of the record.
5354
INC HL 23
Increment Register Pair HL to byte +12H of the record, the access password code.
5355
BIT 1,D CB 4A
Test bit 1 of Register D (the change mask): ACC was given.
5357
If the Z FLAG is set (no ACC), JUMP to 5362H.
5359
LD A,(51F5H) 3A F5 51
Fetch the low byte of the access password code from 51F5H into Register A.
535C
LD (HL),A 77
Store Register A to byte +12H of the record at Register Pair HL.
535D
LD A,(51F6H) 3A F6 51
Fetch the high byte of the access password code from 51F6H into Register A.
5360
INC HL 23
Increment Register Pair HL to byte +13H of the record.
5361
LD (HL),A 77
Store Register A (the high byte of the code) to byte +13H at Register Pair HL.
5362
GOSUB to 4B1FH to write the directory sector in 4200H back for entry Register B on drive Register C, with the read back check: the Z FLAG when written.
5365
If the NZ FLAG is set (error 12H or 0FH in Register A), JUMP to 536BH to display it and abort.
5368
JUMP to 402DH, the normal exit: VTOS READY. The file is left open; nothing of it was written.
536BH - Error Exits and Messages
536BH displays the message of the error code in Register A (the text alone) through 4409H, which then goes to the abort exit. The member's own three messages are displayed through 447BH (the display and the job log) before the abort exit 4030H.
536B
OR 40H F6 40
Set bit 6 of Register A (the error code): OR 40H asks for the text of the message alone.
536D
JUMP to 4409H to display the message of the error in Register A; with bit 7 clear it then goes to the abort exit 4030H.
5370
LD HL,5379H 21 79 53
Point Register Pair HL to 5379H, the message FILE SPEC REQUIRED.
5373
GOSUB to 447BH to display the text at Register Pair HL (5379H) up to its 0DH and write it to the job log.
5376
JUMP to 4030H, the abort exit: request A3H, the command ends and VTOS READY is displayed.
5379-538A
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5370H, displayed when there is no file specification or it names a device.
538B
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED at 5379H, for 447BH.
538C
LD HL,5395H 21 95 53
Point Register Pair HL to 5395H, the message -NOTHING DONE-.
538F
GOSUB to 447BH to display the text at Register Pair HL (5395H) up to its 0DH and write it to the job log.
5392
JUMP to 4030H, the abort exit: request A3H, the command ends and VTOS READY is displayed.
5395-53A2
DEFM "-NOTHING DONE-" 2D 4E 4F 54 48 49 4E 47 20 44 4F 4E 45 2D
The message of 538CH, displayed when no parameter list in parentheses follows the file specification.
53A3
DEFB 0DH 0D
The carriage return that ends the message -NOTHING DONE- at 5395H, for 447BH.
53A4
LD HL,53ADH 21 AD 53
Point Register Pair HL to 53ADH, the message PARAMETER ERROR.
53A7
GOSUB to 447BH to display the text at Register Pair HL (53ADH) up to its 0DH and write it to the job log.
53AA
JUMP to 4030H, the abort exit: request A3H, the command ends and VTOS READY is displayed.
53AD-53BB
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message of 53A4H, displayed for an unknown parameter, a missing or unexpected value, an unknown level or a list not closed.
53BC
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR at 53ADH, for 447BH.
53BDH - Make the Line Upper Case
Register Pair HL = the text. Every byte from 61H up (the small letters, and the bytes above them) loses bit 5, until the first byte below 20H (the 0DH at the end of the line).
53BD
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
53BE
CP 20H FE 20
Compare Register A (the character) against 20H, a space: below it is a control byte, the end of the line.
53C0
RET C D8
If the C FLAG is set (the end of the line), RETURN.
53C1
CP 61H FE 61
Compare Register A (the character) against 61H, the small letter a.
53C3
If the C FLAG is set (below a), JUMP to 53C7H and leave the character as it is.
53C5
RES 5,(HL) CB AE
Reset bit 5 of the character at Register Pair HL: a small letter becomes the capital letter.
53C7
INC HL 23
Increment Register Pair HL to the next character of the line.
53C8
JUMP to 53BDH for the next character at Register Pair HL.
53CA
DEFB 0DH 0D
A carriage return that no code of the member reads: the table of levels starts at 53CBH (525DH).
53CBH - The Table of Levels
Eight entries of two characters, read by 5260H-526EH: the first two characters of the value of PROT. Entry n (counted from 1) gives the level 8 less n except for the first, which gives 0 (5270H-5275H).
53CB-53CC
DEFM "AL" 41 4C
Entry 1: ALL, level 0, full access: 5271H-5273H give 00H for it by its own test.
53CD-53CE
DEFM "EX" 45 58
Entry 2: EXEC, level 6, the level the manual calls execute only.
53CF-53D0
DEFM "RE" 52 45
Entry 3: READ, level 5, reading without writing (SYS0/SYS's 49A3H refuses a write from level 5 up); RENA and RENAME, with N third, give level 2 instead (527BH).
53D1-53D2
DEFM "WR" 57 52
Entry 4: WRIT or WRITE, level 4: reading and writing (below level 5).
53D3-53D4
DEFM "~~" 7E 7E
Entry 5, level 3: two tilde characters, which no value can match (5226H turns a tilde into 5EH and 50B1H copies only letters and digits), so level 3 cannot be given.
53D5-53D6
DEFM "NA" 4E 41
Entry 6: NAME, level 2, the same level as RENAME.
53D7-53D8
DEFM "KI" 4B 49
Entry 7: KILL, level 1, the level the manual names after KILL.
53D9-53DA
DEFM "FU" 46 55
Entry 8: FULL, level 0, full access, the same level as ALL in entry 1.
53DBH - Work Area Above the Member
Not in the file: the control block of the file follows the member's last byte (53DAH).
53DB-53FA
DEFS 32
Not in the file: the control block of the file. 441CH writes the specification (5203H), 5209H reads its first byte, the open fills it (5215H); 521CH reads +01H (53DCH, the access level) and 5323H reads +06H-+07H (53E1H-53E2H, the drive and the directory entry code).
5200H - Member 19 (PROT, Code 52H): Refuse the Command While a Chain File Runs
SYS1/SYS's command interpreter runs this member for the word PROT (member code 52H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL pointing at the rest of the command line after the word PROT and its delimiter. PROT changes the protection data of the diskette in a drive: NAME (the diskette name, allocation table +D0H-+D7H), PW (the master password code, +CEH-+CFH), LOCK and UNLOCK (the access and update password codes of every user file), and needs the current master password, from MPW or typed at a prompt. First the member refuses to run while 430FH bit 5 is set (a chain file is being executed).
5200
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A: bit 5 is set while SYS7/SYS executes the commands of a chain file.
5203
BIT 5,A CB 6F
Test bit 5 of Register A (the system flags from 430FH): the NZ FLAG is set while a chain file is being executed.
5205
If the NZ FLAG is set (a chain file runs), JUMP to 5452H to display INVALID COMMAND DURING PROGRAM CHAINING and abort.
5208
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the value stored below as the MPW parameter's word: no MPW given yet.
520B
JUMP over the patch code at 520DH-521AH to 521BH, which stores Register Pair BC (0000H).
520DH - Patch Code: Prompt When a Value Is a Flag
These bytes belong to the patch the distributor's manual prints for PROT: its line D26,9C gives the 16 bytes 520BH-521AH (the JR at 520BH, this code and the two 00H). 53A0H jumps here with Register Pair DE = a parameter's value that is not 0000H. A value of FFFFH (the name typed without a value, or =Y, =YES, =ON) goes to the prompt at 53BBH; any other value is the address of a text and goes to the copy at 53A3H with Register Pair HL = 5600H. The two 00H bytes at 5219H-521AH end the patch; nothing executes them.
520D
LD A,D 7A
Copy Register D (the high byte of the parameter's value) into Register A.
520E
AND E A3
AND Register E (the low byte of the value) into Register A: Register A = FFH only when Register Pair DE = FFFFH.
520F
INC A 3C
Increment Register A: the Z FLAG is set when Register A was FFH, the value FFFFH of a parameter given without a text.
5210
If the Z FLAG is set (Register Pair DE = FFFFH), JUMP to 53BBH to display the prompt at Register Pair HL and read the text from the keyboard.
5213
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the 8 byte text buffer, where the text at Register Pair DE is to be copied.
5216
JUMP to 53A3H to copy the text at Register Pair DE (the address the parameter holds) to the buffer at Register Pair HL (5600H).
5219-521A
NOP x 2 00 x 2
Two 00H bytes at the end of the patch. The JR at 520BH jumps over them and no other path reaches them.
521BH - Clear MPW and Read the Drive Number
The MPW word at 5394H-5395H is not in the file, so it is set to 0000H before the parameter list is read. The drive is a colon and one character right after the command word: the character less 30H is the drive, with no range test; without a colon the drive is 0. The drive goes to 5370H, the operand of LD C,00H at 536FH, which 52A7H and 5303H read too. Then SYS1/SYS's 510FH reads the parameter list with the table at 54F4H.
521B
LD (5394H),BC ED 43 94 53
Store Register Pair BC (0000H from 5208H) to 5394H-5395H, the word of the MPW parameter (not in the file): no master password given yet.
521F
LD C,00H 0E 00
Load Register C with 00H, drive 0, the drive when the command names none.
5221
LD A,(HL) 7E
Fetch the character at Register Pair HL (the first one after the command word PROT and its delimiter) into Register A.
5222
CP 3AH FE 3A
Compare Register A (the first character of the parameters) against 3AH, a colon: a drive number follows.
5224
If the NZ FLAG is set (no colon), JUMP to 522CH with Register C = 00H, drive 0.
5226
INC HL 23
Increment Register Pair HL past the colon, onto the drive digit.
5227
LD A,(HL) 7E
Fetch the drive digit at Register Pair HL into Register A.
5228
SUB 30H D6 30
SUBtract 30H from Register A (the drive digit): the digits 0-7 give the drives 0-7. No range test follows: any character is taken.
522A
LD C,A 4F
Copy Register A (the drive number) into Register C.
522B
INC HL 23
Increment Register Pair HL past the drive digit, onto the parameter list.
522C
LD A,C 79
Copy Register C (the drive: 00H, or the digit's value) into Register A.
522D
LD (5370H),A 32 70 53
Store Register A (the drive) to 5370H, the operand of LD C,00H at 536FH, which 52A7H and 5303H also read.
5230
LD DE,54F4H 11 F4 54
Point Register Pair DE to 54F4H, the parameter table of PROT: PW, LOCK, UNLOCK, NAME and MPW.
5233
GOSUB to 4476H (request E3H, SYS1/SYS's 510FH) to read the parameter list at Register Pair HL with the table at Register Pair DE (54F4H): each name found stores its value into the word the table gives (5267H, 52EDH, 52F7H, 524FH, 5394H). The Z FLAG returns for a good list or for none.
5236
If the NZ FLAG is set (an unknown name or a bad value), JUMP to 5439H to display PARAMETER ERROR and abort.
5239H - Need a Change, Then the Master Password
At least one of PW, LOCK, UNLOCK and NAME must have been given: only the low bytes of their words are ORed, so a value whose low byte is 00H counts as not given (a text in the command line buffer 4318H-4357H never has such an address). MPW alone changes nothing and ends with -NOTHING DONE-. Then 5364H must accept the master password; it returns with the allocation table of the drive in 5700H-57FFH.
5239
LD A,(5267H) 3A 67 52
Fetch the low byte of the PW parameter's value from 5267H (the operand of LD DE,0000H at 5266H) into Register A.
523C
LD HL,52EDH 21 ED 52
Point Register Pair HL to 52EDH, the low byte of the LOCK parameter's value (the operand of LD DE,0000H at 52ECH).
523F
OR (HL) B6
OR the byte at Register Pair HL (the low byte of LOCK's value) into Register A.
5240
LD HL,52F7H 21 F7 52
Point Register Pair HL to 52F7H, the low byte of the UNLOCK parameter's value (the operand of LD DE,0000H at 52F6H).
5243
OR (HL) B6
OR the byte at Register Pair HL (the low byte of UNLOCK's value) into Register A.
5244
LD HL,524FH 21 4F 52
Point Register Pair HL to 524FH, the low byte of the NAME parameter's value (the operand of LD DE,0000H at 524EH).
5247
OR (HL) B6
OR the byte at Register Pair HL (the low byte of NAME's value) into Register A: the Z FLAG is set when none of PW, LOCK, UNLOCK and NAME was given.
5248
If the Z FLAG is set (nothing to change), JUMP to 5483H to display -NOTHING DONE- and abort.
524B
GOSUB to 5364H to get the master password (from MPW or typed) and check it against the drive's allocation table, read into 5700H-57FFH. It returns only when the password is right, with the Z FLAG; otherwise it ends the command itself.
524EH - NAME: Store the New Diskette Name
With NAME given, the 8 characters of the name (the text of NAME="text", or typed at the prompt NEW DISK PACK NAME ? when NAME has no text) are copied to 57D0H-57D7H, the name field +D0H-+D7H of the allocation table in 5700H. The LDIR leaves Register C = 00H, so from here Register C no longer holds the drive.
524E
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the NAME parameter's value: the operand 524FH-5250H is 0000H in the file and SYS1/SYS's 510FH stores the value there at 5233H: FFFFH for NAME alone, the address of the text for NAME="text", 0000H when NAME is not given.
5251
LD A,D 7A
Copy Register D (the high byte of NAME's value) into Register A.
5252
OR E B3
OR Register E (the low byte of NAME's value) into Register A: the Z FLAG is set when Register Pair DE = 0000H, NAME not given.
5253
If the Z FLAG is set (no NAME), JUMP to 5266H to look at PW.
5255
LD HL,549BH 21 9B 54
Point Register Pair HL to 549BH, the prompt NEW DISK PACK NAME ? for a NAME without a text.
5258
GOSUB to 539CH to put the 8 characters of the name into 5600H-5607H, copied from the text at Register Pair DE or typed after the prompt at Register Pair HL (549BH); Register Pair DE returns 5600H.
525B
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the 8 characters of the new name.
525E
LD DE,57D0H 11 D0 57
Point Register Pair DE to 57D0H, the name field +D0H-+D7H of the allocation table in 5700H.
5261
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 characters of a diskette name.
5264
LDIR ED B0
Copy the 8 bytes from Register Pair HL (5600H) to Register Pair DE (57D0H): the new name is in the table. Register Pair BC ends at 0000H, so Register C (the drive) is 00H from here on.
5266H - PW: Store the New Master Password Code
With PW given, the 8 characters of the new master password (the text of PW="text", or typed at the prompt NEW MASTER PASSWORD ? when PW has no text) are turned into their hash code by SYS2/SYS (request E4H), stored at 57CEH-57CFH, the master password code +CEH-+CFH of the allocation table in 5700H.
5266
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the PW parameter's value: the operand 5267H-5268H is 0000H in the file and SYS1/SYS's 510FH stores the value there at 5233H: FFFFH for PW alone, the address of the text for PW="text", 0000H when PW is not given.
5269
LD A,D 7A
Copy Register D (the high byte of PW's value) into Register A.
526A
OR E B3
OR Register E (the low byte of PW's value) into Register A: the Z FLAG is set when Register Pair DE = 0000H, PW not given.
526B
If the Z FLAG is set (no PW), JUMP to 5276H to read the hash index table.
526D
LD HL,54B3H 21 B3 54
Point Register Pair HL to 54B3H, the prompt NEW MASTER PASSWORD ? for a PW without a text.
5270
GOSUB to 5396H to get the 8 characters of the new password (from the text at Register Pair DE or typed after the prompt at Register Pair HL, 54B3H) and their hash code into Register Pair HL.
5273
LD (57CEH),HL 22 CE 57
Store Register Pair HL (the hash code of the new master password) to 57CEH-57CFH, the master password code +CEH-+CFH of the allocation table in 5700H.
5276H - Read the Hash Index Table
Sector 1 of the directory cylinder, the hash index table (one byte per directory record, the hash code of its name, 00H for a free record), is read into 5800H-58FFH. The drive is Register C as it is now: the drive only when neither NAME nor a typed PW ran before. After NAME (the LDIR at 5264H) Register C is 00H and after a typed PW (the ROM's line input at 53C3H) it is 08H; 47A0H takes bits 2-0, so both read drive 0's table and drive 0's directory cylinder into Register D.
5276
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D (and Register A). Register C is 00H after NAME (5264H) or 08H after a typed PW (the ROM's 0040H), both drive 0; otherwise the drive of the command.
5279
LD E,01H 1E 01
Load Register E with 01H, sector 1 of the directory cylinder: the hash index table.
527B
LD HL,5800H 21 00 58
Point Register Pair HL to 5800H, the buffer for the hash index table.
527E
GOSUB to 4B45H to read cylinder Register D, sector Register E (01H) of drive Register C into the buffer at Register Pair HL (5800H); the Z FLAG for a sector with the directory data mark.
5281
If the NZ FLAG is set (a read error), JUMP to 5434H with the error code in Register A to display it and abort.
5284H - A Table From Another System: Count the Cylinders
FORMAT/CMD writes 40H at +CBH of the allocation table; a value below 30H at 57CBH is taken as a table that VTOS did not make, and +CCH (57CCH, the cylinders past 35, which SYS2/SYS adds to 22H for the last cylinder) is worked out from the lockout bytes +60H-+BFH: FFH marks a cylinder that is not there. Cylinder 70 there gives 2AH (77 cylinders), else cylinder 40 gives 23H (70 cylinders), else cylinder 35 gives 05H (40 cylinders), else 00H (35 cylinders).
5284
LD A,(57CBH) 3A CB 57
Fetch byte +CBH of the allocation table from 57CBH into Register A: 40H in a table written by FORMAT/CMD.
5287
CP 30H FE 30
Compare Register A (the byte +CBH from 57CBH) against 30H. The operand 30H and the JR NC below are the patch line D27,19 of the distributor's manual.
5289
If the NC FLAG is set (+CBH is 30H or more, a table VTOS made), JUMP to 52A7H and leave +CCH as it is.
528B
LD A,(57A6H) 3A A6 57
Fetch the lockout byte of cylinder 70 (46H) from 57A6H (+A6H of the table) into Register A: FFH when the cylinder is not there.
528E
INC A 3C
Increment Register A (the lockout byte from 57A6H): the Z FLAG is set when it was FFH, cylinder 70 missing.
528F
LD A,2AH 3E 2A
Load Register A with 2AH, the cylinders past 35 of a 77 cylinder diskette. LD does not change the flags.
5291
If the NZ FLAG is set (cylinder 70 is there), JUMP to 52A4H to store Register A (2AH).
5293
LD A,(5788H) 3A 88 57
Fetch the lockout byte of cylinder 40 (28H) from 5788H (+88H of the table) into Register A.
5296
INC A 3C
Increment Register A (the lockout byte from 5788H): the Z FLAG is set when it was FFH, cylinder 40 missing.
5297
LD A,23H 3E 23
Load Register A with 23H, 35 cylinders past 35 (70 cylinders). LD does not change the flags.
5299
If the NZ FLAG is set (cylinder 40 is there), JUMP to 52A4H to store Register A (23H).
529B
LD A,(5783H) 3A 83 57
Fetch the lockout byte of cylinder 35 (23H) from 5783H (+83H of the table) into Register A.
529E
INC A 3C
Increment Register A (the lockout byte from 5783H): the Z FLAG is set when it was FFH, cylinder 35 missing.
529F
LD A,05H 3E 05
Load Register A with 05H, 5 cylinders past 35 (40 cylinders). LD does not change the flags.
52A1
If the NZ FLAG is set (cylinder 35 is there), JUMP to 52A4H to store Register A (05H).
52A3
XOR A AF
Set Register A to 00H (XOR A): no cylinder past 35, a diskette of 35 cylinders.
52A4
LD (57CCH),A 32 CC 57
Store Register A (2AH, 23H, 05H or 00H) to 57CCH, byte +CCH of the allocation table: the cylinders past 35.
52A7H - Write the Allocation Table
The table in 5700H (with the new name, the new master password code and +CCH) is written back to the drive of the command, taken again from 5370H.
52A7
LD A,(5370H) 3A 70 53
Fetch the drive from 5370H (the operand of LD C at 536FH, stored at 522DH) into Register A.
52AA
LD C,A 4F
Copy Register A (the drive of the command) into Register C.
52AB
GOSUB to 541BH to write the allocation table from 5700H to drive Register C and read it back; Register Pairs DE and HL are kept (Register D the directory cylinder from 5276H, Register E 01H, Register Pair HL 5800H).
52AE
If the NZ FLAG is set (error 15H, GAT WRITE ERROR), JUMP to 5434H to display it and abort.
52B1H - A Table From Another System: Repair DIR/SYS
For the same tables (+CBH below 30H), when the hash index byte of directory entry code 01H (5801H: sector 3, record 0, the record of DIR/SYS) is 2CH, it becomes C4H, the hash code that SYS2/SYS's 50CBH gives the name DIR/SYS. The index sector is written back from 5800H, then DIR/SYS's record is read, its access password code (+12H-+13H at 4212H) set to 4296H, the code of 8 spaces (no password), and written back, and the note FILE 'DIR/SYS' IS NOW READ ENABLED is shown. Neither write is read back; both use Register D from 5276H as the cylinder.
52B1
LD A,(57CBH) 3A CB 57
Fetch byte +CBH of the allocation table from 57CBH into Register A once more.
52B4
CP 30H FE 30
Compare Register A (the byte +CBH from 57CBH) against 30H.
52B6
If the NC FLAG is set (+CBH is 30H or more, a table VTOS made), JUMP to 52E9H for LOCK and UNLOCK.
52B8
LD A,(5801H) 3A 01 58
Fetch the hash index byte of entry code 01H from 5801H into Register A: the hash code of DIR/SYS's record (sector 3, record 0).
52BB
CP 2CH FE 2C
Compare Register A (the index byte from 5801H) against 2CH.
52BD
If the NZ FLAG is set (the byte is not 2CH), JUMP to 52E9H: no repair.
52BF
LD A,C4H 3E C4
Load Register A with C4H, the hash code of the name DIR/SYS (SYS2/SYS 50CBH over "DIR SYS").
52C1
LD (5801H),A 32 01 58
Store Register A (C4H) to 5801H, the index byte of DIR/SYS's record.
52C4
GOSUB to 4768H to write the buffer at Register Pair HL (5800H) to cylinder Register D (from 5276H), sector Register E (01H) of drive Register C with the directory data mark FAH.
52C7
If the NZ FLAG is set (a write error), JUMP to 5434H with the error code in Register A.
52CA
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer.
52CD
LD E,03H 1E 03
Load Register E with 03H, sector 3 of the directory cylinder: the directory records of entry codes x1H, DIR/SYS's first.
52CF
GOSUB to 4B45H to read cylinder Register D (from 5276H), sector Register E (03H) of drive Register C into 4200H at Register Pair HL.
52D2
If the NZ FLAG is set (a read error), JUMP to 5434H with the error code in Register A.
52D5
PUSH HL E5
Save Register Pair HL (4200H, the sector buffer holding DIR/SYS's record) to the stack.
52D6
LD HL,4296H 21 96 42
Load Register Pair HL with 4296H, the hash code of 8 spaces: no password.
52D9
LD (4212H),HL 22 12 42
Store Register Pair HL (4296H) to 4212H-4213H, the access password code +12H-+13H of record 0 in 4200H, the record of DIR/SYS: it can be read without a password.
52DC
POP HL E1
Restore Register Pair HL from the stack: 4200H, the sector buffer.
52DD
GOSUB to 4768H to write the sector at Register Pair HL (4200H) back to cylinder Register D, sector Register E (03H) of drive Register C with the directory data mark FAH.
52E0
If the NZ FLAG is set (a write error), JUMP to 5434H with the error code in Register A.
52E3
LD HL,54CBH 21 CB 54
Point Register Pair HL to 54CBH, the text NOTE: FILE 'DIR/SYS' IS NOW READ ENABLED.
52E6
GOSUB to 447BH to display the text at Register Pair HL (54CBH) and write it to the job log.
52E9H - LOCK or UNLOCK: Pick the Password Code
LOCK gives the files the master password code at 57CEH (the new one when PW was given), UNLOCK the code 4296H of 8 spaces; when both are given LOCK wins. Without either the command ends here at 402DH, VTOS READY.
52E9
LD HL,(57CEH) 2A CE 57
Fetch the master password code from 57CEH-57CFH (+CEH-+CFH of the table in 5700H, the new code when PW ran) into Register Pair HL.
52EC
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the LOCK parameter's value: the operand 52EDH-52EEH is 0000H in the file and SYS1/SYS's 510FH stores the value there at 5233H, FFFFH for LOCK.
52EF
LD A,D 7A
Copy Register D (the high byte of LOCK's value) into Register A.
52F0
OR E B3
OR Register E (the low byte of LOCK's value) into Register A: the NZ FLAG is set when LOCK was given.
52F1
If the NZ FLAG is set (LOCK), JUMP to 5300H with Register Pair HL = the master password code.
52F3
LD HL,4296H 21 96 42
Load Register Pair HL with 4296H, the hash code of 8 spaces: no password.
52F6
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the UNLOCK parameter's value: the operand 52F7H-52F8H is 0000H in the file and SYS1/SYS's 510FH stores the value there at 5233H, FFFFH for UNLOCK.
52F9
LD A,D 7A
Copy Register D (the high byte of UNLOCK's value) into Register A.
52FA
OR E B3
OR Register E (the low byte of UNLOCK's value) into Register A: the NZ FLAG is set when UNLOCK was given.
52FB
If the NZ FLAG is set (UNLOCK), JUMP to 5300H with Register Pair HL = 4296H.
52FD
JUMP to 402DH, VTOS READY: neither LOCK nor UNLOCK, the command is done.
5300H - LOCK and UNLOCK: Set the Passwords of Every User File
The hash index table in 5800H is walked sector by sector: Register L = s, s+20H, ... s+E0H is the entry code of record 0-7 of directory sector s+2, for s = 00H-1FH. Entry codes whose bits 7, 6, 4 and 3 are all 0 (00H-07H and 20H-27H, the system files) and index bytes 00H (free) are passed over. The sector of the others is read into 4200H once (531EH remembers it); a record whose attribute byte has bits 7-3 = 00010B (in use, not an extension record, bit 6 the system bit and bit 3 the invisible bit clear) gets the code at +10H-+11H (update) and +12H-+13H (access). Each sector read is written back. The hash index table used is the one read at 5276H, drive 0's after NAME or a typed PW.
5300
LD (5339H),HL 22 39 53
Store Register Pair HL (the code to give: the master password code or 4296H) to 5339H-533AH, the operand of LD DE,0000H at 5338H.
5303
LD A,(5370H) 3A 70 53
Fetch the drive from 5370H (stored at 522DH) into Register A.
5306
LD C,A 4F
Copy Register A (the drive of the command) into Register C.
5307
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D. Nothing below uses Register D: 4B10H and 4B1FH find the cylinder themselves.
530A
LD HL,5800H 21 00 58
Point Register Pair HL to 5800H, the hash index table: Register L is the entry code of the record.
530D
LD A,L 7D
Copy Register L (the entry code of the record) into Register A.
530E
AND D8H E6 D8
Mask Register A (the entry code) with D8H, bits 7, 6, 4 and 3: the Z FLAG is set for 00H-07H and 20H-27H, records 0 and 1 of sectors 2-9, the system files.
5310
If the Z FLAG is set (a system file's record), JUMP to 5347H to go on to the next record.
5312
LD A,(HL) 7E
Fetch the hash index byte at Register Pair HL into Register A.
5313
OR A B7
OR Register A (the index byte) with itself: the Z FLAG is set for 00H, a free record.
5314
If the Z FLAG is set (a free record), JUMP to 5347H to go on to the next record.
5316
LD B,L 45
Copy Register L (the entry code) into Register B, for 4B10H and 4B1FH.
5317
PUSH BC C5
Save Register Pair BC (Register B the entry code, Register C the drive) to the stack.
5318
LD A,L 7D
Copy Register L (the entry code) into Register A.
5319
AND E0H E6 E0
Mask Register A (the entry code) to bits 7-5: the record number times 32, its offset in the sector.
531B
LD L,A 6F
Copy Register A (the record's offset) into Register L.
531C
XOR B A8
Exclusive OR Register A with Register B (the entry code): Register A = bits 4-0, the directory sector less 2.
531D
CP FFH FE FF
Self-Modifying Code
Compare Register A (the sector less 2) against the sector already in 4200H: the operand 531EH is FFH in the file (no sector yet) and 5321H stores each sector read there.
531F
If the Z FLAG is set (the sector is in 4200H already), JUMP to 532AH without reading it.
5321
LD (531EH),A 32 1E 53
Store Register A (the sector less 2) to 531EH, the operand of CP at 531DH: the sector now in 4200H.
5324
GOSUB to 4B10H to read the directory sector of entry code Register B on drive Register C into 4200H; Register Pair HL returns the record's address.
5327
If the NZ FLAG is set (error 11H, DIRECTORY READ ERROR), JUMP to 5434H to display it and abort.
532A
LD H,42H 26 42
Load Register H with 42H: Register Pair HL = 4200H plus the offset in Register L, the record in the sector buffer.
532C
LD A,(HL) 7E
Fetch the attribute byte of the record at Register Pair HL into Register A.
532D
AND F8H E6 F8
Mask Register A (the attribute byte) to bits 7-3.
532F
CP 10H FE 10
Compare Register A against 10H: bit 4 (in use) set and bits 7 (extension record), 6 (system), 5 and 3 (invisible) clear.
5331
If the NZ FLAG is set (free, an extension record, a system or an invisible file), JUMP to 5343H and leave the record.
5333
LD A,L 7D
Copy Register L (the low byte of the record's address) into Register A.
5334
ADD A,10H C6 10
Add 10H to Register A: byte +10H of the record, the update password code.
5336
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +10H of the record.
5337
PUSH DE D5
Save Register Pair DE (Register D the directory cylinder from 5307H) to the stack, to free it for the code.
5338
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the code to give: the operand 5339H-533AH is 0000H in the file and 5300H stores the master password code (LOCK) or 4296H (UNLOCK) there.
533B
LD (HL),E 73
Store Register E (the low byte of the code) to +10H of the record at Register Pair HL.
533C
INC L 2C
Increment Register L to +11H of the record, the high byte of the update password code.
533D
LD (HL),D 72
Store Register D (the high byte of the code) to +11H at Register Pair HL: the update password code is set.
533E
INC L 2C
Increment Register L to +12H of the record, the low byte of the access password code.
533F
LD (HL),E 73
Store Register E (the low byte of the code) to +12H at Register Pair HL.
5340
INC L 2C
Increment Register L to +13H of the record, the high byte of the access password code.
5341
LD (HL),D 72
Store Register D (the high byte of the code) to +13H at Register Pair HL: the access password code is set too.
5342
POP DE D1
Restore Register Pair DE from the stack: Register D is the directory cylinder from 5307H again.
5343
POP BC C1
Restore Register Pair BC from the stack: Register B the entry code, Register C the drive.
5344
LD H,58H 26 58
Load Register H with 58H, the page of the hash index table.
5346
LD L,B 68
Copy Register B (the entry code) into Register L: Register Pair HL = the record's byte in the hash index table again.
5347
LD A,L 7D
Copy Register L (the entry code) into Register A.
5348
ADD A,20H C6 20
Add 20H to Register A: the next record of the same sector; the CARRY FLAG is set after record 7.
534A
LD L,A 6F
Copy Register A into Register L: the next entry code, or bits 4-0 alone after the carry.
534B
If the NC FLAG is set (records of the sector left), JUMP back to 530DH.
534D
LD A,(531EH) 3A 1E 53
Fetch the sector last read from 531EH (the operand of CP at 531DH) into Register A.
5350
XOR L AD
Exclusive OR Register A with Register L (the sector less 2 just walked): the Z FLAG is set when this sector was read into 4200H.
5351
If the NZ FLAG is set (the sector was not read), JUMP to 535BH: there is nothing to write.
5353
PUSH HL E5
Save Register Pair HL (Register L the sector less 2) to the stack.
5354
GOSUB to 4B1FH to write 4200H back to the directory sector of entry code Register B (the last record handled in it) on drive Register C, and read it back.
5357
If the NZ FLAG is set (error 12H, DIRECTORY WRITE ERROR, or 0FH), JUMP to 5434H to display it and abort.
535A
POP HL E1
Restore Register Pair HL from the stack: Register L the sector less 2.
535B
LD A,L 7D
Copy Register L (the sector less 2 just done) into Register A.
535C
INC L 2C
Increment Register L to the next sector, record 0.
535D
CP 1FH FE 1F
Compare Register A (the sector just done) against 1FH, the last of the 32 sectors the table covers.
535F
If the NZ FLAG is set (sectors left), JUMP back to 530DH.
5361
JUMP to 402DH, VTOS READY: the command is done.
5364H - Ask for and Check the Master Password
The text of MPW (from 5394H) or the 8 characters typed after MASTER PASSWORD ? are turned into their hash code; the allocation table of the drive is read into 5700H. The code C294H is accepted for every diskette; otherwise the code must equal the table's master password code at +CEH-+CFH (57CEH). Returns the Z FLAG with Register A = 00H and Register C = the drive; a wrong password ends with INVALID MASTER PASSWORD and the abort exit, a read error with error 14H.
5364
LD DE,(5394H) ED 5B 94 53
Load Register Pair DE with the MPW parameter's value from 5394H-5395H: 0000H (cleared at 521BH), FFFFH for MPW alone, or the address of the text.
5368
LD HL,53D8H 21 D8 53
Point Register Pair HL to 53D8H, the prompt MASTER PASSWORD ? for a password not given with a text.
536B
GOSUB to 5396H to get the 8 characters of the password (from the text at Register Pair DE or typed after the prompt at Register Pair HL, 53D8H) and their hash code into Register Pair HL.
536E
PUSH HL E5
Save Register Pair HL (the hash code of the password given) to the stack.
536F
LD C,00H 0E 00
Self-Modifying Code
Load Register C with the drive of the command: the operand 5370H is 00H in the file and 522DH stores the drive there.
5371
GOSUB to 5408H to read the allocation table of drive Register C into 5700H-57FFH.
5374
If the NZ FLAG is set (error 14H, GAT READ ERROR), JUMP to 538FH to display it and abort (the hash code stays on the stack; the abort exit resets the Stack Pointer).
5377
POP DE D1
Restore Register Pair DE from the stack: the hash code of the password given.
5378
LD HL,C294H 21 94 C2
Load Register Pair HL with C294H, a hash code accepted for every diskette.
537B
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the SBC below.
537C
SBC HL,DE ED 52
SUBtract Register Pair DE (the code given) from Register Pair HL (C294H): the Z FLAG is set when they are equal.
537E
RET Z C8
If the Z FLAG is set (the code is C294H), RETURN with the Z FLAG: the password is accepted.
537F
LD HL,(57CEH) 2A CE 57
Fetch the master password code of the diskette from 57CEH-57CFH (+CEH-+CFH of the table in 5700H) into Register Pair HL.
5382
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the SBC below.
5383
SBC HL,DE ED 52
SUBtract Register Pair DE (the code given) from Register Pair HL (the diskette's code): the Z FLAG is set when they are equal.
5385
RET Z C8
If the Z FLAG is set (the right master password), RETURN with the Z FLAG and Register A = 00H.
5386
LD HL,53F0H 21 F0 53
Point Register Pair HL to 53F0H, the text INVALID MASTER PASSWORD.
5389
GOSUB to 447BH to display the text at Register Pair HL (53F0H) and write it to the job log.
538C
JUMP to 4030H, the abort exit: the password was wrong and nothing has been changed.
538F
OR 40H F6 40
OR 40H into Register A (the error code 14H): bit 6 asks 4409H for the text alone; bit 7 clear means no return.
5391
JUMP to 4409H to display the error message of Register A (54H: GAT READ ERROR) and abort.
5394-5395
DEFS 2
Not in the file (the gap between the load blocks 52FEH-5393H and 5396H-5493H): the word of the MPW parameter. 521BH stores 0000H there, SYS1/SYS's 510FH (called at 5233H) stores FFFFH for MPW alone or the address of the text of MPW="text", and 5364H reads it.
5396H - Get a Text and Its Hash Code
Register Pair DE = a parameter's value (FFFFH, or the address of its text), Register Pair HL = the prompt. 539CH puts the 8 characters at 5600H; then RST 28H with Register A = E4H runs SYS2/SYS's 511EH (the hash code of the 8 characters at Register Pair DE) through the request handler, which drops the return address of RST 28H, so SYS2/SYS returns straight to the caller of 5396H with Register Pair HL = the hash code. The hash keeps Register C; a typed text leaves it 08H (the ROM's line input).
5396
GOSUB to 539CH to put the 8 characters of the text into 5600H-5607H; Register Pair DE returns 5600H.
5399
LD A,E4H 3E E4
Load Register A with E4H, the request of SYS2/SYS function 6 (its 511EH): the hash code of the 8 characters at Register Pair DE.
539B
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H, which loads SYS2/SYS at 4E00H (unless it is there) and runs it with Register Pair DE = 5600H. The return address of RST 28H is dropped, so SYS2/SYS returns to the caller of 5396H with Register Pair HL = the hash code.
539CH - Get 8 Characters From a Parameter or the Keyboard
Register Pair DE = a parameter's value, Register Pair HL = the prompt. With DE = 0000H or FFFFH (the patch code at 520DH) the prompt is displayed and at most 8 characters are read from the keyboard into 5600H (the ROM's line input, which returns Register B = the count and Register C = 08H). Otherwise up to 8 characters are copied from the text at Register Pair DE, ending at 0DH (the closing quote SYS1/SYS replaced), a comma or a double quote. The rest of the 8 is filled with spaces. Returns Register Pair DE = 5600H.
539C
LD A,D 7A
Copy Register D (the high byte of the parameter's value) into Register A.
539D
OR E B3
OR Register E (the low byte of the value) into Register A: the Z FLAG is set when Register Pair DE = 0000H.
539E
If the Z FLAG is set (Register Pair DE = 0000H), JUMP to 53BBH to display the prompt at Register Pair HL and read the text from the keyboard.
53A0
JUMP to 520DH, the patch code: FFFFH also goes to the prompt, an address goes to 53A3H. This JP is the patch line D28,37 of the distributor's manual.
53A3
LD B,08H 06 08
Load Register B with 08H, the most characters copied.
53A5
LD A,(DE) 1A
Fetch a character of the text at Register Pair DE into Register A.
53A6
CP 0DH FE 0D
Compare Register A (the character) against 0DH, the end SYS1/SYS's 510FH put in place of the closing double quote.
53A8
If the Z FLAG is set (0DH), JUMP to 53CFH to fill the rest with spaces.
53AA
CP 2CH FE 2C
Compare Register A (the character) against 2CH, a comma.
53AC
If the Z FLAG is set (a comma), JUMP to 53CFH to fill the rest with spaces.
53AE
CP 22H FE 22
Compare Register A (the character) against 22H, a double quote.
53B0
If the Z FLAG is set (a double quote), JUMP to 53CFH to fill the rest with spaces.
53B2
INC DE 13
Increment Register Pair DE to the next character of the text.
53B3
LD (HL),A 77
Store Register A (the character) to the buffer at Register Pair HL.
53B4
INC HL 23
Increment Register Pair HL to the next byte of the buffer.
53B5
Decrement Register B (the characters left of the 8) and JUMP back to 53A5H until Register B is 00H.
53B7
LD DE,5600H 11 00 56
Point Register Pair DE to 5600H, the 8 characters.
53BA
RET C9
RETURN with Register Pair DE = 5600H, the 8 characters copied from the text.
53BB
GOSUB to 4467H to display the prompt at Register Pair HL (ended by 03H, with the cursor left after its spaces).
53BE
LD B,08H 06 08
Load Register B with 08H, the most characters that can be typed.
53C0
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the buffer for the typed text.
53C3
GOSUB to the ROM's 0040H to read a line of at most Register B (8) characters into the buffer at Register Pair HL (5600H), ended by 0DH: Register Pair HL returns 5600H, Register B the count typed, Register C 08H. The CARRY FLAG of BREAK is not tested.
53C6
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair DE = 5600H, the buffer.
53C7
LD H,00H 26 00
Load Register H with 00H, the high byte of the count.
53C9
LD L,B 68
Copy Register B (the count typed) into Register L: Register Pair HL = the count.
53CA
ADD HL,DE 19
Add Register Pair DE (5600H) to Register Pair HL: Register Pair HL = the byte after the text, the 0DH the ROM stored.
53CB
LD A,09H 3E 09
Load Register A with 09H: the 8 characters plus the 0DH. This operand is the patch line D28,63 of the distributor's manual.
53CD
SUB B 90
SUBtract Register B (the count typed) from Register A: Register A = 9 less the count, 1-9.
53CE
LD B,A 47
Copy Register A into Register B: the bytes to fill with spaces, from the 0DH up to 5608H.
53CF
LD (HL),20H 36 20
Store a space (20H) at Register Pair HL. Rows 53A8H, 53ACH and 53B0H come here with Register B = the characters left of the 8.
53D1
INC HL 23
Increment Register Pair HL to the next byte of the buffer.
53D2
Decrement Register B (the bytes left to fill) and JUMP back to 53CFH until Register B is 00H.
53D4
LD DE,5600H 11 00 56
Point Register Pair DE to 5600H, the 8 characters.
53D7
RET C9
RETURN with Register Pair DE = 5600H, the 8 characters padded with spaces.
53D8-53EE
DEFM "MASTER PASSWORD ? " 4D 41 53 54 45 52 20 50 41 53 53 57 4F 52 44 20 3F 20 20 20 20 20 20
The prompt MASTER PASSWORD ? and 6 spaces, displayed by 53BBH for 5364H: the typed password starts in column 23.
53EF
DEFB 03H 03
The 03H that ends the prompt at 53D8H without a carriage return (4467H does not display it).
53F0-5407
DEFM "INVALID MASTER PASSWORD" / DEFB 0DH 49 4E 56 41 4C 49 44 20 4D 41 53 54 45 52 20 50 41 53 53 57 4F 52 44 0D
The message INVALID MASTER PASSWORD and the carriage return that ends it, displayed and logged by 5386H-5389H.
5408H - Read the Allocation Table
Reads sector 0 of the directory cylinder of drive Register C (the granule allocation table) into 5700H-57FFH. Register Pairs DE and HL are kept. Returns the Z FLAG when read; otherwise the NZ FLAG and Register A = 14H, GAT READ ERROR.
5408
PUSH DE D5
Save Register Pair DE (the caller's) to the stack.
5409
PUSH HL E5
Save Register Pair HL (the caller's) to the stack.
540A
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
540D
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder: the allocation table.
540F
LD HL,5700H 21 00 57
Point Register Pair HL to 5700H, the buffer for the allocation table.
5412
GOSUB to 4B45H to read cylinder Register D, sector Register E (00H) of drive Register C into 5700H at Register Pair HL; the Z FLAG for a sector with the directory data mark.
5415
POP HL E1
Restore Register Pair HL (the caller's) from the stack.
5416
POP DE D1
Restore Register Pair DE (the caller's) from the stack.
5417
RET Z C8
If the Z FLAG is set (read), RETURN with the Z FLAG.
5418
LD A,14H 3E 14
Load Register A with 14H, the error code GAT READ ERROR.
541A
RET C9
RETURN with the NZ FLAG and Register A = 14H.
541BH - Write the Allocation Table
Writes 5700H-57FFH to sector 0 of the directory cylinder of drive Register C with the directory data mark (4768H) and reads it back without storing (4772H): a sector with that mark reads back with the driver result 06H. Register Pairs DE and HL are kept. Returns the Z FLAG when written and checked, else the NZ FLAG; Register A = 15H (GAT WRITE ERROR) in both cases.
541B
PUSH DE D5
Save Register Pair DE (the caller's) to the stack.
541C
PUSH HL E5
Save Register Pair HL (the caller's) to the stack.
541D
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
5420
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder: the allocation table.
5422
LD HL,5700H 21 00 57
Point Register Pair HL to 5700H, the allocation table to write.
5425
GOSUB to 4768H to write the buffer at Register Pair HL (5700H) to cylinder Register D, sector Register E (00H) of drive Register C with the data mark FAH.
5428
If the NZ FLAG is set (the write failed), JUMP to 542FH with the NZ FLAG.
542A
GOSUB to 4772H to read the sector at Register Pair DE back without storing it: Register A = 06H for a sector with the directory data mark.
542D
CP 06H FE 06
Compare Register A (the result of the read back) against 06H: the Z FLAG is set when the sector was written correctly.
542F
LD A,15H 3E 15
Load Register A with 15H, the error code GAT WRITE ERROR. LD does not change the flags.
5431
POP HL E1
Restore Register Pair HL (the caller's) from the stack.
5432
POP DE D1
Restore Register Pair DE (the caller's) from the stack.
5433
RET C9
RETURN with the Z FLAG (written) or the NZ FLAG, Register A = 15H.
5434H - Error Exits and Messages
5434H shows a disk error code in Register A as text alone and aborts; 5439H, 5452H and 5483H display one of the member's messages and take the abort exit 4030H.
5434
OR 40H F6 40
OR 40H into Register A (the error code): bit 6 asks 4409H for the text alone; bit 7 clear means no return.
5436
JUMP to 4409H to display the error message of Register A and abort.
5439
LD HL,5442H 21 42 54
Point Register Pair HL to 5442H, the text PARAMETER ERROR.
543C
GOSUB to 447BH to display the text at Register Pair HL (5442H) and write it to the job log.
543F
JUMP to 4030H, the abort exit, after the message PARAMETER ERROR.
5442-5451
DEFM "PARAMETER ERROR" / DEFB 0DH 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52 0D
The message PARAMETER ERROR and its carriage return, shown by 5439H when SYS1/SYS's 510FH refuses the parameter list.
5452
LD HL,545BH 21 5B 54
Point Register Pair HL to 545BH, the text INVALID COMMAND DURING PROGRAM CHAINING.
5455
GOSUB to 447BH to display the text at Register Pair HL (545BH) and write it to the job log.
5458
JUMP to 4030H, the abort exit, after the message about program chaining.
545B-5482
DEFM "INVALID COMMAND DURING PROGRAM CHAINING" / DEFB 0DH 49 4E 56 41 4C 49 44 20 43 4F 4D 4D 41 4E 44 20 44 55 52 49 4E 47 20 50 52 4F 47 52 41 4D 20 43 48 41 49 4E 49 4E 47 0D
The message INVALID COMMAND DURING PROGRAM CHAINING and its carriage return, shown by 5452H when 430FH bit 5 is set.
5483
LD HL,548CH 21 8C 54
Point Register Pair HL to 548CH, the text -NOTHING DONE-.
5486
GOSUB to 447BH to display the text at Register Pair HL (548CH) and write it to the job log.
5489
JUMP to 4030H, the abort exit, after the message -NOTHING DONE-.
548C-549A
DEFM "-NOTHING DONE-" / DEFB 0DH 2D 4E 4F 54 48 49 4E 47 20 44 4F 4E 45 2D 0D
The message -NOTHING DONE- (a minus sign at each end) and its carriage return, shown by 5483H when none of PW, LOCK, UNLOCK and NAME was given.
549B-54B1
DEFM "NEW DISK PACK NAME ? " 4E 45 57 20 44 49 53 4B 20 50 41 43 4B 20 4E 41 4D 45 20 3F 20 20 20
The prompt NEW DISK PACK NAME ? and 3 spaces, displayed by 53BBH for NAME (5255H): the typed name starts in column 23.
54B2
DEFB 03H 03
The 03H that ends the prompt at 549BH without a carriage return.
54B3-54C9
DEFM "NEW MASTER PASSWORD ? " 4E 45 57 20 4D 41 53 54 45 52 20 50 41 53 53 57 4F 52 44 20 3F 20 20
The prompt NEW MASTER PASSWORD ? and 2 spaces, displayed by 53BBH for PW (526DH): the typed password starts in column 23.
54CA
DEFB 03H 03
The 03H that ends the prompt at 54B3H without a carriage return.
54CB-54F3
DEFM "NOTE: FILE 'DIR/SYS' IS NOW READ ENABLED" / DEFB 0DH 4E 4F 54 45 3A 20 46 49 4C 45 20 27 44 49 52 2F 53 59 53 27 20 49 53 20 4E 4F 57 20 52 45 41 44 20 45 4E 41 42 4C 45 44 0D
The note NOTE: FILE 'DIR/SYS' IS NOW READ ENABLED and its carriage return, shown by 52E3H after DIR/SYS's access password code was set to 4296H.
54F4H - The Parameter Table
Five entries of 8 bytes for SYS1/SYS's 510FH (called at 5233H): 6 characters of the name, padded with spaces, then the address of the word that receives the value. A name must be typed in full (50BCH needs a space in the table where the typed word ends). The 00H at 551CH ends the table.
54F4-54FB
DEFM "PW " / DEFW 5267H 50 57 20 20 20 20 67 52
Entry PW: the new master password; its value goes to 5267H-5268H, the operand of LD DE at 5266H.
54FC-5503
DEFM "LOCK " / DEFW 52EDH 4C 4F 43 4B 20 20 ED 52
Entry LOCK: give every user file the master password; its value goes to 52EDH-52EEH, the operand of LD DE at 52ECH.
5504-550B
DEFM "UNLOCK" / DEFW 52F7H 55 4E 4C 4F 43 4B F7 52
Entry UNLOCK: take the passwords off every user file; its value goes to 52F7H-52F8H, the operand of LD DE at 52F6H.
550C-5513
DEFM "NAME " / DEFW 524FH 4E 41 4D 45 20 20 4F 52
Entry NAME: the new diskette name; its value goes to 524FH-5250H, the operand of LD DE at 524EH.
5514-551B
DEFM "MPW " / DEFW 5394H 4D 50 57 20 20 20 94 53
Entry MPW: the current master password; its value goes to 5394H-5395H, the word between the load blocks that 5364H reads.
551C
DEFB 00H 00
The 00H that ends the parameter table at 54F4H.
5600-5608
DEFS 9
Not in the file: the text buffer of 539CH. 53A3H-53B5H copy up to 8 characters of a parameter's text here, the ROM's line input (53C3H) stores up to 8 typed characters and a 0DH, and 53CFH fills the rest with spaces (up to 5608H after a typed text). 525BH copies 5600H-5607H to the name field and SYS2/SYS's 511EH (539BH) hashes them.
5700-57FF
DEFS 256
Not in the file: the granule allocation table of the drive, read by 5408H (5412H) and written by 541BH (5425H). PROT reads +CBH (57CBH), the lockout bytes 57A6H, 5788H and 5783H and the master password code 57CEH-57CFH, and writes the name 57D0H-57D7H, the code 57CEH-57CFH and +CCH (57CCH).
5800-58FF
DEFS 256
Not in the file: the hash index table (directory sector 1) read at 527EH, one byte per directory entry code. 52C1H may change 5801H (DIR/SYS's byte) and 52C4H writes the sector back; 530AH-535FH walk it for LOCK and UNLOCK.
5200H - Member 20 (RENAME, Code 53H): Read the Two Specifications
SYS1/SYS's command interpreter runs this member for the word RENAME (member code 53H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL at the rest of the command line. The old file specification is read into the control block 539AH and the new one into 53BAH (a preposition such as TO between them is passed over by 441CH). The new specification takes the name, extension and password it lacks from the old one (52C0H) and always the old file's drive (5243H-526CH). The old file is opened (its access level must be 0-2), the new name must not be found on that drive, and then the directory record gets the new name and extension and the hash index the new name's hash code. The flags of the entry (NZ after a load error of the member) are not tested.
5200
LD DE,539AH 11 9A 53
Point Register Pair DE to 539AH, the control block of the old file (32 bytes past the end of the member, not in the file).
5203
GOSUB to 441CH (SYS1/SYS function 4, its 4FCEH) to copy the file specification at Register Pair HL into the block at Register Pair DE as text ended by 03H. It returns the Z FLAG when one was read, with Register Pair HL past it and the character that ended it (a 0DH or 03H is not passed over); Register Pair DE = 539AH again.
5206
If the NZ FLAG is set (no file specification), JUMP to 5320H to display FILE SPEC REQUIRED and abort.
5209
LD A,(DE) 1A
Fetch the first character of the specification at Register Pair DE (539AH) into Register A.
520A
CP 2AH FE 2A
Compare Register A against 2AH, an asterisk: a device specification, which cannot be renamed.
520C
If the Z FLAG is set (a device), JUMP to 5320H to display FILE SPEC REQUIRED and abort.
520F
LD DE,53BAH 11 BA 53
Point Register Pair DE to 53BAH, the control block of the new name (32 bytes past the first block).
5212
GOSUB to 441CH (SYS1/SYS 4FCEH) to copy the next file specification at Register Pair HL into the block at Register Pair DE (53BAH): the Z FLAG when a good specification was read (a name, or an asterisk and a device name); the NZ FLAG when it starts with no name, or when a period or a colon in it is followed by no password or drive.
5215
If the Z FLAG is set (a good specification was read into 53BAH), JUMP to 521DH.
5217
DEC HL 2B
Decrement Register Pair HL by one character. 441CH read no good specification: when a slash, a period or a colon stood first (the new specification gives only an extension, a password or a drive), or ended an empty password or drive, it has passed over that character, so Register Pair HL is back on it; when the line ended there (0DH, which 441CH does not pass over) Register Pair HL is now on the character before the end of the line.
5218
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of the control block.
521B
LDIR ED B0
Copy 32 bytes of the command line from Register Pair HL to the block at Register Pair DE (53BAH) with LDIR: the new specification as typed, such as /TXT, which 52C0H completes from the old one. Register Pair HL ends 32 bytes on, Register Pair DE at 53DAH, Register Pair BC at 0000H.
521D
LD A,(53BAH) 3A BA 53
Fetch the first byte of the new specification from 53BAH into Register A.
5220
CP 0EH FE 0E
Compare Register A (the first byte of the new specification) against 0EH: the C FLAG is set for a control character such as 03H or 0DH, nothing given.
5222
If the C FLAG is set (no new specification), JUMP to 533CH to display RENAME IT TO WHAT? and abort.
5225
LD HL,539AH 21 9A 53
Point Register Pair HL to 539AH, the old specification as text.
5228
LD DE,53BAH 11 BA 53
Point Register Pair DE to 53BAH, the new specification as text.
522B
GOSUB to 52C0H to put the name, the extension and the password the new specification at Register Pair DE lacks into it, from the old specification at Register Pair HL. It returns Register Pair HL at a place in the old text and Register B = 2EH.
522EH - Open the Old File and Check the Drive
The old file is opened (request 94H, SYS2/SYS, which stays in memory at 4E00H-51FFH for the rest of the command). The control block is then filled in: 539BH (+01H) holds the access level in bits 2-0, 53A0H (+06H) the drive, 53A1H (+07H) the directory entry code. A drive given in the new specification must be the old file's; when none is given, a colon and the old file's drive digit are put at the end of the new text, so that the test for the new name below searches that drive only.
522E
LD DE,539AH 11 9A 53
Point Register Pair DE to 539AH, the control block of the old file, holding its specification as text.
5231
GOSUB to 4424H (request 94H, SYS2/SYS 4E69H) to open the file of the block at Register Pair DE. Register Pair HL (a place in the old text, left by 52C0H) becomes the buffer address and Register B (2EH) the record length in the block; RENAME reads nothing from the file, so neither is used. It returns the Z FLAG when the file was found and its password is good, else the NZ FLAG with the error code in Register A.
5234
If the NZ FLAG is set (the old file cannot be opened: 13H, 18H, 19H, 20H and others), JUMP to 531BH to show the error of Register A and abort.
5237
LD A,(539BH) 3A 9B 53
Fetch byte +01H of the opened control block from 539BH into Register A: bits 2-0 the access level the password gave (0 for the full access).
523A
AND 07H E6 07
Mask Register A to bits 2-0 (AND 07H), the access level.
523C
CP 03H FE 03
Compare Register A (the access level) against 03H: the C FLAG is set for the levels 0, 1 and 2, which allow a rename.
523E
LD A,25H 3E 25
Load Register A with 25H, the error code ILLEGAL ACCESS ATTEMPTED TO PROTECTED FILE; LD does not change the flags of the comparison.
5240
If the NC FLAG is set (level 3 or higher), JUMP to 531BH to show error 25H in Register A and abort.
5243
LD HL,53BAH 21 BA 53
Point Register Pair HL to 53BAH, the new specification as text (now completed by 52C0H).
5246
LD A,(HL) 7E
Loop Start
Fetch a character of the new specification from Register Pair HL into Register A.
5247
INC HL 23
Increment Register Pair HL to the next character of the new specification.
5248
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line (the end of a specification the LDIR at 521BH copied).
524A
If the Z FLAG is set (the end of the text, no drive given), JUMP to 525FH to put the old file's drive at the end.
524C
CP 03H FE 03
Compare Register A against 03H, the end of a specification 441CH copied.
524E
If the Z FLAG is set (the end of the text, no drive given), JUMP to 525FH to put the old file's drive at the end.
5250
CP 3AH FE 3A
Compare Register A against 3AH, a colon: a drive follows.
5252
If the NZ FLAG is set (not a colon), JUMP back to 5246H for the next character at Register Pair HL.
5254
LD A,(53A0H) 3A A0 53
Fetch byte +06H of the opened control block from 53A0H into Register A: the drive of the old file.
5257
XOR (HL) AE
Exclusive OR Register A (the old file's drive) with the character at Register Pair HL, the drive digit after the colon.
5258
AND 07H E6 07
Mask Register A to bits 2-0 (AND 07H): the Z FLAG is set when the digit names the old file's drive (only bits 2-0 of the digit are compared).
525A
If the NZ FLAG is set (another drive), JUMP to 5358H to display ILLEGAL DRIVE SPECIFICATION and abort: a file cannot be renamed onto another drive.
525D
JUMP to 526EH: the new specification names the old file's drive already.
525F
DEC HL 2B
Decrement Register Pair HL back onto the 0DH or 03H that ends the new specification.
5260
LD (HL),3AH 36 3A
Store 3AH, a colon, at Register Pair HL, over the end of the text.
5262
INC HL 23
Increment Register Pair HL to the place of the drive digit.
5263
LD A,(53A0H) 3A A0 53
Fetch byte +06H of the opened control block from 53A0H into Register A: the drive of the old file.
5266
AND 07H E6 07
Mask Register A to bits 2-0 (AND 07H), the drive 0-7.
5268
ADD A,30H C6 30
Add 30H to Register A: the drive as a digit character.
526A
LD (HL),A 77
Store Register A (the drive digit) at Register Pair HL, after the colon.
526B
INC HL 23
Increment Register Pair HL to the byte after the drive digit.
526C
LD (HL),0DH 36 0D
Store 0DH at Register Pair HL: the new specification now ends with a colon and the old file's drive.
526EH - The New Name Must Not Exist
The new specification is opened in the control block 53BAH. Found (the Z FLAG) means a file of that name is on the drive: DUPLICATE FILE NAME. Error 18H (FILE NOT IN DIRECTORY) is the good case; any other error is shown. SYS2/SYS's split of the new specification (its 5050H) leaves the new name and extension, padded with spaces, at 51E8H-51F2H for 5294H.
526E
LD HL,(51DEH) 2A DE 51
Fetch the word at 51DEH-51DFH (SYS2/SYS's work cell of the name hash code, both bytes the code of the old name from the open at 5231H) into Register Pair HL.
5271
PUSH HL E5
Save Register Pair HL (the old name's hash code) to the stack.
5272
LD DE,53BAH 11 BA 53
Point Register Pair DE to 53BAH, the control block of the new name, holding the completed new specification.
5275
GOSUB to 4424H (request 94H, SYS2/SYS 4E69H) to open the new specification at Register Pair DE; Register Pair HL (the hash word) is the buffer address and Register B the record length, both unused. The open stores the new name's hash code at 51DEH.
5278
POP HL E1
Restore Register Pair HL from the stack: the old name's hash code. POP does not change the flags of the open.
5279
LD (51DEH),HL 22 DE 51
Store Register Pair HL (the old name's hash code) back to 51DEH-51DFH. Nothing reads it there before 52BDH stores the new name's code over it.
527C
If the Z FLAG is set (a file of the new name exists on the drive), JUMP to 537DH to display DUPLICATE FILE NAME and abort.
527F
CP 18H FE 18
Compare Register A (the error of the open) against 18H, FILE NOT IN DIRECTORY: the new name is free.
5281
If the NZ FLAG is set (another error, such as 13H ILLEGAL FILE NAME, or 19H FILE ACCESS DENIED for an existing file of the new name with another password), JUMP to 531BH to show the error of Register A and abort.
5284H - Write the New Name
The old file's directory record gets the new name and extension at +05H-+0FH; its other bytes (attributes, passwords, extents) stay. Then the record's byte of the hash index (at its entry code) gets the hash code of the new name.
5284
LD BC,(53A0H) ED 4B A0 53
Load Register Pair BC from 53A0H-53A1H, bytes +06H and +07H of the old file's control block: Register C = the drive, Register B = the directory entry code of the file's record.
5288
PUSH BC C5
Save Register Pair BC (the drive and the entry code) to the stack: the LDIR below clears Register Pair BC.
5289
GOSUB to 4B10H (SYS0/SYS) to read the directory sector of entry code Register B on drive Register C into 4200H: Register Pair HL = the record; the NZ FLAG with Register A = 11H when it cannot be read.
528C
If the NZ FLAG is set (error 11H, DIRECTORY READ ERROR, in Register A), JUMP to 531BH to show it and abort.
528F
LD D,H 54
Copy Register H (42H, the page of the sector buffer) into Register D.
5290
LD A,L 7D
Copy Register L (the offset of the record in 4200H: 00H, 20H, up to E0H) into Register A.
5291
ADD A,05H C6 05
Add 05H to Register A: the offset of the record's byte +05H, the name.
5293
LD E,A 5F
Copy Register A into Register E: Register Pair DE = the name of the record in 4200H.
5294
LD HL,51E8H 21 E8 51
Point Register Pair HL to 51E8H, SYS2/SYS's work area holding the new name (8 characters) and extension (3 characters), padded with spaces, from the open at 5275H.
5297
LD BC,000BH 01 0B 00
Load Register Pair BC with 000BH, the 11 characters of the name and extension.
529A
LDIR ED B0
Copy the 11 bytes from 51E8H at Register Pair HL to the record's +05H-+0FH at Register Pair DE (LDIR): the record now has the new name and extension. Register Pair BC ends at 0000H.
529C
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive, Register B = the entry code.
529D
GOSUB to 4B1FH (SYS0/SYS) to write 4200H back to the directory sector of entry code Register B on drive Register C and read it back: the NZ FLAG with Register A = 12H (DIRECTORY WRITE ERROR) or 0FH (WRITE PROTECTED DISK) when it fails.
52A0
If the NZ FLAG is set (the write failed), JUMP to 531BH to show the error of Register A and abort.
52A3
GOSUB to 51B5H in SYS2/SYS (in memory at 4E00H-51FFH since the open at 5231H) to read the hash index (sector 1 of the directory cylinder) of drive Register C into 4200H: Register Pair HL = 4200H, the NZ FLAG with Register A = 16H when it cannot be read; Register Pairs BC and DE are kept.
52A6
If the NZ FLAG is set (error 16H, HIT READ ERROR), JUMP to 531BH to show the error of Register A and abort.
52A9
LD D,H 54
Copy Register H (42H, from Register Pair HL = 4200H) into Register D.
52AA
LD E,B 58
Copy Register B (the directory entry code of the record) into Register E: Register Pair DE = the byte of the hash index that belongs to the record.
52AB
PUSH BC C5
Save Register Pair BC (the drive and the entry code) to the stack: the hash code request uses Register B.
52AC
LD HL,51E8H 21 E8 51
Point Register Pair HL to 51E8H, the new name and extension (11 characters) in SYS2/SYS's work area.
52AF
GOSUB to 52BDH to compute the hash code of the 11 characters at Register Pair HL: Register A = the code (never 00H), also stored at 51DEH-51DFH.
52B2
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive, Register B = the entry code.
52B3
LD (DE),A 12
Store Register A (the new name's hash code) to the record's byte of the hash index at Register Pair DE.
52B4
GOSUB to 51C7H in SYS2/SYS to write the hash index at 4200H to sector 1 of the directory cylinder of drive Register C and read it back: the NZ FLAG with Register A = 17H when it fails.
52B7
If the NZ FLAG is set (error 17H, HIT WRITE ERROR), JUMP to 531BH to show the error of Register A and abort.
52BA
JUMP to 402DH, VTOS READY: the file has its new name.
52BDH - Hash Code of a Name
Register Pair HL = 11 characters (name and extension). Request D4H runs SYS2/SYS function 5 (its 50CBH), already in memory; the request handler drops the return address of RST 28H, so the result comes back to the caller of 52BDH: Register A = the code (never 00H), Registers H and L = the code, 51DEH-51DFH = the code.
52BD
LD A,D4H 3E D4
Load Register A with D4H, SYS2/SYS function 5, the hash code of a name.
52BF
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H, which runs SYS2/SYS with Register A = D4H and returns to 52B2H, the caller of 52BDH.
52C0H - Complete the New Specification
Register Pair HL = the old specification as text (539AH), Register Pair DE = the new one (53BAH). A new specification that does not start with a letter gets the old name in front (52FBH). Then each of the extension (a slash) and the password (a period) that the new text lacks is copied from the old text when the old one has it. Every copied character is put in at Register Pair DE and the rest of the new text, up to its 03H or 0DH, moves one place up (5307H). The drive is not handled here (5243H). Returns Register Pair DE = 53BAH, Register Pair HL = the place after the old name when the name was copied (else 539AH), Register B = 2EH.
52C0
PUSH DE D5
Save Register Pair DE (53BAH, the start of the new text) to the stack.
52C1
LD A,(DE) 1A
Fetch the first character of the new specification at Register Pair DE into Register A.
52C2
CP 41H FE 41
Compare Register A against 41H, the letter A: the C FLAG is set for a character below it, such as a slash, a period or a colon.
52C4
If the C FLAG is set (the new specification has no name, or a name that starts with a digit, which is taken as none), GOSUB to 52FBH to copy the old name from Register Pair HL in front of the new text at Register Pair DE.
52C7
LD B,2FH 06 2F
Load Register B with 2FH, a slash, the separator of the extension.
52C9
GOSUB to 52D4H to find the extension in the new text at Register Pair DE, or copy the old one from Register Pair HL into it.
52CC
LD B,2EH 06 2E
Load Register B with 2EH, a period, the separator of the password.
52CE
GOSUB to 52D4H to find the password in the new text at Register Pair DE, or copy the old one from Register Pair HL into it.
52D1
POP DE D1
Restore Register Pair DE from the stack: 53BAH, the start of the new text.
52D2
RET C9
RETURN to 522EH with the new specification complete but for the drive.
52D3H - Find a Field or Copy It
Register B = the separator of the field (2FH a slash, 2EH a period), Register Pair DE = the place in the new text, Register Pair HL = the place in the old text. The letters and digits at Register Pair DE are passed over; the separator then means the field is there (Register Pair DE past it). Any other character (the end of the text, another separator) means it is missing: the old text is searched from Register Pair HL for the separator, and when it is there the separator and the field's letters and digits are put in at Register Pair DE. Register Pair HL is kept.
52D3
INC DE 13
Increment Register Pair DE past a letter or digit of the new text. 52DAH and 52E2H come back here.
52D4
LD A,(DE) 1A
Loop Start
Fetch the character of the new text at Register Pair DE into Register A.
52D5
CP B B8
Compare Register A against Register B, the separator of the field.
52D6
If the Z FLAG is set (the separator: the field is in the new text), JUMP to 52E6H.
52D8
CP 41H FE 41
Compare Register A against 41H, the letter A: the NC FLAG is set for a letter.
52DA
If the NC FLAG is set (41H or above, a letter), JUMP back to 52D3H to pass over it.
52DC
CP 30H FE 30
Compare Register A against 30H, the digit 0: the C FLAG is set below it.
52DE
If the C FLAG is set (below 30H: 03H, 0DH, the other separator, an exclamation mark), JUMP to 52E8H: the field is missing.
52E0
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9: the C FLAG is set for a digit.
52E2
If the C FLAG is set (a digit), JUMP back to 52D3H to pass over it.
52E4
JUMP to 52E8H: Register A is 3AH-40H (the colon of a drive), the field is missing.
52E6
INC DE 13
Increment Register Pair DE past the separator, to the field in the new text.
52E7
RET C9
RETURN with the field found in the new text and nothing copied.
52E8
PUSH HL E5
Save Register Pair HL (the place in the old text) to the stack: the search below moves Register Pair HL.
52E9
LD A,(HL) 7E
Fetch a character of the old text at Register Pair HL into Register A.
52EA
INC HL 23
Increment Register Pair HL to the next character of the old text.
52EB
CP 03H FE 03
Compare Register A against 03H, the end of the old specification.
52ED
If the Z FLAG is set (the end: the old one has no such field either), JUMP to 52F9H with nothing copied.
52EF
CP 0DH FE 0D
Compare Register A against 0DH, an end of a line.
52F1
If the Z FLAG is set (the end), JUMP to 52F9H with nothing copied.
52F3
CP B B8
Compare Register A against Register B, the separator of the field.
52F4
If the NZ FLAG is set (not the separator), JUMP back to 52E9H for the next character at Register Pair HL.
52F6
GOSUB to 5307H to put the separator in Register A into the new text at Register Pair DE, then the letters and digits of the field that follow it at Register Pair HL.
52F9
POP HL E1
Restore Register Pair HL from the stack: the place in the old text as it was before the search.
52FA
RET C9
RETURN to 52CCH (after the extension) or to 52D1H (after the password), with Register Pair HL kept.
52FBH - Copy Letters and Digits Into the New Text
Register Pair HL = the old text, Register Pair DE = the place in the new text. Each letter or digit at Register Pair HL (30H-39H, 41H and up) is put in at Register Pair DE, both move on; the first other character ends it, with Register Pair HL left on it. 5307H puts one character, Register A, into the new text: the bytes from Register Pair DE up to its 03H or 0DH move one place up.
52FB
LD A,(HL) 7E
Fetch the character of the old text at Register Pair HL into Register A.
52FC
CP 30H FE 30
Compare Register A against 30H, the digit 0: the C FLAG is set below it.
52FE
RET C D8
If the C FLAG is set (a slash, a period, 03H or another character below 30H), RETURN: the field has been copied (to 52C7H after the name, to 52F9H after an extension or password).
52FF
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9: the C FLAG is set for a digit.
5301
If the C FLAG is set (a digit), JUMP to 5306H to copy it.
5303
CP 41H FE 41
Compare Register A against 41H, the letter A: the C FLAG is set for 3AH-40H.
5305
RET C D8
If the C FLAG is set (3AH-40H, the colon of a drive), RETURN: the field has been copied (to 52C7H or 52F9H, as at 52FEH).
5306
INC HL 23
Increment Register Pair HL past the character in Register A, in the old text.
5307
PUSH HL E5
Save Register Pair HL (the place in the old text) to the stack. 52F6H comes here with Register A = the separator.
5308
LD H,D 62
Copy Register D into Register H, the high byte of the place in the new text.
5309
LD L,E 6B
Copy Register E into Register L: Register Pair HL = Register Pair DE, the place where Register A goes in.
530A
LD C,(HL) 4E
Loop Start
Fetch the character of the new text at Register Pair HL into Register C, to move it up one place.
530B
LD (HL),A 77
Store Register A (the character put in, or the one moved up) to the new text at Register Pair HL.
530C
INC HL 23
Increment Register Pair HL to the next place of the new text.
530D
LD A,C 79
Copy Register C (the character taken from that place) into Register A, to be stored one place higher.
530E
CP 03H FE 03
Compare Register A against 03H, the end of a specification.
5310
If the Z FLAG is set (03H, the end), JUMP to 5316H to store it.
5312
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
5314
If the NZ FLAG is set (not the end), JUMP back to 530AH to move the next character at Register Pair HL.
5316
LD (HL),A 77
Store Register A (the 03H or 0DH) at Register Pair HL: the new text now ends one place higher.
5317
POP HL E1
Restore Register Pair HL from the stack: the place in the old text.
5318
INC DE 13
Increment Register Pair DE past the character put in.
5319
JUMP back to 52FBH for the next character of the old text at Register Pair HL.
531BH - Error Exit
Register A = an error code from an open (5234H, 5281H), 25H (5240H), 11H (528CH), 12H or 0FH (52A0H), 16H (52A6H) or 17H (52B7H).
531B
OR 40H F6 40
OR 40H into Register A (the error code): bit 6 asks for the text of the error alone; bit 7 stays clear, so the error message is followed by the abort exit.
531D
JUMP to 4409H to display the error message of Register A (request 86H, SYS4/SYS), then the abort exit 4030H.
5320H - The Messages of RENAME
Each message is displayed and written to the job log by 447BH, then the command ends at 4030H, the abort exit.
5320
LD HL,5329H 21 29 53
Point Register Pair HL to 5329H, the text FILE SPEC REQUIRED.
5323
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
5326
JUMP to 4030H, the abort exit of VTOS: the command ends here.
5329-533A
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5320H: no file specification, or a device, was given first.
533B
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED.
533C
LD HL,5345H 21 45 53
Point Register Pair HL to 5345H, the text RENAME IT TO WHAT?.
533F
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
5342
JUMP to 4030H, the abort exit of VTOS: the command ends here.
5345-5356
DEFM "RENAME IT TO WHAT?" 52 45 4E 41 4D 45 20 49 54 20 54 4F 20 57 48 41 54 3F
The message of 533CH: the new specification starts with a control character (5220H).
5357
DEFB 0DH 0D
The carriage return that ends the message RENAME IT TO WHAT?.
5358
LD HL,5361H 21 61 53
Point Register Pair HL to 5361H, the text ILLEGAL DRIVE SPECIFICATION.
535B
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
535E
JUMP to 4030H, the abort exit of VTOS: the command ends here.
5361-537B
DEFM "ILLEGAL DRIVE SPECIFICATION" 49 4C 4C 45 47 41 4C 20 44 52 49 56 45 20 53 50 45 43 49 46 49 43 41 54 49 4F 4E
The message of 5358H: the new specification names a drive other than the old file's.
537C
DEFB 0DH 0D
The carriage return that ends the message ILLEGAL DRIVE SPECIFICATION.
537D
LD HL,5386H 21 86 53
Point Register Pair HL to 5386H, the text DUPLICATE FILE NAME.
5380
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
5383
JUMP to 4030H, the abort exit of VTOS: the command ends here.
5386-5398
DEFM "DUPLICATE FILE NAME" 44 55 50 4C 49 43 41 54 45 20 46 49 4C 45 20 4E 41 4D 45
The message of 537DH: a file of the new name is on the drive already.
5399
DEFB 0DH 0D
The carriage return that ends the message DUPLICATE FILE NAME.
539AH - The Two Control Blocks
Not in the file: 64 bytes after the last loaded byte.
539A-53B9
DEFS 32
Not in the file: the control block of the old file. 5203H copies the old specification here as text (441CH), 52C0H reads it, the open at 5231H fills it in as an open control block: 539BH (+01H, the access level, read at 5237H), 53A0H (+06H, the drive, read at 5254H, 5263H, 5284H) and 53A1H (+07H, the directory entry code, read at 5284H).
53BA-53D9
DEFS 32
Not in the file: the control block of the new name. 5212H copies the new specification here (441CH), or the LDIR at 521BH 32 bytes of the line; 52C0H completes it, 5243H-526CH add the drive, and the open at 5275H uses it to look for the new name.
5200H - Member 21 (DEVICE, Code 61H): Show the Drives
SYS1/SYS's command interpreter runs this member for the word DEVICE (member code 61H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL pointing at the rest of the command line, which DEVICE never reads. The first part shows one line for each drive 0-7 whose drive code table (4700H-474FH, reached through 478FH) starts with C3H, a JP to a driver. A floppy drive's line reads, for example, :0 5" FLOPPY #1, CYLS= 35, SDEN, SIDES=1, STEP= 6 MS, DLY= 1 S; a rigid drive's line reads :n, two spaces, the size 5 or 8, then " RIGID #s, CYLS=nnn, REMOVABLE or FIXED. Register C counts the drives and is kept on the stack across each line; Index Register IY points at the drive's table. The device list follows at 52FCH.
5200
LD C,00H 0E 00
Load Register C with 00H, the first drive number: Register C counts the drives 0-7 of the display.
5202
PUSH BC C5
Save Register Pair BC (Register C the drive number) to the stack; 52F4H takes it back after the drive's line.
5203
GOSUB to 478FH (SYS0/SYS) to point Index Register IY at the drive code table of the drive in Register C, 4700H plus 10 times the drive; Register Pair HL is kept.
5206
LD A,(IY+00H) FD 7E 00
Fetch byte +00H of the drive code table at Index Register IY into Register A: C3H, the JP to the driver, for a drive that exists, C9H for none.
5209
CP C3H FE C3
Compare Register A (byte +00H of the drive code table) against C3H, the JP that a drive in use has.
520B
If the NZ FLAG is set (no driver: the table starts with C9H), JUMP to 52F4H to go on with the next drive without a line.
520E
LD A,3AH 3E 3A
Load Register A with 3AH, the colon in front of the drive number.
5210
GOSUB to the ROM's 0033H to show Register A (the colon) on the display.
5213
LD A,C 79
Copy Register C (the drive number, 0-7) into Register A.
5214
ADD A,30H C6 30
Add 30H to Register A (the drive number): Register A = the ASCII digit of the drive, 30H-37H.
5216
GOSUB to the ROM's 0033H to show Register A (the drive digit) on the display.
5219
LD A,20H 3E 20
Load Register A with 20H, the first of two spaces after the drive number.
521B
GOSUB to the ROM's 0033H to show Register A (a space) on the display.
521E
LD A,20H 3E 20
Load Register A with 20H, the second space after the drive number.
5220
GOSUB to the ROM's 0033H to show Register A (the second space) on the display.
5223
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of byte +03H of the drive code table at Index Register IY: set for an 8 inch drive, clear for a 5 inch drive.
5227
LD A,35H 3E 35
Load Register A with 35H, the digit 5 of a 5 inch drive. LD does not change the flags of the BIT test.
5229
If the Z FLAG is set (bit 5 of +03H clear, a 5 inch drive), JUMP to 522DH with Register A = 35H.
522B
LD A,38H 3E 38
Load Register A with 38H, the digit 8 of an 8 inch drive (bit 5 of +03H set).
522D
GOSUB to the ROM's 0033H to show Register A (the digit 5 or 8, the size of the drive in inches) on the display.
5230
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of byte +03H of the drive code table at Index Register IY: set for a rigid disk, clear for a floppy drive.
5234
LD HL,542EH 21 2E 54
Point Register Pair HL to 542EH, the text with the inch mark and FLOPPY #. LD does not change the flags of the BIT test.
5237
If the Z FLAG is set (bit 3 of +03H clear, a floppy drive), JUMP to 523CH with Register Pair HL = 542EH.
5239
LD HL,5439H 21 39 54
Point Register Pair HL to 5439H, the text with the inch mark and RIGID # (bit 3 of +03H set, a rigid disk).
523C
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (542EH or 5439H) up to its 03H; Register Pair DE is left at 401DH.
523F
LD A,(IY+04H) FD 7E 04
Fetch byte +04H of the drive code table at Index Register IY into Register A: bits 3-0 are the select bit the driver writes to 37E1H.
5242
AND 0FH E6 0F
Mask Register A (byte +04H of the drive code table) to bits 3-0, the select bit: 01H, 02H, 04H or 08H.
5244
ADD A,90H C6 90
Add 90H to Register A (the select bit, 0-15), the first step of turning it into a hex digit.
5246
DAA 27
Decimal adjust Register A: 90H-99H for the values 0-9, 00H-05H and the CARRY FLAG for 10-15.
5247
ADC A,40H CE 40
Add 40H and the CARRY FLAG (from the DAA) to Register A, the third step of the hex digit.
5249
DAA 27
Decimal adjust Register A: the ASCII hex digit of the select bit, 31H, 32H, 34H or 38H for the drives 0-3 of the tables in SYS0/SYS.
524A
GOSUB to the ROM's 0033H to show Register A (the hex digit of the select bit) after the number sign.
524D
LD L,(IY+06H) FD 6E 06
Fetch byte +06H of the drive code table at Index Register IY into Register L: the last cylinder of the drive (22H = 34 for 35 cylinders).
5250
LD H,00H 26 00
Load Register H with 00H: Register Pair HL = the last cylinder as a 16 bit number.
5252
INC HL 23
Increment Register Pair HL (the last cylinder): Register Pair HL = the number of cylinders.
5253
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of byte +03H of the drive code table at Index Register IY: set for a rigid disk.
5257
If the Z FLAG is set (bit 3 of +03H clear, a floppy drive), JUMP to 525AH with Register Pair HL = the number of cylinders.
5259
ADD HL,HL 29
Add Register Pair HL to itself (a rigid disk): Register Pair HL = twice the number of cylinders, the count the line shows for a rigid disk.
525A
LD DE,544BH 11 4B 54
Point Register Pair DE to 544BH, the three places for the number inside the text , CYLS= at 5444H.
525D
GOSUB to 53BFH to write Register Pair HL (the count of cylinders, below 1000) as three decimal digits, leading zeros as spaces, at 544BH-544DH.
5260
LD HL,5444H 21 44 54
Point Register Pair HL to 5444H, the text , CYLS= with the number just written and the comma and space after it.
5263
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5444H) up to its 03H at 5450H.
5266
BIT 3,(IY+03H) FD CB 03 5E
Test bit 3 of byte +03H of the drive code table at Index Register IY: set for a rigid disk.
526A
If the Z FLAG is set (bit 3 of +03H clear, a floppy drive), JUMP to 527DH to show the density, the sides and the step rate.
526C
BIT 2,(IY+03H) FD CB 03 56
Test bit 2 of byte +03H of the drive code table at Index Register IY, which the rigid disk line shows as REMOVABLE (clear) or FIXED (set).
5270
LD HL,5451H 21 51 54
Point Register Pair HL to 5451H, the text REMOVABLE. LD does not change the flags of the BIT test.
5273
If the Z FLAG is set (bit 2 of +03H clear), JUMP to 5278H with Register Pair HL = 5451H.
5275
LD HL,545BH 21 5B 54
Point Register Pair HL to 545BH, the text FIXED (bit 2 of +03H set).
5278
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5451H REMOVABLE or 545BH FIXED) up to its 03H.
527B
JUMP to 52EFH to end the rigid disk's line with a carriage return.
527D
BIT 6,(IY+03H) FD CB 03 76
Test bit 6 of byte +03H of the drive code table at Index Register IY: set for double density, clear for single density.
5281
LD A,53H 3E 53
Load Register A with 53H, the letter S of single density. LD does not change the flags of the BIT test.
5283
If the Z FLAG is set (bit 6 of +03H clear, single density), JUMP to 5287H with Register A = 53H.
5285
LD A,44H 3E 44
Load Register A with 44H, the letter D of double density (bit 6 of +03H set).
5287
GOSUB to the ROM's 0033H to show Register A (the letter S or D) on the display, the first letter of SDEN or DDEN.
528A
LD HL,5461H 21 61 54
Point Register Pair HL to 5461H, the text DEN, SIDES= that follows the density letter.
528D
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5461H) up to its 03H.
5290
BIT 5,(IY+04H) FD CB 04 6E
Test bit 5 of byte +04H of the drive code table at Index Register IY: set for a drive with two sides.
5294
LD A,31H 3E 31
Load Register A with 31H, the digit 1 of one side. LD does not change the flags of the BIT test.
5296
If the Z FLAG is set (bit 5 of +04H clear, one side), JUMP to 529AH with Register A = 31H.
5298
LD A,32H 3E 32
Load Register A with 32H, the digit 2 of two sides (bit 5 of +04H set).
529A
GOSUB to the ROM's 0033H to show Register A (the number of sides, 1 or 2) on the display.
529D
LD HL,546DH 21 6D 54
Point Register Pair HL to 546DH, the text , STEP= in front of the step rate.
52A0
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (546DH) up to its 03H.
52A3
LD A,(IY+03H) FD 7E 03
Fetch byte +03H of the drive code table at Index Register IY into Register A: bits 1-0 the stepping rate, bit 5 the 8 inch drive.
52A6
AND 23H E6 23
Mask Register A (byte +03H of the drive code table) to bits 5, 1 and 0 (23H): the size bit and the stepping rate.
52A8
LD B,A 47
Copy Register A (bits 5, 1 and 0 of +03H) into Register B, to be ORed back below.
52A9
RRCA 0F
Rotate Register A right, the first of three: bit 5 (the size) is moving down to bit 2.
52AA
RRCA 0F
Rotate Register A right, the second of three; bits 1-0 (the rate) go round to bits 7-6.
52AB
RRCA 0F
Rotate Register A right, the third: Register A holds the size bit in bit 2 and the rate in bits 6-5.
52AC
OR B B0
OR Register B (bits 5, 1 and 0 of +03H) into Register A: bits 2-0 of Register A = the size bit and the two rate bits.
52AD
RLCA 07
Rotate Register A left: bits 3-1 of Register A = the size bit (bit 3) and the rate (bits 2-1), twice the entry number of the step table.
52AE
AND 0EH E6 0E
Mask Register A to bits 3-1 (0EH): Register A = 2 times the rate, plus 8 for an 8 inch drive, the offset of a 2 character entry of the table at 541EH.
52B0
ADD A,1EH C6 1E
Add 1EH to Register A (the offset): Register A = the low byte of the step rate's text in the table 541EH-542DH.
52B2
LD L,A 6F
Copy Register A (the low byte of the entry) into Register L.
52B3
LD H,54H 26 54
Load Register H with 54H: Register Pair HL = the step rate's entry at 541EH-542DH.
52B5
LD A,(HL) 7E
Fetch the first character of the step rate's entry at Register Pair HL into Register A (a space or the tens digit).
52B6
INC HL 23
Increment Register Pair HL to the second character of the step rate's entry.
52B7
GOSUB to the ROM's 0033H to show Register A (the first character of the step rate) on the display.
52BA
LD A,(HL) 7E
Fetch the second character of the step rate's entry at Register Pair HL into Register A (the units digit).
52BB
GOSUB to the ROM's 0033H to show Register A (the second character of the step rate) on the display.
52BE
LD HL,5475H 21 75 54
Point Register Pair HL to 5475H, the text MS (milliseconds) after the step rate.
52C1
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5475H) up to its 03H.
52C4
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of byte +03H of the drive code table at Index Register IY: set for an 8 inch drive, whose line has no DLY= part.
52C8
If the NZ FLAG is set (bit 5 of +03H set, an 8 inch drive), JUMP to 52EFH to end the line.
52CA
LD HL,5479H 21 79 54
Point Register Pair HL to 5479H, the text , DLY= of a 5 inch drive's line.
52CD
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5479H) up to its 03H.
52D0
BIT 2,(IY+03H) FD CB 03 56
Test bit 2 of byte +03H of the drive code table at Index Register IY: set for the shorter wait for a drive that is not ready (shown as .5 seconds), clear for 1 second.
52D4
LD A,20H 3E 20
Load Register A with 20H, a space, the first character of the delay 1. LD does not change the flags of the BIT test.
52D6
LD B,31H 06 31
Load Register B with 31H, the digit 1, the second character of the delay 1.
52D8
If the Z FLAG is set (bit 2 of +03H clear), JUMP to 52DEH with Register A = 20H and Register B = 31H.
52DA
LD A,2EH 3E 2E
Load Register A with 2EH, a period, the first character of the delay .5 (bit 2 of +03H set).
52DC
LD B,35H 06 35
Load Register B with 35H, the digit 5, the second character of the delay .5.
52DE
GOSUB to the ROM's 0033H to show Register A (a space or a period) on the display; the code relies on the ROM keeping Register B.
52E1
LD A,B 78
Copy Register B (the digit 1 or 5 loaded at 52D6H or 52DCH) into Register A.
52E2
GOSUB to the ROM's 0033H to show Register A (the digit of the delay) on the display.
52E5
LD A,20H 3E 20
Load Register A with 20H, the space between the delay and its unit.
52E7
GOSUB to the ROM's 0033H to show Register A (the space) on the display.
52EA
LD A,53H 3E 53
Load Register A with 53H, the letter S, the unit of the delay (seconds).
52EC
GOSUB to the ROM's 0033H to show Register A (the letter S) on the display.
52EF
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the drive's line (the rigid disk's line comes here from 527BH, the 8 inch drive's from 52C8H).
52F1
GOSUB to the ROM's 0033H to show Register A (the carriage return) on the display.
52F4
POP BC C1
Restore Register Pair BC from the stack: Register C = the drive number pushed at 5202H (a drive without a driver comes here from 520BH).
52F5
INC C 0C
Increment Register C to the next drive number.
52F6
LD A,C 79
Copy Register C (the next drive number) into Register A.
52F7
CP 08H FE 08
Compare Register A (the next drive number) against 08H, one past the last drive 7.
52F9
If the NZ FLAG is set (drives are left), JUMP back to 5202H to show the next drive; with Register C = 08H go on below to the devices.
52FCH - Show the Devices
One line for each device control block in use: the three at 4015H (KI), 401DH (DO) and 4025H (PR), then the eight at 43C0H-43FFH (43C0H JL, 43C8H SI, 43D0H LO and the five free blocks 43D8H-43FFH). A block whose type byte is 00H is passed over. Each line is built in the buffer 53F6H-541DH: an asterisk and the name (+06H-+07H); for a block that is not routed the direction of its type byte (53A0H: a less than sign for input, the equals sign, a greater than sign for output), then NIL for a NIL block or X' and the driver address (+01H-+02H) in hex and an apostrophe; for a routed block, for each block of the route the direction of that target block and its asterisk and name, and for a route to an open file the direction <=> and the file's name, extension and drive from its directory record. Register Pair HL walks the blocks; the line is shown with 4467H. After the last block the command ends at 402DH.
52FC
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the KI device control block, the first of the blocks to show.
52FF
LD A,(HL) 7E
Fetch the type byte (+00H) of the device control block at Register Pair HL into Register A: 00H for a block not in use.
5300
OR A B7
OR Register A (the type byte) with itself to set the flags: the Z FLAG for a block not in use.
5301
If the Z FLAG is set (type 00H, a free block), JUMP to 5366H to go on with the next block without a line.
5303
LD DE,53F6H 11 F6 53
Point Register Pair DE to 53F6H, the start of the line buffer 53F6H-541DH.
5306
PUSH HL E5
Save Register Pair HL (the device control block) to the stack while Register L is moved to its name.
5307
LD A,L 7D
Copy Register L (the low byte of the device control block's address) into Register A.
5308
ADD A,06H C6 06
Add 06H to Register A: the low byte of the block's name at +06H-+07H. The block does not cross a page boundary, so Register H stays right.
530A
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the name of the device control block, +06H.
530B
LD A,2AH 3E 2A
Load Register A with 2AH, an asterisk, the start of a device name.
530D
LD (DE),A 12
Store Register A (the asterisk) to the line buffer at Register Pair DE.
530E
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
530F
LD A,(HL) 7E
Fetch the first letter of the name at Register Pair HL (+06H of the block) into Register A.
5310
LD (DE),A 12
Store Register A (the first letter of the name) to the line buffer at Register Pair DE.
5311
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
5312
INC L 2C
Increment Register L to the second letter of the name, +07H of the block.
5313
LD A,(HL) 7E
Fetch the second letter of the name at Register Pair HL (+07H of the block) into Register A.
5314
LD (DE),A 12
Store Register A (the second letter of the name) to the line buffer at Register Pair DE.
5315
INC DE 13
Increment Register Pair DE to the next place in the line buffer, after the asterisk and the two letters.
5316
POP HL E1
Restore Register Pair HL from the stack: the device control block.
5317
PUSH HL E5
Save Register Pair HL (the device control block) to the stack again; 5365H takes it back after the line is shown.
5318
BIT 4,(HL) CB 66
Test bit 4 of the type byte at Register Pair HL: set for a block routed to another block or to a file (+01H-+02H the target).
531A
If the Z FLAG is set (bit 4 clear, not routed), JUMP to 533FH to show the direction and the driver or NIL.
531C
INC L 2C
Increment Register L to +01H of the routed block, the low byte of the target's address. The route loop starts here and 533BH comes back for a target that is routed in its turn.
531D
LD A,(HL) 7E
Fetch the low byte of the target's address at Register Pair HL (+01H) into Register A.
531E
INC L 2C
Increment Register L to +02H of the routed block, the high byte of the target's address.
531F
LD H,(HL) 66
Fetch the high byte of the target's address at Register Pair HL (+02H) into Register H.
5320
LD L,A 6F
Copy Register A (the low byte) into Register L: Register Pair HL = the target of the route, a device control block or a file control block.
5321
BIT 7,(HL) CB 7E
Test bit 7 of the first byte of the target at Register Pair HL: set for an open file control block (a route to a file).
5323
If the NZ FLAG is set (the target is an open file), JUMP to 5378H to put the file's name in the line.
5325
PUSH HL E5
Save Register Pair HL (the target device control block) to the stack while Register L is moved to its name.
5326
GOSUB to 53A0H to write the direction of the target block at Register Pair HL (a space, the less than sign or a space, the equals sign, the greater than sign or a space, a space) at Register Pair DE.
5329
LD A,L 7D
Copy Register L (the low byte of the target block's address) into Register A.
532A
ADD A,06H C6 06
Add 06H to Register A: the low byte of the target block's name at +06H-+07H.
532C
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the name of the target block, +06H.
532D
LD A,2AH 3E 2A
Load Register A with 2AH, an asterisk, the start of the target's device name.
532F
LD (DE),A 12
Store Register A (the asterisk) to the line buffer at Register Pair DE.
5330
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
5331
LD A,(HL) 7E
Fetch the first letter of the target's name at Register Pair HL (+06H) into Register A.
5332
LD (DE),A 12
Store Register A (the first letter of the target's name) to the line buffer at Register Pair DE.
5333
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
5334
INC L 2C
Increment Register L to the second letter of the target's name, +07H.
5335
LD A,(HL) 7E
Fetch the second letter of the target's name at Register Pair HL (+07H) into Register A.
5336
LD (DE),A 12
Store Register A (the second letter of the target's name) to the line buffer at Register Pair DE.
5337
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
5338
POP HL E1
Restore Register Pair HL from the stack: the target device control block.
5339
BIT 4,(HL) CB 66
Test bit 4 of the target's type byte at Register Pair HL: set when the target is routed in its turn.
533B
If the NZ FLAG is set (the target is routed too), JUMP back to 531CH to follow its route. A ring of routes would never end this loop.
533D
JUMP to 535CH to end the line: a route target that is not routed is shown by its name alone, with no driver address.
533F
GOSUB to 53A0H to write the direction of the block at Register Pair HL (from bits 0 and 1 of its type byte) at Register Pair DE.
5342
BIT 3,(HL) CB 5E
Test bit 3 of the type byte at Register Pair HL: set for a NIL block, which takes no input and sends no output.
5344
If the NZ FLAG is set (a NIL block), JUMP to 5396H to put the text NIL in the line.
5346
LD A,58H 3E 58
Load Register A with 58H, the letter X in front of the hex driver address.
5348
LD (DE),A 12
Store Register A (the letter X) to the line buffer at Register Pair DE.
5349
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
534A
LD A,27H 3E 27
Load Register A with 27H, the apostrophe that opens the hex driver address.
534C
LD (DE),A 12
Store Register A (the apostrophe) to the line buffer at Register Pair DE.
534D
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
534E
INC L 2C
Increment Register L to +01H of the device control block, the low byte of its driver address.
534F
LD A,(HL) 7E
Fetch the low byte of the driver address at Register Pair HL (+01H) into Register A.
5350
INC L 2C
Increment Register L to +02H of the device control block, the high byte of its driver address.
5351
LD H,(HL) 66
Fetch the high byte of the driver address at Register Pair HL (+02H) into Register H.
5352
LD L,A 6F
Copy Register A (the low byte) into Register L: Register Pair HL = the driver address of the device control block.
5353
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair DE = the driver address, Register Pair HL = the place in the line buffer.
5354
GOSUB to 4DE7H (SYS0/SYS) to write Register Pair DE (the driver address) as four hex digits at Register Pair HL, which ends after the digits.
5357
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair DE = the place in the line buffer after the digits, Register Pair HL = the driver address.
5358
LD A,27H 3E 27
Load Register A with 27H, the apostrophe that closes the hex driver address.
535A
LD (DE),A 12
Store Register A (the apostrophe) to the line buffer at Register Pair DE.
535B
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
535C
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return that ends the line (the routes come here from 533DH and 5391H, NIL from 539EH).
535E
LD (DE),A 12
Store Register A (the carriage return) to the line buffer at Register Pair DE: the line in 53F6H-541DH is complete.
535F
LD HL,53F6H 21 F6 53
Point Register Pair HL to 53F6H, the start of the line buffer.
5362
GOSUB to 4467H (SYS0/SYS) to display the line at Register Pair HL (53F6H) up to and with its carriage return; Register Pair DE is left at 401DH.
5365
POP HL E1
Restore Register Pair HL from the stack: the device control block of the line just shown, pushed at 5317H.
5366
LD A,L 7D
Copy Register L (the low byte of the device control block's address) into Register A (a free block comes here from 5301H).
5367
ADD A,08H C6 08
Add 08H to Register A: the low byte of the next block, 8 bytes on. The CARRY FLAG is set when it passes FFH, after the last block 43F8H.
5369
LD L,A 6F
Copy Register A (the low byte of the next block) into Register L. LD does not change the flags.
536A
If the CARRY FLAG is set (past 43F8H, the last block), JUMP to 402DH, VTOS READY: DEVICE ends normally.
536D
CP 2DH FE 2D
Compare Register A (the low byte of the next block) against 2DH, one past the PR block 4025H-402CH.
536F
If the NZ FLAG is set (401DH, 4025H or a block of 43C8H-43F8H), JUMP back to 52FFH to show the block at Register Pair HL.
5372
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the JL block, the first of the eight blocks at 43C0H-43FFH, after the three at 4015H-402CH.
5375
JUMP back to 52FFH to show the block at Register Pair HL (43C0H).
5378H - A Route to an Open File
Register Pair HL = the open file control block that a block routes to, Register Pair DE = the place in the line buffer. The direction is always shown as <=> (53F1H). Then SYS3/SYS's function B5H (CALL 44BBH) reads the directory record of the file (Register B = the directory entry code, +07H of the file control block, Register C = the drive, +06H) and writes NAME/EXT:d and 03H at Register Pair DE; the 03H is found and replaced by the carriage return at 535CH.
5378
PUSH HL E5
Save Register Pair HL (the open file control block of the route's target) to the stack while the direction is copied.
5379
LD HL,53F1H 21 F1 53
Point Register Pair HL to 53F1H, the text <=> (a space, the less than sign, the equals sign, the greater than sign and a space).
537C
LD BC,0005H 01 05 00
Load Register Pair BC with 0005H, the 5 characters of the direction text.
537F
LDIR ED B0
Copy the 5 bytes from 53F1H at Register Pair HL to the line buffer at Register Pair DE; Register Pair DE ends after them, Register Pair BC at 0000H.
5381
POP HL E1
Restore Register Pair HL from the stack: the open file control block.
5382
LD A,L 7D
Copy Register L (the low byte of the file control block's address) into Register A.
5383
ADD A,06H C6 06
Add 06H to Register A: the low byte of +06H of the file control block, the drive. Register H is not changed, so a control block that crosses a page boundary gives the wrong bytes.
5385
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the file control block.
5386
LD C,(HL) 4E
Fetch +06H of the file control block at Register Pair HL (the drive of the file) into Register C.
5387
INC HL 23
Increment Register Pair HL to +07H of the file control block, the directory entry code of the file.
5388
LD B,(HL) 46
Fetch +07H of the file control block at Register Pair HL (the directory entry code) into Register B.
5389
PUSH DE D5
Save Register Pair DE (the place in the line buffer for the file's name) to the stack.
538A
GOSUB to 44BBH (SYS0/SYS), request B5H: SYS3/SYS, now loaded over the overlay area 4E00H, reads the directory record of entry Register B on drive Register C into 4200H and writes NAME/EXT:d and 03H at Register Pair DE; it returns Register A = 00H and the Z FLAG, or 11H and the NZ FLAG when the record could not be read, and nothing is written then. The result is not tested.
538D
POP DE D1
Restore Register Pair DE from the stack: the place in the line buffer where the file's name starts.
538E
LD A,(DE) 1A
Fetch the byte at Register Pair DE (the line buffer) into Register A. The search for the 03H that ends the file's name starts here.
538F
CP 03H FE 03
Compare Register A against 03H, the byte SYS3/SYS put after the drive digit.
5391
If the Z FLAG is set (the 03H), JUMP to 535CH to store the carriage return over it at Register Pair DE and show the line.
5393
INC DE 13
Increment Register Pair DE to the next byte of the line buffer.
5394
JUMP back to 538EH to test the next byte. After a directory read error nothing was written, so the search runs on through the buffer and the memory beyond it to the first 03H byte.
5396H - A NIL Device
Register Pair DE = the place in the line buffer after the direction; the text NIL is copied there and the line is ended at 535CH.
5396
LD HL,53EEH 21 EE 53
Point Register Pair HL to 53EEH, the text NIL of a NIL device. The device control block's address is still on the stack.
5399
LD BC,0003H 01 03 00
Load Register Pair BC with 0003H, the 3 letters of NIL.
539C
LDIR ED B0
Copy the 3 bytes from 53EEH at Register Pair HL to the line buffer at Register Pair DE; Register Pair DE ends after them, Register Pair BC at 0000H.
539E
JUMP to 535CH to end the line with a carriage return and show it.
53A0H - Write the Direction
Register Pair HL = a device control block, Register Pair DE = the place in the line buffer. Writes 5 characters: a space; the less than sign when bit 0 of the type byte (input) is set, else a space; the equals sign; the greater than sign when bit 1 (output) is set, else a space; a space. Register Pair DE ends 5 bytes on; Register Pair HL is kept.
53A0
LD A,20H 3E 20
Load Register A with 20H, a space, the first character of the direction.
53A2
LD (DE),A 12
Store Register A (the space) to the line buffer at Register Pair DE.
53A3
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
53A4
BIT 0,(HL) CB 46
Test bit 0 of the type byte at Register Pair HL: set for a device that takes input. Register A is still 20H.
53A6
If the Z FLAG is set (bit 0 clear, no input), JUMP to 53AAH to store the space in Register A.
53A8
LD A,3CH 3E 3C
Load Register A with 3CH, the less than sign, the arrow of input (bit 0 of the type byte set).
53AA
LD (DE),A 12
Store Register A (the less than sign or the space) to the line buffer at Register Pair DE.
53AB
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
53AC
LD A,3DH 3E 3D
Load Register A with 3DH, the equals sign, the shaft of the arrows.
53AE
LD (DE),A 12
Store Register A (the equals sign) to the line buffer at Register Pair DE.
53AF
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
53B0
LD A,20H 3E 20
Load Register A with 20H, a space, for a device that sends no output.
53B2
BIT 1,(HL) CB 4E
Test bit 1 of the type byte at Register Pair HL: set for a device that takes output.
53B4
If the Z FLAG is set (bit 1 clear, no output), JUMP to 53B8H to store the space in Register A.
53B6
LD A,3EH 3E 3E
Load Register A with 3EH, the greater than sign, the arrow of output (bit 1 of the type byte set).
53B8
LD (DE),A 12
Store Register A (the greater than sign or the space) to the line buffer at Register Pair DE.
53B9
INC DE 13
Increment Register Pair DE to the next place in the line buffer.
53BA
LD A,20H 3E 20
Load Register A with 20H, a space, the last character of the direction.
53BC
LD (DE),A 12
Store Register A (the space) to the line buffer at Register Pair DE.
53BD
INC DE 13
Increment Register Pair DE to the next place in the line buffer, after the 5 characters.
53BE
RET C9
RETURN to the caller (5326H or 533FH) with Register Pair DE after the direction and Register Pair HL unchanged.
53BFH - Three Decimal Digits
Register Pair HL = a number below 1000, Register Pair DE = the place for the digits. Writes the hundreds (53D3H with 100), the tens (53D3H with 10) and the units; a zero digit before the first digit that is not zero is written as a space, so 35 shows as a space, 3 and 5. The units digit is always a digit. Register Pair DE ends 3 bytes on; Register Pair BC is changed.
53BF
LD A,20H 3E 20
Load Register A with 20H, a space: the character written for a leading zero, until the first digit that is not zero.
53C1
LD BC,0064H 01 64 00
Load Register Pair BC with 0064H (100), the value of the hundreds digit.
53C4
GOSUB to 53D3H to write the hundreds digit of Register Pair HL at Register Pair DE; Register Pair HL returns the rest below 100 and Register A the filler for the next digit.
53C7
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH (10), the value of the tens digit.
53CA
GOSUB to 53D3H to write the tens digit of Register Pair HL at Register Pair DE; Register Pair HL returns the units, 0-9.
53CD
LD A,L 7D
Copy Register L (the units, 0-9) into Register A.
53CE
ADD A,30H C6 30
Add 30H to Register A: the ASCII digit of the units, written even when it is zero.
53D0
LD (DE),A 12
Store Register A (the units digit) at Register Pair DE.
53D1
INC DE 13
Increment Register Pair DE past the units digit.
53D2
RET C9
RETURN to the caller (525DH) with the three characters at 544BH-544DH.
53D3
PUSH DE D5
Save Register Pair DE (the place for the digit) to the stack, as Register D and Register E count below.
53D4
LD E,A 5F
Copy Register A (the filler: a space before the first digit that is not zero, else the digit 0) into Register E.
53D5
LD D,FFH 16 FF
Load Register D with FFH: the first increment below makes the count of subtractions 00H.
53D7
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A), so that the first SBC subtracts Register Pair BC alone.
53D8
INC D 14
Increment Register D, the count of times Register Pair BC (the value of the digit) has been subtracted. The loop starts here.
53D9
SBC HL,BC ED 42
Subtract Register Pair BC (100 or 10) and the CARRY FLAG from Register Pair HL (the number): the CARRY FLAG is set when Register Pair HL goes below 0000H.
53DB
If the NC FLAG is set (the subtraction did not go below 0000H), LOOP BACK to 53D8H to count it and subtract again.
53DD
ADD HL,BC 09
Add Register Pair BC (100 or 10) back to Register Pair HL, undoing the subtraction that went below 0000H: Register Pair HL = the rest of the number.
53DE
LD A,E 7B
Copy Register E (the filler, a space or the digit 0) into Register A.
53DF
LD B,D 42
Copy Register D (the count of subtractions, the digit 0-9) into Register B.
53E0
POP DE D1
Restore Register Pair DE from the stack: the place for the digit.
53E1
LD (DE),A 12
Store Register A (the filler) at Register Pair DE; a digit that is not zero replaces it below.
53E2
INC B 04
Increment Register B (the digit) to set the flags with the next instruction.
53E3
DEC B 05
Decrement Register B back to the digit: the Z FLAG is set when the digit is 0.
53E4
If the Z FLAG is set (the digit is 0), JUMP to 53ECH: the filler stays in the place and in Register A for the next digit.
53E6
LD A,B 78
Copy Register B (the digit, 1-9) into Register A.
53E7
ADD A,30H C6 30
Add 30H to Register A: the ASCII digit, 31H-39H.
53E9
LD (DE),A 12
Store Register A (the digit) at Register Pair DE, over the filler.
53EA
LD A,30H 3E 30
Load Register A with 30H, the digit 0: after a digit that is not zero every later zero is written as 0, not as a space.
53EC
INC DE 13
Increment Register Pair DE to the next place for a digit.
53ED
RET C9
RETURN to 53C7H or 53CDH with Register A = the filler for the next digit, Register Pair HL = the rest of the number and Register B = the digit just found.
53EEH - Texts and the Line Buffer
NIL for a NIL device (5396H), the direction of a route to a file (5379H), then the 40 bytes of the line buffer that are not in the file.
53EE-53F0
DEFM "NIL" 4E 49 4C
The text NIL that 5396H-539CH copies into the line of a device whose type byte has bit 3 set.
53F1-53F5
DEFM " <=> " 20 3C 3D 3E 20
The direction of a route to an open file, a space, the less than sign, the equals sign, the greater than sign and a space, copied into the line by 5379H-537FH.
53F6-541D
DEFS 40
Not in the file: the gap between the second and third load blocks is the line buffer of the device list. 5303H points Register Pair DE here for each line; 530DH-5315H, 53A0H, 5348H-535BH, 537FH, 538AH (SYS3/SYS's NAME/EXT:d) and 539CH write the line, 535EH ends it with 0DH and 535FH-5362H displays it.
541EH - Step Rates and the Texts of the Drive Lines
The table of the step rates, 2 characters an entry, indexed by 52A3H-52B3H with 2 times the rate (bits 1-0 of +03H of the drive code table) plus 8 for an 8 inch drive (bit 5); then the texts of the drive lines, each ended by 03H (not displayed by 4467H).
541E-541F
DEFM " 6" 20 36
Step rate 0 of a 5 inch drive: 6 milliseconds.
5420-5421
DEFM "12" 31 32
Step rate 1 of a 5 inch drive: 12 milliseconds.
5422-5423
DEFM "20" 32 30
Step rate 2 of a 5 inch drive: 20 milliseconds.
5424-5425
DEFM "40" 34 30
Step rate 3 of a 5 inch drive: 40 milliseconds.
5426-5427
DEFM " 3" 20 33
Step rate 0 of an 8 inch drive: 3 milliseconds.
5428-5429
DEFM " 6" 20 36
Step rate 1 of an 8 inch drive: 6 milliseconds.
542A-542B
DEFM "10" 31 30
Step rate 2 of an 8 inch drive: 10 milliseconds.
542C-542D
DEFM "15" 31 35
Step rate 3 of an 8 inch drive: 15 milliseconds.
542E-5438
DEFB 22H / DEFM " FLOPPY #" / DEFB 03H 22 20 46 4C 4F 50 50 59 20 23 03
The text of a floppy drive (5234H): the quotation mark 22H as the inch sign after the 5 or 8, then FLOPPY # and the 03H that ends it; the select bit follows as a hex digit (5249H).
5439-5443
DEFB 22H / DEFM " RIGID #" / DEFB 03H 22 20 52 49 47 49 44 20 20 23 03
The text of a rigid disk (5239H): the inch sign 22H, then RIGID # with two spaces and the 03H that ends it.
5444-544A
DEFM ", CYLS=" 2C 20 43 59 4C 53 3D
The text , CYLS= in front of the number of cylinders, displayed from here by 5260H-5263H.
544B-544D
DEFM " " 20 20 20
Three spaces in the file: the places of the number of cylinders, written by 53BFH (Register Pair DE = 544BH from 525AH) before each display.
544E-5450
DEFM ", " / DEFB 03H 2C 20 03
A comma and a space after the number of cylinders, then the 03H that ends the text displayed from 5444H.
5451-545A
DEFM "REMOVABLE" / DEFB 03H 52 45 4D 4F 56 41 42 4C 45 03
The text REMOVABLE of a rigid disk with bit 2 of +03H of its drive code table clear (5270H), ended by 03H.
545B-5460
DEFM "FIXED" / DEFB 03H 46 49 58 45 44 03
The text FIXED of a rigid disk with bit 2 of +03H set (5275H), ended by 03H.
5461-546C
DEFM "DEN, SIDES=" / DEFB 03H 44 45 4E 2C 20 53 49 44 45 53 3D 03
The text after the density letter S or D (528AH), then the 03H; the number of sides follows (529AH).
546D-5474
DEFM ", STEP=" / DEFB 03H 2C 20 53 54 45 50 3D 03
The text , STEP= in front of the step rate (529DH), ended by 03H.
5475-5478
DEFM " MS" / DEFB 03H 20 4D 53 03
The text MS (milliseconds) after the step rate (52BEH), ended by 03H.
5479-547F
DEFM ", DLY=" / DEFB 03H 2C 20 44 4C 59 3D 03
The text , DLY= of a 5 inch drive's line (52CAH), ended by 03H; the delay 1 or .5 and S follow.
5200H - Member 22 (LINK, Code 62H): Read the Two Device Specifications
SYS1/SYS's command interpreter runs this member for the word LINK (member code 62H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL at the rest of the command line. LINK, an asterisk and the device name d1, the word TO when wanted, then an asterisk and the device name d2, makes the device d1 also send its output to d2 and take input from d2 when d1 gives none. Both device control blocks are found by their names; then the 30 byte routine 526AH-5287H, with the old driver address of d1 and the address of the block of d2 put into it, is copied to the top of memory (4049H is lowered by 30) and d1's driver address (+01H-+02H) is pointed at the copy. LINK is refused when 402DH holds a JP (C3H). The flags of the entry (NZ after a load error of the member) are not tested.
5200
LD A,(402DH) 3A 2D 40
Fetch the first byte of the exit 402DH into Register A: 3EH, the LD A,93H of VTOS READY, unless a program has put a JP of its own there (BASIC/CMD stores C3H at 402DH, its 66A6H-66A9H, before it runs a command line through 4405H).
5203
CP C3H FE C3
Compare Register A (the byte at 402DH) against C3H, a JP.
5205
If the Z FLAG is set (402DH is a JP: a program's command is running), JUMP to 52D1H to display CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL and abort.
5208
LD DE,5304H 11 04 53
Point Register Pair DE to 5304H, the block for the first device specification (past the end of the member, not in the file).
520B
GOSUB to 441CH (SYS1/SYS function 4, its 4FCEH) to copy the specification at Register Pair HL into the block at Register Pair DE as text ended by 03H: the Z FLAG when one was read, Register Pair HL past it.
520E
If the NZ FLAG is set (no specification), JUMP to 52B3H to display DEVICE SPEC REQUIRED and abort.
5211
LD A,(DE) 1A
Fetch the first character of the specification at Register Pair DE (5304H) into Register A.
5212
CP 2AH FE 2A
Compare Register A against 2AH, an asterisk, the start of a device specification.
5214
If the NZ FLAG is set (a file, not a device), JUMP to 52B3H to display DEVICE SPEC REQUIRED and abort.
5217
LD DE,5324H 11 24 53
Point Register Pair DE to 5324H, the block for the second device specification (not in the file).
521A
GOSUB to 441CH (SYS1/SYS 4FCEH) to copy the next specification at Register Pair HL into the block at Register Pair DE (5324H); a preposition such as TO is passed over.
521D
If the NZ FLAG is set (no second specification), JUMP to 52B3H to display DEVICE SPEC REQUIRED and abort.
5220
LD A,(DE) 1A
Fetch the first character of the second specification at Register Pair DE (5324H) into Register A.
5221
CP 2AH FE 2A
Compare Register A against 2AH, an asterisk, the start of a device specification.
5223
If the NZ FLAG is set (a file, not a device), JUMP to 52B3H to display DEVICE SPEC REQUIRED and abort.
5226H - Find the Two Device Control Blocks and Build the Routine
The two characters after each asterisk (5305H-5306H, 5325H-5326H; a one letter name has 03H as its second character) are looked up by 5288H. The address of the second block goes into the two LD DE,0000H of the routine (5276H, 5283H), the driver address of the first block into its two CALL 0000H (526FH, 527EH).
5226
LD DE,(5305H) ED 5B 05 53
Fetch the two characters of the first device name from 5305H-5306H into Register Pair DE: Register E = the first letter, Register D = the second (03H for a one letter name).
522A
GOSUB to 5288H to find the device control block named by Register Pair DE: Register Pair HL = the block and the Z FLAG, or the NZ FLAG with Register A = 08H.
522D
If the NZ FLAG is set (no such device), JUMP to 52AEH to show error 08H (DEVICE NOT AVAILABLE) in Register A and abort.
5230
PUSH HL E5
Save Register Pair HL (the first device's control block) to the stack.
5231
LD DE,(5325H) ED 5B 25 53
Fetch the two characters of the second device name from 5325H-5326H into Register Pair DE: Register E = the first letter, Register D = the second.
5235
GOSUB to 5288H to find the device control block named by Register Pair DE: Register Pair HL = the block and the Z FLAG, or the NZ FLAG with Register A = 08H.
5238
If the NZ FLAG is set (no such device), JUMP to 52AEH to show error 08H (DEVICE NOT AVAILABLE) in Register A and abort.
523B
LD (5276H),HL 22 76 52
Store Register Pair HL (the second device's control block) to 5276H-5277H, the operand of LD DE,0000H at 5275H in the routine: the block its output goes to.
523E
LD (5283H),HL 22 83 52
Store Register Pair HL (the second device's control block) to 5283H-5284H, the operand of LD DE,0000H at 5282H in the routine: the block its input comes from.
5241
POP HL E1
Restore Register Pair HL from the stack: the first device's control block, saved at 5230H.
5242
INC HL 23
Increment Register Pair HL to byte +01H of the first block, the low byte of its driver address.
5243
PUSH HL E5
Save Register Pair HL (the address of byte +01H) to the stack, for the store of the new driver address at 5264H.
5244
LD A,(HL) 7E
Fetch the low byte of the first device's driver address from Register Pair HL into Register A.
5245
INC HL 23
Increment Register Pair HL to byte +02H, the high byte of the driver address.
5246
LD H,(HL) 66
Fetch the high byte of the driver address from Register Pair HL into Register H.
5247
LD L,A 6F
Copy Register A (the low byte) into Register L: Register Pair HL = the driver address of the first device.
5248
LD (526FH),HL 22 6F 52
Store Register Pair HL (the first device's driver) to 526FH-5270H, the operand of CALL 0000H at 526EH in the routine: the old driver for output.
524B
LD (527EH),HL 22 7E 52
Store Register Pair HL (the first device's driver) to 527EH-527FH, the operand of CALL 0000H at 527DH in the routine: the old driver for input.
524EH - Move the Routine to the Top of Memory
The top of memory (4049H-404AH, the highest address free for use) is lowered by 30 and the 30 bytes 526AH-5287H go to the 30 bytes above the new top. The first device's driver address then points at the copy.
524E
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL: the highest address programs may use.
5251
LD BC,001EH 01 1E 00
Load Register Pair BC with 001EH, the 30 bytes of the routine 526AH-5287H.
5254
XOR A AF
Set Register A to 00H (XOR A), which also clears the CARRY FLAG for the SBC below.
5255
SBC HL,BC ED 42
SUBtract Register Pair BC (30) from Register Pair HL (the top of memory): Register Pair HL = the new top.
5257
LD (4049H),HL 22 49 40
Store Register Pair HL (the new top) to 4049H-404AH: the 30 bytes above it now belong to the routine.
525A
INC HL 23
Increment Register Pair HL to the first of the 30 bytes, where the routine goes.
525B
PUSH HL E5
Save Register Pair HL (the address of the copy) to the stack.
525C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the address of the copy, the destination.
525D
LD HL,526AH 21 6A 52
Point Register Pair HL to 526AH, the routine with its four operands filled in.
5260
LDIR ED B0
Copy the 30 bytes of the routine from 526AH at Register Pair HL to the top of memory at Register Pair DE (LDIR, Register Pair BC = 001EH). Register Pair BC ends at 0000H.
5262
POP DE D1
Restore Register Pair DE from the stack: the address of the copy, the new driver of the first device.
5263
POP HL E1
Restore Register Pair HL from the stack: the address of byte +01H of the first device's control block, saved at 5243H.
5264
LD (HL),E 73
Store Register E (the low byte of the copy's address) to byte +01H of the first block at Register Pair HL.
5265
INC HL 23
Increment Register Pair HL to byte +02H of the first block.
5266
LD (HL),D 72
Store Register D (the high byte of the copy's address) to byte +02H at Register Pair HL: the first device's driver is now the routine at the top of memory.
5267
JUMP to 402DH, VTOS READY: the link is made and stays until the block's driver address is changed again.
526AH - The Link Routine (Copied to the Top of Memory)
These 30 bytes run only as the copy at the top of memory, as the driver of the first device: the ROM's 03C2H enters it with Index Register IX and Register Pair DE = the first device's control block, Register C = the character to send, Register A = the request (01H input, 02H output, 04H control) and the flags of CP 02H (the C FLAG for an input). Output and control: the old driver runs, then Register A is sent to the second device; the caller gets the old driver's Register A and flags. Input: the old driver is asked; when it gives 00H the second device is asked instead. The JR is relative and the other branches go to fixed addresses, so the routine works at any address.
526A
If the C FLAG is set (an input request), JUMP to 527DH, 19 bytes on in the copy.
526C
PUSH AF F5
Save Register Pair AF (the request in Register A and its flags) to the stack.
526D
PUSH BC C5
Save Register Pair BC (Register C = the character to send) to the stack.
526E
CALL 0000H CD 00 00
Self-Modifying Code
GOSUB to the first device's old driver with the request as it came. The operand at 526FH-5270H is 0000H in the file; 5248H stores the driver address of the first device there before the LDIR at 5260H copies the routine, so the copy holds it.
5271
POP BC C1
Restore Register Pair BC from the stack: Register C = the character to send.
5272
PUSH AF F5
Save Register Pair AF (the old driver's Register A and flags) to the stack.
5273
POP HL E1
Restore Register Pair HL from the stack: Register Pair HL = the old driver's Register Pair AF.
5274
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer, the top of the stack: the old driver's Register Pair AF takes the place of the request's (saved at 526CH), which goes into Register Pair HL and is dropped.
5275
LD DE,0000H 11 00 00
Self-Modifying Code
Point Register Pair DE to the control block of the second device. The operand at 5276H-5277H is 0000H in the file; 523BH stores the second device's block there before the copy.
5278
GOSUB to the ROM's 001BH to send Register A (the old driver's Register A, the character itself for a driver that returns it in Register A, as the ROM's display driver does) to the device at Register Pair DE, the second device. Its result is not used.
527B
POP AF F1
Restore Register Pair AF from the stack: Register A and the flags as the old driver returned them.
527C
RET C9
RETURN to the ROM's 03DDH with the first device's result.
527D
CALL 0000H CD 00 00
Self-Modifying Code
GOSUB to the first device's old driver for an input. The operand at 527EH-527FH is 0000H in the file; 524BH stores the driver address of the first device there before the copy.
5280
OR A B7
OR Register A (the character the first device gave) with itself: the Z FLAG is set for 00H, no character.
5281
RET NZ C0
If the NZ FLAG is set (a character), RETURN to the ROM's 03DDH with it in Register A.
5282
LD DE,0000H 11 00 00
Self-Modifying Code
Point Register Pair DE to the control block of the second device. The operand at 5283H-5284H is 0000H in the file; 523EH stores the second device's block there before the copy.
5285
JUMP to the ROM's 0013H to take a byte from the device at Register Pair DE, the second device: its Register A and flags go back to the caller.
5288H - Find a Device Control Block by Name
Register Pair DE = the name (Register E the first character, Register D the second). The blocks are 8 bytes, bytes +06H-+07H the name: 4015H (KI), 401DH (DO), 4025H (PR), then 43C0H-43FFH (JL, SI, LO and the five free blocks). Returns the Z FLAG and Register A = 00H with Register Pair HL = the block; the NZ FLAG and Register A = 08H (DEVICE NOT AVAILABLE) when no name matches. The type of the block is not looked at.
5288
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the first device control block (KI).
528B
PUSH HL E5
Loop Start
Save Register Pair HL (the start of the block) to the stack.
528C
LD A,L 7D
Copy Register L (the low byte of the block) into Register A.
528D
ADD A,06H C6 06
Add 06H to Register A: the low byte of the block's +06H, the first character of its name.
528F
LD L,A 6F
Copy Register A into Register L: Register Pair HL = byte +06H of the block.
5290
LD A,(HL) 7E
Fetch the first character of the block's name from Register Pair HL into Register A.
5291
INC L 2C
Increment Register L to byte +07H, the second character of the name.
5292
CP E BB
Compare Register A (the block's first character) against Register E (the first character typed).
5293
If the NZ FLAG is set (they differ), JUMP to 529CH for the next block.
5295
LD A,(HL) 7E
Fetch the second character of the block's name from Register Pair HL into Register A.
5296
CP D BA
Compare Register A (the block's second character) against Register D (the second character typed).
5297
If the NZ FLAG is set (they differ), JUMP to 529CH for the next block.
5299
POP HL E1
Restore Register Pair HL from the stack: the start of the block that matched.
529A
XOR A AF
Set Register A to 00H and set the Z FLAG (XOR A): found.
529B
RET C9
RETURN to 522DH or 5238H with Register Pair HL = the device control block and the Z FLAG.
529C
POP AF F1
Restore Register Pair AF from the stack: the start of the block, saved at 528BH, is dropped (Register Pair HL is at its +07H).
529D
INC L 2C
Increment Register L from +07H to the first byte of the next block: Register L becomes 00H after the last block, 43F8H.
529E
If the NZ FLAG is set (Register L is not 00H), JUMP to 52A4H.
52A0
LD A,08H 3E 08
Load Register A with 08H, the error code DEVICE NOT AVAILABLE.
52A2
OR A B7
OR Register A (08H) with itself: the NZ FLAG.
52A3
RET C9
RETURN to 522DH or 5238H with the NZ FLAG and Register A = 08H: no block has the name.
52A4
LD A,L 7D
Copy Register L (the low byte of the next block) into Register A.
52A5
CP 2DH FE 2D
Compare Register A against 2DH: after the PR block 4025H-402CH comes 402DH, which is not a device control block.
52A7
If the NZ FLAG is set (another block follows), JUMP back to 528BH for the block at Register Pair HL.
52A9
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the first of the device control blocks at 43C0H-43FFH (JL).
52AC
JUMP back to 528BH for the block at Register Pair HL.
52AEH - Error Exit
Register A = 08H from 5288H.
52AE
OR 40H F6 40
OR 40H into Register A (the error code 08H): bit 6 asks for the text of the error alone; bit 7 stays clear, so the error message is followed by the abort exit.
52B0
JUMP to 4409H to display the error message of Register A (request 86H, SYS4/SYS), then the abort exit 4030H.
52B3H - The Messages of LINK
Each message is displayed and written to the job log by 447BH, then the command ends at 4030H, the abort exit.
52B3
LD HL,52BCH 21 BC 52
Point Register Pair HL to 52BCH, the text DEVICE SPEC REQUIRED.
52B6
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
52B9
JUMP to 4030H, the abort exit of VTOS: the command ends here.
52BC-52CF
DEFM "DEVICE SPEC REQUIRED" 44 45 56 49 43 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 52B3H: one of the two specifications is missing or is not a device (an asterisk and a name).
52D0
DEFB 0DH 0D
The carriage return that ends the message DEVICE SPEC REQUIRED.
52D1
LD HL,52DAH 21 DA 52
Point Register Pair HL to 52DAH, the text CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL.
52D4
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL and write it to the job log.
52D7
JUMP to 4030H, the abort exit of VTOS: the command ends here.
52DA-5302
DEFM "CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL" 43 41 4E 27 54 20 2D 2D 20 4F 4E 4C 59 20 56 41 4C 49 44 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C
The message of 52D1H: 402DH holds a JP (5205H), so the command was run from inside a program.
5303
DEFB 0DH 0D
The carriage return that ends the message CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL.
5304H - The Two Specification Blocks
Not in the file: 64 bytes after the last loaded byte.
5304-5323
DEFS 32
Not in the file: the block of the first device specification. 520BH (441CH) copies the specification here as text: an asterisk at 5304H (tested at 5211H), the name at 5305H-5306H (read at 5226H), 03H after it. A file specification (refused) can fill up to 25 bytes.
5324-5343
DEFS 32
Not in the file: the block of the second device specification. 521AH (441CH) copies it here: the asterisk at 5324H (tested at 5220H), the name at 5325H-5326H (read at 5231H).
5200H - Member 23 (RESET, Code 63H): Reset One Device
SYS1/SYS's command interpreter runs this member for the word RESET (member code 63H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL pointing at the rest of the command line. First the start-up driver addresses of KI, DO and PR (43B8H, 43BAH, 43BCH, stored by SYS0/SYS's reset) are put into the device control block templates at 532CH. Then 441CH reads a specification from the line into the control block 5405H. When none is read (RESET alone, or text that is not a specification) all devices are reset at 525CH. A file specification gives DEVICE SPEC REQUIRED and the abort exit. A device specification (an asterisk and two letters) is looked up among the device control blocks (535CH); a name not found gives error 08H, DEVICE NOT AVAILABLE. The block found has an open file at the end of its route closed (52EAH) and is made NIL (type 08H); KI, DO and PR (the blocks at 4015H-402CH) are then copied back from their templates, and for DO the screen is cleared. The command ends at 402DH.
5200
PUSH HL E5
Save Register Pair HL (the parameters text after the word RESET) to the stack while Register Pair HL copies the start-up driver addresses.
5201
LD HL,(43B8H) 2A B8 43
Fetch the word at 43B8H-43B9H into Register Pair HL: the KI driver address that SYS0/SYS's reset found in 4016H at the start.
5204
LD (532DH),HL 22 2D 53
Store Register Pair HL (the start-up KI driver) to 532DH-532EH, +01H-+02H of the KI template at 532CH.
5207
LD HL,(43BAH) 2A BA 43
Fetch the word at 43BAH-43BBH into Register Pair HL: the DO driver address at the start, kept by SYS0/SYS's reset.
520A
LD (5335H),HL 22 35 53
Store Register Pair HL (the start-up DO driver) to 5335H-5336H, +01H-+02H of the DO template at 5334H.
520D
LD HL,(43BCH) 2A BC 43
Fetch the word at 43BCH-43BDH into Register Pair HL: the PR driver address at the start, kept by SYS0/SYS's reset.
5210
LD (533DH),HL 22 3D 53
Store Register Pair HL (the start-up PR driver) to 533DH-533EH, +01H-+02H of the PR template at 533CH.
5213
POP HL E1
Restore Register Pair HL from the stack: the parameters text after the word RESET.
5214
LD DE,5405H 11 05 54
Point Register Pair DE to 5405H, the control block (not in the file) that receives the specification.
5217
GOSUB to 441CH (SYS0/SYS), request C3H: SYS1/SYS's 4FCEH copies a file or device specification from the text at Register Pair HL into the block at Register Pair DE (5405H), ended by 03H; the Z FLAG when one was read.
521A
If the NZ FLAG is set (no specification: RESET alone, or text that is not one), JUMP to 525CH to reset all the devices.
521D
LD A,(DE) 1A
Fetch the first byte of the specification at Register Pair DE (5405H) into Register A.
521E
CP 2AH FE 2A
Compare Register A (the first byte of the specification) against 2AH, the asterisk that starts a device specification.
5220
If the NZ FLAG is set (a file specification), JUMP to 5387H to show DEVICE SPEC REQUIRED and abort.
5223
LD DE,(5406H) ED 5B 06 54
Fetch the word at 5406H-5407H into Register Pair DE: Register E = the first letter of the device name, Register D = the second letter (or the 03H after a one letter name).
5227
GOSUB to 535CH to find the device control block whose name (+06H-+07H) is Register E and Register D: the Z FLAG and Register Pair HL = the block, or the NZ FLAG and Register A = 08H.
522A
If the NZ FLAG is set (no block has the name), JUMP to 5382H with Register A = 08H to show DEVICE NOT AVAILABLE and abort.
522D
PUSH HL E5
Save Register Pair HL (the device control block found) to the stack.
522E
GOSUB to 52EAH to follow the block's route and close the open file at its end, if there is one.
5231
POP HL E1
Restore Register Pair HL from the stack: the device control block found.
5232
LD (HL),08H 36 08
Store 08H to the type byte (+00H) of the device control block at Register Pair HL: the device is NIL, it takes no input and sends no output.
5234
LD A,40H 3E 40
Load Register A with 40H, the page of the KI, DO and PR blocks 4015H-402CH.
5236
CP H BC
Compare Register A (40H) against Register H, the page of the device control block.
5237
If the NZ FLAG is set (a block of 43C0H-43FFH: JL, SI, LO or a free block), JUMP to 402DH, VTOS READY: the device stays NIL.
523A
DI F3
Disable the interrupts while the KI, DO or PR block is rewritten.
523B
LD D,H 54
Copy Register H (40H) into Register D, the high byte of the block's address for the copy.
523C
LD E,L 5D
Copy Register L (the low byte of the block, 15H, 1DH or 25H) into Register E: Register Pair DE = the device control block, the destination.
523D
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the SBC below.
523E
LD BC,4015H 01 15 40
Load Register Pair BC with 4015H, the first of the three blocks at 4015H-402CH.
5241
SBC HL,BC ED 42
Subtract Register Pair BC (4015H) from Register Pair HL (the block): Register Pair HL = 0000H for KI, 0008H for DO, 0010H for PR.
5243
LD BC,532CH 01 2C 53
Load Register Pair BC with 532CH, the first of the three templates at 532CH-5343H.
5246
ADD HL,BC 09
Add Register Pair BC (532CH) to Register Pair HL (the offset): Register Pair HL = the template of the block, 532CH, 5334H or 533CH.
5247
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 bytes of a device control block.
524A
LDIR ED B0
Copy the 8 bytes of the template at Register Pair HL to the device control block at Register Pair DE: its type, its start-up driver, its other bytes and its name. Register Pair DE ends 8 bytes on (401DH, 4025H or 402DH), Register Pair BC at 0000H.
524C
EI FB
Enable the interrupts again: the block is complete.
524D
LD A,25H 3E 25
Load Register A with 25H, the low byte of the address after the DO block 401DH-4024H.
524F
CP E BB
Compare Register A (25H) against Register E, the low byte of the address after the block just copied.
5250
If the NZ FLAG is set (KI or PR was reset), JUMP to 402DH, VTOS READY.
5253
LD HL,5309H 21 09 53
Point Register Pair HL to 5309H, the display codes 1CH and 1FH ended by 03H: DO's cursor is 3C00H again, so the screen is cleared to match.
5256
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5309H): 1CH puts the cursor at the top left, 1FH clears to the end of the screen.
5259
JUMP to 402DH, VTOS READY: RESET of DO is done.
525CH - Reset All Devices
RESET with no device specification. Every device control block (4015H, 401DH, 4025H, then 43C0H-43F8H) has the open file at the end of its route closed (52EAH). The 12 task slots at 4500H are searched for a task control block above the top of memory (4049H); when none is there and 402DH holds its normal code, the top of memory is found again by testing FFFFH down in 1K steps, as SYS0/SYS's reset does. Then the KI, DO and PR blocks are copied from their templates (the cursor kept), 43BEH-43BFH is cleared, JL, SI and LO are copied from their templates and 43D8H-43FFH (the free blocks) are cleared. A task in high memory gives CAN'T RESET MEMORY, FOREGROUND TASK(S) EXIST: the devices are reset, the top of memory is left. A 402DH changed to a JP gives CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL and the abort exit.
525C
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the KI device control block, the first of the blocks whose routes are closed.
525F
PUSH HL E5
Save Register Pair HL (the device control block) to the stack. The loop over the blocks starts here.
5260
GOSUB to 52EAH to follow the route of the block at Register Pair HL and close the open file at its end, if there is one.
5263
POP HL E1
Restore Register Pair HL from the stack: the device control block.
5264
LD A,L 7D
Copy Register L (the low byte of the device control block's address) into Register A.
5265
ADD A,08H C6 08
Add 08H to Register A: the low byte of the next block, 8 bytes on; the Z FLAG is set when it passes from F8H to 00H, after the last block 43F8H.
5267
LD L,A 6F
Copy Register A (the low byte of the next block) into Register L. LD does not change the flags.
5268
If the Z FLAG is set (past 43F8H, the last block), JUMP to 5273H to look at the task slots.
526A
CP 2DH FE 2D
Compare Register A (the low byte of the next block) against 2DH, one past the PR block 4025H-402CH.
526C
If the NZ FLAG is set (401DH, 4025H or a block of 43C8H-43F8H), JUMP back to 525FH for the block at Register Pair HL.
526E
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the JL block, the first of the eight blocks at 43C0H-43FFH.
5271
JUMP back to 525FH for the block at Register Pair HL (43C0H).
5273
LD B,0CH 06 0C
Load Register B with 0CH, the 12 task slots at 4500H-4517H.
5275
LD HL,4500H 21 00 45
Point Register Pair HL to 4500H, the first task slot: each slot holds the address of a task control block (45BBH for an empty slot).
5278
LD E,(HL) 5E
Fetch the low byte of the task control block's address at Register Pair HL into Register E.
5279
INC HL 23
Increment Register Pair HL to the high byte of the slot.
527A
LD D,(HL) 56
Fetch the high byte of the task control block's address at Register Pair HL into Register D: Register Pair DE = the slot's task control block.
527B
INC HL 23
Increment Register Pair HL to the next task slot.
527C
PUSH HL E5
Save Register Pair HL (the next task slot) to the stack.
527D
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL: the highest address programs may use.
5280
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the SBC below.
5281
SBC HL,DE ED 52
Subtract Register Pair DE (the task control block) from Register Pair HL (the top of memory): the CARRY FLAG is set when the task control block lies above the top of memory.
5283
POP HL E1
Restore Register Pair HL from the stack: the next task slot. POP does not change the flags.
5284
If the CARRY FLAG is set (a task in high memory, above 4049H), JUMP to 52A2H: the top of memory may not be moved.
5286
Decrement Register B (the slots left) and LOOP BACK to 5278H until the 12 slots are tested.
5288
LD A,(402DH) 3A 2D 40
Fetch the byte at 402DH into Register A: 3EH, the LD A,93H of the normal exit, unless a program has put a JP there.
528B
CP C3H FE C3
Compare Register A (the byte at 402DH) against C3H, a JP.
528D
If the Z FLAG is set (402DH holds a JP: RESET was given from inside a program), JUMP to 53A5H to show CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL and abort.
5290
DI F3
Disable the interrupts for the memory test and the rewriting of the device control blocks.
5291
LD HL,FFFFH 21 FF FF
Point Register Pair HL to FFFFH, the highest address, the first one tested for memory.
5294
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A. The memory test loop starts here.
5295
LD B,A 47
Copy Register A (the byte at Register Pair HL) into Register B, to put it back after the test.
5296
CPL 2F
Complement Register A (the byte): every bit changed.
5297
LD (HL),A 77
Store Register A (the complemented byte) to Register Pair HL.
5298
CP (HL) BE
Compare Register A (the complemented byte) against the byte now at Register Pair HL: the Z FLAG is set when the memory kept it, so there is memory there.
5299
LD (HL),B 70
Store Register B (the original byte) back to Register Pair HL. LD does not change the flags.
529A
If the Z FLAG is set (memory at Register Pair HL), JUMP to 52B1H to store Register Pair HL as the top of memory.
529C
LD A,H 7C
Copy Register H (the high byte of the address tested) into Register A.
529D
SUB 04H D6 04
Subtract 04H from Register A (the high byte of the address tested): 400H, 1K, lower.
529F
LD H,A 67
Copy Register A into Register H: Register Pair HL = the address 1K lower (FBFFH, F7FFH and so on).
52A0
JUMP back to 5294H to test the address at Register Pair HL.
52A2
LD HL,53D8H 21 D8 53
Point Register Pair HL to 53D8H, the text CAN'T RESET MEMORY, FOREGROUND TASK(S) EXIST (a task slot pointed above 4049H).
52A5
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL (53D8H) and write it to the job log.
52A8
LD A,03H 3E 03
Load Register A with 03H, the byte that ends a text without being displayed.
52AA
LD (5309H),A 32 09 53
Store Register A (03H) to 5309H over the display code 1CH: the clear screen text displayed at 52E4H shows nothing, so the message stays on the screen.
52AD
DI F3
Disable the interrupts for the rewriting of the device control blocks.
52AE
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL, so that the store below leaves it unchanged.
52B1
LD (4049H),HL 22 49 40
Store Register Pair HL to 4049H-404AH, the top of memory: the highest address with memory found by the test, or the value it had (from 52AEH).
52B4
LD HL,(4020H) 2A 20 40
Fetch the cursor of the DO device control block from 4020H-4021H into Register Pair HL.
52B7
PUSH HL E5
Save Register Pair HL (the cursor) to the stack, as the template copied over the block holds 3C00H.
52B8
LD HL,532CH 21 2C 53
Point Register Pair HL to 532CH, the templates of the KI, DO and PR blocks.
52BB
LD DE,4015H 11 15 40
Point Register Pair DE to 4015H, the KI device control block, the first of the blocks 4015H-402CH.
52BE
LD BC,0018H 01 18 00
Load Register Pair BC with 0018H, the 24 bytes of the three blocks.
52C1
LDIR ED B0
Copy the 24 bytes of the templates at Register Pair HL (532CH) to the blocks at Register Pair DE (4015H-402CH): KI, DO and PR get their type, their start-up driver and their names. Register Pair BC ends at 0000H.
52C3
POP HL E1
Restore Register Pair HL from the stack: the cursor of DO as it was.
52C4
LD (4020H),HL 22 20 40
Store Register Pair HL (the cursor) to 4020H-4021H, the cursor of the DO device control block, over the 3C00H of the template.
52C7
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the value that clears the word at 43BEH-43BFH.
52CA
LD (43BEH),HL 22 BE 43
Store Register Pair HL (0000H) to 43BEH-43BFH, the saved KI driver word that SYS7/SYS and KSM/DVR keep there.
52CD
LD HL,5344H 21 44 53
Point Register Pair HL to 5344H, the templates of the JL, SI and LO blocks.
52D0
LD DE,43C0H 11 C0 43
Point Register Pair DE to 43C0H, the JL device control block, the first of the blocks 43C0H-43D7H.
52D3
LD BC,0018H 01 18 00
Load Register Pair BC with 0018H, the 24 bytes of the three blocks.
52D6
LDIR ED B0
Copy the 24 bytes of the templates at Register Pair HL (5344H) to the blocks at Register Pair DE (43C0H-43D7H): JL NIL, SI routed to 4015H (KI), LO routed to 401DH (DO). Register Pair DE ends at 43D8H, Register Pair BC at 0000H.
52D8
LD HL,43D8H 21 D8 43
Point Register Pair HL to 43D8H, the first of the five free device control blocks 43D8H-43FFH.
52DB
XOR A AF
Set Register A to 00H, the value that clears the free blocks.
52DC
LD (HL),A 77
Store Register A (00H) to the byte at Register Pair HL. The clearing loop starts here.
52DD
INC L 2C
Increment Register L to the next byte; the Z FLAG is set when Register L passes FFH, after 43FFH.
52DE
If the NZ FLAG is set (bytes of 43D8H-43FFH are left), JUMP back to 52DCH to clear the next one.
52E0
EI FB
Enable the interrupts again: the device control blocks are complete.
52E1
LD HL,5309H 21 09 53
Point Register Pair HL to 5309H, the display codes 1CH and 1FH ended by 03H, or the 03H alone after 52AAH.
52E4
GOSUB to 4467H (SYS0/SYS) to display the text at Register Pair HL (5309H): the screen is cleared from the top left, or nothing is shown after a foreground task message.
52E7
JUMP to 402DH, VTOS READY: RESET of all the devices is done.
52EAH - Close the File at the End of a Route
Register Pair HL = a device control block. Routed blocks (type bit 4) are followed through +01H-+02H to the first block that is not routed. When that block is an open file control block (bit 7 of its first byte), its 32 bytes are copied to 530CH and the copy is closed with 4428H (SYS3/SYS); a close error goes to 5382H and the abort. Returns with the Z FLAG when nothing was closed, after a good close with the flags of the close.
52EA
BIT 4,(HL) CB 66
Test bit 4 of the first byte of the block at Register Pair HL: set for a device control block routed to another block or to a file.
52EC
If the Z FLAG is set (bit 4 clear, the end of the route), JUMP to 52F5H to see whether the block is an open file.
52EE
INC HL 23
Increment Register Pair HL to +01H of the routed block, the low byte of the target's address.
52EF
LD A,(HL) 7E
Fetch the low byte of the target's address at Register Pair HL (+01H) into Register A.
52F0
INC HL 23
Increment Register Pair HL to +02H of the routed block, the high byte of the target's address.
52F1
LD H,(HL) 66
Fetch the high byte of the target's address at Register Pair HL (+02H) into Register H.
52F2
LD L,A 6F
Copy Register A (the low byte) into Register L: Register Pair HL = the target of the route.
52F3
JUMP back to 52EAH to test the target at Register Pair HL. A ring of routes would never end this loop.
52F5
BIT 7,(HL) CB 7E
Test bit 7 of the first byte of the block at Register Pair HL: set for an open file control block.
52F7
RET Z C8
If the Z FLAG is set (a device, not an open file), RETURN to the caller with nothing closed.
52F8
LD DE,530CH 11 0C 53
Point Register Pair DE to 530CH, the 32 bytes (not in the file) that receive a copy of the file control block.
52FB
PUSH DE D5
Save Register Pair DE (530CH) to the stack, for the close below.
52FC
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a file control block.
52FF
LDIR ED B0
Copy the 32 bytes of the file control block at Register Pair HL to 530CH-532BH at Register Pair DE; Register Pair BC ends at 0000H. The control block itself keeps its open bit.
5301
POP DE D1
Restore Register Pair DE from the stack: 530CH, the copy of the file control block.
5302
GOSUB to 4428H (SYS0/SYS), request 95H: SYS3/SYS closes the file of the control block at Register Pair DE (530CH), writing its directory record; the Z FLAG on success, else the NZ FLAG and the error code in Register A.
5305
If the NZ FLAG is set (the close failed), JUMP to 5382H to show the error in Register A and abort.
5308
RET C9
RETURN to the caller (522EH or 5260H) with the file closed.
5309H - Clear Screen Codes and the Control Block Copy
The text displayed after RESET of DO and after RESET of all the devices, and the gap of 32 bytes between the second and third load blocks.
5309-530B
DEFB 1CH,1FH,03H 1C 1F 03
The display codes 1CH (cursor to the top left) and 1FH (clear to the end of the screen) and the 03H that ends the text, displayed by 5253H-5256H and 52E1H-52E4H. 52AAH stores 03H over the 1CH when a foreground task exists, so that the reset of all devices does not clear its message from the screen; the member is loaded again from the file for each command, so the 1CH is back the next time.
530C-532B
DEFS 32
Not in the file: the gap between the second and third load blocks receives a copy of the open file control block at the end of a route (52F8H-52FFH), which 5302H closes with 4428H; SYS3/SYS rewrites the copy's first bytes as the file's name.
532CH - Device Control Block Templates
Six blocks of 8 bytes: +00H the type, +01H-+02H the driver or the block routed to, +03H-+05H the driver's bytes, +06H-+07H the name. The first three are copied to 4015H-402CH (5241H-524AH for one of them, 52B8H-52C1H for all), the last three to 43C0H-43D7H (52CDH-52D6H). The driver words of KI, DO and PR are filled in at 5201H-5212H from 43B8H-43BDH.
532C-5333
DEFB 01H / DEFW 0000H / DEFB 00H,00H,00H / DEFM "KI" 01 00 00 00 00 00 4B 49
The KI template: type 01H (input), the driver word 0000H in the file, replaced at 5204H by the start-up KI driver from 43B8H at every run, three bytes 00H (4018H the key held, 4019H the repeat tick, 401AH unused) and the name KI.
5334-533B
DEFB 07H / DEFW 0000H / DEFW 3C00H / DEFB 00H / DEFM "DO" 07 00 00 00 3C 00 44 4F
The DO template: type 07H (input, output and control), the driver word 0000H in the file, replaced at 520AH by the start-up DO driver from 43BAH, the cursor 3C00H (the top left of the screen, 4020H-4021H), 00H and the name DO.
533C-5343
DEFB 06H / DEFW 0000H / DEFB 42H,00H,00H / DEFM "PR" 06 00 00 42 00 00 50 52
The PR template: type 06H (output and control), the driver word 0000H in the file, replaced at 5210H by the start-up PR driver from 43BCH, 42H (66 lines a page, 4028H), the line count 00H (4029H), 00H and the name PR.
5344-534B
DEFB 08H / DEFW 0000H / DEFB 00H,00H,00H / DEFM "JL" 08 00 00 00 00 00 4A 4C
The JL (job log) template for 43C0H: type 08H, NIL, so the job log is off; the word and the driver bytes 00H and the name JL.
534C-5353
DEFB 10H / DEFW 4015H / DEFB 00H,00H,00H / DEFM "SI" 10 15 40 00 00 00 53 49
The SI template for 43C8H: type 10H, routed to the block at 4015H (KI); three bytes 00H and the name SI.
5354-535B
DEFB 10H / DEFW 401DH / DEFB 00H,00H,00H / DEFM "LO" 10 1D 40 00 00 00 4C 4F
The LO template for 43D0H: type 10H, routed to the block at 401DH (DO); three bytes 00H and the name LO.
535CH - Find a Device Control Block by Name
Register E = the first letter of the name, Register D = the second. The blocks 4015H, 401DH, 4025H and then 43C0H-43F8H are compared at +06H-+07H. Found: the Z FLAG, Register A = 00H and Register Pair HL = the block. Not found: the NZ FLAG and Register A = 08H, DEVICE NOT AVAILABLE.
535C
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the KI device control block, the first one compared.
535F
PUSH HL E5
Save Register Pair HL (the device control block) to the stack. The search loop starts here.
5360
LD A,L 7D
Copy Register L (the low byte of the device control block's address) into Register A.
5361
ADD A,06H C6 06
Add 06H to Register A: the low byte of the block's name at +06H.
5363
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the device control block, the first letter of its name.
5364
LD A,(HL) 7E
Fetch the first letter of the block's name at Register Pair HL (+06H) into Register A.
5365
INC L 2C
Increment Register L to +07H of the device control block, the second letter of its name.
5366
CP E BB
Compare Register A (the block's first letter) against Register E (the first letter typed).
5367
If the NZ FLAG is set (the first letters differ), JUMP to 5370H to go on with the next block.
5369
LD A,(HL) 7E
Fetch the second letter of the block's name at Register Pair HL (+07H) into Register A.
536A
CP D BA
Compare Register A (the block's second letter) against Register D (the second letter typed).
536B
If the NZ FLAG is set (the second letters differ), JUMP to 5370H to go on with the next block.
536D
POP HL E1
Restore Register Pair HL from the stack: the device control block whose name matches.
536E
XOR A AF
Set Register A to 00H and the Z FLAG (XOR A): the block is found.
536F
RET C9
RETURN to 5227H with the Z FLAG, Register A = 00H and Register Pair HL = the device control block.
5370
POP AF F1
Restore Register Pair AF from the stack: the block's address pushed at 535FH is dropped into Register Pair AF; Register Pair HL still points at +07H of the block.
5371
INC L 2C
Increment Register L from +07H of the block to the next block, 8 bytes after the last; the Z FLAG is set when Register L passes FFH, after the last block 43F8H.
5372
If the NZ FLAG is set (blocks are left), JUMP to 5378H.
5374
LD A,08H 3E 08
Load Register A with 08H, the error code DEVICE NOT AVAILABLE.
5376
OR A B7
OR Register A (08H) with itself to set the NZ FLAG: no block has the name.
5377
RET C9
RETURN to 5227H with the NZ FLAG and Register A = 08H.
5378
LD A,L 7D
Copy Register L (the low byte of the next block) into Register A.
5379
CP 2DH FE 2D
Compare Register A (the low byte of the next block) against 2DH, one past the PR block 4025H-402CH.
537B
If the NZ FLAG is set (401DH, 4025H or a block of 43C8H-43F8H), JUMP back to 535FH to compare the block at Register Pair HL.
537D
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the JL block, the first of the eight blocks at 43C0H-43FFH.
5380
JUMP back to 535FH to compare the block at Register Pair HL (43C0H).
5382H - Errors and Their Texts
5382H shows an error code as text alone and aborts (08H from the search, a close error from 52EAH); 5387H and 53A5H show this member's own texts with 447BH (display and job log) and take the abort exit 4030H.
5382
OR 40H F6 40
OR Register A (the error code: 08H DEVICE NOT AVAILABLE, or the close error from 5305H) with 40H: bit 6 asks 4409H for the text of the error alone; bit 7 stays clear, so 4409H does not return.
5384
JUMP to 4409H to display the error message of the code in Register A; SYS4/SYS then takes the abort exit 4030H.
5387
LD HL,5390H 21 90 53
Point Register Pair HL to 5390H, the text DEVICE SPEC REQUIRED, for a file specification after RESET.
538A
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL (5390H) and write it to the job log.
538D
JUMP to 4030H, the abort exit of the system: RESET of a file is refused.
5390-53A3
DEFM "DEVICE SPEC REQUIRED" 44 45 56 49 43 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The text DEVICE SPEC REQUIRED, shown by 5387H-538AH when the specification after RESET does not start with an asterisk.
53A4
DEFB 0DH 0D
The carriage return that ends the text DEVICE SPEC REQUIRED; 447BH displays it and stops.
53A5
LD HL,53AEH 21 AE 53
Point Register Pair HL to 53AEH, the text CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL, for 402DH holding a JP.
53A8
GOSUB to 447BH (SYS0/SYS) to display the text at Register Pair HL (53AEH) and write it to the job log.
53AB
JUMP to 4030H, the abort exit of the system: the files at the ends of routes are closed already (525CH-5271H), nothing else has been reset.
53AE-53D6
DEFM "CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL" 43 41 4E 27 54 20 2D 2D 20 56 41 4C 49 44 20 4F 4E 4C 59 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C
The text CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL, shown by 53A5H-53A8H when 402DH holds a JP (C3H) and all devices were to be reset.
53D7
DEFB 0DH 0D
The carriage return that ends the text CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL.
53D8-5403
DEFM "CAN'T RESET MEMORY, FOREGROUND TASK(S) EXIST" 43 41 4E 27 54 20 52 45 53 45 54 20 4D 45 4D 4F 52 59 2C 20 46 4F 52 45 47 52 4F 55 4E 44 20 54 41 53 4B 28 53 29 20 45 58 49 53 54
The text CAN'T RESET MEMORY, FOREGROUND TASK(S) EXIST, shown by 52A2H-52A5H when a task slot points above the top of memory 4049H; the devices are reset all the same.
5404
DEFB 0DH 0D
The carriage return that ends the text CAN'T RESET MEMORY, FOREGROUND TASK(S) EXIST.
5405-5424
DEFS 32
Not in the file: the control block that receives the specification after RESET (5214H-5217H, 441CH: the asterisk, the device name and 03H, or a file specification); 521DH reads its first byte and 5223H the two letters at 5406H-5407H.
5200H - Member 24 (ROUTE, Code 64H): Read the Device to Route
SYS1/SYS's command interpreter runs this member for the word ROUTE (member code 64H): the request handler of SYS0/SYS loads it at 5200H and CALLs 5200H with Register Pair HL pointing at the rest of the command line after the word ROUTE and its delimiter. The syntax the code reads is ROUTE an asterisk and a device name, then either the parameter list (NIL), or (with or without TO) a second device or a file. The first specification goes to the control block at 5389H through 441CH (SYS1/SYS's 4FCEH) and must start with an asterisk; otherwise DEVICE SPEC REQUIRED.
5200
LD DE,5389H 11 89 53
Point Register Pair DE to 5389H, the 32 byte control block (not in the file) for the device to route.
5203
GOSUB to 441CH (request C3H, SYS1/SYS's 4FCEH) to copy the specification at Register Pair HL into the control block at Register Pair DE (5389H): Register Pair HL returns past it and its delimiter, the Z FLAG for a good specification.
5206
If the NZ FLAG is set (no good specification), JUMP to 5352H to display DEVICE SPEC REQUIRED and abort.
5209
LD A,(DE) 1A
Fetch the first byte of the specification from the control block at Register Pair DE (5389H) into Register A.
520A
CP 2AH FE 2A
Compare Register A (the first byte of the specification at 5389H) against 2AH, an asterisk: a device.
520C
If the NZ FLAG is set (a file name, not a device), JUMP to 5352H to display DEVICE SPEC REQUIRED and abort.
520F
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the value of the NIL parameter when it is not given.
5212
LD (5220H),DE ED 53 20 52
Store Register Pair DE (0000H) to 5220H-5221H, the operand of LD BC at 521FH: NIL not given yet. The operand is 0000H in the file already.
5216
LD DE,5305H 11 05 53
Point Register Pair DE to 5305H, the parameter table of ROUTE, which holds the one name NIL.
5219
GOSUB to 4476H (request E3H, SYS1/SYS's 510FH) to read a parameter list at Register Pair HL with the table at Register Pair DE (5305H): NIL stores FFFFH at 5220H. Without an opening parenthesis nothing is stored and the Z FLAG returns.
521C
If the NZ FLAG is set (an unknown name or a bad list), JUMP to 5370H to display PARAMETER ERROR and abort.
521F
LD BC,0000H 01 00 00
Self-Modifying Code
Load Register Pair BC with the NIL parameter's value: the operand 5220H-5221H is 0000H in the file, stored as 0000H again at 5212H, and SYS1/SYS's 510FH stores FFFFH there at 5219H when (NIL) is given.
5222
LD A,B 78
Copy Register B (the high byte of NIL's value) into Register A.
5223
OR C B1
OR Register C (the low byte of NIL's value) into Register A: the NZ FLAG is set when NIL was given.
5224
If the NZ FLAG is set (NIL), JUMP to 52D6H to make the device a NIL device.
5227H - Read Where the Device Goes
The second specification (after a TO, which SYS1/SYS's 4FCEH passes over as a preposition) goes to the control block at 53A9H. An asterisk first makes it a device: its device control block is found by name and the device to route is pointed at it. Anything else is a file (526EH).
5227
LD DE,53A9H 11 A9 53
Point Register Pair DE to 53A9H, the 32 byte control block (not in the file) for the device or file the device is routed to.
522A
GOSUB to 441CH (request C3H, SYS1/SYS's 4FCEH) to copy the next specification at Register Pair HL into the control block at Register Pair DE (53A9H); a preposition such as TO is passed over and the word after it is read.
522D
If the NZ FLAG is set (no good second specification), JUMP to 5352H to display DEVICE SPEC REQUIRED and abort.
5230
LD A,(DE) 1A
Fetch the first byte of the second specification from the control block at Register Pair DE (53A9H) into Register A.
5231
CP 2AH FE 2A
Compare Register A (the first byte at 53A9H) against 2AH, an asterisk: a device.
5233
If the NZ FLAG is set (a file), JUMP to 526EH to route the device to the file.
5235
LD DE,(53AAH) ED 5B AA 53
Fetch the two letters of the second device's name from 53AAH-53ABH into Register Pair DE: Register E the first letter, Register D the second.
5239
GOSUB to 53C9H to find the device control block whose name (+06H-+07H) is Register E and Register D: Register Pair HL = the block and the Z FLAG when it is found.
523C
If the NZ FLAG is set (no such device, Register A = 08H), JUMP to 534DH to display DEVICE NOT AVAILABLE and abort.
523F
PUSH HL E5
Save Register Pair HL (the device control block the device is routed to) to the stack; 525FH takes it back.
5240H - Point the Device at Its New Target
The stack holds the target: a device control block, or the control block of the file in high memory (from 52A1H). The device to route is found by name (5389H +01H-+02H); a new name takes the first free block (name 0000H), and none left gives error 21H. A route it had to an open file is closed first (530EH). Then, with interrupts off, the block gets type 10H (routed), the target at +01H-+02H and the name at +06H-+07H.
5240
LD DE,(538AH) ED 5B 8A 53
Fetch the two letters of the name of the device to route from 538AH-538BH into Register Pair DE: Register E the first letter, Register D the second.
5244
GOSUB to 53C9H to find the device control block named Register E and Register D: Register Pair HL = the block and the Z FLAG when it is found.
5247
If the Z FLAG is set (the device exists), JUMP to 5256H with Register Pair HL = its block.
5249
PUSH DE D5
Save Register Pair DE (the two letters of the new device's name) to the stack.
524A
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the name of a free device control block.
524D
GOSUB to 53C9H to find the first device control block whose name is 0000H: Register Pair HL = the free block and the Z FLAG when there is one.
5250
LD A,21H 3E 21
Load Register A with 21H, the error code NO DEVICE SPACE AVAILABLE. LD does not change the flags.
5252
If the NZ FLAG is set (no free block), JUMP to 534DH to display NO DEVICE SPACE AVAILABLE and abort.
5255
POP DE D1
Restore Register Pair DE from the stack: the two letters of the new device's name.
5256
PUSH HL E5
Save Register Pair HL (the device control block of the device to route) to the stack.
5257
GOSUB to 530EH to follow the device's routes from Register Pair HL and close the file it reaches, if any.
525A
POP HL E1
Restore Register Pair HL from the stack: the device control block of the device to route.
525B
DI F3
Disable interrupts: no interrupt routine can use the device control block while it is half changed.
525C
LD (HL),10H 36 10
Store 10H, the type of a routed device, to +00H of the device control block at Register Pair HL.
525E
INC L 2C
Increment Register L to +01H of the device control block.
525F
POP BC C1
Restore Register Pair BC from the stack: the target, a device control block or the file's control block in high memory (pushed at 523FH or 529BH).
5260
LD (HL),C 71
Store Register C (the low byte of the target's address) to +01H of the device control block at Register Pair HL.
5261
INC L 2C
Increment Register L to +02H of the device control block.
5262
LD (HL),B 70
Store Register B (the high byte of the target's address) to +02H at Register Pair HL: the device now goes to Register Pair BC.
5263
LD A,L 7D
Copy Register L (the low byte of +02H's address) into Register A.
5264
ADD A,04H C6 04
Add 04H to Register A: the low byte of +06H, the name of the device control block.
5266
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the device control block.
5267
LD (HL),E 73
Store Register E (the first letter of the name) to +06H of the device control block at Register Pair HL.
5268
INC L 2C
Increment Register L to +07H of the device control block.
5269
LD (HL),D 72
Store Register D (the second letter of the name) to +07H at Register Pair HL: a new device gets its name here.
526A
EI FB
Enable interrupts again: the device control block is complete.
526B
JUMP to 402DH, VTOS READY: the device is routed.
526EH - Route to a File: Open It in High Memory
Only at the command level: when the exit 402DH begins with C3H (a JP placed there instead of LD A,93H, as BASIC/CMD does at its 66A6H-66ABH) the route to a file is refused. The 256 byte buffer is the top page below 4049H's top of memory; the file is opened or created there with record length 256 (B = 00H) and positioned to its end, so the data is added after what the file holds. The 32 byte control block is then copied from 53A9H to just below the buffer and the top of memory lowered below it; the copy's address goes on the stack as the target for 5240H.
526E
LD A,(402DH) 3A 2D 40
Fetch the first byte of the exit 402DH into Register A: 3EH (LD A,93H) as SYS0/SYS loads it, C3H when a program has put a JP there.
5271
CP C3H FE C3
Compare Register A (the byte at 402DH) against C3H, a JP.
5273
If the Z FLAG is set (the exit 402DH has been taken over), JUMP to 52A3H to display CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL and abort.
5276
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL.
5279
INC HL 23
Increment Register Pair HL to the byte above the top of memory.
527A
DEC H 25
Decrement Register H: Register Pair HL = the top of memory plus 1 less 0100H, the start of the 256 byte buffer.
527B
PUSH HL E5
Save Register Pair HL (the start of the buffer) to the stack.
527C
LD B,00H 06 00
Load Register B with 00H, the record length 256 for the open.
527E
GOSUB to 4420H (request A4H, SYS2/SYS) to open the file of the control block at Register Pair DE (53A9H) with the buffer at Register Pair HL and record length Register B, creating the file when it is not there.
5281
If the NZ FLAG is set (the file cannot be opened or created), JUMP to 534DH with the error code in Register A to display it and abort.
5284
GOSUB to 4448H to position the open file of the control block at Register Pair DE (53A9H) to its end of file.
5287
If the Z FLAG is set (positioned), JUMP to 528EH.
5289
CP 1CH FE 1C
Compare Register A (the result of the positioning) against 1CH, END OF FILE ENCOUNTERED, which the position at the end gives.
528B
If the NZ FLAG is set (another error), JUMP to 534DH with the error code in Register A to display it and abort.
528E
POP HL E1
Restore Register Pair HL from the stack: the start of the 256 byte buffer.
528F
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a file control block.
5292
XOR A AF
Set Register A to 00H and clear the CARRY FLAG (XOR A) for the SBC below.
5293
SBC HL,BC ED 42
SUBtract Register Pair BC (0020H) from Register Pair HL: Register Pair HL = the place of the file control block, just below the buffer.
5295
PUSH HL E5
Save Register Pair HL (the place of the file control block) to the stack.
5296
DEC HL 2B
Decrement Register Pair HL to the byte below the file control block.
5297
LD (4049H),HL 22 49 40
Store Register Pair HL to 4049H-404AH, the top of memory: the control block and the buffer above it are now kept from other programs.
529A
POP DE D1
Restore Register Pair DE from the stack: the place of the file control block in high memory.
529B
PUSH DE D5
Save Register Pair DE (the file control block in high memory) to the stack again: it is the target that 525FH stores in the device control block.
529C
LD HL,53A9H 21 A9 53
Point Register Pair HL to 53A9H, the open file control block.
529F
LDIR ED B0
Copy the 32 bytes (Register Pair BC = 0020H) from Register Pair HL (53A9H) to Register Pair DE (the place in high memory): the open file control block is moved up. Register Pair BC ends at 0000H.
52A1
JUMP back to 5240H to find the device to route and point it at the file control block in high memory.
52A3
LD HL,52ACH 21 AC 52
Point Register Pair HL to 52ACH, the text CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL.
52A6
GOSUB to 447BH to display the text at Register Pair HL (52ACH) and write it to the job log.
52A9
JUMP to 4030H, the abort exit, after the message about the command level.
52AC-52D5
DEFM "CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL" / DEFB 0DH 43 41 4E 27 54 20 2D 2D 20 4F 4E 4C 59 20 56 41 4C 49 44 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C 0D
The message CAN'T -- ONLY VALID AT VTOS COMMAND LEVEL (two minus signs after CAN'T) and its carriage return, shown by 52A3H when 402DH holds a JP.
52D6H - NIL: Make the Device a NIL Device
(NIL) gives the device type 08H, NIL, for which SYS0/SYS's 44C4H returns 00H without calling a driver. A device that exists keeps its name and +01H-+02H; a route it had to an open file is closed first. A new name takes the first free device control block (error 21H when none is left) and gets the type and the name.
52D6
LD DE,(538AH) ED 5B 8A 53
Fetch the two letters of the name of the device from 538AH-538BH into Register Pair DE: Register E the first letter, Register D the second.
52DA
GOSUB to 53C9H to find the device control block named Register E and Register D: Register Pair HL = the block and the Z FLAG when it is found.
52DD
If the NZ FLAG is set (no such device), JUMP to 52E8H to take a free device control block.
52E0
PUSH HL E5
Save Register Pair HL (the device control block found) to the stack.
52E1
GOSUB to 530EH to follow the device's routes from Register Pair HL and close the file it reaches, if any.
52E4
POP HL E1
Restore Register Pair HL from the stack: the device control block of the device.
52E5
LD (HL),08H 36 08
Store 08H, the type of a NIL device, to +00H of the device control block at Register Pair HL.
52E7
RET C9
RETURN to the request handler's 4C4BH, which returns to 402DH, VTOS READY: the device is NIL.
52E8
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the name of a free device control block.
52EB
GOSUB to 53C9H to find the first device control block whose name is 0000H: Register Pair HL = the free block and the Z FLAG when there is one.
52EE
LD A,21H 3E 21
Load Register A with 21H, the error code NO DEVICE SPACE AVAILABLE. LD does not change the flags.
52F0
If the NZ FLAG is set (no free block), JUMP to 534DH to display NO DEVICE SPACE AVAILABLE and abort.
52F3
DI F3
Disable interrupts: no interrupt routine can use the device control block while it is half changed.
52F4
LD DE,(538AH) ED 5B 8A 53
Fetch the two letters of the new device's name from 538AH-538BH into Register Pair DE again: Register E the first letter, Register D the second.
52F8
LD (HL),08H 36 08
Store 08H, the type of a NIL device, to +00H of the free device control block at Register Pair HL.
52FA
LD A,L 7D
Copy Register L (the low byte of the block's address) into Register A.
52FB
ADD A,06H C6 06
Add 06H to Register A: the low byte of +06H, the name of the device control block.
52FD
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the device control block.
52FE
LD (HL),E 73
Store Register E (the first letter of the name) to +06H of the device control block at Register Pair HL.
52FF
INC L 2C
Increment Register L to +07H of the device control block.
5300
LD (HL),D 72
Store Register D (the second letter of the name) to +07H at Register Pair HL: the new device has its name.
5301
EI FB
Enable interrupts again: the device control block is complete.
5302
JUMP to 402DH, VTOS READY: the new device is NIL.
5305-530C
DEFM "NIL " / DEFW 5220H 4E 49 4C 20 20 20 20 52
The one entry of the parameter table (5216H): the name NIL padded with spaces, then 5220H, the operand of LD BC at 521FH that receives its value.
530D
DEFB 00H 00
The 00H that ends the parameter table at 5305H.
530EH - Close the File a Device Reaches
Register Pair HL = a device control block. While its type has bit 4 set (10H, routed) the route at +01H-+02H is followed. When the end of the chain is an open file control block (+00H bit 7 set) its 32 bytes are copied to 532DH and the copy is closed by SYS3/SYS (4428H); the control block in high memory is left as it is and the memory under 4049H is not given back. Returns with the Z FLAG when there was no file, or after the close.
530E
BIT 4,(HL) CB 66
Test bit 4 of +00H of the block at Register Pair HL: set for type 10H, a routed device.
5310
If the Z FLAG is set (not routed), JUMP to 5319H to look for a file.
5312
INC HL 23
Increment Register Pair HL to +01H, the low byte of the route's target.
5313
LD A,(HL) 7E
Fetch the low byte of the target from +01H at Register Pair HL into Register A.
5314
INC HL 23
Increment Register Pair HL to +02H, the high byte of the target.
5315
LD H,(HL) 66
Fetch the high byte of the target from +02H at Register Pair HL into Register H.
5316
LD L,A 6F
Copy Register A (the low byte of the target) into Register L: Register Pair HL = the block the device is routed to.
5317
JUMP back to 530EH to look at the block the route goes to.
5319
BIT 7,(HL) CB 7E
Test bit 7 of +00H of the block at Register Pair HL: set for an open file control block.
531B
RET Z C8
If the Z FLAG is set (a device, not a file), RETURN: there is nothing to close.
531C
LD DE,532DH 11 2D 53
Point Register Pair DE to 532DH, the 32 bytes (not in the file) for a copy of the file control block.
531F
PUSH DE D5
Save Register Pair DE (532DH) to the stack, for the close below.
5320
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a file control block.
5323
LDIR ED B0
Copy the 32 bytes (Register Pair BC) of the file control block from Register Pair HL to Register Pair DE (532DH). Register Pair BC ends at 0000H.
5325
POP DE D1
Restore Register Pair DE from the stack: 532DH, the copy of the file control block.
5326
GOSUB to 4428H (request 95H, SYS3/SYS's 4E0DH) to close the file of the control block at Register Pair DE (532DH).
5329
If the NZ FLAG is set (the close failed), JUMP to 534DH with the error code in Register A to display it and abort.
532C
RET C9
RETURN with the Z FLAG: the file the device reached is closed.
532D-534C
DEFS 32
Not in the file (the gap between the load blocks 52FEH-532CH and 534DH-5388H): the copy of the file control block that 530EH closes. 5323H copies the control block found at the end of a device's routes here, and 4428H (5326H) closes it.
534DH - Error Exits and Messages
534DH shows the error code in Register A as text alone and aborts; 5352H and 5370H display one of the member's messages and take the abort exit 4030H.
534D
OR 40H F6 40
OR 40H into Register A (the error code): bit 6 asks 4409H for the text alone; bit 7 clear means no return.
534F
JUMP to 4409H to display the error message of Register A and abort.
5352
LD HL,535BH 21 5B 53
Point Register Pair HL to 535BH, the text DEVICE SPEC REQUIRED.
5355
GOSUB to 447BH to display the text at Register Pair HL (535BH) and write it to the job log.
5358
JUMP to 4030H, the abort exit, after the message DEVICE SPEC REQUIRED.
535B-536F
DEFM "DEVICE SPEC REQUIRED" / DEFB 0DH 44 45 56 49 43 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44 0D
The message DEVICE SPEC REQUIRED and its carriage return, shown by 5352H when a specification is missing, bad, or (the first one) not a device.
5370
LD HL,5379H 21 79 53
Point Register Pair HL to 5379H, the text PARAMETER ERROR.
5373
GOSUB to 447BH to display the text at Register Pair HL (5379H) and write it to the job log.
5376
JUMP to 4030H, the abort exit, after the message PARAMETER ERROR.
5379-5388
DEFM "PARAMETER ERROR" / DEFB 0DH 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52 0D
The message PARAMETER ERROR and its carriage return, shown by 5370H when SYS1/SYS's 510FH refuses the parameter list.
5389-53A8
DEFS 32
Not in the file (the gap between the load blocks 534DH-5388H and 53C9H-53EEH): the control block of the first specification, the device to route. 5203H fills it through SYS1/SYS's 4FCEH; 5209H tests its asterisk, and 5240H, 52D6H and 52F4H read the device name at 538AH-538BH.
53A9-53C8
DEFS 32
Not in the file (the same gap): the control block of the second specification. 522AH fills it; 5230H tests its asterisk and 5235H reads the device name at 53AAH-53ABH; for a file 527EH opens it here, 5284H positions it and 529FH copies it to high memory.
53C9H - Find a Device Control Block by Name
Register E and Register D = the two letters of a name (0000H for a free block). The blocks are 8 bytes: 4015H (KI), 401DH (DO), 4025H (PR), then 43C0H-43FFH (JL, SI, LO and five more); +06H-+07H hold the name. Returns the Z FLAG, Register A = 00H and Register Pair HL = the block; or the NZ FLAG and Register A = 08H, DEVICE NOT AVAILABLE. Register Pair DE is kept.
53C9
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the first device control block (KI).
53CC
PUSH HL E5
Save Register Pair HL (the start of the device control block) to the stack.
53CD
LD A,L 7D
Copy Register L (the low byte of the block's address) into Register A.
53CE
ADD A,06H C6 06
Add 06H to Register A: the low byte of +06H, the first letter of the block's name.
53D0
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the device control block.
53D1
LD A,(HL) 7E
Fetch the first letter of the block's name from +06H at Register Pair HL into Register A.
53D2
INC L 2C
Increment Register L to +07H, the second letter of the name.
53D3
CP E BB
Compare Register A (the block's first letter) against Register E (the first letter wanted).
53D4
If the NZ FLAG is set (another first letter), JUMP to 53DDH for the next block.
53D6
LD A,(HL) 7E
Fetch the second letter of the block's name from +07H at Register Pair HL into Register A.
53D7
CP D BA
Compare Register A (the block's second letter) against Register D (the second letter wanted).
53D8
If the NZ FLAG is set (another second letter), JUMP to 53DDH for the next block.
53DA
POP HL E1
Restore Register Pair HL from the stack: the start of the device control block found.
53DB
XOR A AF
Set Register A to 00H and the Z FLAG (XOR A): the block is found.
53DC
RET C9
RETURN with the Z FLAG and Register Pair HL = the device control block.
53DD
POP AF F1
Restore Register Pair AF from the stack: this drops the saved start of the block; Register Pair HL stays at +07H.
53DE
INC L 2C
Increment Register L from +07H to the first byte of the next device control block; the Z FLAG is set when Register L wraps to 00H past 43FFH.
53DF
If the NZ FLAG is set (more blocks), JUMP to 53E5H.
53E1
LD A,08H 3E 08
Load Register A with 08H, the error code DEVICE NOT AVAILABLE.
53E3
OR A B7
OR Register A (08H) with itself to set the NZ FLAG.
53E4
RET C9
RETURN with the NZ FLAG and Register A = 08H: no block has the name.
53E5
LD A,L 7D
Copy Register L (the low byte of the next block) into Register A.
53E6
CP 2DH FE 2D
Compare Register A against 2DH, the byte after the PR block 4025H-402CH.
53E8
If the NZ FLAG is set (still among 4015H-402CH or 43C0H-43FFH), JUMP back to 53CCH for this block.
53EA
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the first of the other device control blocks (JL).
53ED
JUMP back to 53CCH to look at the block at 43C0H.
5A00H - Member 25 (FILTER, SET, Codes 66H, 65H): FILTER Entry, Code 66H
SYS1/SYS's command interpreter runs this member for the words FILTER (member code 66H, entry 5A00H) and SET (member code 65H, entry 5A01H); the request handler of SYS0/SYS loads it at 5A00H-5B19H, not at 5200H, so that the driver or filter file it loads can take 5200H. Register Pair HL points at the rest of the command line: a device specification (an asterisk and a name of one or two letters), an optional preposition (TO, ON, OVER or USING), a file specification and an optional parameter text for the loaded program. The member refuses to run when 402DH holds a JP (C3H), the sign that a program such as BASIC/CMD has taken over the system exits. It finds the device control block of the device among 4015H, 401DH, 4025H and 43C0H-43F8H by its name at +06H-+07H (SET takes a free block, name 0000H, when the device does not exist yet; FILTER needs an existing device), loads the file (default extension DVR for SET, FLT for FILTER) with 4430H and jumps to its transfer address with Register Pair DE = the device control block and Register Pair HL = the rest of the command line. Before that jump (after the load), SET writes the device name into the block. Errors end through 4409H (08H DEVICE NOT AVAILABLE, 21H NO DEVICE SPACE AVAILABLE, a load error) or with a message and the abort exit 4030H.
5A00
OR AFH F6 AF
OR Register A with AFH (FILTER enters here; SET enters at 5A01H, the second byte of this instruction): Register A, the code from 430EH, becomes AFH or more, never 00H, the flag of FILTER.
5A01H - SET Entry, Code 65H, and the Common Part
SET enters at 5A01H, the operand byte AFH of the OR at 5A00H, which is the instruction XOR A: Register A = 00H, the flag of SET. FILTER runs through the OR at 5A00H instead and arrives at 5A02H with Register A not 00H. The flag is stored at 5A64H, the operand of LD A,00H at 5A63H, and read at 5A2CH and 5A44H as well.
5A02
LD (5A64H),A 32 64 5A
Store Register A (00H for SET, AFH or more for FILTER) to 5A64H, the operand of LD A,00H at 5A63H: the flag that tells SET from FILTER.
5A05
LD A,(402DH) 3A 2D 40
Fetch the first byte of the normal exit at 402DH into Register A: 3EH (LD A,93H) as the system has it, C3H (JP) when a program has replaced the exit with its own jump.
5A08
CP C3H FE C3
Compare Register A (the first byte at 402DH) against C3H, the opcode JP.
5A0A
If the Z FLAG is set (402DH is a JP: the command was given from inside a program such as BASIC/CMD, which writes C3H there at its 66A9H), JUMP to 5AE7H to display CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL and abort.
5A0D
LD DE,5B1AH 11 1A 5B
Point Register Pair DE to 5B1AH, the first control block of the member (not in the file), which takes the device specification.
5A10
GOSUB to 441CH, SYS1/SYS function 4: copy the specification from the text at Register Pair HL (the rest of the command line) into the block at Register Pair DE (5B1AH). It returns the Z FLAG when good, Register Pair HL past the specification and Register Pair DE = 5B1AH.
5A13
If the NZ FLAG is set (no valid specification), JUMP to 5AC9H to display DEVICE SPEC REQUIRED and abort.
5A16
LD A,(DE) 1A
Fetch the first byte of the specification from the block at Register Pair DE (5B1AH) into Register A.
5A17
CP 2AH FE 2A
Compare Register A (the first byte of the specification) against 2AH, the asterisk that starts a device name.
5A19
If the NZ FLAG is set (a file was named, not a device), JUMP to 5AC9H to display DEVICE SPEC REQUIRED and abort.
5A1C
LD DE,5B3AH 11 3A 5B
Point Register Pair DE to 5B3AH, the second control block of the member (not in the file), which takes the file specification of the driver or filter.
5A1F
GOSUB to 441CH, SYS1/SYS function 4: copy the next specification from the text at Register Pair HL into the block at Register Pair DE (5B3AH). A preposition (TO, ON, OVER, USING) is passed over and the word after it read into the same block. Register Pair HL ends past the specification, at the parameter text.
5A22
If the NZ FLAG is set (no valid file specification), JUMP to 5AADH to display FILE SPEC REQUIRED and abort.
5A25
LD A,(DE) 1A
Fetch the first byte of the file specification from the block at Register Pair DE (5B3AH) into Register A.
5A26
CP 2AH FE 2A
Compare Register A (the first byte) against 2AH, an asterisk, which would name a device in place of the file.
5A28
If the Z FLAG is set (a device was named), JUMP to 5AADH to display FILE SPEC REQUIRED and abort.
5A2B
PUSH HL E5
Save Register Pair HL (the rest of the command line, the parameter text for the loaded program) to the stack; 5A7AH takes it back.
5A2C
LD A,(5A64H) 3A 64 5A
Fetch the flag from 5A64H (00H SET, not 00H FILTER) into Register A.
5A2F
OR A B7
OR Register A (the flag) with itself: the Z FLAG is set for SET.
5A30
LD HL,5A7CH 21 7C 5A
Point Register Pair HL to 5A7CH, the default extension DVR of SET. LD does not change the flags.
5A33
If the Z FLAG is set (SET), JUMP to 5A38H with the extension DVR.
5A35
LD HL,5A7FH 21 7F 5A
Point Register Pair HL to 5A7FH, the default extension FLT of FILTER.
5A38
GOSUB to 4473H, SYS1/SYS function 5: add the extension at Register Pair HL (DVR or FLT) to the file specification in the block at Register Pair DE (5B3AH) when it has none.
5A3B
LD DE,(5B1BH) ED 5B 1B 5B
Fetch the two letters of the device name from 5B1BH-5B1CH (after the asterisk at 5B1AH) into Register Pair DE: Register E the first letter, Register D the second.
5A3F
GOSUB to 5A82H to find the device control block whose name at +06H-+07H equals Register Pair DE: the Z FLAG with Register Pair HL = the block when found, else the NZ FLAG.
5A42
If the Z FLAG is set (the device exists), JUMP to 5A59H to load the file for its block in Register Pair HL.
5A44
LD A,(5A64H) 3A 64 5A
Fetch the flag from 5A64H (00H SET, not 00H FILTER) into Register A.
5A47
OR A B7
OR Register A (the flag) with itself: the NZ FLAG is set for FILTER.
5A48
LD A,08H 3E 08
Load Register A with 08H, the error code DEVICE NOT AVAILABLE. LD does not change the flags.
5A4A
If the NZ FLAG is set (FILTER on a device that does not exist), JUMP to 5AA8H to display error 08H, DEVICE NOT AVAILABLE, and abort.
5A4C
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the name of a free device control block (the reset clears the five free blocks 43D8H-43FFH).
5A4F
GOSUB to 5A82H to find a device control block whose name at +06H-+07H is Register Pair DE (0000H): the Z FLAG with Register Pair HL = a free block, else the NZ FLAG.
5A52
If the Z FLAG is set (a free block was found), JUMP to 5A59H to load the driver for it.
5A54
LD A,21H 3E 21
Load Register A with 21H, the error code NO DEVICE SPACE AVAILABLE: every device control block is in use.
5A56
JUMP to 5AA8H to display error 21H, NO DEVICE SPACE AVAILABLE, and abort.
5A59H - Load the Driver or Filter and Enter It
Register Pair HL = the device control block (found or free). It is pushed and the file named at 5B3AH is loaded with 4430H (SYS0/SYS's program loader; on success Register Pair HL = its transfer address). SET then writes the two letters of the device name into +06H-+07H of the block, with the interrupts off between the two stores; FILTER leaves the block as it is. Finally Register Pair DE = the block, Register Pair HL = the parameter text, and the RET jumps to the transfer address of the loaded file. The stack below is the member's own entry stack, so a driver that ends with RET returns to 4C4BH, the request handler, and the command ends normally.
5A59
PUSH HL E5
Save Register Pair HL (the device control block found or free) to the stack.
5A5A
LD DE,5B3AH 11 3A 5B
Point Register Pair DE to 5B3AH, the control block with the file specification of the driver or filter.
5A5D
GOSUB to 4430H to load the program file named by the control block at Register Pair DE (5B3AH): the Z FLAG and Register Pair HL = its transfer address when loaded, else the NZ FLAG and the error code (bit 6 set) in Register A.
5A60
If the NZ FLAG is set (the file could not be loaded), JUMP to 5AA8H to display the error in Register A and abort.
5A63
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the flag of the command. 5A02H stores it at each start: 00H for SET (entry 5A01H), AFH or more for FILTER (entry 5A00H).
5A65
OR A B7
OR Register A (the flag) with itself: the NZ FLAG is set for FILTER.
5A66
If the NZ FLAG is set (FILTER), JUMP to 5A79H: the name of the device is not written.
5A68
POP DE D1
Restore Register Pair DE from the stack: the device control block, pushed at 5A59H.
5A69
PUSH DE D5
Save Register Pair DE (the device control block) to the stack again, for 5A79H.
5A6A
DI F3
Disable interrupts while the name is written into the device control block.
5A6B
LD A,E 7B
Copy Register E (the low byte of the device control block address) into Register A.
5A6C
ADD A,06H C6 06
Add 06H to Register A (the low byte of the block's address): the low byte of +06H, the first letter of the name. No device control block crosses a 256 byte boundary (4015H-402CH, 43C0H-43FFH), so no carry is needed into Register D.
5A6E
LD E,A 5F
Copy Register A (the low byte of +06H) into Register E: Register Pair DE = the address of the name in the device control block.
5A6F
LD A,(5B1BH) 3A 1B 5B
Fetch the first letter of the device name from 5B1BH (after the asterisk at 5B1AH) into Register A.
5A72
LD (DE),A 12
Store Register A (the first letter) to +06H of the device control block at Register Pair DE.
5A73
INC E 1C
Increment Register E: Register Pair DE = +07H of the device control block, the second letter of the name.
5A74
LD A,(5B1CH) 3A 1C 5B
Fetch the second letter of the device name from 5B1CH into Register A.
5A77
EI FB
Enable interrupts; they are taken only after the next instruction, so the name is complete first.
5A78
LD (DE),A 12
Store Register A (the second letter) to +07H of the device control block at Register Pair DE.
5A79
POP DE D1
Restore Register Pair DE from the stack: the device control block, pushed at 5A59H (or at 5A69H for SET).
5A7A
EX (SP),HL E3
Exchange Register Pair HL (the transfer address of the loaded file) with the word at the Stack Pointer (the parameter text pushed at 5A2BH): Register Pair HL = the parameter text, the stack top = the transfer address.
5A7B
RET C9
RETURN, which jumps to the transfer address of the driver or filter with Register Pair DE = the device control block and Register Pair HL = the parameter text; a RET of the driver then returns to 4C4BH, the request handler.
5A7C-5A7E
DEFM "DVR" 44 56 52
The default extension of SET: 5A30H points Register Pair HL here for 4473H.
5A7F-5A81
DEFM "FLT" 46 4C 54
The default extension of FILTER: 5A35H points Register Pair HL here for 4473H.
5A82H - Find a Device Control Block by Name
Register Pair DE = the name (Register E the first letter, Register D the second; 0000H for a free block). The blocks are 8 bytes, the name at +06H-+07H: 4015H (KI), 401DH (DO), 4025H (PR), then 43C0H, 43C8H, ... 43F8H. Returns the Z FLAG, Register A = 00H and Register Pair HL = the block when found; otherwise the NZ FLAG and Register A = 08H when Register L wraps to 00H after 43F8H.
5A82
LD HL,4015H 21 15 40
Point Register Pair HL to 4015H, the first device control block (KI, the keyboard).
5A85
PUSH HL E5
Loop Start
Save Register Pair HL (the device control block being tested) to the stack.
5A86
LD A,L 7D
Copy Register L (the low byte of the block's address) into Register A.
5A87
ADD A,06H C6 06
Add 06H to Register A (the low byte): the low byte of +06H, the first letter of the name.
5A89
LD L,A 6F
Copy Register A into Register L: Register Pair HL = +06H of the device control block.
5A8A
LD A,(HL) 7E
Fetch the first letter of the block's name from Register Pair HL into Register A.
5A8B
INC L 2C
Increment Register L: Register Pair HL = +07H of the block, the second letter of the name.
5A8C
CP E BB
Compare Register A (the first letter of the block's name) against Register E (the first letter wanted).
5A8D
If the NZ FLAG is set (the first letters differ), JUMP to 5A96H to try the next block.
5A8F
LD A,(HL) 7E
Fetch the second letter of the block's name from Register Pair HL into Register A.
5A90
CP D BA
Compare Register A (the second letter of the block's name) against Register D (the second letter wanted).
5A91
If the NZ FLAG is set (the second letters differ), JUMP to 5A96H to try the next block.
5A93
POP HL E1
Restore Register Pair HL from the stack: the address of the device control block that matched.
5A94
XOR A AF
Set Register A to 00H with XOR A and the Z FLAG: found.
5A95
RET C9
RETURN with the Z FLAG and Register Pair HL = the device control block whose name is Register Pair DE.
5A96
POP AF F1
Restore Register Pair AF from the stack: this drops the saved block address (Register Pair HL stays at +07H of the block).
5A97
INC L 2C
Increment Register L: Register Pair HL = +08H, the start of the next device control block; the Z FLAG is set when Register L wraps to 00H (after 43F8H).
5A98
If the NZ FLAG is set (Register L did not wrap), JUMP to 5A9EH to see whether the system blocks are done.
5A9A
LD A,08H 3E 08
Load Register A with 08H, the error code DEVICE NOT AVAILABLE: no block has the name.
5A9C
OR A B7
OR Register A (08H) with itself: the NZ FLAG is set.
5A9D
RET C9
RETURN with the NZ FLAG and Register A = 08H: the name was not found.
5A9E
LD A,L 7D
Copy Register L (the low byte of the next block's address) into Register A.
5A9F
CP 2DH FE 2D
Compare Register A against 2DH: 402DH follows the PR block 4025H, the end of the three system blocks.
5AA1
If the NZ FLAG is set (not 402DH), JUMP back to 5A85H to test the block at Register Pair HL.
5AA3
LD HL,43C0H 21 C0 43
Point Register Pair HL to 43C0H, the first of the other device control blocks (JL, SI, LO and five free blocks up to 43F8H).
5AA6
JUMP back to 5A85H to test the block at Register Pair HL (43C0H).
5AA8H - Error Exit
Register A = the error code (08H, 21H, or a load error of 4430H, which has bit 6 set already). 4409H shows the text of the error alone (bit 6) and then, bit 7 being clear, takes the abort exit 4030H.
5AA8
OR 40H F6 40
OR Register A (the error code) with 40H: bit 6 set asks 4409H for the text of the error alone; bit 7 clear means 4409H does not return.
5AAA
JUMP to 4409H to display the error message of the code in Register A (48H DEVICE NOT AVAILABLE, 61H NO DEVICE SPACE AVAILABLE, or the load error) and take the abort exit.
5AADH - FILE SPEC REQUIRED
Reached when the second specification is missing, not valid or names a device: the message is displayed and logged through 447BH and the command ends with the abort exit 4030H.
5AAD
LD HL,5AB6H 21 B6 5A
Point Register Pair HL to 5AB6H, the message FILE SPEC REQUIRED ended by a carriage return.
5AB0
GOSUB to 447BH to display the text at Register Pair HL (5AB6H) up to its carriage return and write it to the job log.
5AB3
JUMP to 4030H, the abort exit of the system (request A3H).
5AB6-5AC7
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5AADH, displayed when no file specification of a driver or filter is given.
5AC8
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED: 447BH sends it and stops there.
5AC9H - DEVICE SPEC REQUIRED
Reached when the first specification is missing, not valid or is not a device (no asterisk first): the message is displayed and logged through 447BH and the command ends with the abort exit 4030H.
5AC9
LD HL,5AD2H 21 D2 5A
Point Register Pair HL to 5AD2H, the message DEVICE SPEC REQUIRED ended by a carriage return.
5ACC
GOSUB to 447BH to display the text at Register Pair HL (5AD2H) up to its carriage return and write it to the job log.
5ACF
JUMP to 4030H, the abort exit of the system (request A3H).
5AD2-5AE5
DEFM "DEVICE SPEC REQUIRED" 44 45 56 49 43 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 5AC9H, displayed when the command does not start with a device specification.
5AE6
DEFB 0DH 0D
The carriage return that ends the message DEVICE SPEC REQUIRED: 447BH sends it and stops there.
5AE7H - Refused Inside a Program
Reached from 5A0AH when 402DH holds a JP (C3H): a program that replaced the system exits is in memory (BASIC/CMD writes C3H at 402DH, 4030H and 4409H at its 66A6H-66AFH) and the command came through it. The message is displayed and logged through 447BH and the command ends with the abort exit 4030H, the program's own exit at that moment.
5AE7
LD HL,5AF0H 21 F0 5A
Point Register Pair HL to 5AF0H, the message CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL ended by a carriage return.
5AEA
GOSUB to 447BH to display the text at Register Pair HL (5AF0H) up to its carriage return and write it to the job log.
5AED
JUMP to 4030H, the abort exit (here the jump a program such as BASIC/CMD put at 4030H).
5AF0-5B18
DEFM "CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL" 43 41 4E 27 54 20 2D 2D 20 56 41 4C 49 44 20 4F 4E 4C 59 20 41 54 20 56 54 4F 53 20 43 4F 4D 4D 41 4E 44 20 4C 45 56 45 4C
The message of 5AE7H, displayed when SET or FILTER is given from inside a program that took over the exit 402DH.
5B19
DEFB 0DH 0D
The carriage return that ends the message CAN'T -- VALID ONLY AT VTOS COMMAND LEVEL: 447BH sends it and stops there.
5B1A-5B39
DEFS 32
Not in the file: the control block of the device specification. 441CH (from 5A10H) copies the asterisk and the two letters of the name there (5B1AH-5B1CH, then 03H); 5A16H tests the asterisk, 5A3BH, 5A6FH and 5A74H read the letters at 5B1BH-5B1CH.
5B3A-5B59
DEFS 32
Not in the file: the control block of the driver or filter file. 441CH (from 5A1FH) copies the file specification there, 4473H (from 5A38H) adds DVR or FLT, 4430H (from 5A5DH) opens and loads the file with it.
5200H - Member 26 (DUMP, Code 71H): Entry
SYS1/SYS runs DUMP through request 88H with Register B = 71H, so the request handler of SYS0/SYS loads this member at 5200H and calls 5200H with Register Pair HL pointing at the rest of the command line, after the word DUMP. The syntax the code reads is DUMP filespec (START=s,END=e,TRA=t), with S, E and T as short names. The member writes the memory from s through e to the file as a load module: a module name record 05H, load blocks 01H of at most 254 bytes, and a transfer record 02H. The default extension is CIM, the default addresses are 6000H for s and e and 402DH for t, and s must be at least 6000H.
5200
JUMP to 5212H, the start of DUMP, over the byte output routine 5203H that the rest of the member calls.
5203H - Write a Byte to the File
Called with Register A = the byte and Register Pair DE = the file control block 5390H. It returns with the Z FLAG when the byte went into the file; on an error it shows the error message and ends the command through the abort exit, with the file left open.
5203
GOSUB to the ROM's 001BH to send Register A to the device control block at Register Pair DE, here the file control block 5390H: the ROM finds bit 1 clear in its first byte (80H, or 84H once written: an open file) and goes through 4033H to SYS0/SYS's file routine 48E1H, which puts the byte into the buffer 5400H and writes each full sector. The ROM keeps Register Pairs BC, DE and HL.
5206
RET Z C8
If the Z FLAG is set (the byte went into the file), RETURN to the caller with Register Pairs BC, DE and HL unchanged.
5207
SET 6,A CB F7
Set bit 6 of Register A, the error code from the file routine: bit 6 asks 4409H for the text of the message alone.
5209
RES 7,A CB BF
Reset bit 7 of Register A, the error code: with bit 7 clear 4409H ends the command through the abort exit 4030H after the message.
520B
JUMP to 4409H to display the error message for the code in Register A and abort. The file at 5390H is not closed.
520E-5211
NOP x 4 00 x 4
Four 00H bytes after the routine 5203H. Nothing jumps or reads here: the code never reaches these bytes.
5212H - Read the File Specification and the Parameters
Register Pair HL points at the command line after DUMP. The file specification goes into the control block 5390H; a device (an asterisk and a device name) is refused like a missing specification. The parameter list is read against the table at 5359H, which stores the values straight into the operands 5294H (START), 529AH (END) and 52D7H (TRA).
5212
LD DE,5390H 11 90 53
Point Register Pair DE to 5390H, the file control block above the member that receives the file specification.
5215
GOSUB to 441CH (SYS1/SYS function 4, its 4FCEH) to copy the file specification from the text at Register Pair HL into the control block at Register Pair DE (5390H). It returns the Z FLAG when the specification is good, Register Pair HL past it and Register Pair DE = 5390H.
5218
If the NZ FLAG is set (no file specification or a bad one), JUMP to 52EFH to display FILE SPEC REQUIRED and abort.
521B
LD A,(DE) 1A
Fetch the first byte of the control block at Register Pair DE (5390H) into Register A: the first character of the specification text.
521C
CP 2AH FE 2A
Compare Register A (the first character of the specification) against 2AH, an asterisk, which starts a device name.
521E
If the Z FLAG is set (an asterisk and a device name), JUMP to 52EFH to display FILE SPEC REQUIRED: DUMP writes to a disk file only.
5221
LD DE,5359H 11 59 53
Point Register Pair DE to 5359H, the parameter table of DUMP (START, END, TRA, S, E, T).
5224
GOSUB to 4476H (SYS1/SYS function 6, its 510FH) to read the parameter list in parentheses from the text at Register Pair HL against the table at Register Pair DE (5359H): each value given is stored as a word at the address the entry names. No list leaves the defaults in place and returns the Z FLAG.
5227
If the NZ FLAG is set (an unknown parameter or a bad value), JUMP to 52F8H to display PARAMETER ERROR and abort.
522AH - Make the Module Name
The first six characters of the file name, from the specification text at 5390H, are copied to 538AH for the module name record. The copy stops at the first character that is not a digit or a capital letter (the "/" of an extension, the "." of a password, the ":" of a drive or the 03H at the end), and the rest of the six places get spaces.
522A
LD DE,538AH 11 8A 53
Point Register Pair DE to 538AH, the six byte module name above the member.
522D
LD HL,5390H 21 90 53
Point Register Pair HL to 5390H, the specification text in the file control block.
5230
LD B,06H 06 06
Load Register B with 06H, the six characters of the module name, for the DJNZ loops at 5246H and 524EH.
5232
LD A,(HL) 7E
Loop Start
Fetch the next character of the specification at Register Pair HL into Register A.
5233
CP 30H FE 30
Compare Register A (the character of the specification) against 30H, the digit 0.
5235
If the C FLAG is set (Register A is below 30H, not a digit or letter), JUMP to 524AH to fill the rest of the name with spaces.
5237
CP 3AH FE 3A
Compare Register A (the character of the specification) against 3AH, one past the digit 9.
5239
If the C FLAG is set (Register A is a digit 0 to 9), JUMP to 5243H to store it in the name.
523B
CP 41H FE 41
Compare Register A (the character of the specification) against 41H, the letter A.
523D
If the C FLAG is set (Register A is between 3AH and 40H, a sign such as the ":" of a drive), JUMP to 524AH to fill the rest of the name with spaces.
523F
CP 5BH FE 5B
Compare Register A (the character of the specification) against 5BH, one past the letter Z.
5241
If the NC FLAG is set (Register A is above the letter Z), JUMP to 524AH to fill the rest of the name with spaces.
5243
LD (DE),A 12
Store Register A (a digit or capital letter of the file name) to the module name at Register Pair DE (538AH up).
5244
INC HL 23
Increment Register Pair HL to the next character of the specification at 5390H up.
5245
INC DE 13
Increment Register Pair DE to the next place of the module name at 538AH up.
5246
Decrement Register B (the places of the name left) and LOOP BACK to 5232H until all six places are filled.
5248
JUMP to 5250H: the six places 538AH-538FH hold the first six characters of the name.
524A
LD A,20H 3E 20
Loop Start
Load Register A with 20H, a space, to fill the places of the module name the file name did not reach.
524C
LD (DE),A 12
Store Register A (a space) to the module name at Register Pair DE.
524D
INC DE 13
Increment Register Pair DE to the next place of the module name.
524E
Decrement Register B (the places left) and LOOP BACK to 524AH until the six places 538AH-538FH are filled.
5250H - Open the File and Write the Module Name Record
The extension CIM is added to a specification without one, and the file is opened, or created when it is not on the disk, with the sector buffer at 5400H and a record length of 256. The first record written is the module name: 05H, the length 06H and the six characters at 538AH.
5250
LD DE,5390H 11 90 53
Point Register Pair DE to 5390H, the file control block with the specification text.
5253
LD HL,5356H 21 56 53
Point Register Pair HL to 5356H, the three letters CIM of the default extension.
5256
GOSUB to 4473H (SYS1/SYS function 5, its 5042H) to put "/" and the extension at Register Pair HL (CIM) into the specification at Register Pair DE (5390H) when it has no extension. Register Pair DE is kept.
5259
LD B,00H 06 00
Load Register B with 00H, the record length for the open: 00H means 256, a whole sector at a time.
525B
LD HL,5400H 21 00 54
Point Register Pair HL to 5400H, the 256 byte sector buffer of the file above the member.
525E
GOSUB to 4420H (SYS2/SYS function 2, its 4E61H) to open the file in the control block at Register Pair DE (5390H) with the buffer at Register Pair HL (5400H) and the record length in Register B, or to create it when it is not in the directory. SYS0/SYS's 4A0CH gives back Register Pairs BC, DE and HL; the Z FLAG means opened or created.
5261
If the NZ FLAG is set (the open or the create failed), JUMP to 52EAH to display the error message for Register A and abort.
5264
LD A,05H 3E 05
Load Register A with 05H, the record type of a module name record.
5266
GOSUB to 5203H to write Register A (05H) to the file at Register Pair DE (5390H).
5269
LD A,06H 3E 06
Load Register A with 06H, the length of the module name record: six characters.
526B
GOSUB to 5203H to write Register A (06H, the length) to the file at Register Pair DE.
526E
LD B,06H 06 06
Load Register B with 06H, the count of the six name characters for the DJNZ at 5278H.
5270
LD HL,538AH 21 8A 53
Point Register Pair HL to 538AH, the module name made at 522AH-524EH.
5273
LD A,(HL) 7E
Loop Start
Fetch the next character of the module name at Register Pair HL (538AH up) into Register A.
5274
INC HL 23
Increment Register Pair HL to the next character of the module name.
5275
GOSUB to 5203H to write Register A (a character of the name) to the file at Register Pair DE.
5278
Decrement Register B (the characters left) and LOOP BACK to 5273H until the six characters are written.
527AH - Check the Addresses
The end address must not be below the start address, and the start address must be 6000H or above. The checks come after the file was opened and its first eight bytes written: on an error the message is shown and the command aborts without closing the file.
527A
LD HL,(529AH) 2A 9A 52
Fetch the word at 529AH-529BH into Register Pair HL: the end address, the operand of LD HL at 5299H that the END or E parameter wrote (6000H when it was not given).
527D
LD BC,(5294H) ED 4B 94 52
Fetch the word at 5294H-5295H into Register Pair BC: the start address, the operand of LD HL at 5293H that the START or S parameter wrote (6000H when it was not given).
5281
XOR A AF
Set Register A to 00H and clear the C FLAG (XOR A) for the subtraction below.
5282
SBC HL,BC ED 42
SUBtract Register Pair BC (the start) from Register Pair HL (the end): the C FLAG is set when the end is below the start.
5284
LD HL,5307H 21 07 53
Point Register Pair HL to 5307H, the message END LESS THAN START, for 5301H. LD does not change the flags.
5287
If the C FLAG is set (the end address is below the start address), JUMP to 5301H to display the message at Register Pair HL (5307H) and abort.
5289
LD HL,5FFFH 21 FF 5F
Load Register Pair HL with 5FFFH, the highest start address DUMP refuses.
528C
SBC HL,BC ED 42
SUBtract Register Pair BC (the start) from Register Pair HL (5FFFH), with the C FLAG clear from the jump not taken: the NC FLAG is set when the start is 5FFFH or below.
528E
LD HL,531BH 21 1B 53
Point Register Pair HL to 531BH, the message START LESS THAN X'6000', for 5301H. LD does not change the flags.
5291
If the NC FLAG is set (the start address is below 6000H), JUMP to 5301H to display the message at Register Pair HL (531BH) and abort.
5293H - Write the Load Blocks
Register Pair HL runs from the start address to the end address. Each pass works out the bytes left (end + 1 - address) and writes a load block: 01H, the length (the count of data bytes + 2 for the address), the load address low byte first, then the data. A block holds 254 bytes, or the bytes left when they are fewer than 255. The loop ends when no bytes are left.
5293
LD HL,6000H 21 00 60
Self-Modifying Code
Load Register Pair HL with the start address, the operand 5294H-5295H. The parameter reader 510FH (call at 5224H) stores the value of START or S there; the file holds 6000H, the start when the parameter is not given. Register Pair HL = the address of the first byte to write.
5296
PUSH HL E5
Loop Start
Save Register Pair HL (the address of the next byte to write) to the stack.
5297
LD B,H 44
Copy Register H (the high byte of the next address) into Register B.
5298
LD C,L 4D
Copy Register L (the low byte of the next address) into Register C: Register Pair BC = the next address to write.
5299
LD HL,6000H 21 00 60
Self-Modifying Code
Load Register Pair HL with the end address, the operand 529AH-529BH. The parameter reader 510FH (call at 5224H) stores the value of END or E there; the file holds 6000H, the end when the parameter is not given.
529C
INC HL 23
Increment Register Pair HL (the end address) to the address after the last byte to write.
529D
XOR A AF
Set Register A to 00H and clear the C FLAG (XOR A) for the subtraction below.
529E
SBC HL,BC ED 42
SUBtract Register Pair BC (the next address) from Register Pair HL (the end + 1): Register Pair HL = the count of bytes left to write.
52A0
If the Z FLAG is set (no bytes left), JUMP to 52CBH to write the transfer record.
52A2
LD B,FEH 06 FE
Load Register B with FEH, the 254 data bytes of a full load block.
52A4
LD A,H 7C
Copy Register H (the high byte of the count of bytes left) into Register A.
52A5
OR A B7
OR Register A with itself to test the high byte of the count of bytes left: the NZ FLAG is set when 256 or more bytes are left.
52A6
If the NZ FLAG is set (256 or more bytes left), JUMP to 52AEH with Register B = FEH, a full block.
52A8
LD A,L 7D
Copy Register L (the count of bytes left, below 256) into Register A.
52A9
CP FFH FE FF
Compare Register A (the count of bytes left) against FFH: the NC FLAG is set when 255 bytes are left.
52AB
If the NC FLAG is set (255 bytes left), JUMP to 52AEH with Register B = FEH: this block takes 254 bytes and the next one the last byte.
52AD
LD B,L 45
Copy Register L (the count of bytes left, at most 254) into Register B: the last block holds them all.
52AE
POP HL E1
Restore Register Pair HL from the stack: the address of the next byte to write, saved at 5296H.
52AF
LD A,01H 3E 01
Load Register A with 01H, the record type of a load block.
52B1
GOSUB to 5203H to write Register A (01H) to the file at Register Pair DE (5390H).
52B4
LD A,B 78
Copy Register B (the count of data bytes of this block) into Register A.
52B5
ADD A,02H C6 02
Add 02H to Register A: the length byte counts the two bytes of the load address too. For 254 data bytes it is 00H, which the loader reads as 254.
52B7
GOSUB to 5203H to write Register A (the length of the block) to the file at Register Pair DE.
52BA
LD A,L 7D
Copy Register L (the low byte of the load address of the block) into Register A.
52BB
GOSUB to 5203H to write Register A (the low byte of the load address) to the file at Register Pair DE.
52BE
LD A,H 7C
Copy Register H (the high byte of the load address of the block) into Register A.
52BF
GOSUB to 5203H to write Register A (the high byte of the load address) to the file at Register Pair DE.
52C2
LD A,(HL) 7E
Loop Start
Fetch the next memory byte to dump from Register Pair HL into Register A.
52C3
INC HL 23
Increment Register Pair HL to the next memory byte.
52C4
GOSUB to 5203H to write Register A (the memory byte) to the file at Register Pair DE. The routine keeps Register B.
52C7
Decrement Register B (the data bytes of the block left) and LOOP BACK to 52C2H until the block is written.
52C9
JUMP back to 5296H for the next block, with Register Pair HL at the first byte after this block.
52CBH - Write the Transfer Record and Close the File
After the last block the transfer record is written: 02H, the length 02H and the transfer address, the TRA or T value or 402DH (VTOS READY) when none was given. The file is closed and the command ends at VTOS READY.
52CB
POP HL E1
Restore Register Pair HL from the stack, the address after the end that 5296H saved: it is dropped, as the stack must be level for the exit.
52CC
LD A,02H 3E 02
Load Register A with 02H, the record type of a transfer record.
52CE
GOSUB to 5203H to write Register A (02H) to the file at Register Pair DE (5390H).
52D1
LD A,02H 3E 02
Load Register A with 02H, the length of the transfer record: the two bytes of the address.
52D3
GOSUB to 5203H to write Register A (02H, the length) to the file at Register Pair DE.
52D6
LD HL,402DH 21 2D 40
Self-Modifying Code
Load Register Pair HL with the transfer address, the operand 52D7H-52D8H. The parameter reader 510FH (call at 5224H) stores the value of TRA or T there; the file holds 402DH, the VTOS READY exit, so a module dumped without TRA returns to the system when it is run.
52D9
LD A,L 7D
Copy Register L (the low byte of the transfer address) into Register A.
52DA
GOSUB to 5203H to write Register A (the low byte of the transfer address) to the file at Register Pair DE.
52DD
LD A,H 7C
Copy Register H (the high byte of the transfer address) into Register A.
52DE
GOSUB to 5203H to write Register A (the high byte of the transfer address) to the file at Register Pair DE.
52E1
GOSUB to 4428H (SYS3/SYS function 1, its 4E0DH) to close the file in the control block at Register Pair DE (5390H): the last part sector is written and the directory record is brought up to date.
52E4
If the NZ FLAG is set (the close failed), JUMP to 52EAH to display the error message for Register A and abort.
52E7
JUMP to 402DH, the normal exit: the file is written and closed, and VTOS READY is shown.
52EAH - Error Exits
A system error from the open or the close is shown as its message text; DUMP's own errors show their texts. All of them end the command through the abort exit 4030H.
52EA
OR 40H F6 40
OR 40H into Register A, the error code from the open (4420H) or the close (4428H): bit 6 asks 4409H for the text alone, and bit 7 stays clear, so the command aborts after the message.
52EC
JUMP to 4409H to display the error message for the code in Register A and abort through 4030H.
52EF
LD HL,5333H 21 33 53
Point Register Pair HL to 5333H, the message FILE SPEC REQUIRED (no specification, a bad one, or a device).
52F2
GOSUB to 447BH to display the message at Register Pair HL (5333H) and write it to the job log.
52F5
JUMP to 4030H, the abort exit: nothing was opened, so nothing is left to close.
52F8
LD HL,5346H 21 46 53
Point Register Pair HL to 5346H, the message PARAMETER ERROR.
52FB
GOSUB to 447BH to display the message at Register Pair HL (5346H) and write it to the job log.
52FE
JUMP to 4030H, the abort exit: the parameters are read before the open, so no file is open.
5301
GOSUB to 447BH to display the message at Register Pair HL (5307H or 531BH, loaded by the address checks at 5284H and 528EH) and write it to the job log.
5304
JUMP to 4030H, the abort exit. The file opened at 525EH is left open, never closed.
5307H - Messages
The texts of DUMP's errors, each ended by 0DH, shown with 447BH.
5307-5319
DEFM "END LESS THAN START" 45 4E 44 20 4C 45 53 53 20 54 48 41 4E 20 53 54 41 52 54
The message shown when the end address is below the start address (5284H, 5301H).
531A
DEFB 0DH 0D
The carriage return that ends the message END LESS THAN START.
531B-5331
DEFM "START LESS THAN X'6000'" 53 54 41 52 54 20 4C 45 53 53 20 54 48 41 4E 20 58 27 36 30 30 30 27
The message shown when the start address is below 6000H (528EH, 5301H).
5332
DEFB 0DH 0D
The carriage return that ends the message START LESS THAN X'6000'.
5333-5344
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message shown when the command line has no good file specification or names a device (52EFH).
5345
DEFB 0DH 0D
The carriage return that ends the message FILE SPEC REQUIRED.
5346-5354
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message shown when the parameter list cannot be read (52F8H).
5355
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
5356H - Default Extension and Parameter Table
The three letters of the default extension, then the parameter table 4476H reads: 8 bytes an entry, six characters of the name padded with spaces and the address of the word the value goes to; a 00H ends the table.
5356-5358
DEFM "CIM" 43 49 4D
The default extension CIM that 4473H puts into the specification at 5256H when it has none.
5359-5360
DEFM "START " / DEFW 5294H 53 54 41 52 54 20 94 52
Parameter START: its value goes to 5294H-5295H, the operand of LD HL at 5293H, the start address.
5361-5368
DEFM "END " / DEFW 529AH 45 4E 44 20 20 20 9A 52
Parameter END: its value goes to 529AH-529BH, the operand of LD HL at 5299H, the end address.
5369-5370
DEFM "TRA " / DEFW 52D7H 54 52 41 20 20 20 D7 52
Parameter TRA: its value goes to 52D7H-52D8H, the operand of LD HL at 52D6H, the transfer address.
5371-5378
DEFM "S " / DEFW 5294H 53 20 20 20 20 20 94 52
Parameter S, the short name of START: its value goes to 5294H-5295H, the start address.
5379-5380
DEFM "E " / DEFW 529AH 45 20 20 20 20 20 9A 52
Parameter E, the short name of END: its value goes to 529AH-529BH, the end address.
5381-5388
DEFM "T " / DEFW 52D7H 54 20 20 20 20 20 D7 52
Parameter T, the short name of TRA: its value goes to 52D7H-52D8H, the transfer address.
5389
DEFB 00H 00
The 00H that ends the parameter table, the last byte of the member in the file.
538A-538F
DEFS 6
Not in the file: the module name, the first six characters of the file name padded with spaces, made at 522AH-524EH and written into the module name record at 5270H-5278H.
5390-53AF
DEFS 32
Not in the file: the file control block. 441CH (5215H) puts the specification text here, 4473H (5256H) adds the extension, 4420H (525EH) opens it; every byte goes through it (5203H) and 4428H (52E1H) closes it.
5400-54FF
DEFS 256
Not in the file: the sector buffer of the file, given to the open at 525BH; SYS0/SYS's file routine collects the bytes here and writes each full sector.
5200H - Member 27 (PURGE, Code 72H): Check the Chain Flag and Read the Drive
SYS1/SYS runs PURGE through request 88H with Register B = 72H; the request handler of SYS0/SYS loads this member at 5200H and calls 5200H with Register Pair HL pointing at the rest of the command line, after the word PURGE. The syntax the code reads is PURGE :d (MPW="password"). PURGE refuses to run inside a chain of commands. The drive digit after a colon (drive 0 when there is none) is stored in the operand 5320H, the drive is tested, and the master password is checked before any file is shown.
5200
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A. Bit 5 is set by SYS7/SYS while it runs the command lines of a chain file (its 4E19H) and cleared at the end of the chain (its 4EA6H).
5203
BIT 5,A CB 6F
Test bit 5 of Register A (the system flags from 430FH): the NZ FLAG is set while a chain of commands is running.
5205
If the NZ FLAG is set (a chain is running), JUMP to 53D9H to display INVALID COMMAND DURING PROGRAM CHAINING and abort.
5208
LD C,00H 0E 00
Load Register C with 00H, drive 0, the drive PURGE works on when the command line names none.
520A
LD A,(HL) 7E
Fetch the first character of the parameters at Register Pair HL into Register A.
520B
CP 3AH FE 3A
Compare Register A (the first character of the parameters) against 3AH, the colon that comes before a drive digit.
520D
If the NZ FLAG is set (no colon), JUMP to 5215H with Register C = 00H, drive 0.
520F
INC HL 23
Increment Register Pair HL past the colon to the drive digit.
5210
LD A,(HL) 7E
Fetch the drive digit at Register Pair HL into Register A.
5211
INC HL 23
Increment Register Pair HL past the drive digit, to the rest of the line (the parameter list).
5212
SUB 30H D6 30
SUBtract 30H from Register A (the drive digit): Register A = the drive number. Nothing checks that the character was a digit 0 to 7.
5214
LD C,A 4F
Copy Register A (the drive number) into Register C.
5215
LD A,C 79
Copy Register C (the drive number, 00H by default) into Register A.
5216
LD (5320H),A 32 20 53
Store Register A (the drive number) to 5320H, the operand of LD C,00H at 531FH, from where 5236H and 52EDH also fetch it.
5219
PUSH HL E5
Save Register Pair HL (the rest of the command line) to the stack while the drive is tested.
521A
GOSUB to 44B8H (SYS2/SYS function 4, its 5147H) to test drive Register C: the Z FLAG when its drive code table has a driver and the drive is ready (for a floppy drive SYS2/SYS also reads its allocation table).
521D
POP HL E1
Restore Register Pair HL from the stack: the rest of the command line, the parameter list.
521E
LD A,20H 3E 20
Load Register A with 20H, the error code ILLEGAL DRIVE NUMBER, for any failure of the drive test. LD does not change the flags of the test.
5220
If the NZ FLAG is set (the drive is not there or not ready), JUMP to 53CBH to display ILLEGAL DRIVE NUMBER and abort.
5223
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the value of the MPW word when the parameter is not given.
5226
LD (5344H),BC ED 43 44 53
Store Register Pair BC (0000H) to 5344H-5345H, the MPW word that the parameter reader fills in when MPW is given.
522A
LD DE,544EH 11 4E 54
Point Register Pair DE to 544EH, the parameter table of PURGE, whose one entry is MPW.
522D
GOSUB to 4476H (SYS1/SYS function 6, its 510FH) to read the parameter list in parentheses from the text at Register Pair HL against the table at Register Pair DE (544EH): MPW="text" stores the address of the text (its closing quote made 0DH) at 5344H.
5230
If the NZ FLAG is set (an unknown parameter or a bad value), JUMP to 53D0H to display PARAMETER ERROR and abort.
5233
GOSUB to 5314H to get the master password (from MPW or by asking) and compare it with the diskette's; a wrong one does not return.
5236H - Read the Hash Index
The hash index sector (sector 1 of the directory cylinder) of the drive is read into 5700H. Its 256 bytes stand for the 256 directory entry codes: the byte at 5700H + code is the name hash of the file in that record, 00H for none. PURGE walks them in the order of the directory: the eight records of a sector (bits 7-5 of the code), then the next sector (bits 4-0).
5236
LD A,(5320H) 3A 20 53
Fetch the drive number from 5320H into Register A, stored there at 5216H.
5239
LD C,A 4F
Copy Register A (the drive number) into Register C for 4B65H and the reads below.
523A
GOSUB to 4B65H to fetch the directory cylinder of drive Register C from its drive code table into Register D.
523D
LD E,01H 1E 01
Load Register E with 01H, sector 1 of the directory cylinder, the hash index.
523F
LD HL,5700H 21 00 57
Point Register Pair HL to 5700H, the buffer for the hash index above the member.
5242
GOSUB to 4B45H to read cylinder Register D, sector Register E (01H) of drive Register C into the buffer at Register Pair HL (5700H): the Z FLAG when the sector carries the directory's data mark.
5245
LD A,16H 3E 16
Load Register A with 16H, the error code HIT READ ERROR. LD does not change the flags of the read.
5247
If the NZ FLAG is set (the hash index could not be read), JUMP to 53CBH to display HIT READ ERROR and abort.
524A
LD HL,5700H 21 00 57
Point Register Pair HL to 5700H, the index byte of entry code 00H, the first place.
524D
JUMP to 5266H to test the first entry code (00H) without stepping on.
524FH - Step to the Next Directory Entry
Every file ends its turn here with its entry code in Register B and the drive in Register C on the stack (pushed at 5270H). The next code is the code plus 20H (the next record of the same sector); past the last record of a sector it is the first record of the next sector. After the last code, FFH, PURGE ends with VTOS READY.
524F
POP BC C1
Restore Register Pair BC from the stack (pushed at 5270H): Register B = the entry code of the file just handled, Register C = the drive.
5250
LD H,57H 26 57
Load Register H with 57H, the page of the hash index buffer 5700H.
5252
LD L,B 68
Copy Register B (the entry code) into Register L: Register Pair HL = the index byte of that entry at 5700H up.
5253
LD A,L 7D
Copy Register L (the entry code of the index place) into Register A.
5254
ADD A,20H C6 20
Add 20H to Register A: the next record of the same directory sector (bits 7-5 of the entry code).
5256
LD L,A 6F
Copy Register A (the next entry code) into Register L.
5257
If the NC FLAG is set (no carry: a record of the same sector), JUMP to 5266H to test that entry.
5259
INC L 2C
Increment Register L: after the carry Register L holds the sector bits of the sector just finished, so Register L is now the first record of the next sector.
525A
CP 1FH FE 1F
Compare Register A (the sector bits of the sector just finished) against 1FH, the last of the 32 sector values.
525C
If the NZ FLAG is set (more sectors), JUMP to 5266H to test the entry code in Register L.
525E
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the last line on the display.
5260
GOSUB to the ROM's 0033H to display Register A, the carriage return.
5263
JUMP to 402DH, the normal exit: all 256 entry codes are done, VTOS READY.
5266H - Test the Entry and Read its Directory Record
Entry codes 00H and 01H (the first records of directory sectors 2 and 3, BOOT/SYS and DIR/SYS) are never offered. An index byte of 00H means no file. For any other code the directory sector is read into SYS0/SYS's buffer 4200H, unless the sector bits are those of the sector read last (5277H). Free records and extension records are passed over.
5266
LD A,L 7D
Copy Register L (the entry code of the index place) into Register A.
5267
AND FEH E6 FE
Mask Register A (the entry code) with FEH: the Z FLAG is set for the codes 00H and 01H.
5269
If the Z FLAG is set (entry code 00H or 01H, BOOT/SYS or DIR/SYS), JUMP to 5253H to step on without offering it.
526B
LD A,(HL) 7E
Fetch the index byte at Register Pair HL (5700H + the entry code) into Register A: the name hash of the record, 00H when it holds no file.
526C
OR A B7
OR Register A with itself to test the index byte: the Z FLAG is set when it is 00H.
526D
If the Z FLAG is set (no file in this record), JUMP to 5253H to step on.
526F
LD B,L 45
Copy Register L (the entry code) into Register B, for 4B10H and for 524FH.
5270
PUSH BC C5
Save Register Pair BC (Register B the entry code, Register C the drive) to the stack; 524FH and 52E7H take it back.
5271
LD A,L 7D
Copy Register L (the entry code) into Register A.
5272
AND E0H E6 E0
Mask Register A to bits 7-5 (AND E0H): the record number times 32, the offset of the record in its sector.
5274
LD L,A 6F
Copy Register A (the offset of the record) into Register L: 4200H + Register L will be the record.
5275
XOR B A8
Exclusive OR Register A with Register B (the entry code): Register A = bits 4-0 of the entry code, the sector bits (the directory sector less 2).
5276
CP FFH FE FF
Self-Modifying Code
Compare Register A (the sector bits) against the operand 5277H, the sector bits of the directory sector now in 4200H. 527AH stores them after each read, and 530EH stores FFH after a file was purged (SYS10/SYS has used 4200H); the file holds FFH, which no sector matches, so the first entry is always read.
5278
If the Z FLAG is set (the sector is already in 4200H), JUMP to 5283H without reading it.
527A
LD (5277H),A 32 77 52
Store Register A (the sector bits) to 5277H, the operand of CP at 5276H: the sector about to be read.
527D
GOSUB to 4B10H to read the directory sector of entry code Register B, drive Register C, into 4200H. Register Pair HL comes back at the record; the Z FLAG means read.
5280
If the NZ FLAG is set (error 11H, DIRECTORY READ ERROR, in Register A), JUMP to 53CBH to display it and abort.
5283
LD H,42H 26 42
Load Register H with 42H: Register Pair HL = 4200H plus the record's offset (Register L), the directory record of the entry.
5285
LD A,(HL) 7E
Fetch the attribute byte, byte +00H of the directory record at Register Pair HL, into Register A.
5286
BIT 4,A CB 67
Test bit 4 of Register A (the attribute byte): set when the record is in use.
5288
If the Z FLAG is set (the record is free), JUMP to 524FH to step on to the next entry.
528B
BIT 7,A CB 7F
Test bit 7 of Register A (the attribute byte): set in an extension record, which holds more extents of a file and is not a file of its own.
528D
If the NZ FLAG is set (an extension record), JUMP to 524FH to step on to the next entry.
5290H - Show the File and Ask
The prompt PURGE FILE: is shown, then the name and extension of the record as NAME/EXT (NAME alone without an extension), then " ? ". The ROM's line input reads up to 3 characters into 541AH; only a first character Y purges the file.
5290
PUSH HL E5
Save Register Pair HL (the directory record in 4200H) to the stack while the prompt is shown.
5291
LD HL,541EH 21 1E 54
Point Register Pair HL to 541EH, the text PURGE FILE: ended by 03H.
5294
GOSUB to 4467H to display the text at Register Pair HL (541EH), PURGE FILE: with a space after it.
5297
POP HL E1
Restore Register Pair HL from the stack: the directory record in 4200H.
5298
LD A,L 7D
Copy Register L (the low byte of the record's address) into Register A.
5299
ADD A,05H C6 05
Add 05H to Register A: byte +05H of the record, the first of the eight characters of the file name.
529B
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the file name in the directory record.
529C
LD DE,5441H 11 41 54
Point Register Pair DE to 5441H, the buffer where the name is put together as text.
529F
LD B,08H 06 08
Load Register B with 08H, the eight characters of the name field, for the DJNZ at 52A9H.
52A1
LD A,(HL) 7E
Loop Start
Fetch the next character of the name field at Register Pair HL into Register A.
52A2
INC HL 23
Increment Register Pair HL to the next byte of the record.
52A3
CP 20H FE 20
Compare Register A (the character of the name) against 20H, the space that fills a shorter name.
52A5
If the Z FLAG is set (a space: the name has ended), JUMP to 52ADH to move Register Pair HL to the extension.
52A7
LD (DE),A 12
Store Register A (a character of the name) to the text at Register Pair DE (5441H up).
52A8
INC DE 13
Increment Register Pair DE to the next place of the text.
52A9
Decrement Register B (the characters of the name field left) and LOOP BACK to 52A1H until all eight were taken.
52AB
JUMP to 52B1H: Register Pair HL is at byte +0DH of the record, the extension.
52AD
LD A,L 7D
Copy Register L (one past the space just read) into Register A.
52AE
ADD A,B 80
Add Register B (the places of the name field left, the space included) to Register A.
52AF
DEC A 3D
Decrement Register A: Register A = the low byte of byte +0DH of the record, the first character of the extension.
52B0
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the extension field of the directory record.
52B1
LD A,(HL) 7E
Fetch the first character of the extension at Register Pair HL into Register A.
52B2
CP 20H FE 20
Compare Register A (the first character of the extension) against 20H, a space: a file without an extension.
52B4
If the Z FLAG is set (no extension), JUMP to 52C6H to end the text after the name.
52B6
LD A,2FH 3E 2F
Load Register A with 2FH, the "/" that comes before an extension.
52B8
LD (DE),A 12
Store Register A (the "/") to the text at Register Pair DE.
52B9
INC DE 13
Increment Register Pair DE to the next place of the text.
52BA
LD B,03H 06 03
Load Register B with 03H, the three characters of the extension field, for the DJNZ at 52C4H.
52BC
LD A,(HL) 7E
Loop Start
Fetch the next character of the extension at Register Pair HL into Register A.
52BD
INC HL 23
Increment Register Pair HL to the next byte of the extension field.
52BE
CP 20H FE 20
Compare Register A (the character of the extension) against 20H, a space that ends a shorter extension.
52C0
If the Z FLAG is set (a space: the extension has ended), JUMP to 52C6H to end the text.
52C2
LD (DE),A 12
Store Register A (a character of the extension) to the text at Register Pair DE.
52C3
INC DE 13
Increment Register Pair DE to the next place of the text.
52C4
Decrement Register B (the characters of the extension left) and LOOP BACK to 52BCH until all three were taken.
52C6
LD A,03H 3E 03
Load Register A with 03H, the byte that ends a text for 4467H without being shown.
52C8
LD (DE),A 12
Store Register A (03H) to the text at Register Pair DE, after the name or the extension.
52C9
LD HL,5441H 21 41 54
Point Register Pair HL to 5441H, the name of the file as text.
52CC
GOSUB to 4467H to display the text at Register Pair HL (5441H), NAME/EXT. 4467H returns Register Pair HL unchanged.
52CF
PUSH HL E5
Save Register Pair HL (5441H) to the stack. The value taken back at 52E3H is not used again.
52D0
LD HL,542BH 21 2B 54
Point Register Pair HL to 542BH, the text " ? " ended by 03H.
52D3
GOSUB to 4467H to display the text at Register Pair HL (542BH), the question mark after the name.
52D6
LD HL,541AH 21 1A 54
Point Register Pair HL to 541AH, the buffer for the answer.
52D9
LD B,03H 06 03
Load Register B with 03H, the most characters the ROM's line input may take.
52DB
GOSUB to the ROM's 0040H to read a line of at most Register B (3) characters into the buffer at Register Pair HL (541AH), ended by ENTER (0DH stored). The C FLAG it gives for BREAK is not tested.
52DE
LD A,(541AH) 3A 1A 54
Fetch the first character of the answer from 541AH into Register A.
52E1
CP 59H FE 59
Compare Register A (the first character of the answer) against 59H, the letter Y.
52E3
POP HL E1
Restore Register Pair HL from the stack (5441H, pushed at 52CFH). POP does not change the flags.
52E4
If the NZ FLAG is set (any answer but Y: N, ENTER alone or anything else), JUMP to 524FH to keep the file and step on.
52E7H - Purge the File
The control block 5457H is made by hand for SYS10/SYS: +00H 80H (open), +01H 01H (access level 1), +06H the drive and +07H the entry code. SYS10/SYS function 1 (442CH) then removes the file: it frees the granules of each extent in the allocation table, clears bit 4 of the attribute byte, clears the hash index byte, follows any extension records, writes the sectors back and sets the 32 bytes of the control block to 00H. SYS10/SYS reads the hash index through 4200H, so 5277H is set to FFH to read the directory sector again.
52E7
POP BC C1
Restore Register Pair BC from the stack (pushed at 5270H): Register B = the entry code of the file, Register C = the drive.
52E8
PUSH BC C5
Save Register Pair BC (entry code and drive) to the stack again, for 524FH after the purge.
52E9
LD A,B 78
Copy Register B (the directory entry code of the file) into Register A.
52EA
LD (545EH),A 32 5E 54
Store Register A (the entry code) to 545EH, byte +07H of the control block 5457H, the directory entry code of the file.
52ED
LD A,(5320H) 3A 20 53
Fetch the drive number from 5320H into Register A.
52F0
LD (545DH),A 32 5D 54
Store Register A (the drive number) to 545DH, byte +06H of the control block 5457H, the drive.
52F3
LD A,01H 3E 01
Load Register A with 01H, access level 1, low enough for SYS10/SYS's test (its 4E0DH-4E14H refuses level 2 and above with error 25H).
52F5
LD (5458H),A 32 58 54
Store Register A (01H) to 5458H, byte +01H of the control block 5457H, the access byte.
52F8
LD A,80H 3E 80
Load Register A with 80H, bit 7 of byte +00H: the mark of an open file, which SYS10/SYS's call to 49EBH requires.
52FA
LD (5457H),A 32 57 54
Store Register A (80H) to 5457H, byte +00H of the control block.
52FD
LD DE,5457H 11 57 54
Point Register Pair DE to 5457H, the control block just made.
5300
GOSUB to 442CH (SYS10/SYS function 1, its 4E05H) to remove the file of the control block at Register Pair DE (5457H) from drive +06H. The Z FLAG means removed; the control block comes back cleared to 00H.
5303
If the NZ FLAG is set (the removal failed, the error code in Register A), JUMP to 53CBH to display the error and abort.
5306
LD HL,5430H 21 30 54
Point Register Pair HL to 5430H, the text that reports the purge.
5309
GOSUB to 4467H to display the text at Register Pair HL (5430H): 35 spaces, the cursor up a line, then PURGED between three asterisks on each side, at the right of the question line.
530C
LD A,FFH 3E FF
Load Register A with FFH, sector bits no directory sector has.
530E
LD (5277H),A 32 77 52
Store Register A (FFH) to 5277H, the operand of CP at 5276H: SYS10/SYS has read the hash index into 4200H over the directory sector, so the next entry reads its sector again.
5311
JUMP to 524FH, which takes the entry code and drive back from the stack, to step on to the next entry.
5314H - Check the Master Password
The password is taken from MPW or asked for (5346H), its hash code is worked out by SYS2/SYS, and the allocation table of the drive is read into 5600H. The code C294H, or the master password code of the diskette at +CEH-+CFH of the table (56CEH), lets PURGE go on; any other gives INVALID MASTER PASSWORD and the abort exit.
5314
LD DE,(5344H) ED 5B 44 53
Fetch the MPW word from 5344H-5345H into Register Pair DE: 0000H when MPW was not given, otherwise the value 510FH stored (the address of the text for MPW="text").
5318
LD HL,5388H 21 88 53
Point Register Pair HL to 5388H, the prompt MASTER PASSWORD ?, for 536BH when the password must be asked for.
531B
GOSUB to 5346H to put the password into 5500H and have it hashed: it comes back here with Register Pair HL = the hash code of the eight characters.
531E
PUSH HL E5
Save Register Pair HL (the hash code of the password given) to the stack.
531F
LD C,00H 0E 00
Self-Modifying Code
Load Register C with the drive number, the operand 5320H, which 5216H wrote from the command line (00H in the file).
5321
GOSUB to 53B8H to read the allocation table of drive Register C into 5600H.
5324
If the NZ FLAG is set (error 14H, GAT READ ERROR, in Register A), JUMP to 533FH to display it and abort.
5327
POP DE D1
Restore Register Pair DE from the stack: the hash code of the password given.
5328
LD HL,C294H 21 94 C2
Load Register Pair HL with C294H, a code accepted on every diskette.
532B
XOR A AF
Set Register A to 00H and clear the C FLAG (XOR A) for the subtraction below.
532C
SBC HL,DE ED 52
SUBtract Register Pair DE (the code of the password given) from Register Pair HL (C294H): the Z FLAG is set when they are equal.
532E
RET Z C8
If the Z FLAG is set (the code is C294H), RETURN to 5236H: the password is taken without the diskette's.
532F
LD HL,(56CEH) 2A CE 56
Fetch the master password code of the diskette from 56CEH-56CFH, bytes +CEH-+CFH of the allocation table at 5600H, into Register Pair HL.
5332
XOR A AF
Set Register A to 00H and clear the C FLAG (XOR A) for the subtraction below.
5333
SBC HL,DE ED 52
SUBtract Register Pair DE (the code of the password given) from Register Pair HL (the diskette's code): the Z FLAG is set when they are equal.
5335
RET Z C8
If the Z FLAG is set (the master password is right), RETURN to 5236H to go through the files.
5336
LD HL,53A0H 21 A0 53
Point Register Pair HL to 53A0H, the message INVALID MASTER PASSWORD.
5339
GOSUB to 447BH to display the message at Register Pair HL (53A0H) and write it to the job log.
533C
JUMP to 4030H, the abort exit: no file was offered.
533F
OR 40H F6 40
OR 40H into Register A, the error code 14H from 53B8H: bit 6 asks 4409H for the text alone, and bit 7 stays clear, so the command aborts.
5341
JUMP to 4409H to display the error message for the code in Register A (GAT READ ERROR) and abort through 4030H.
5344-5345
DEFS 2
Not in the file (the gap between two load blocks): the MPW word. 5226H sets it to 0000H, the parameter reader 510FH (call at 522DH) writes the value of MPW there, and 5314H reads it.
5346H - Get the Password and Hash It
Register Pair DE = the MPW value, Register Pair HL = the prompt. 534CH puts eight characters into 5500H (from the MPW text, or from the keyboard when the value is 0000H), padded with spaces. The RST 28H with Register A = E4H runs SYS2/SYS function 6 (its 511EH) on them; the request handler drops the return address of the RST, so SYS2/SYS returns to the caller of 5346H with Register Pair HL = the hash code.
5346
GOSUB to 534CH to put the eight characters of the password into 5500H: it returns with Register Pair DE = 5500H.
5349
LD A,E4H 3E E4
Load Register A with E4H: SYS2/SYS (bits 3-0 = 4), function 6, the hash code of the password at Register Pair DE.
534B
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H, which runs SYS2/SYS's 511EH on the eight characters at Register Pair DE (5500H) and returns to 531EH, the caller of 5346H, with Register Pair HL = the hash code.
534C
LD A,D 7A
Copy Register D (the high byte of the MPW value) into Register A.
534D
OR E B3
OR Register E (the low byte of the MPW value) into Register A: the Z FLAG is set when the value is 0000H, MPW not given.
534E
If the Z FLAG is set (no MPW), JUMP to 536BH to ask for the password.
5350
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the eight byte password buffer.
5353
LD B,08H 06 08
Load Register B with 08H, the eight characters of a password, for the DJNZ at 5365H.
5355
LD A,(DE) 1A
Loop Start
Fetch the next character of the MPW text at Register Pair DE into Register A.
5356
CP 0DH FE 0D
Compare Register A (the character of the MPW text) against 0DH, which 510FH put in place of the closing quote.
5358
If the Z FLAG is set (the end of the text), JUMP to 537FH to fill the rest of the password with spaces.
535A
CP 2CH FE 2C
Compare Register A (the character of the MPW text) against 2CH, a comma.
535C
If the Z FLAG is set (a comma), JUMP to 537FH to fill the rest of the password with spaces.
535E
CP 22H FE 22
Compare Register A (the character of the MPW text) against 22H, a quotation mark.
5360
If the Z FLAG is set (a quotation mark), JUMP to 537FH to fill the rest of the password with spaces.
5362
INC DE 13
Increment Register Pair DE to the next character of the MPW text.
5363
LD (HL),A 77
Store Register A (a character of the password) to the buffer at Register Pair HL (5500H up).
5364
INC HL 23
Increment Register Pair HL to the next place of the password buffer.
5365
Decrement Register B (the places left) and LOOP BACK to 5355H until eight characters were taken; a longer text is cut to eight.
5367
LD DE,5500H 11 00 55
Point Register Pair DE to 5500H, the eight characters of the password, for SYS2/SYS.
536A
RET C9
RETURN to 5349H with Register Pair DE = 5500H.
536B
GOSUB to 4467H to display the text at Register Pair HL (5388H), the prompt MASTER PASSWORD ? followed by spaces.
536E
LD B,08H 06 08
Load Register B with 08H, the most characters the ROM's line input may take for a password.
5370
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the password buffer.
5373
GOSUB to the ROM's 0040H to read a line of at most Register B (8) characters into the buffer at Register Pair HL (5500H). It returns Register Pair HL = 5500H and Register B = the count of characters typed; the 0DH is stored after them.
5376
EX DE,HL EB
Exchange Register Pair DE with Register Pair HL: Register Pair DE = 5500H, the start of the password.
5377
LD H,00H 26 00
Load Register H with 00H, the high byte of the count.
5379
LD L,B 68
Copy Register B (the count of characters typed) into Register L: Register Pair HL = the count.
537A
ADD HL,DE 19
Add Register Pair DE (5500H) to Register Pair HL: Register Pair HL = the place of the 0DH after the characters typed.
537B
LD A,08H 3E 08
Load Register A with 08H, the eight places of the password.
537D
SUB B 90
SUBtract Register B (the count typed) from Register A: Register A = the places left to fill.
537E
LD B,A 47
Copy Register A (the places left) into Register B for the DJNZ at 5382H. With eight characters typed it is 00H, and the loop runs 256 times.
537F
LD (HL),20H 36 20
Loop Start
Store 20H, a space, to the password buffer at Register Pair HL (the places after the end of the password).
5381
INC HL 23
Increment Register Pair HL to the next place of the password buffer.
5382
Decrement Register B (the places left) and LOOP BACK to 537FH until the password is filled to eight places.
5384
LD DE,5500H 11 00 55
Point Register Pair DE to 5500H, the eight characters of the password, for SYS2/SYS.
5387
RET C9
RETURN to 5349H with Register Pair DE = 5500H.
5388H - Password Texts and the Allocation Table Read
The prompt and the error message of the master password, and the routine that reads the allocation table (sector 0 of the directory cylinder) into 5600H.
5388-539E
DEFM "MASTER PASSWORD ? " 4D 41 53 54 45 52 20 50 41 53 53 57 4F 52 44 20 3F 20 20 20 20 20 20
The prompt shown by 536BH when MPW was not given, with six spaces after the question mark before the place where the password is typed.
539F
DEFB 03H 03
The 03H that ends the prompt for 4467H without being shown, so the line input starts after it.
53A0-53B6
DEFM "INVALID MASTER PASSWORD" 49 4E 56 41 4C 49 44 20 4D 41 53 54 45 52 20 50 41 53 53 57 4F 52 44
The message shown by 5336H when the code of the password given is neither the diskette's nor C294H.
53B7
DEFB 0DH 0D
The carriage return that ends the message INVALID MASTER PASSWORD.
53B8
PUSH DE D5
Save Register Pair DE to the stack, kept for the caller.
53B9
PUSH HL E5
Save Register Pair HL to the stack (the hash code of the password, from 531BH), kept for the caller.
53BA
GOSUB to 4B65H to fetch the directory cylinder of drive Register C into Register D.
53BD
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder, the allocation table.
53BF
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the buffer for the allocation table above the member.
53C2
GOSUB to 4B45H to read cylinder Register D, sector Register E (00H) of drive Register C into the buffer at Register Pair HL (5600H): the Z FLAG when read.
53C5
POP HL E1
Restore Register Pair HL from the stack: the caller's value.
53C6
POP DE D1
Restore Register Pair DE from the stack: the caller's value.
53C7
RET Z C8
If the Z FLAG is set (the allocation table was read), RETURN to the caller with Register A = 00H.
53C8
LD A,14H 3E 14
Load Register A with 14H, the error code GAT READ ERROR. LD does not change the NZ FLAG of the read.
53CA
RET C9
RETURN to the caller with Register A = 14H and the NZ FLAG.
53CBH - Error Exits
A system error code becomes the text of its message; PURGE's own errors show their texts. Every error ends the command through the abort exit 4030H.
53CB
OR 40H F6 40
OR 40H into Register A, the error code (20H, 16H, 11H or the code of SYS10/SYS): bit 6 asks 4409H for the text alone, and bit 7 stays clear, so the command aborts after the message.
53CD
JUMP to 4409H to display the error message for the code in Register A and abort through 4030H.
53D0
LD HL,53E2H 21 E2 53
Point Register Pair HL to 53E2H, the message PARAMETER ERROR.
53D3
GOSUB to 447BH to display the message at Register Pair HL (53E2H) and write it to the job log.
53D6
JUMP to 4030H, the abort exit: the parameter list could not be read.
53D9
LD HL,53F2H 21 F2 53
Point Register Pair HL to 53F2H, the message INVALID COMMAND DURING PROGRAM CHAINING.
53DC
GOSUB to 447BH to display the message at Register Pair HL (53F2H) and write it to the job log.
53DF
JUMP to 4030H, the abort exit: PURGE does not run inside a chain of commands.
53E2H - Messages and Display Texts
The texts PURGE shows: the two error messages ended by 0DH, the prompt texts ended by 03H (the line goes on), the purge report, and the buffers between them that are not in the file.
53E2-53F0
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message shown by 53D0H when the parameter list cannot be read.
53F1
DEFB 0DH 0D
The carriage return that ends the message PARAMETER ERROR.
53F2-5418
DEFM "INVALID COMMAND DURING PROGRAM CHAINING" 49 4E 56 41 4C 49 44 20 43 4F 4D 4D 41 4E 44 20 44 55 52 49 4E 47 20 50 52 4F 47 52 41 4D 20 43 48 41 49 4E 49 4E 47
The message shown by 53D9H when 430FH bit 5 tells that a chain of commands is running.
5419
DEFB 0DH 0D
The carriage return that ends the message INVALID COMMAND DURING PROGRAM CHAINING.
541A-541D
DEFS 4
Not in the file (the gap between two load blocks): the answer buffer. The ROM's line input (52DBH) stores up to three characters and the 0DH here; 52DEH reads the first character.
541E-5429
DEFM "PURGE FILE: " 50 55 52 47 45 20 46 49 4C 45 3A 20
The start of the question line, shown by 5294H for each file offered.
542A
DEFB 03H 03
The 03H that ends the text PURGE FILE: without being shown, so the name follows on the same line.
542B-542E
DEFM " ? " 20 3F 20 20
The question mark and spaces shown after the name by 52D3H, before the answer is typed.
542F
DEFB 03H 03
The 03H that ends the question text without being shown, so the answer is typed on the same line.
5430
DEFB E3H E3
The first byte of the purge report: E3H, which the ROM's display driver shows as 23H (35) spaces, moving the cursor along the empty line below the question.
5431
DEFB 1BH 1B
The display code 1BH, which moves the cursor up one line, to the question line at the column after the 35 spaces.
5432-543F
DEFM "*** PURGED ***" 2A 2A 2A 20 50 55 52 47 45 44 20 2A 2A 2A
The word PURGED between three asterisks on each side, shown by 5309H on the question line after a file was removed.
5440
DEFB 0DH 0D
The carriage return that ends the purge report and the question line.
5441-544D
DEFS 13
Not in the file (the gap between two load blocks): the name of the file offered, as text NAME/EXT and 03H (at most 8 + 1 + 3 + 1 = 13 bytes), made at 529CH-52C8H and shown by 52CCH.
544EH - Parameter Table
The table 4476H reads at 522DH: one 8 byte entry (six characters of the name, the address of the word its value goes to) and the 00H that ends it.
544E-5455
DEFM "MPW " / DEFW 5344H 4D 50 57 20 20 20 44 53
Parameter MPW, the master password: its value goes to 5344H-5345H, read by 5314H.
5456
DEFB 00H 00
The 00H that ends the parameter table, the last byte of the member in the file.
5457-5476
DEFS 32
Not in the file: the control block of the file to purge, made at 52E9H-52FAH (+00H 80H, +01H 01H, +06H the drive at 545DH, +07H the entry code at 545EH) and passed to 442CH at 52FDH; SYS10/SYS sets its 32 bytes to 00H.
5500-55FF
DEFS 256
Not in the file: the password buffer 5500H-5507H, filled by 534CH from the MPW text or the keyboard and hashed by SYS2/SYS. When eight characters are typed the pad loop at 537FH runs 256 times and writes spaces over 5508H-5607H, into the start of the allocation table buffer, which 5321H reads afterwards.
5600-56FF
DEFS 256
Not in the file: the allocation table of the drive, read by 53B8H (call at 5321H); 532FH compares its bytes +CEH-+CFH (56CEH), the master password code.
5700-57FF
DEFS 256
Not in the file: the hash index sector of the drive, read at 5242H; 526BH reads the byte of each entry code (5700H + code).
5200H - Member 28 (XFER, Code 73H): Check for Chaining, Take the File Specification and Find the Drive
XFER copies one file from a source diskette to a destination diskette in the same drive, asking for the diskettes to be changed, so that neither of them needs the system. SYS0/SYS's request handler enters it at 5200H (request 88H, member code 73H in Register B) with Register Pair HL pointing at the text after the word XFER. It refuses to run while a chain file is running (430FH bit 5), takes the file specification into the source control block at 54CEH, works out the page limit of the transfer buffer (5600H up to the page below the top of memory) and the drive number from the specification (0 when none is given).
5200
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A, to test bit 5, which is set while SYS7/SYS is running the commands of a chain file.
5203
BIT 5,A CB 6F
Test bit 5 of Register A (the system flags from 430FH): the NZ FLAG is set while a chain file is running.
5205
If the NZ FLAG is set (a chain file is running), JUMP to 53FEH to display "INVALID COMMAND DURING PROGRAM CHAINING" and abort.
5208
LD DE,54CEH 11 CE 54
Point Register Pair DE to 54CEH, the control block of the source file (32 bytes above the member, not in the file), for the file specification.
520B
GOSUB to 441CH (SYS1/SYS function 4) to copy the file specification from the text at Register Pair HL (the parameters after XFER) into the control block at Register Pair DE, in upper case and ended by 03H. The Z FLAG is set when the specification is good.
520E
If the NZ FLAG is set (no specification or a bad one), JUMP to 53F5H to display "FILE SPEC REQUIRED" and abort.
5211
LD HL,(4049H) 2A 49 40
Fetch the top of memory from 4049H-404AH into Register Pair HL, the highest address the transfer buffer may come near.
5214
INC HL 23
Increment Register Pair HL to the address one above the top of memory (0000H when the top is FFFFH).
5215
DEC H 25
Decrement Register H: Register H is now the high byte of the top of memory plus 1 less 256, the first page the buffer of 5600H up does not use (FFH when the top is FFFFH, so the buffer is 5600H-FEFFH).
5216
LD A,H 7C
Copy Register H (the page limit of the transfer buffer) into Register A.
5217
LD (52D4H),A 32 D4 52
Store Register A (the page limit) to 52D4H, the operand of CP 60H at 52D3H, which ends the filling of the buffer from the source file.
521A
LD (52EBH),A 32 EB 52
Store Register A (the page limit) to 52EBH, the operand of CP 60H at 52EAH, which ends the writing of a full buffer to the destination file.
521D
LD HL,54CEH 21 CE 54
Point Register Pair HL to 54CEH, the specification text just copied into the source control block, to look for a drive number in it.
5220
LD C,00H 0E 00
Load Register C with 00H, drive 0, the drive XFER uses when the specification names none.
5222
LD A,(HL) 7E
Loop Start
Fetch the next character of the specification at Register Pair HL into Register A.
5223
INC HL 23
Increment Register Pair HL to the character after the one in Register A.
5224
CP 3AH FE 3A
Compare Register A (the character) against 3AH, a colon, which comes before the drive number.
5226
If the Z FLAG is set (a colon), JUMP to 522EH to take the drive digit after it.
5228
CP 20H FE 20
Compare Register A (the character) against 20H: the C FLAG is set for a control character, the 03H that ends the specification.
522A
If the C FLAG is set (the end of the specification and no colon), JUMP to 5232H with Register C still 00H, drive 0.
522C
JUMP back to 5222H for the next character of the specification.
522E
LD A,(HL) 7E
Fetch the character after the colon at Register Pair HL, the drive digit, into Register A.
522F
SUB 30H D6 30
SUBtract 30H, the character 0, from Register A: the drive digit becomes the drive number. Nothing here checks the value.
5231
LD C,A 4F
Copy Register A (the drive number from the specification) into Register C.
5232
LD A,C 79
Copy Register C (the drive number, 00H when there is no colon) into Register A.
5233
LD (5358H),A 32 58 53
Store Register A (the drive number) to 5358H, the operand of LD A,00H at 5357H: the drive whose diskettes are checked, and when it is 00H the sign that the system diskette has to be put back in drive 0 before each overlay load.
5236H - Make the Destination Control Block, Read the Two Diskettes' Identities and Open the Source
The specification is copied to the destination control block at 54EEH. SYS2/SYS is loaded while the system diskette is still in drive 0. The source diskette is asked for, its identity (allocation table bytes CEH-DFH: master password hash, diskette name and date) saved at 550EH and the source file opened with the buffer at 5600H and 256 byte records; then the destination diskette is asked for and its identity saved at 5520H. When the two identities are the same XFER aborts with "SOURCE AND DESTINATION DISKS ARE THE SAME".
5236
LD HL,54CEH 21 CE 54
Point Register Pair HL to 54CEH, the source control block that holds the file specification.
5239
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the control block of the destination file (32 bytes, not in the file).
523C
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a control block.
523F
LDIR ED B0
Copy the 32 bytes from Register Pair HL (54CEH) to Register Pair DE (54EEH): the destination file gets the same specification, name, extension, password and drive, as the source. Register Pair HL ends at 54EEH, Register Pair DE at 550EH and Register Pair BC at 0000H.
5241
GOSUB to 53D4H (request 84H) to load SYS2/SYS, which does the open and the create, into the overlay area now, while the system diskette is in drive 0.
5244
LD HL,548BH 21 8B 54
Point Register Pair HL to 548BH, the prompt "INSERT SOURCE DISK (ENTER)".
5247
GOSUB to 53A7H to show the prompt at Register Pair HL, blinking, until the ENTER key is pressed.
524A
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H (stored at 5233H) into Register A.
524D
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for 53DDH.
524E
GOSUB to 53DDH to read the allocation table sector of the diskette in drive Register C into 4200H; it returns the NZ FLAG and Register A = 14H when the sector cannot be read.
5251
If the NZ FLAG is set (error 14H, GAT READ ERROR), JUMP to 534FH to display the error and abort.
5254
LD HL,42CEH 21 CE 42
Point Register Pair HL to 42CEH, bytes CEH-DFH of the allocation table just read into 4200H: the master password hash, the diskette name and the date.
5257
LD DE,550EH 11 0E 55
Point Register Pair DE to 550EH, where the identity of the source diskette is kept.
525A
LD BC,0012H 01 12 00
Load Register Pair BC with 0012H, the 18 bytes of a diskette's identity.
525D
LDIR ED B0
Copy the 18 bytes from Register Pair HL (42CEH) to Register Pair DE (550EH): the identity by which the source diskette is recognised later. Register Pair HL ends at 42E0H, Register Pair DE at 5520H and Register Pair BC at 0000H.
525F
LD DE,54CEH 11 CE 54
Point Register Pair DE to 54CEH, the source control block, for the open.
5262
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the start of the transfer buffer, as the sector buffer of the source control block.
5265
LD B,00H 06 00
Load Register B with 00H, the record length 256: each read moves one whole sector into the control block's buffer.
5267
GOSUB to 4424H (request 94H, SYS2/SYS, in memory since 5241H) to open the source file named in the control block at Register Pair DE, with the buffer at Register Pair HL and the record length in Register B.
526A
If the NZ FLAG is set (the file was not found or could not be opened), JUMP to 534FH to display the error in Register A and abort.
526D
LD HL,54AAH 21 AA 54
Point Register Pair HL to 54AAH, the prompt "INSERT DESTINATION DISK (ENTER)".
5270
GOSUB to 53A7H to show the prompt at Register Pair HL, blinking, until the ENTER key is pressed.
5273
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H (stored at 5233H) into Register A.
5276
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for 53DDH.
5277
GOSUB to 53DDH to read the allocation table sector of the diskette in drive Register C into 4200H; NZ FLAG and Register A = 14H on an error.
527A
If the NZ FLAG is set (error 14H, GAT READ ERROR), JUMP to 534FH to display the error and abort.
527D
LD HL,42CEH 21 CE 42
Point Register Pair HL to 42CEH, the identity bytes CEH-DFH of the destination diskette's allocation table.
5280
LD DE,5520H 11 20 55
Point Register Pair DE to 5520H, where the identity of the destination diskette is kept.
5283
LD BC,0012H 01 12 00
Load Register Pair BC with 0012H, the 18 bytes of a diskette's identity.
5286
LDIR ED B0
Copy the 18 bytes from Register Pair HL (42CEH) to Register Pair DE (5520H): the identity of the destination diskette. Register Pair HL ends at 42E0H, Register Pair DE at 5532H and Register Pair BC at 0000H.
5288
LD HL,550EH 21 0E 55
Point Register Pair HL to 550EH, the identity of the source diskette.
528B
LD DE,5520H 11 20 55
Point Register Pair DE to 5520H, the identity of the destination diskette.
528E
LD B,12H 06 12
Load Register B with 12H, the 18 bytes to compare.
5290
GOSUB to 539EH to compare the 18 bytes at Register Pair DE with those at Register Pair HL: the Z FLAG is set when all are equal.
5293
If the NZ FLAG is set (two different diskettes), JUMP to 52A1H to open the destination file.
5295
GOSUB to 5357H to ask for the system diskette when the drive is 0, since the abort below loads SYS1/SYS from drive 0.
5298
LD HL,5442H 21 42 54
Point Register Pair HL to 5442H, the message "SOURCE AND DESTINATION DISKS ARE THE SAME".
529B
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
529E
JUMP to 4030H, the abort exit: XFER does not copy a file onto the diskette it comes from.
52A1H - Open the Destination File and Load SYS8/SYS
The destination diskette is in the drive. SYS2/SYS (still in memory) opens the destination file or creates it, with the same buffer and record length. Then, after asking for the system diskette when the drive is 0, SYS8/SYS is loaded, the overlay SYS0/SYS calls (request 9AH) when a write needs more space for the file; being in memory already, it is not loaded from drive 0 during the writes.
52A1
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the destination control block.
52A4
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the start of the transfer buffer, as the sector buffer of the destination control block.
52A7
LD B,00H 06 00
Load Register B with 00H, the record length 256: each write moves one whole sector from the control block's buffer.
52A9
GOSUB to 4420H (request A4H, SYS2/SYS function 2, still in memory) to open the file of the control block at Register Pair DE, creating it when it is not in the directory, with the buffer at Register Pair HL and record length Register B.
52AC
If the NZ FLAG is set (the file could not be opened or created), JUMP to 534FH to display the error in Register A and abort.
52AF
GOSUB to 5357H to ask for the system diskette when the drive is 0, for the overlay load below.
52B2
GOSUB to 53D7H (request 8AH) to load SYS8/SYS into the overlay area from drive 0.
52B5H - The Transfer Loop: Fill the Buffer from the Source, Then Write It
Each pass asks for the source diskette, reads sectors of the source file one by one straight into the pages 5600H up (by changing the buffer address at +03H of the source control block) until the page limit at 52D4H, then asks for the destination diskette and writes the same pages to the destination file. An end of file (error 1CH or 1DH) leaves the loop at 530EH; another error goes to 534FH.
52B5
Loop Start
GOSUB to 5364H to ask for the source diskette until the diskette in the drive has the identity saved at 550EH.
52B8
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the first page of the transfer buffer.
52BB
LD (54D1H),HL 22 D1 54
Loop Start
Store Register Pair HL (the page for the next sector) to 54D1H-54D2H, bytes +03H-+04H of the source control block, its buffer address: the read puts the sector straight into this page.
52BE
LD DE,54CEH 11 CE 54
Point Register Pair DE to 54CEH, the source control block.
52C1
GOSUB to 4436H to read the next record of the file at Register Pair DE: with the record length 256, the next sector of the source file goes into the page of 54D1H. The Z FLAG is set when it is read.
52C4
If the Z FLAG is set (the sector is read), JUMP to 52D1H for the next page.
52C6
CP 1CH FE 1C
Compare Register A (the error code of the read) against 1CH, END OF FILE ENCOUNTERED.
52C8
If the Z FLAG is set (error 1CH, the whole file is read), JUMP to 530EH to write the rest and close the destination.
52CA
CP 1DH FE 1D
Compare Register A (the error code of the read) against 1DH, RECORD NUMBER OUT OF RANGE.
52CC
If the Z FLAG is set (error 1DH, past the end of the file), JUMP to 530EH to write the rest and close the destination.
52CE
JUMP to 534FH to display the read error in Register A and abort.
52D1
INC H 24
Increment Register H: Register Pair HL is the next page of the transfer buffer.
52D2
LD A,H 7C
Copy Register H (the next page) into Register A.
52D3
CP 60H FE 60
Self-Modifying Code
Compare Register A (the next page) against the page limit, the operand at 52D4H (60H in the file), which 5217H overwrites at the start with the page below the top of memory plus one.
52D5
If the NZ FLAG is set (the buffer has room), JUMP back to 52BBH to read the next sector into the page in Register Pair HL.
52D7
GOSUB to 5381H to ask for the destination diskette until the diskette in the drive has the identity saved at 5520H: the buffer is full.
52DA
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the first page of the transfer buffer.
52DD
LD (54F1H),HL 22 F1 54
Loop Start
Store Register Pair HL (the page to write) to 54F1H-54F2H, bytes +03H-+04H of the destination control block, its buffer address.
52E0
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the destination control block.
52E3
GOSUB to 4439H to write a record to the file at Register Pair DE: with the record length 256, the page of 54F1H becomes the next sector of the destination file.
52E6
If the NZ FLAG is set (a write error), JUMP to 534FH to display the error in Register A and abort.
52E8
INC H 24
Increment Register H: Register Pair HL is the next page of the transfer buffer.
52E9
LD A,H 7C
Copy Register H (the next page) into Register A.
52EA
CP 60H FE 60
Self-Modifying Code
Compare Register A (the next page) against the page limit, the operand at 52EBH (60H in the file), which 521AH overwrites at the start with the same value as 52D4H.
52EC
If the NZ FLAG is set (pages are left), JUMP back to 52DDH to write the next page.
52EE
JUMP back to 52B5H to ask for the source diskette and fill the buffer again.
52F0H - An Ending That No Branch Reaches
No instruction of XFER, and nothing else, jumps or calls to 52F0H: the JR at 52EEH before it always jumps. These rows are the same as the ending at 530EH except that they do not copy the end of file offset from the source control block, so they would leave the destination's last sector counted as full.
52F0
GOSUB to 5333H to write the pages read in this pass to the destination file (not reached: nothing branches to 52F0H).
52F3
GOSUB to 5357H to ask for the system diskette when the drive is 0 (in the unreached ending at 52F0H).
52F6
GOSUB to 53DAH (request 85H) to load SYS3/SYS, the close, from drive 0 (in the unreached ending at 52F0H).
52F9
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H into Register A (in the unreached ending at 52F0H).
52FC
OR A B7
OR Register A (the drive number) with itself: the Z FLAG is set for drive 0, where the system diskette has just been put in.
52FD
If the Z FLAG is set (drive 0), GOSUB to 5381H to ask for the destination diskette again (in the unreached ending at 52F0H).
5300
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the destination control block (in the unreached ending at 52F0H).
5303
GOSUB to 4428H (request 95H, SYS3/SYS) to close the destination file of the control block at Register Pair DE (in the unreached ending).
5306
If the NZ FLAG is set (the close failed), JUMP to 534FH to display the error in Register A and abort (in the unreached ending).
5308
GOSUB to 5357H to ask for the system diskette when the drive is 0 (in the unreached ending at 52F0H).
530B
JUMP to 402DH, the normal exit to VTOS READY (in the unreached ending at 52F0H).
530EH - End of the Source File: Write the Rest and Close the Destination
The read loop comes here at the end of the source file with Register H = the page the failed read was for, so the pages 5600H up to below it hold the last sectors. They are written, the end of file offset of the source is copied to the destination control block, SYS3/SYS is loaded from the system diskette and the destination file is closed. With drive 0 the destination diskette is asked for before the close (5321H); with another drive the close runs on the diskette the last pass left in the drive, which is the source diskette when that pass read no sector (5336H returns without asking for the destination). The source file is never closed: it was only read.
530E
GOSUB to 5333H to write the pages read in this last pass to the destination file; Register H is the page after the last sector read.
5311
LD HL,(54D6H) 2A D6 54
Fetch bytes +08H-+09H of the source control block from 54D6H-54D7H into Register Pair HL: Register L = the end of file offset (the bytes used in the last sector), Register H = the record length.
5314
LD (54F6H),HL 22 F6 54
Store Register Pair HL to 54F6H-54F7H, bytes +08H-+09H of the destination control block: the destination file ends at the same byte of its last sector as the source, and the record length is the same 00H.
5317
GOSUB to 5357H to ask for the system diskette when the drive is 0, for the overlay load below.
531A
GOSUB to 53DAH (request 85H) to load SYS3/SYS, which does the close, from drive 0.
531D
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H (stored at 5233H) into Register A.
5320
OR A B7
OR Register A (the drive number) with itself: the Z FLAG is set for drive 0, which now holds the system diskette.
5321
If the Z FLAG is set (drive 0), GOSUB to 5381H to ask for the destination diskette again. For another drive nothing is asked, and the diskette in the drive is the one the last pass left there: the destination when 5333H wrote pages, but the source when the last pass read no sector, so the close then works on the source diskette.
5324
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the destination control block.
5327
GOSUB to 4428H (request 95H, SYS3/SYS, just loaded) to close the destination file of the control block at Register Pair DE, which writes its directory record.
532A
If the NZ FLAG is set (the close failed), JUMP to 534FH to display the error in Register A and abort.
532D
GOSUB to 5357H to ask for the system diskette when the drive is 0, since VTOS READY loads SYS1/SYS from it.
5330
JUMP to 402DH, the normal exit to VTOS READY: the file is transferred.
5333H - Write the Pages Read to the Destination
Called from 530E (and from the unreached 52F0H) with Register H = the page after the last one filled. When nothing was read in this pass (Register H = 56H) it returns at once without asking for any diskette; otherwise it asks for the destination diskette and writes the pages 5600H up to below Register H.
5333
LD A,H 7C
Copy Register H (the page after the last page read) into Register A.
5334
CP 56H FE 56
Compare Register A against 56H, the first page of the transfer buffer: the Z FLAG is set when no sector was read in this pass.
5336
RET Z C8
If the Z FLAG is set (nothing to write), RETURN at once, without asking for the destination diskette.
5337
GOSUB to 5381H to ask for the destination diskette until the diskette in the drive has the identity saved at 5520H; Register Pair HL is kept.
533A
LD B,H 44
Copy Register H (the page after the last page read) into Register B, the page at which the writing stops.
533B
LD HL,5600H 21 00 56
Point Register Pair HL to 5600H, the first page of the transfer buffer.
533E
LD (54F1H),HL 22 F1 54
Loop Start
Store Register Pair HL (the page to write) to 54F1H-54F2H, bytes +03H-+04H of the destination control block, its buffer address.
5341
LD DE,54EEH 11 EE 54
Point Register Pair DE to 54EEH, the destination control block.
5344
GOSUB to 4439H to write the page of 54F1H as the next sector of the destination file at Register Pair DE.
5347
If the NZ FLAG is set (a write error), JUMP to 534FH to display the error in Register A; the return address of this routine stays on the stack, which the abort exit discards.
5349
INC H 24
Increment Register H: Register Pair HL is the next page of the transfer buffer.
534A
LD A,H 7C
Copy Register H (the next page) into Register A.
534B
CP B B8
Compare Register A (the next page) against Register B, the page after the last page read.
534C
If the NZ FLAG is set (pages are left), JUMP back to 533EH to write the next page.
534E
RET C9
RETURN to the caller: every page read in this pass is written.
534FH - The Error Exit
Every error after the first prompt comes here with the error code in Register A. The system diskette is asked for when the drive is 0, because the error message overlay SYS4/SYS is loaded from drive 0; then 53F0H displays the message.
534F
PUSH AF F5
Save Register Pair AF (the error code in Register A) to the stack, across the prompt.
5350
GOSUB to 5357H to ask for the system diskette when the drive is 0.
5353
POP AF F1
Restore Register Pair AF (the error code in Register A) from the stack.
5354
JUMP to 53F0H to display the error message of the code in Register A and abort.
5357H - Ask for the System Diskette When the Drive Is 0
With drive 0 the source and destination diskettes take the system diskette's place, so before any overlay is loaded (and before the exits) the system diskette is asked for. With another drive the system diskette stays in drive 0 and nothing is asked. Register Pair HL is kept.
5357
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the drive number: the operand at 5358H (00H in the file) is stored by 5233H at the start with the drive of the file specification.
5359
OR A B7
OR Register A (the drive number) with itself: the Z FLAG is set for drive 0.
535A
RET NZ C0
If the NZ FLAG is set (a drive other than 0), RETURN: the system diskette is in drive 0 all the time.
535B
PUSH HL E5
Save Register Pair HL (the caller's) to the stack.
535C
LD HL,546CH 21 6C 54
Point Register Pair HL to 546CH, the prompt "INSERT SYSTEM DISK (ENTER)".
535F
GOSUB to 53A7H to show the prompt at Register Pair HL, blinking, until the ENTER key is pressed.
5362
POP HL E1
Restore Register Pair HL (the caller's) from the stack.
5363
RET C9
RETURN to the caller with the system diskette in drive 0. This routine does not check which diskette it is.
5364H - Wait for the Source Diskette
Asks for the source diskette, reads the allocation table of the drive and compares its bytes CEH-DFH with the identity saved at 550EH, again and again until they match. A read error is not tested: the compare is made on whatever 4200H holds, and when that is not the source's identity the prompt comes again. Register Pair HL is kept.
5364
PUSH HL E5
Loop Start
Save Register Pair HL (the caller's) to the stack.
5365
LD HL,548BH 21 8B 54
Point Register Pair HL to 548BH, the prompt "INSERT SOURCE DISK (ENTER)".
5368
GOSUB to 53A7H to show the prompt at Register Pair HL, blinking, until the ENTER key is pressed.
536B
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H (stored at 5233H) into Register A.
536E
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for 53DDH.
536F
GOSUB to 53DDH to read the allocation table of drive Register C into 4200H. Its result in Register A and the flags is not tested.
5372
LD HL,42CEH 21 CE 42
Point Register Pair HL to 42CEH, the identity bytes CEH-DFH of the allocation table just read.
5375
LD DE,550EH 11 0E 55
Point Register Pair DE to 550EH, the identity of the source diskette saved at 525DH.
5378
LD B,12H 06 12
Load Register B with 12H, the 18 bytes to compare.
537A
GOSUB to 539EH to compare the 18 bytes at Register Pair DE with those at Register Pair HL: the Z FLAG is set when the source diskette is in the drive.
537D
POP HL E1
Restore Register Pair HL (the caller's) from the stack. POP does not change the flags.
537E
If the NZ FLAG is set (another diskette), JUMP back to 5364H to ask for the source diskette again.
5380
RET C9
RETURN to the caller with the source diskette in the drive and Register Pair HL as it was.
5381H - Wait for the Destination Diskette
The same as 5364H for the destination diskette: the prompt "INSERT DESTINATION DISK (ENTER)" until the allocation table bytes CEH-DFH of the diskette in the drive match the identity saved at 5520H. Register Pair HL is kept.
5381
PUSH HL E5
Loop Start
Save Register Pair HL (the caller's: at 5337H the page after the last page read) to the stack.
5382
LD HL,54AAH 21 AA 54
Point Register Pair HL to 54AAH, the prompt "INSERT DESTINATION DISK (ENTER)".
5385
GOSUB to 53A7H to show the prompt at Register Pair HL, blinking, until the ENTER key is pressed.
5388
LD A,(5358H) 3A 58 53
Fetch the drive number from 5358H (stored at 5233H) into Register A.
538B
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for 53DDH.
538C
GOSUB to 53DDH to read the allocation table of drive Register C into 4200H. Its result in Register A and the flags is not tested.
538F
LD HL,42CEH 21 CE 42
Point Register Pair HL to 42CEH, the identity bytes CEH-DFH of the allocation table just read.
5392
LD DE,5520H 11 20 55
Point Register Pair DE to 5520H, the identity of the destination diskette saved at 5286H.
5395
LD B,12H 06 12
Load Register B with 12H, the 18 bytes to compare.
5397
GOSUB to 539EH to compare the 18 bytes at Register Pair DE with those at Register Pair HL: the Z FLAG is set when the destination diskette is in the drive.
539A
POP HL E1
Restore Register Pair HL (the caller's) from the stack. POP does not change the flags.
539B
If the NZ FLAG is set (another diskette), JUMP back to 5381H to ask for the destination diskette again.
539D
RET C9
RETURN to the caller with the destination diskette in the drive and Register Pair HL as it was.
539EH - Compare Two Diskette Identities
Compares Register B bytes at Register Pair DE with those at Register Pair HL. Returns the NZ FLAG at the first difference, or Register A = 00H and the Z FLAG when all are equal.
539E
LD A,(DE) 1A
Loop Start
Fetch the next byte of the first identity at Register Pair DE into Register A.
539F
CP (HL) BE
Compare Register A against the byte of the second identity at Register Pair HL.
53A0
RET NZ C0
If the NZ FLAG is set (the bytes differ), RETURN with the NZ FLAG: two different diskettes.
53A1
INC HL 23
Increment Register Pair HL to the next byte of the second identity.
53A2
INC DE 13
Increment Register Pair DE to the next byte of the first identity.
53A3
Decrement Register B (the bytes left) and JUMP back to 539EH while it is not zero.
53A5
XOR A AF
Set Register A to 00H and the Z FLAG (XOR A): all the bytes are equal.
53A6
RET C9
RETURN with Register A = 00H and the Z FLAG: the same diskette.
53A7H - Show a Prompt Blinking Until ENTER Is Pressed
Register Pair HL = a prompt made of 1DH (cursor to the start of the line), 1EH (erase to the end of the line), the text and 1DH again, ended by 03H. The prompt is shown, the ENTER key (keyboard row 6 at 3840H, bit 0) is first awaited up, then tested 4000H times; when it is not pressed the line is erased, the ROM's delay with 3333H runs and the prompt is shown again, so it blinks. When ENTER is pressed the key is taken with the ROM's 0049H and the line is erased.
53A7
Loop Start
GOSUB to 4467H to display the prompt at Register Pair HL; its last 1DH leaves the cursor at the start of the prompt's line, and Register Pair HL comes back unchanged.
53AA
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A: bit 0 is the ENTER key, 1 while it is held down.
53AD
RRCA 0F
Rotate Register A right: bit 0, the ENTER key, goes into the CARRY FLAG.
53AE
If the C FLAG is set (ENTER is still held down, for example from the line just typed), JUMP back to 53AAH until it is released.
53B0
LD BC,4000H 01 00 40
Load Register Pair BC with 4000H, the number of times the ENTER key is tested while the prompt is on the screen.
53B3
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A, to test the ENTER key in bit 0.
53B6
RRCA 0F
Rotate Register A right: bit 0, the ENTER key, goes into the CARRY FLAG.
53B7
If the C FLAG is set (ENTER is pressed), JUMP to 53CBH to take the key and return.
53B9
DEC BC 0B
Decrement Register Pair BC, the count of tests left.
53BA
LD A,B 78
Copy Register B (the high byte of the count) into Register A.
53BB
OR C B1
OR Register A with Register C (the low byte of the count): the Z FLAG is set when Register Pair BC is 0000H.
53BC
If the NZ FLAG is set (tests are left), JUMP back to 53B3H to test the ENTER key again.
53BE
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases to the end of the line.
53C0
GOSUB to the ROM's 0033H to display Register A (1EH) at the cursor, the start of the prompt's line: the prompt disappears.
53C3
LD BC,3333H 01 33 33
Load Register Pair BC with 3333H, the count for the ROM's delay: the time the prompt stays off.
53C6
GOSUB to the ROM's 0060H to wait for the count in Register Pair BC.
53C9
JUMP back to 53A7H to show the prompt at Register Pair HL again and go on testing the ENTER key.
53CB
GOSUB to the ROM's 0049H to wait for a key from the keyboard, which the ENTER key just pressed gives; the key returned in Register A is not looked at.
53CE
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases to the end of the line.
53D0
GOSUB to the ROM's 0033H to display Register A (1EH) at the start of the prompt's line: the prompt is erased.
53D3
RET C9
RETURN to the caller, the ENTER key pressed and the cursor at the start of the empty line.
53D4H - Load an Overlay from the System Diskette
Three entries, each a request with function 0, which only returns: their use is to have SYS2/SYS (84H), SYS8/SYS (8AH) or SYS3/SYS (85H) loaded into 4E00H-51FFH from drive 0 while the system diskette is there. SYS0/SYS's request handler drops the return address of RST 28H, so each RST 28H returns to the caller of the entry; later requests to the same overlay (94H, A4H; 9AH; 95H) find it in memory and do not load it again.
53D4
LD A,84H 3E 84
Load Register A with 84H, function 0 of SYS2/SYS, which returns at once with the NZ FLAG.
53D6
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H: SYS2/SYS is loaded from drive 0 (430EH becomes 84H) and run, and the handler returns to the caller of 53D4H.
53D7
LD A,8AH 3E 8A
Load Register A with 8AH, function 0 of SYS8/SYS, whose entry (AND 70H, CP 10H) returns at once with Register A = 00H and the NZ FLAG.
53D9
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H: SYS8/SYS is loaded from drive 0 (430EH becomes 8AH) and run, and the handler returns to the caller of 53D7H.
53DA
LD A,85H 3E 85
Load Register A with 85H, function 0 of SYS3/SYS, which returns at once with the NZ FLAG.
53DC
RST 28H EF
RST 28H to 400CH and the request handler at 4C31H: SYS3/SYS is loaded from drive 0 (430EH becomes 85H) and run, and the handler returns to the caller of 53DAH.
53DDH - Read the Allocation Table of the Drive
Register C = the drive. Reads sector 0 of the directory cylinder, the allocation table, into 4200H with SYS0/SYS's directory read. Returns the Z FLAG when it is read, else the NZ FLAG and Register A = 14H (GAT READ ERROR). Register Pairs DE and HL are kept.
53DD
PUSH DE D5
Save Register Pair DE (the caller's) to the stack.
53DE
PUSH HL E5
Save Register Pair HL (the caller's) to the stack.
53DF
GOSUB to 4B65H to load Register D with the directory cylinder of drive Register C, byte +09H of its drive code table.
53E2
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder: the allocation table.
53E4
LD HL,4200H 21 00 42
Point Register Pair HL to 4200H, SYS0/SYS's sector buffer.
53E7
GOSUB to 4B45H to read cylinder Register D, sector Register E of drive Register C into the buffer at Register Pair HL; the Z FLAG is set when it is read as a directory sector (with an ordinary data mark 4B45H takes the directory cylinder from the boot sector and reads again).
53EA
POP HL E1
Restore Register Pair HL (the caller's) from the stack.
53EB
POP DE D1
Restore Register Pair DE (the caller's) from the stack.
53EC
RET Z C8
If the Z FLAG is set (the allocation table is at 4200H), RETURN with the Z FLAG.
53ED
LD A,14H 3E 14
Load Register A with 14H, the error code GAT READ ERROR, in place of the error of the read. LD does not change the NZ FLAG.
53EF
RET C9
RETURN with the NZ FLAG and Register A = 14H.
53F0H - Display an Error and Abort
53F0H shows the error message of the code in Register A; 53F5H and 53FEH show XFER's own two messages. All of them end at the abort exit.
53F0
OR 40H F6 40
OR Register A (the error code) with 40H: bit 6 set asks for the text of the message alone.
53F2
JUMP to 4409H to display the error message of the code in Register A; bit 7 is clear, so it ends at the abort exit 4030H.
53F5
LD HL,5407H 21 07 54
Point Register Pair HL to 5407H, the message "FILE SPEC REQUIRED".
53F8
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
53FB
JUMP to 4030H, the abort exit, which loads SYS1/SYS and shows VTOS READY.
53FE
LD HL,541AH 21 1A 54
Point Register Pair HL to 541AH, the message "INVALID COMMAND DURING PROGRAM CHAINING".
5401
GOSUB to 447BH to display the message at Register Pair HL and write it to the job log.
5404
JUMP to 4030H, the abort exit, which loads SYS1/SYS and shows VTOS READY.
5407H - Messages and Prompts
The three messages end with a carriage return. The three prompts begin with 1DH (cursor to the start of the line) and 1EH (erase to the end of the line) and end with 1DH and 03H, so the cursor stays at the start of the prompt's line for 53A7H to erase it.
5407-5418
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message of 53F5H when 441CH finds no good file specification after XFER.
5419
DEFB 0DH 0D
The carriage return that ends the message "FILE SPEC REQUIRED" and the display of 4467H.
541A-5440
DEFM "INVALID COMMAND DURING PROGRAM CHAINING" 49 4E 56 41 4C 49 44 20 43 4F 4D 4D 41 4E 44 20 44 55 52 49 4E 47 20 50 52 4F 47 52 41 4D 20 43 48 41 49 4E 49 4E 47
The message of 53FEH when bit 5 of 430FH shows a chain file running.
5441
DEFB 0DH 0D
The carriage return that ends the message "INVALID COMMAND DURING PROGRAM CHAINING".
5442-546A
DEFM "SOURCE AND DESTINATION DISKS ARE THE SAME" 53 4F 55 52 43 45 20 41 4E 44 20 44 45 53 54 49 4E 41 54 49 4F 4E 20 44 49 53 4B 53 20 41 52 45 20 54 48 45 20 53 41 4D 45
The message of 5298H when the identities of the two diskettes (allocation table bytes CEH-DFH) are equal.
546B
DEFB 0DH 0D
The carriage return that ends the message "SOURCE AND DESTINATION DISKS ARE THE SAME".
546C-546D
DEFB 1DH,1EH 1D 1E
The start of the system prompt (5357H): 1DH moves the cursor to the start of the line, 1EH erases the line from there.
546E-5488
DEFM "INSERT SYSTEM DISK (ENTER)" 49 4E 53 45 52 54 20 53 59 53 54 45 4D 20 44 49 53 4B 20 20 28 45 4E 54 45 52 29
The text of the system prompt, shown by 53A7H when the drive is 0.
5489-548A
DEFB 1DH,03H 1D 03
The end of the system prompt: 1DH puts the cursor back at the start of the line, 03H ends the text without a new line.
548B-548C
DEFB 1DH,1EH 1D 1E
The start of the source prompt (5244H, 5365H): cursor to the start of the line, then erase the line.
548D-54A7
DEFM "INSERT SOURCE DISK (ENTER)" 49 4E 53 45 52 54 20 53 4F 55 52 43 45 20 44 49 53 4B 20 20 28 45 4E 54 45 52 29
The text of the source prompt, shown by 53A7H.
54A8-54A9
DEFB 1DH,03H 1D 03
The end of the source prompt: the cursor goes back to the start of the line and 03H ends the text.
54AA-54AB
DEFB 1DH,1EH 1D 1E
The start of the destination prompt (526DH, 5382H): cursor to the start of the line, then erase the line.
54AC-54CB
DEFM "INSERT DESTINATION DISK (ENTER)" 49 4E 53 45 52 54 20 44 45 53 54 49 4E 41 54 49 4F 4E 20 44 49 53 4B 20 20 28 45 4E 54 45 52 29
The text of the destination prompt, shown by 53A7H.
54CC-54CD
DEFB 1DH,03H 1D 03
The end of the destination prompt and the last byte of the member: the cursor goes back to the start of the line and 03H ends the text.
54CEH - Work Areas Above the Member
Not in the file: the two control blocks, the two diskette identities and the transfer buffer that XFER uses above its last byte 54CDH.
54CE-54ED
DEFS 32
Not in the file: the control block of the source file. 441CH (at 520BH) puts the specification here, 4424H (5267H) opens it; 52BBH changes its buffer address at 54D1H-54D2H for each sector read by 4436H (52C1H), and 5311H takes its end of file offset and record length from 54D6H-54D7H.
54EE-550D
DEFS 32
Not in the file: the control block of the destination file, a copy of the source's specification (LDIR at 523FH), opened or created by 4420H (52A9H); 52DDH and 533EH change its buffer address at 54F1H-54F2H for each sector written by 4439H, 5314H stores the end of file offset at 54F6H, and 4428H (5327H) closes it.
550E-551F
DEFS 18
Not in the file: the identity of the source diskette, bytes CEH-DFH of its allocation table (master password hash, name, date), stored at 525DH and compared at 5288H-5290H and 5375H-537AH.
5520-5531
DEFS 18
Not in the file: the identity of the destination diskette, bytes CEH-DFH of its allocation table, stored at 5286H and compared at 528BH-5290H and 5392H-5397H.
5532-55FF
DEFS 206
Not in the file and not used: nothing in XFER reads or writes the bytes between the identities and the transfer buffer.
5600-56FF
DEFS 256
Not in the file: the first page of the transfer buffer, which goes on page by page up to the page below the limit stored at 52D4H and 52EBH (5600H-FEFFH when the top of memory is FFFFH). The source control block's buffer is set to each page for a read (52BBH) and the destination's for a write (52DDH, 533EH).
5200H - Member 29 (LOAD, RUN, Codes 81H and 82H): LOAD Entry
LOAD filespec (X) and RUN filespec (X). Entered from SYS1/SYS's command interpreter (request 88H, Register B = 81H for LOAD at 5200H, 82H for RUN at 520DH) with Register Pair HL pointing at the text after the command word. Both read the file specification (default extension CMD) and the parameter X through 5216H, then load the program with 4430H. LOAD returns to VTOS READY (402DH, pushed at 5206H); RUN jumps to the program's transfer address. The member's own load block is 5200H-52D1H; the code that loads the program and gives the second prompt, 52F2H-5324H, comes from the load blocks of the patch SYS6C2 after the member's 07H record, and the jumps to it at 520AH and 5213H (with 5204H, 5222H-5224H and 522BH-5233H) are bytes of the first block that the distributor's notes list as the in place patch SYS6C1. With X the member shows INSERT SOURCE DISK (ENTER) before the load and INSERT SYSTEM DISK (ENTER) after it, each blinking until ENTER is pressed.
5200
GOSUB to 5216H to read the file specification from the command text at Register Pair HL into the control block at 52D2H and the parameter X, and to give the INSERT SOURCE DISK prompt when X was given.
5203
LD DE,402DH 11 2D 40
Load Register Pair DE with 402DH, the VTOS READY exit, the address LOAD ends at.
5206
PUSH DE D5
Save Register Pair DE (402DH) to the stack: the RET at the end of the patch code (52FFH or 526EH) goes to VTOS READY.
5207
LD DE,52D2H 11 D2 52
Point Register Pair DE to 52D2H, the control block holding the file specification of the program.
520A
JUMP to 52F2H, the patch SYS6C2's LOAD code: load the program named at Register Pair DE (52D2H) without running it.
520DH - RUN Entry (Code 82H)
RUN filespec (X): the same reading of the command text as LOAD, then the patch code at 5300H loads the program and RETurns to its transfer address. Nothing is pushed, so the program finds the request handler's return 4C4BH on the top of the stack.
520D
GOSUB to 5216H to read the file specification from the command text at Register Pair HL into the control block at 52D2H and the parameter X, and to give the INSERT SOURCE DISK prompt when X was given.
5210
LD DE,52D2H 11 D2 52
Point Register Pair DE to 52D2H, the control block holding the file specification of the program.
5213
JUMP to 5300H, the patch SYS6C2's RUN code: load the program named at Register Pair DE (52D2H) and run it.
5216H - Read the File Specification and the Parameter X
Entry: Register Pair HL = the command text. The specification is copied into the control block at 52D2H (441CH); none, a bad one, or a device (an asterisk first) gives FILE SPEC REQUIRED. The extension CMD is added when none is given (4473H). The parameter list is read against the table at 52C6H (one entry, X, whose word is the operand at 5239H-523AH): FFFFH when X is given, 0000H as loaded; a bad list gives PARAMETER ERROR. Then request 84H brings SYS2/SYS into the overlay area, so that the open of the program needs no system file read from drive 0 after the disks are changed, and with X the prompt INSERT SOURCE DISK (ENTER) is given. Exit: Register Pair HL = the command text after the parameters.
5216
LD DE,52D2H 11 D2 52
Point Register Pair DE to 52D2H, the 32 byte control block (not in the file) that receives the file specification.
5219
GOSUB to 441CH (SYS1/SYS's 4FCEH) to copy the file specification from the command text at Register Pair HL into the control block at Register Pair DE (52D2H), upper case and ended by 03H: the Z FLAG is set for a good specification and Register Pair HL is past it.
521C
If the NZ FLAG is set (no file specification, or a bad one), JUMP to 5272H to show FILE SPEC REQUIRED and abort.
521F
LD A,(DE) 1A
Fetch the first character of the copied specification at Register Pair DE (52D2H) into Register A.
5220
CP 2AH FE 2A
Compare Register A (the first character) against 2AH, the asterisk that starts a device name.
5222
If the Z FLAG is set (a device, not a file), JUMP to 5272H to show FILE SPEC REQUIRED and abort.
5224
PUSH HL E5
Save Register Pair HL (the command text after the specification) to the stack.
5225
LD HL,52CFH 21 CF 52
Point Register Pair HL to 52CFH, the default extension CMD.
5228
GOSUB to 4473H (SYS1/SYS's 5042H) to add the extension at Register Pair HL (CMD) to the specification in the control block at Register Pair DE (52D2H) when it has none.
522B
POP HL E1
Restore Register Pair HL from the stack: the command text after the specification.
522C
LD DE,52C6H 11 C6 52
Point Register Pair DE to 52C6H, the parameter table with the single entry X.
522F
GOSUB to 4476H (SYS1/SYS's 510FH) to read the parameter list in parentheses from the text at Register Pair HL against the table at Register Pair DE (52C6H): X alone stores FFFFH at 5239H-523AH, and no list leaves 0000H there.
5232
If the NZ FLAG is set (an unknown parameter or a bad list), JUMP to 527BH to show PARAMETER ERROR and abort.
5234
PUSH HL E5
Save Register Pair HL (the command text after the parameters) to the stack.
5235
GOSUB to 526FH, which issues request 84H: SYS2/SYS is loaded into 4E00H-51FFH and returns at once; the handler's return comes back to 5238H.
5238
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the parameter word of X: the operand at 5239H-523AH is 0000H as loaded, and SYS1/SYS's 510FH (called at 522FH) writes FFFFH there when X is given, or the value given with X=.
523B
LD A,D 7A
Copy Register D (the high byte of the X word) into Register A.
523C
OR E B3
OR Register E (the low byte of the X word) into Register A: the NZ FLAG is set when X was given.
523D
LD HL,52A7H 21 A7 52
Point Register Pair HL to 52A7H, the prompt INSERT SOURCE DISK (ENTER); LD does not change the flags.
5240
If the NZ FLAG is set (X given), GOSUB to 5245H to show the prompt at Register Pair HL (52A7H) and wait for ENTER.
5243
POP HL E1
Restore Register Pair HL from the stack: the command text after the parameters.
5244
RET C9
RETURN to the caller, 5203H (LOAD) or 5210H (RUN).
5245H - Show a Prompt and Wait for ENTER
Entry: Register Pair HL = a prompt text (52A7H or 5306H) that starts with 1DH (cursor to the start of the line) and 1EH (erase to the end of the line) and ends with 1DH and 03H. The prompt is displayed; once ENTER (keyboard row 6 at 3840H, bit 0) is up, the keyboard is polled 4000H times; when ENTER goes down the line is erased (1EH) and the routine returns. When the count runs out the line is erased, the ROM's delay 0060H waits with 3333H counts and the prompt is shown again, so it blinks until ENTER is pressed. Register Pair HL is kept by 4467H.
5245
Loop Start
GOSUB to 4467H to display the prompt text at Register Pair HL up to its ending 03H; Register Pair HL is returned unchanged, at the start of the text, and the cursor is back at the start of the line (the last 1DH).
5248
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A: bit 0 is ENTER.
524B
RRCA 0F
Rotate Register A right: bit 0 (ENTER) goes into the CARRY FLAG.
524C
If the CARRY FLAG is set (ENTER is still down), LOOP BACK to 5248H until it is let go.
524E
LD BC,4000H 01 00 40
Load Register Pair BC with 4000H, the number of keyboard polls before the prompt is blinked off.
5251
LD A,(3840H) 3A 40 38
Loop Start
Fetch keyboard row 6 from 3840H into Register A: bit 0 is ENTER.
5254
RRCA 0F
Rotate Register A right: bit 0 (ENTER) goes into the CARRY FLAG.
5255
If the CARRY FLAG is set (ENTER pressed), JUMP to 5269H to erase the prompt and return.
5257
DEC BC 0B
Decrement Register Pair BC, the number of keyboard polls left before the blink.
5258
LD A,B 78
Copy Register B (the high byte of the polls left) into Register A.
5259
OR C B1
OR Register C (the low byte of the polls left) into Register A: the Z FLAG is set when Register Pair BC = 0000H.
525A
If the NZ FLAG is set (polls left in Register Pair BC), LOOP BACK to 5251H.
525C
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
525E
GOSUB to the ROM's 0033H to display Register A (1EH): the prompt line is wiped, the cursor stays at its start.
5261
LD BC,3333H 01 33 33
Load Register Pair BC with 3333H, the count for the ROM's delay loop: how long the prompt stays off.
5264
GOSUB to the ROM's 0060H to wait for Register Pair BC (3333H) counts.
5267
JUMP back to 5245H to show the prompt at Register Pair HL again.
5269
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases from the cursor to the end of the line.
526B
GOSUB to the ROM's 0033H to display Register A (1EH): the prompt is wiped off the line.
526E
RET C9
RETURN to the caller with ENTER pressed (to 5243H, or for the prompt of the patch code to 402DH for LOAD or to the program's transfer address for RUN).
526FH - Bring SYS2/SYS In, and the Exits
526FH issues request 84H (SYS2/SYS function 0, which RETurns at once): the request handler drops the return address of RST 28H, so the result goes back to the caller of 526FH. 5272H and 527BH display FILE SPEC REQUIRED or PARAMETER ERROR and go to the abort exit 4030H.
526F
LD A,84H 3E 84
Load Register A with 84H, request code 84H: SYS2/SYS (bits 3-0 = 4), function 0, which only returns.
5271
RST 28H EF
RST 28H to 400CH, the request handler: SYS2/SYS is read into 4E00H-51FFH unless it is there already, and its RET comes back to 5238H, the return of the CALL at 5235H; the return address of RST 28H itself (5272H) is dropped.
5272
LD HL,5284H 21 84 52
Point Register Pair HL to 5284H, the text FILE SPEC REQUIRED ended by 0DH.
5275
GOSUB to 447BH to display the text at Register Pair HL (5284H) and write it to the job log.
5278
JUMP to 4030H, the abort exit: nothing is loaded.
527B
LD HL,5297H 21 97 52
Point Register Pair HL to 5297H, the text PARAMETER ERROR ended by 0DH.
527E
GOSUB to 447BH to display the text at Register Pair HL (5297H) and write it to the job log.
5281
JUMP to 4030H, the abort exit: nothing is loaded.
5284H - Messages, the Parameter Table and the Default Extension
The two error texts, the first prompt, the table of the one parameter X for 510FH (6 characters of name, then the address of its word) ended by 00H, and the extension CMD for 5042H.
5284-5295
DEFM "FILE SPEC REQUIRED" 46 49 4C 45 20 53 50 45 43 20 52 45 51 55 49 52 45 44
The message 5272H shows when the command text holds no file specification, a bad one or a device name.
5296
DEFB 0DH 0D
The carriage return that ends the message at 5284H.
5297-52A5
DEFM "PARAMETER ERROR" 50 41 52 41 4D 45 54 45 52 20 45 52 52 4F 52
The message 527BH shows when the parameter list cannot be read.
52A6
DEFB 0DH 0D
The carriage return that ends the message at 5297H.
52A7-52A8
DEFB 1DH,1EH 1D 1E
The prompt at 52A7H starts with 1DH (cursor to the start of the line) and 1EH (erase to the end of the line), so it is written over a clean line.
52A9-52C3
DEFM "INSERT SOURCE DISK (ENTER)" 49 4E 53 45 52 54 20 53 4F 55 52 43 45 20 44 49 53 4B 20 20 28 45 4E 54 45 52 29
The first prompt of X, given by 5240H before the program is loaded: the diskette with the program is to be put in.
52C4-52C5
DEFB 1DH,03H 1D 03
The end of the prompt at 52A7H: 1DH puts the cursor back at the start of the line, so that the 1EH of 525CH and 5269H wipes the whole prompt; 03H ends the text and is not displayed.
52C6-52CB
DEFM "X " 58 20 20 20 20 20
The parameter table's only entry: the name X filled with five spaces to six characters.
52CC-52CD
DEFW 5239H 39 52
The address of the word of X: the operand of LD DE,0000H at 5238H, written by 510FH (522FH).
52CE
DEFB 00H 00
The byte 00H that ends the parameter table at 52C6H.
52CF-52D1
DEFM "CMD" 43 4D 44
The default extension given to 4473H at 5225H for a program named with no extension.
52D2-52F1
DEFS 32
Not in the file: the control block of the program. 441CH (5219H) copies the specification here, 4473H (5228H) adds CMD, and 4430H (52F2H or 5300H) opens and loads the program through it. Nothing of the member is loaded here; the patch's first block starts just after it, at 52F2H.
52F2H - Patch SYS6C2: LOAD the Program
The 07H record SYS6C2 is followed by four load blocks: 52F2H-52FFH, 5300H-5307H, 5308H-5323H and 5323H-5324H. The member's own block ends at 52D1H and 52D2H-52F1H is the control block, so before the patch nothing of the member was at 52F2H-5324H: every byte here is added by the patch. This block loads the program named at Register Pair DE with 4430H and then, when X was given, shows INSERT SYSTEM DISK (ENTER) and waits for ENTER, so that VTOS READY (402DH, on the stack) can read SYS1/SYS from the system diskette. The result of 4430H is not tested.
52F2
GOSUB to 4430H to load the program file named by the control block at Register Pair DE (52D2H), without running it: on return the Z FLAG and Register Pair HL = the transfer address, or the NZ FLAG and Register A = the error code (bit 6 set).
52F5
LD A,(5239H) 3A 39 52
Fetch the low byte of the X word from 5239H (the operand of LD DE,0000H at 5238H: FFH with X, 00H without) into Register A; the error code of a failed load in Register A is lost here.
52F8
OR A B7
OR Register A (the low byte of the X word) with itself: the NZ FLAG is set when X was given.
52F9
LD HL,5306H 21 06 53
Point Register Pair HL to 5306H, the prompt INSERT SYSTEM DISK (ENTER); LD does not change the flags.
52FC
If the NZ FLAG is set (X given), JUMP to 5245H to show the prompt at Register Pair HL (5306H) and wait for ENTER; its RET at 526EH then goes to the address on the stack.
52FF
RET C9
RETURN to the address on the stack: 402DH (VTOS READY) for LOAD, pushed at 5206H, or for RUN the transfer address pushed at 5303H.
5300H - Patch SYS6C2: RUN the Program
Loads the program with 4430H, pushes the transfer address in Register Pair HL and joins the LOAD code at 52F5H, whose RET (or the RET of the prompt) then jumps to the program. The program is started without DEBUG and without the flags of SYS0/SYS's 4433H, and a failed load is not tested: the RET goes to whatever Register Pair HL held after the failure.
5300
GOSUB to 4430H to load the program file named by the control block at Register Pair DE (52D2H): on return the Z FLAG and Register Pair HL = the transfer address, or the NZ FLAG and Register A = the error code.
5303
PUSH HL E5
Save Register Pair HL (the transfer address of the program) to the stack, as the address the RET at 52FFH or 526EH goes to.
5304
JUMP back to 52F5H to give the INSERT SYSTEM DISK prompt when X was given and then RETurn to the program at the transfer address on the stack.
5306-5307
DEFB 1DH,1EH 1D 1E
The patch's second prompt starts with 1DH (cursor to the start of the line) and 1EH (erase to the end of the line); these two bytes are the end of the load block 5300H-5307H.
5308-5322
DEFM "INSERT SYSTEM DISK (ENTER)" 49 4E 53 45 52 54 20 53 59 53 54 45 4D 20 44 49 53 4B 20 20 28 45 4E 54 45 52 29
The second prompt of X, loaded by the patch block 5308H-5323H and given by 52FCH after the program is loaded: the system diskette is to be put back.
5323-5324
DEFB 1DH,03H 1D 03
The end of the prompt at 5306H: 1DH puts the cursor back at the start of the line and 03H ends the text. 5323H is loaded twice: the last byte of the block 5308H-5323H puts a space (20H) there, a third space after DISK (ENTER) in the patch's text, and the block 5323H-5324H, loaded after it, writes 1DH over it and the 03H at 5324H.