4E00H - Entry: The Four Functions
SYS7/SYS is loaded at 4E00H by the request handler of SYS0/SYS (4C31H) for a request code whose bits 3-0 are 9 (directory entry code 21H) and called at 4E00H with Register A = the request code (fetched from 430EH at 4C45H). Bits 6-4 choose the function: 99H (1) starts the execution phase of CHAIN (SYS6/SYS member 12 issues it at its 52BEH); A9H (2) and B9H (3) are the requests that SYS7/SYS itself writes into the exits 402DH and 4030H while chaining; C9H (4) comes from SYS0/SYS's 44BEH, which SYS7/SYS makes the keyboard driver. Any other code returns at once with the NZ FLAG set.
4E00
AND 70H E6 70
Mask Register A (the request code) with 70H, keeping bits 6-4, the function number times 10H.
4E02
CP 20H FE 20
Compare Register A against 20H, function 2 (request A9H, the normal exit 402DH while chaining): the Z FLAG is set on a match.
4E04
If the Z FLAG is set (function 2), JUMP to 4E58H to give the system the next command line of the file.
4E06
CP 30H FE 30
Compare Register A against 30H, function 3 (request B9H, the abort exit 4030H while chaining).
4E08
If the Z FLAG is set (function 3), JUMP to 4E8CH to show CHAINING ABORTED! and end the chaining.
4E0B
CP 40H FE 40
Compare Register A against 40H, function 4 (request C9H, the keyboard driver 44BEH while chaining).
4E0D
If the Z FLAG is set (function 4), JUMP to 4EC8H, the keyboard driver of the execution phase.
4E10
CP 10H FE 10
Compare Register A against 10H, function 1 (request 99H from CHAIN).
4E12
RET NZ C0
If the NZ FLAG is set (functions 0, 5, 6 and 7: requests 89H, D9H, E9H, F9H), RETURN to the request handler with Register A = the masked code (00H, 50H, 60H or 70H) and the NZ FLAG set.
4E13H - Function 1 (99H): Start the Execution Phase
CHAIN has opened the file of commands (normally SYSTEM/JCL) in the control block 4358H with SYS0/SYS's sector buffer 4200H. 430FH bit 5 is set; when it was clear before, the keyboard driver of the KI device control block (4016H-4017H) is saved at 43BEH and the two exits are pointed at SYS7/SYS: 402DH becomes LD A,A9H / RST 28H and 4030H LD A,B9H / RST 28H. The first line is then read through the driver 4E52H and handed to 4405H to be executed, and from then on the keyboard driver is 44BEH. A CHAIN met while chaining (bit 5 already set) keeps the saved driver and the exits.
4E13
DI F3
Disable interrupts while the system flags, the keyboard driver word and the exits are changed.
4E14
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte.
4E17
BIT 5,(HL) CB 6E
Test bit 5 of the system flags at Register Pair HL: the NZ FLAG is set when a chaining is already under way.
4E19
SET 5,(HL) CB EE
Set bit 5 of the system flags at Register Pair HL: the execution phase of CHAIN runs. SET does not change the flags of the BIT above.
4E1B
If the NZ FLAG is set (bit 5 was already set: a CHAIN inside a chained file), JUMP to 4E2CH and keep the keyboard driver saved at 43BEH and the exits as they are.
4E1D
LD HL,(4016H) 2A 16 40
Fetch the driver address of the KI device control block from 4016H-4017H into Register Pair HL: the keyboard driver in use (SYS0/SYS's 439CH or one a program has set).
4E20
LD (43BEH),HL 22 BE 43
Store Register Pair HL (the keyboard driver) to 43BEH-43BFH, where 4EACH takes it back from at the end and 4EDCH passes key requests to it.
4E23
LD HL,A93EH 21 3E A9
Load Register Pair HL with A93EH: the bytes 3EH A9H, LD A,A9H, for 402DH-402EH.
4E26
LD DE,B93EH 11 3E B9
Load Register Pair DE with B93EH: the bytes 3EH B9H, LD A,B9H, for 4030H-4031H.
4E29
GOSUB to 4EB8H to write Register Pair HL to 402DH and Register Pair DE to 4030H, each followed by EFH (RST 28H): a command that ends at 402DH now runs function 2 of SYS7/SYS, one that aborts at 4030H function 3.
4E2C
LD SP,41E0H 31 E0 41
Load the Stack Pointer with 41E0H, the stack the command level uses: the stack of CHAIN is dropped.
4E2F
EI FB
Enable interrupts again: the system flags, the saved driver and the exits are set.
4E30
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands.
4E33
GOSUB to 444BH to compare the position of the file at Register Pair DE with its end: Register A = 00H and the Z FLAG before the end, error 1CH (at the end) or 1DH (past it) with the NZ FLAG.
4E36
If the NZ FLAG is set (the file is empty, or error 26H: the control block 4358H is not open), JUMP to 4409H to show the error in Register A; the error ends through 4030H, which is now LD A,B9H / RST 28H, so 4E8CH shows CHAINING ABORTED! after it.
4E39
LD DE,4E52H 11 52 4E
Point Register Pair DE to 4E52H, a driver that takes every key from the file.
4E3C
LD (4016H),DE ED 53 16 40
Store Register Pair DE (4E52H) to 4016H-4017H, the driver address of the KI device control block 4015H: the first line is read straight from the file.
4E40
LD HL,4318H 21 18 43
Point Register Pair HL to 4318H, the command line buffer 4318H-4357H.
4E43
LD B,3FH 06 3F
Load Register B with 3FH, the most characters of the line: 63.
4E45
GOSUB to the ROM's line input at 0040H: the keys come through the KI driver 4E52H, so the first line of the file is copied into the buffer at Register Pair HL and shown, up to its 0DH. Register Pair HL = 4318H on return.
4E48
LD DE,44BEH 11 BE 44
Point Register Pair DE to 44BEH, SYS0/SYS's LD A,C9H / RST 28H: request C9H, function 4 of SYS7/SYS.
4E4B
LD (4016H),DE ED 53 16 40
Store Register Pair DE (44BEH) to 4016H-4017H, the driver address of the KI device control block: from now on every key request goes to 4EC8H.
4E4F
JUMP to 4405H to execute the command line at Register Pair HL (4318H), through request B3H of SYS1/SYS. When the command ends at 402DH, function 2 reads the next line.
4E52H - The Driver of the First Line
The keyboard driver while 4E45H reads the first line: every key is the next byte of the file. Reached from the ROM's 03C2H through the KI device control block 4015H. The first line is not checked for a slash, a 00H byte or the end of the file.
4E52
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands.
4E55
JUMP to the ROM's 0013H to read the next byte of the file at Register Pair DE into Register A; it returns to the ROM's line input as the key.
4E58H - Function 2 (A9H): The Next Command Line
A command has ended through 402DH (LD A,A9H / RST 28H while chaining). As at the command level, the BREAK vector is armed when DEBUG is on. BREAK held down (unless 430FH bit 4 says BREAK is ignored) ends the chaining with MANUAL CHAINING ABORT!; the end of the file ends it with CHAINING COMPLETED. Otherwise the ROM's line input reads the next line, whose keys come from 4EC8H, and 4405H executes it.
4E58
LD SP,41E0H 31 E0 41
Load the Stack Pointer with 41E0H, the stack of the command level: whatever the ended command left on its stack is dropped.
4E5B
EI FB
Enable interrupts, as the command level runs with them on (the clock and the tasks).
4E5C
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte.
4E5F
BIT 7,(HL) CB 7E
Test bit 7 of the system flags at Register Pair HL (DEBUG on): the Z FLAG is set when it is clear.
4E61
If the Z FLAG is set (DEBUG off), JUMP to 4E68H and leave the BREAK vector byte as the request handler left it, C9H.
4E63
LD A,C3H 3E C3
Load Register A with C3H, the JP opcode, to arm the BREAK vector.
4E65
LD (4315H),A 32 15 43
Store Register A (C3H) to 4315H, the BREAK vector byte: BREAK jumps to the address at 4316H-4317H, which DEBUG ON points at 400FH.
4E68
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
4E6B
BIT 4,A CB 67
Test bit 4 of Register A: set when BREAK is to be ignored (a non breakable AUTO command or SYSTEM (BREAK=N)).
4E6D
If the NZ FLAG is set (BREAK ignored), JUMP to 4E79H without looking at the key.
4E6F
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A: bit 2 is the BREAK key.
4E72
AND 04H E6 04
Mask Register A to bit 2: the NZ FLAG is set when BREAK is held down.
4E74
LD HL,51E4H 21 E4 51
Point Register Pair HL to 51E4H, the text MANUAL CHAINING ABORT! and 0DH. LD does not change the flags.
4E77
If the NZ FLAG is set (BREAK held down), JUMP to 4E94H to show the text at Register Pair HL and end the chaining.
4E79
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands.
4E7C
GOSUB to 444BH to compare the position of the file at Register Pair DE with its end: the Z FLAG before the end, the NZ FLAG at or past it.
4E7F
If the NZ FLAG is set (the whole file has been read), JUMP to 4E91H to show CHAINING COMPLETED and end the chaining.
4E81
LD HL,4318H 21 18 43
Point Register Pair HL to 4318H, the command line buffer.
4E84
LD B,3FH 06 3F
Load Register B with 3FH, the most characters of the line: 63.
4E86
GOSUB to the ROM's line input at 0040H: the keys come through the KI driver 44BEH and so from 4EC8H, which hands it the next line of the file (and runs any directive lines before it). Register Pair HL = 4318H on return.
4E89
JUMP to 4405H to execute the command line at Register Pair HL (4318H), through request B3H of SYS1/SYS.
4E8CH - Function 3 (B9H) and //ABORT: Chaining Aborted
A command ended through the abort exit 4030H (LD A,B9H / RST 28H while chaining), for instance after an error message of 4409H, or the file has a line //ABORT. 4E91H is //EXIT and the end of the file; 4E94H shows the text at Register Pair HL on a new line, logs it, ends the chaining and goes to VTOS READY.
4E8C
LD HL,51D2H 21 D2 51
Point Register Pair HL to 51D2H, the text CHAINING ABORTED! and 0DH (the second half of the text at 51C5H).
4E8F
JUMP to 4E94H to show it and end the chaining.
4E91
LD HL,51B2H 21 B2 51
Point Register Pair HL to 51B2H, the text CHAINING COMPLETED and 0DH: the end of the file, a byte 00H at the start of a line, or the line //EXIT.
4E94
LD A,0AH 3E 0A
Load Register A with 0AH, a character the ROM's display routine takes as a carriage return (0AH-0DH go to its 0564H).
4E96
GOSUB to the ROM's 0033H to send Register A (0AH) to the display: the message starts on a new line.
4E99
GOSUB to 447BH to display the text at Register Pair HL up to its 0DH and write it to the job log.
4E9C
GOSUB to 4EA2H to end the chaining: 430FH bit 5 cleared, the control block 4358H marked closed, the keyboard driver and the two exits put back.
4E9F
JUMP to 402DH, which 4EA2H has made LD A,93H / RST 28H again: SYS1/SYS's VTOS READY.
4EA2H - End the Chaining
Clears 430FH bit 5, stores 00H in byte +00H of the control block 4358H (bit 7 clear: not open; the file is only read, so nothing is written), puts the keyboard driver saved at 43BEH back into 4016H-4017H and writes the original exits: 402DH LD A,93H / RST 28H (VTOS READY) and 4030H LD A,A3H / RST 28H (the abort exit). Interrupts are left disabled: no EI follows the DI. 4EB8H, the end of it, writes the exits from Register Pairs HL and DE.
4EA2
DI F3
Disable interrupts while the system flags, the keyboard driver word and the exits are changed. Nothing in 4EA2H-4EC7H enables them again.
4EA3
LD HL,430FH 21 0F 43
Point Register Pair HL to 430FH, the system flags byte.
4EA6
RES 5,(HL) CB AE
Reset bit 5 of the system flags at Register Pair HL: the execution phase of CHAIN has ended.
4EA8
XOR A AF
Set Register A to 00H, the value that marks the control block 4358H closed.
4EA9
LD (4358H),A 32 58 43
Store Register A (00H) to 4358H, byte +00H of the control block of the file of commands: with bit 7 clear the block is not open (49EBH refuses it with error 26H). The file is not closed through 4428H.
4EAC
LD HL,(43BEH) 2A BE 43
Fetch the keyboard driver saved by 4E20H from 43BEH-43BFH into Register Pair HL.
4EAF
LD (4016H),HL 22 16 40
Store Register Pair HL (the saved keyboard driver) to 4016H-4017H, the driver address of the KI device control block: keys come from the keyboard again.
4EB2
LD HL,933EH 21 3E 93
Load Register Pair HL with 933EH: the bytes 3EH 93H, LD A,93H, for 402DH-402EH.
4EB5
LD DE,A33EH 11 3E A3
Load Register Pair DE with A33EH: the bytes 3EH A3H, LD A,A3H, for 4030H-4031H.
4EB8
LD A,EFH 3E EF
Load Register A with EFH, the opcode RST 28H. 4E29H calls here with Register Pair HL = A93EH and Register Pair DE = B93EH.
4EBA
LD (402DH),HL 22 2D 40
Store Register Pair HL to 402DH-402EH, the first two bytes of the normal exit: 3EH and the request code, LD A,code.
4EBD
LD (402FH),A 32 2F 40
Store Register A (EFH) to 402FH: RST 28H after the LD A of the normal exit.
4EC0
LD (4030H),DE ED 53 30 40
Store Register Pair DE to 4030H-4031H, the first two bytes of the abort exit: 3EH and the request code, LD A,code.
4EC4
LD (4032H),A 32 32 40
Store Register A (EFH) to 4032H: RST 28H after the LD A of the abort exit.
4EC7
RET C9
RETURN to the caller with interrupts still disabled.
4EC8H - Function 4 (C9H): The Keyboard Driver While Chaining
44BEH (LD A,C9H / RST 28H) is the driver of the KI device control block while chaining, so every key request of the ROM (0013H through 03C2H, from 002BH and 0049H) comes here. On entry the stack holds 4C4BH (the request handler's return), 03DDH (the return into the ROM's 03C2H), the words 03C2H pushed (Register Pairs DE, IX and HL), the Register Pair BC that 0013H pushed, the return address of the CALL to 0013H or 002BH, and the word above it. Only a request made by the ROM's line input, whose CALL 0049H at 05E0H leaves 05E3H at the stack's 0EH, is served from the file; every other key request (INKEY$, a program's own key wait, the //KEYIN answer) goes to the keyboard driver saved at 43BEH.
4EC8
LD HL,000AH 21 0A 00
Load Register Pair HL with 000AH, the offset of the word that the ROM's 0013H pushed.
4ECB
ADD HL,SP 39
Add the Stack Pointer to Register Pair HL: Register Pair HL = the address of that word, the caller's Register Pair BC. The CARRY FLAG is set only for a Stack Pointer of FFF6H or more.
4ECC
LD C,(HL) 4E
Fetch the low byte at Register Pair HL into Register C: for the ROM's line input, the most characters of the line (05DFH copies Register B into Register C).
4ECD
INC HL 23
Increment Register Pair HL to the high byte of the saved Register Pair BC.
4ECE
LD B,(HL) 46
Fetch the high byte at Register Pair HL into Register B: for the line input, the room left, which equals Register C until a character has been typed.
4ECF
INC HL 23
Increment Register Pair HL past the saved Register Pair BC, to the return address of the CALL to 0013H or 002BH (004CH for 0049H).
4ED0
INC HL 23
Increment Register Pair HL to the high byte of that return address.
4ED1
INC HL 23
Increment Register Pair HL to the word above it, at the stack's offset 0EH.
4ED2
LD E,(HL) 5E
Fetch the low byte at Register Pair HL into Register E.
4ED3
INC HL 23
Increment Register Pair HL to the high byte of the word.
4ED4
LD D,(HL) 56
Fetch the high byte at Register Pair HL into Register D: Register Pair DE = the word at offset 0EH, 05E3H when the ROM's line input called 0049H.
4ED5
LD HL,05E3H 21 E3 05
Load Register Pair HL with 05E3H, the return address of the CALL 0049H at 05E0H in the ROM's line input.
4ED8
SBC HL,DE ED 52
Subtract Register Pair DE (the word on the stack) and the CARRY FLAG from Register Pair HL (05E3H): the Z FLAG is set when the key request comes from the line input.
4EDA
If the Z FLAG is set (the ROM's line input asks for a key), JUMP to 4EE0H to give it the file's next byte.
4EDC
LD HL,(43BEH) 2A BE 43
Fetch the keyboard driver saved by 4E20H from 43BEH-43BFH into Register Pair HL.
4EDF
JP (HL) E9
JUMP to the keyboard driver at Register Pair HL with the stack as the ROM built it plus 4C4BH on top: the key is read from the keyboard and returns through the request handler's 4C4BH. The driver gets Register A = 40H (the masked request code), Register Pair BC = the caller's word from the stack, Register Pair DE = the word at offset 0EH and the flags of 4ED8H (NZ) instead of what 03C2H gives (Register B = 01H, Register C = the caller's Register A, the flags of CP 02H); Index Register IX still points at 4015H as 03C6H set it.
4EE0H - The Next Byte for the Line Input
Register B = the room left, Register C = the most characters of the line. At the end of the file the chaining ends with CHAINING COMPLETED. The end of the file is tested at every key request, so a last line cut off by the end of the file is dropped. Inside a line the next byte of the file is the key. At the start of a line (Register B = Register C) the file is first set back to the sector of its buffer, since 4200H, the buffer of 4358H, is also where SYS0/SYS reads the overlays (a line whose 0DH is the last byte of a sector makes this replay that sector, 4EEFH); then the first byte is read: 00H ends the chaining, a slash starts a directive line (4F02H), anything else is the key. 4F50H comes back here after a directive line.
4EE0
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands.
4EE3
PUSH BC C5
Save Register Pair BC (the line input's counts) to the stack.
4EE4
GOSUB to 444BH to compare the position of the file at Register Pair DE with its end: the Z FLAG before the end, the NZ FLAG at or past it.
4EE7
POP BC C1
Restore Register Pair BC (the line input's counts) from the stack.
4EE8
If the NZ FLAG is set (the whole file has been read), JUMP to 4E91H to show CHAINING COMPLETED and end the chaining; the line input never gets its key.
4EEA
LD A,B 78
Copy Register B (the room left) into Register A.
4EEB
CP C B9
Compare Register A against Register C (the most characters): the Z FLAG is set at the start of a line.
4EEC
If the NZ FLAG is set (inside a line), JUMP to the ROM's 0013H to read the next byte of the file at Register Pair DE (4358H) into Register A; it returns through 4C4BH to the line input as the key. A byte 00H inside a line is passed over by the ROM's 0049H, which asks again; a slash is an ordinary character there.
4EEF
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 4200H: an overlay loaded since then has used the same buffer. When the 0DH of the line before was the last byte of a sector, the offset is 00H and the next record number already names the next sector; 4454H then goes back to the sector just finished, and its lines are given again from its first byte, again and again, until BREAK is held when a command ends.
4EF2
If the NZ FLAG is set (4454H failed, error 26H when the control block at Register Pair DE is not open), JUMP to 4409H to show the error in Register A.
4EF5
GOSUB to the ROM's 0013H to read the first byte of the line from the file at Register Pair DE into Register A.
4EF8
OR A B7
OR Register A with itself: the Z FLAG is set for a byte 00H.
4EF9
If the Z FLAG is set (a byte 00H), JUMP to 4E91H to show CHAINING COMPLETED and end the chaining.
4EFB
PUSH AF F5
Save Register Pair AF (the byte and the NZ FLAG) to the stack.
4EFC
CP 2FH FE 2F
Compare Register A (the first byte of the line) against 2FH, a slash.
4EFE
If the Z FLAG is set (the line starts with a slash), JUMP to 4F02H to read the whole line.
4F00
POP AF F1
Restore Register Pair AF from the stack: Register A = the byte, the NZ FLAG set.
4F01
RET C9
RETURN through the request handler's 4C4BH to the line input with the first character of the line in Register A.
4F02H - A Line Starting With a Slash
The whole line is read into the command line buffer 4318H, up to and including its 0DH; nothing limits its length. A line with one slash is dropped. Three slashes end every block of //KEYIN (4FBDH := 00H). Two slashes and a digit are a block label: 4FBCH compares 39H less the digit with 4FBDH. Two slashes and anything else: the line is written to the job log, spaces are passed over, and the word that follows (6 letters or digits at most, made upper case) is looked up in the table of directives at 50B6H. A directive is entered with Register Pair HL past the word and the character after it (on that character when it is 03H, 0DH or an opening parenthesis), and the stack holding 4318H, then Register Pair DE (4358H), then Register Pair BC. A line whose word is not in the table is only logged.
4F02
POP AF F1
Restore Register Pair AF from the stack: Register A = the slash.
4F03
PUSH BC C5
Save Register Pair BC (the line input's counts) to the stack.
4F04
PUSH DE D5
Save Register Pair DE (4358H, the control block of the file) to the stack.
4F05
LD HL,4318H 21 18 43
Point Register Pair HL to 4318H, the command line buffer.
4F08
PUSH HL E5
Save Register Pair HL (4318H, the start of the line) to the stack.
4F09
LD (HL),A 77
Store Register A (the byte of the line) at Register Pair HL in the buffer.
4F0A
INC HL 23
Increment Register Pair HL to the next place in the buffer.
4F0B
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
4F0D
If the Z FLAG is set (the 0DH is stored), JUMP to 4F14H. The loop has no other end: the 65th byte of a longer line is stored over byte +00H of the control block 4358H of the file itself, and the reads after it fail (error 26H, stored again and again) or jump through the line's bytes as a driver address; a last line with no 0DH stores the error code 1CH that 0013H returns at the end of the file up to 4358H and then fails the same way.
4F0F
GOSUB to the ROM's 0013H to read the next byte of the line from the file at Register Pair DE (4358H) into Register A.
4F12
LOOP BACK to 4F09H to store the byte just read in Register A.
4F14
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line.
4F15
PUSH HL E5
Save Register Pair HL (4318H) to the stack again.
4F16
INC HL 23
Increment Register Pair HL to the second character of the line.
4F17
LD A,(HL) 7E
Fetch the second character from Register Pair HL into Register A.
4F18
CP 2FH FE 2F
Compare Register A (the second character) against 2FH, a slash.
4F1A
If the NZ FLAG is set (one slash only), JUMP to 4F4DH: the line is dropped and the next one is read.
4F1C
INC HL 23
Increment Register Pair HL to the third character of the line.
4F1D
SUB (HL) 96
SUBtract the third character at Register Pair HL from Register A (2FH): Register A = 2FH less the character, 00H for a third slash.
4F1E
If the Z FLAG is set (three slashes), JUMP to 4FC0H with Register A = 00H: the end of the blocks.
4F21
SUB F6H D6 F6
SUBtract F6H from Register A: no borrow (the NC FLAG) only when 2FH less the character was F6H-FFH, that is for the digits 30H-39H; Register A = 39H less the character, 09H for 0 down to 00H for 9.
4F23
If the NC FLAG is set (a digit: a block label), JUMP to 4FBCH to compare Register A (39H less the digit) with the block 4FBDH holds.
4F26
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer: Register Pair HL = 4318H, the start of the line; the stack holds the address of the third character.
4F27
GOSUB to 447EH to write the line at Register Pair HL, up to its 0DH, to the job log.
4F2A
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer again: Register Pair HL = the address of the third character, the stack holds 4318H.
4F2B
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
4F2C
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4F2E
If the Z FLAG is set (nothing after the two slashes), JUMP to 4F4DH: the line is only logged.
4F30
CP 20H FE 20
Compare Register A (the character after the slashes) against 20H, a space.
4F32
INC HL 23
Increment Register Pair HL to the next character. INC of a register pair does not change the flags.
4F33
If the Z FLAG is set (a space), LOOP BACK to 4F2BH to pass over it.
4F35
DEC HL 2B
Decrement Register Pair HL back to the first character that is not a space.
4F36
LD DE,51AAH 11 AA 51
Point Register Pair DE to 51AAH, the word buffer.
4F39
LD B,06H 06 06
Load Register B with 06H, the most characters of the word.
4F3B
GOSUB to 50FFH to copy the word at Register Pair HL (letters and digits, made upper case) to the word buffer at Register Pair DE, ended by 03H: the NZ FLAG for an empty word; Register Pair HL past the character that ended it, or on it when it is 03H, 0DH or an opening parenthesis.
4F3E
If the NZ FLAG is set (no letter or digit), JUMP to 4F4DH: the line is only logged.
4F40
LD DE,51AAH 11 AA 51
Point Register Pair DE to 51AAH, the word buffer, for the search.
4F43
LD BC,50B6H 01 B6 50
Point Register Pair BC to 50B6H, the table of directives.
4F46
GOSUB to 5143H to search the table at Register Pair BC for the word at Register Pair DE: the Z FLAG and Register Pair DE = the routine's address when found, the NZ FLAG when not.
4F49
If the NZ FLAG is set (not a directive), JUMP to 4F4DH: the line is only logged.
4F4B
PUSH DE D5
Save Register Pair DE (the address of the directive's routine) to the stack.
4F4C
RET C9
RETURN to the address just saved: JUMP to the directive's routine with Register Pair HL past the word.
4F4DH - The Next Line
Every directive and every dropped line ends here: the three words saved at 4F03H-4F08H are taken off the stack and the next line is begun at 4EE0H, still with Register B = Register C, so the line input gets the first character of the next line that is not a directive.
4F4D
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line.
4F4E
POP DE D1
Restore Register Pair DE from the stack: 4358H, the control block of the file.
4F4F
POP BC C1
Restore Register Pair BC from the stack: the line input's counts, Register B = Register C.
4F50
JUMP to 4EE0H to begin the next line of the file for the line input.
4F52H - Invalid JCL
A //WAIT time without its colons, or a closing parenthesis of //ALERT with no opening one before it, ends the chaining here.
4F52
LD HL,51C5H 21 C5 51
Point Register Pair HL to 51C5H, the text INVALID JCL, CHAINING ABORTED! and 0DH.
4F55
JUMP to 4E94H to show it on a new line, log it, end the chaining and go to VTOS READY.
4F58H - //STOP
Ends the chaining with no message and gives the line input that is waiting a key from the keyboard: the rest of the line, and the commands after it, are typed by the user.
4F58
GOSUB to 4EA2H to end the chaining: the keyboard driver and the exits put back. Interrupts stay disabled until other code enables them (the disk driver's EI at 46DAH, or VTOS READY at SYS1/SYS 4E3BH).
4F5B
POP HL E1
Restore Register Pair HL from the stack: 4318H.
4F5C
POP DE D1
Restore Register Pair DE from the stack: 4358H.
4F5D
POP BC C1
Restore Register Pair BC from the stack: the line input's counts.
4F5E
LD DE,4015H 11 15 40
Point Register Pair DE to 4015H, the KI device control block, whose driver 4EA2H has just put back.
4F61
JUMP to the ROM's 0013H to read a key through the device control block at Register Pair DE: the keyboard. It returns through the request handler's 4C4BH to the line input.
4F64H - //DELAY n
Waits n times 96 ms, about 0.1 second (n taken modulo 256; 0, no number, or a second space before the number gives 256, about 24.6 seconds). No key ends the wait, although the manual says ENTER or BREAK stops it.
4F64
GOSUB to 5190H to read the decimal number at Register Pair HL into Register Pair BC.
4F67
LD B,C 41
Copy Register C (the number, low byte) into Register B, the count of waits.
4F68
GOSUB to 501EH to wait about 0.1 second (96 ms); Register B is kept.
4F6B
Decrement Register B and LOOP BACK to 4F68H until Register B is 00H.
4F6D
JUMP to 4F4DH to go on with the next line of the file.
4F6FH - //PAUSE
Shows the whole line, //PAUSE included, and waits while neither ENTER nor BREAK is held down.
4F6F
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line.
4F70
PUSH HL E5
Save Register Pair HL (4318H) to the stack again for 4F4DH.
4F71
GOSUB to 4467H to display the line at Register Pair HL up to and including its 0DH.
4F74
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A: bit 0 ENTER, bit 2 BREAK.
4F77
AND 05H E6 05
Mask Register A to bits 0 and 2: the Z FLAG is set while neither key is held.
4F79
If the Z FLAG is set (no key), LOOP BACK to 4F74H.
4F7B
JUMP to 4F4DH to go on with the next line of the file: ENTER or BREAK was pressed.
4F7DH - //KEYIN
Shows the whole line, //KEYIN included, waits for a key from the keyboard and shows it; the key is stored in 4FBDH, and the lines of the file are read and passed over up to a line of two slashes and that key (the block of the answer) or a line of three slashes. The key is read with the ROM's 0049H, which 4EC8H sends to the keyboard.
4F7D
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line.
4F7E
PUSH HL E5
Save Register Pair HL (4318H) to the stack again.
4F7F
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
4F80
INC HL 23
Increment Register Pair HL to the next character. INC of a register pair does not change the flags.
4F81
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4F83
If the Z FLAG is set (the end of the line), JUMP to 4F8AH; the 0DH is not shown.
4F85
GOSUB to the ROM's 0033H to send the character in Register A to the display.
4F88
LOOP BACK to 4F7FH for the next character of the line at Register Pair HL.
4F8A
GOSUB to the ROM's 0049H to wait for a key: the KI request reaches 4EC8H, which finds no line input on the stack and passes it to the keyboard driver. Register A = the key. This request runs inside the request of 4EC8H, and the request handler's second save of the BREAK vector byte (4C3DH) keeps C9H, so the outer request ends with 4315H = C9H.
4F8D
GOSUB to the ROM's 0033H to show the key in Register A.
4F90
LD (4FBDH),A 32 BD 4F
Store Register A (the key) to 4FBDH, the operand of CP 00H at 4FBCH: the block to run.
4F93
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to end the line on the display.
4F95
GOSUB to the ROM's 0033H to end the displayed line.
4F98
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line buffer. 4FB1H, 4FB5H and 4FBEH also come here to read the next line of a search.
4F99
PUSH HL E5
Save Register Pair HL (4318H) to the stack again.
4F9A
LD DE,4358H 11 58 43
Point Register Pair DE to 4358H, the control block of the file of commands.
4F9D
GOSUB to 444BH to compare the position of the file at Register Pair DE with its end: the NZ FLAG at or past it.
4FA0
If the NZ FLAG is set (the end of the file came before the block), JUMP to 4E91H to show CHAINING COMPLETED and end the chaining.
4FA3
GOSUB to the ROM's 0013H to read the next byte of the file at Register Pair DE into Register A.
4FA6
LD (HL),A 77
Store Register A (the byte) at Register Pair HL in the line buffer.
4FA7
INC HL 23
Increment Register Pair HL to the next place in the buffer.
4FA8
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
4FAA
If the NZ FLAG is set (not yet the end), LOOP BACK to 4FA3H. As at 4F0DH, nothing limits the length of the line.
4FAC
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line just read.
4FAD
PUSH HL E5
Save Register Pair HL (4318H) to the stack again.
4FAE
LD A,(HL) 7E
Fetch the first character of the line from Register Pair HL into Register A.
4FAF
CP 2FH FE 2F
Compare Register A (the first character of the line) against 2FH, a slash.
4FB1
If the NZ FLAG is set (not a slash), LOOP BACK to 4F98H to pass over the line.
4FB3
INC HL 23
Increment Register Pair HL to the second character.
4FB4
CP (HL) BE
Compare Register A (2FH) against the second character at Register Pair HL.
4FB5
If the NZ FLAG is set (not two slashes), LOOP BACK to 4F98H to pass over the line.
4FB7
INC HL 23
Increment Register Pair HL to the third character.
4FB8
SUB (HL) 96
SUBtract the third character at Register Pair HL from Register A (2FH): the Z FLAG is set for a third slash.
4FB9
If the Z FLAG is set (three slashes, the end of the blocks), JUMP to 4FC0H with Register A = 00H. A line of two slashes alone does not end the search: its third character 0DH is compared with the key below.
4FBB
LD A,(HL) 7E
Fetch the third character from Register Pair HL into Register A.
4FBC
CP 00H FE 00
Self-Modifying Code
Compare Register A against the block waited for: the operand 4FBDH, 00H in the file, the key of //KEYIN (4F90H) or the value 4FC0H stores. From 4F23H Register A is 39H less the digit of a label met in the file, which equals 00H only for the digit 9.
4FBE
If the NZ FLAG is set (another block), LOOP BACK to 4F98H to pass over the lines up to the block wanted or the end of the blocks.
4FC0H - A Label Line Taken
Register A = 00H (three slashes), the key (a match in the search of //KEYIN) or 39H less the digit of a label that matched 4FBDH at 4F23H. It is stored in 4FBDH, the line is written to the job log and the lines after it are executed.
4FC0
LD (4FBDH),A 32 BD 4F
Store Register A to 4FBDH, the operand of CP 00H at 4FBCH: 00H after three slashes (no block waited for), the key itself after a match in the search of //KEYIN (4FBBH), or 39H less the digit of a label matched at 4F23H, which leaves 4FBDH as it was.
4FC3
POP HL E1
Restore Register Pair HL from the stack: 4318H, the start of the line.
4FC4
PUSH HL E5
Save Register Pair HL (4318H) to the stack again.
4FC5
GOSUB to 447EH to write the label line at Register Pair HL to the job log.
4FC8
JUMP to 4F4DH to go on with the next line of the file: the lines of the block run.
4FCBH - //ALERT
//ALERT n1,n2,... or //ALERT (n1,n2,...): each number is a count of units of about 0.1 second, sound and silence by turns (the first number sound, the next silence, and so on; the turn is kept in 4FF7H and goes on from one //ALERT line to the next when no command line runs between them, since each command loads SYS1/SYS over SYS7/SYS). Spaces and commas are passed over; an opening parenthesis is remembered at 4FE8H and the closing one goes back to it, so the list in parentheses repeats until ENTER or BREAK is held down; 0DH ends the line. ENTER or BREAK ends the directive at once. The sound is made by switching the cassette select latch 37E4H on and off, a square wave of about 59 Hz.
4FCB
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
4FCC
INC HL 23
Increment Register Pair HL past it. INC of a register pair does not change the flags.
4FCD
CP 20H FE 20
Compare Register A (the character of the list) against 20H, a space.
4FCF
If the Z FLAG is set (a space), LOOP BACK to 4FCBH.
4FD1
CP 2CH FE 2C
Compare Register A (the character of the list) against 2CH, a comma.
4FD3
If the Z FLAG is set (a comma), LOOP BACK to 4FCBH.
4FD5
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4FD7
If the Z FLAG is set (the end of the line), JUMP to 4F4DH to go on with the next line.
4FDA
CP 29H FE 29
Compare Register A against 29H, a closing parenthesis.
4FDC
If the Z FLAG is set (a closing parenthesis), JUMP to 4FE7H to go back to the opening one.
4FDE
CP 28H FE 28
Compare Register A against 28H, an opening parenthesis.
4FE0
If the NZ FLAG is set (anything else: a number), JUMP to 4FF1H.
4FE2
LD (4FE8H),HL 22 E8 4F
Store Register Pair HL (the address after the opening parenthesis) to 4FE8H-4FE9H, the operand of LD HL,0000H at 4FE7H.
4FE5
LOOP BACK to 4FCBH to read the list after the opening parenthesis.
4FE7
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the address after the opening parenthesis, the operand 4FE8H-4FE9H: 0000H in the file, stored at 4FE2H. It is set back to 0000H only when SYS7/SYS is loaded again (after each command line): a closing parenthesis with no opening one on its line goes back to the place of an earlier //ALERT line with no command between them.
4FEA
LD A,H 7C
Copy Register H (the high byte of the address) into Register A.
4FEB
OR L B5
OR Register L (the low byte) into Register A: the Z FLAG is set when the address is 0000H.
4FEC
If the NZ FLAG is set (an opening parenthesis was met), LOOP BACK to 4FCBH to run the list from the opening parenthesis again.
4FEE
JUMP to 4F52H to show INVALID JCL, CHAINING ABORTED! (a closing parenthesis with no opening one).
4FF1
DEC HL 2B
Decrement Register Pair HL back to the character that is not a space, comma or parenthesis.
4FF2
GOSUB to 5190H to read the decimal number at Register Pair HL into Register Pair BC; Register Pair HL ends on the first character that is not a digit. A character that is not a digit gives 0 and is met again at 4FCBH, so the alert then goes on until ENTER or BREAK.
4FF5
LD B,C 41
Copy Register C (the number, low byte) into Register B, the count of units: 0 counts as 256.
4FF6
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the turn of the last number, the operand 4FF7H: 00H in the file, FFH after a number of sound, 00H after one of silence.
4FF8
XOR FFH EE FF
Exclusive OR Register A with FFH: the turn changes, FFH for sound, 00H for silence.
4FFA
LD (4FF7H),A 32 F7 4F
Store Register A (the new turn) to 4FF7H, the operand of LD A,00H at 4FF6H.
4FFD
LD C,A 4F
Copy Register A (the turn: FFH sound, 00H silence) into Register C.
4FFE
BIT 0,C CB 41
Test bit 0 of Register C: the NZ FLAG is set for a unit of sound.
5000
If the NZ FLAG is set (sound), GOSUB to 5014H for six cycles of the latch 37E4H, about 0.1 second.
5003
BIT 0,C CB 41
Test bit 0 of Register C again: the Z FLAG is set for a unit of silence.
5005
If the Z FLAG is set (silence), GOSUB to 501EH to wait about 0.1 second.
5008
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A: bit 0 ENTER, bit 2 BREAK.
500B
AND 05H E6 05
Mask Register A to bits 0 and 2: the NZ FLAG is set when ENTER or BREAK is held down.
500D
If the NZ FLAG is set (ENTER or BREAK), JUMP to 4F4DH: the alert ends and the next line is read.
5010
Decrement Register B (the units left) and LOOP BACK to 4FFEH until Register B is 00H.
5012
LOOP BACK to 4FCBH for the next number of the list.
5014H - One Unit of Sound
Six cycles of the cassette select latch (502FH), about 0.1 second.
5014
PUSH BC C5
Save Register Pair BC (Register B the units left, Register C the turn) to the stack.
5015
LD B,06H 06 06
Load Register B with 06H, the count of cycles.
5017
GOSUB to 502FH for one cycle: 01H then 00H to the latch 37E4H, each followed by a wait of about 8.4 ms.
501A
Decrement Register B and LOOP BACK to 5017H until the six cycles are done.
501C
POP BC C1
Restore Register Pair BC (the units left and the turn) from the stack.
501D
RET C9
RETURN to the caller with Register Pair BC as it was.
501EH - Wait About 0.1 Second
The ROM's delay 0060H with Register Pair BC = 199BH (6555 passes of 26 clock cycles, about 96 ms at the Model I's 1.77 MHz), made twice when 430FH bit 3 says the clock runs fast (SYSTEM (FAST)). //DELAY, //FLASH and the silence of //ALERT use it.
501E
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
5021
BIT 3,A CB 5F
Test bit 3 of Register A: set when the clock runs fast.
5023
If the NZ FLAG is set (fast clock), GOSUB to 5026H for a first wait; the code then runs on into 5026H for the second.
5026
PUSH BC C5
Save Register Pair BC (the caller's counts) to the stack.
5027
LD BC,199BH 01 9B 19
Load Register Pair BC with 199BH, the count of the ROM's delay loop: 6555.
502A
GOSUB to the ROM's 0060H, which counts Register Pair BC down to 0000H: about 96 ms.
502D
POP BC C1
Restore Register Pair BC (the caller's counts) from the stack.
502E
RET C9
RETURN to the caller with Register Pair BC as it was, after the wait.
502FH - One Cycle of the Latch
Writes 01H and then 00H to 37E4H, the cassette select latch of the expansion interface (0 cassette 1, 1 cassette 2), each followed by a wait of 0240H passes of 26 clock cycles (about 8.4 ms), made twice with the fast clock.
502F
LD A,01H 3E 01
Load Register A with 01H, the value that selects cassette 2.
5031
GOSUB to 5036H to write Register A to the latch and wait.
5034
LD A,00H 3E 00
Load Register A with 00H, the value that selects cassette 1; the code runs on into 5036H.
5036
LD (37E4H),A 32 E4 37
Store Register A to 37E4H, the cassette select latch.
5039
LD A,(430FH) 3A 0F 43
Fetch the system flags from 430FH into Register A.
503C
BIT 3,A CB 5F
Test bit 3 of Register A: set when the clock runs fast.
503E
If the NZ FLAG is set (fast clock), GOSUB to 5041H for a first wait; the code then runs on into 5041H for the second.
5041
LD DE,0240H 11 40 02
Load Register Pair DE with 0240H, the count of the wait: 576.
5044
DEC DE 1B
Decrement Register Pair DE, the count of the wait loop (26 clock cycles a pass with the three instructions after it).
5045
LD A,D 7A
Copy Register D (the high byte of the count) into Register A.
5046
OR E B3
OR Register E (the low byte) into Register A: the Z FLAG is set when Register Pair DE is 0000H.
5047
If the NZ FLAG is set (not yet 0000H), LOOP BACK to 5044H.
5049
RET C9
RETURN to the caller: 5034H after the 01H half of a cycle, 501AH after the 00H half, or 5041H after the first of two waits.
504AH - //FLASH n
Flashes the screen n times (n modulo 256; 0, no number, or a second space before the number gives 256), each flash about 0.3 second; ENTER or BREAK held down ends it.
504A
GOSUB to 5190H to read the decimal number at Register Pair HL into Register Pair BC.
504D
LD B,C 41
Copy Register C (the number, low byte) into Register B, the count of flashes.
504E
GOSUB to 505EH for one flash of the screen, about 0.3 second.
5051
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 from 3840H into Register A: bit 0 ENTER, bit 2 BREAK.
5054
AND 05H E6 05
Mask Register A to bits 0 and 2: the NZ FLAG is set when ENTER or BREAK is held down.
5056
If the NZ FLAG is set (ENTER or BREAK), JUMP to 4F4DH to go on with the next line.
5059
Decrement Register B and LOOP BACK to 504EH until Register B is 00H.
505B
JUMP to 4F4DH to go on with the next line of the file: all flashes done.
505EH - One Flash
A wait, every byte of the screen changed (5064H), a wait, every byte changed back (5064H run a second time), a wait: three waits of about 0.1 second.
505E
GOSUB to 501EH to wait about 0.1 second before the screen changes.
5061
GOSUB to 5064H to change every byte of the screen and wait; its RET comes back to 5064H, which runs a second time and changes the bytes back.
5064
LD HL,3C00H 21 00 3C
Point Register Pair HL to 3C00H, the first byte of video memory. 5061H calls here, and the code runs on into here after that call.
5067
LD A,(HL) 7E
Fetch the byte of the screen at Register Pair HL into Register A.
5068
XOR DFH EE DF
Exclusive OR Register A with DFH: every bit but bit 5 is turned over, so a space 20H becomes FFH, a fully lit graphics character.
506A
LD (HL),A 77
Store Register A back to the screen at Register Pair HL.
506B
INC L 2C
Increment Register L to the next byte of the 256 byte page.
506C
If the NZ FLAG is set (Register L did not wrap to 00H), LOOP BACK to 5067H.
506E
INC H 24
Increment Register H to the next page of video memory.
506F
LD A,H 7C
Copy Register H (the page of video memory) into Register A for the compare.
5070
CP 40H FE 40
Compare Register A against 40H, the page after video memory 3C00H-3FFFH.
5072
If the NZ FLAG is set (pages 3CH-3FH not all done), LOOP BACK to 5067H.
5074
JUMP to 501EH to wait about 0.1 second; its RET returns to the caller of this pass.
5076H - //WAIT hh:mm:ss
Shows the whole line and waits until the clock (4043H hours, 4042H minutes, 4041H seconds) shows exactly the time given. The three numbers must be separated by colons, and the first must follow WAIT after exactly one character that is not a letter or digit (a space, a comma, a colon); otherwise INVALID JCL ends the chaining (with no such character the word is WAIT and the digits, which is no directive, and the line is only logged). No key ends the wait, and an hour above 23 or a minute or second above 59 waits for ever.
5076
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer: Register Pair HL = 4318H, the start of the line; the stack holds the address past the word WAIT.
5077
GOSUB to 4467H to display the line at Register Pair HL up to and including its 0DH.
507A
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer again: Register Pair HL = the address past WAIT, the stack holds 4318H.
507B
GOSUB to 5190H to read the hours at Register Pair HL into Register Pair BC; Register Pair HL ends on the character after the digits.
507E
LD A,(HL) 7E
Fetch the character after the hours from Register Pair HL into Register A.
507F
CP 3AH FE 3A
Compare Register A (the character after the hours) against 3AH, a colon.
5081
If the NZ FLAG is set (no colon), JUMP to 4F52H to show INVALID JCL, CHAINING ABORTED!.
5084
LD A,C 79
Copy Register C (the hours, the low byte of the number) into Register A.
5085
LD (50A2H),A 32 A2 50
Store Register A (the hours) to 50A2H, the operand of CP 00H at 50A1H.
5088
INC HL 23
Increment Register Pair HL past the colon, to the minutes.
5089
GOSUB to 5190H to read the minutes at Register Pair HL into Register Pair BC.
508C
LD A,(HL) 7E
Fetch the character after the minutes from Register Pair HL into Register A.
508D
CP 3AH FE 3A
Compare Register A (the character after the minutes) against 3AH, a colon.
508F
If the NZ FLAG is set (no colon), JUMP to 4F52H to show INVALID JCL, CHAINING ABORTED!.
5092
LD A,C 79
Copy Register C (the minutes) into Register A.
5093
LD (50A9H),A 32 A9 50
Store Register A (the minutes) to 50A9H, the operand of CP 00H at 50A8H.
5096
INC HL 23
Increment Register Pair HL past the colon, to the seconds.
5097
GOSUB to 5190H to read the seconds at Register Pair HL into Register Pair BC; whatever follows them is not tested.
509A
LD A,C 79
Copy Register C (the seconds) into Register A.
509B
LD (50B0H),A 32 B0 50
Store Register A (the seconds) to 50B0H, the operand of CP 00H at 50AFH.
509E
LD A,(4043H) 3A 43 40
Fetch the hours of the clock from 4043H into Register A.
50A1
CP 00H FE 00
Self-Modifying Code
Compare Register A against the hours given, the operand 50A2H (00H in the file, stored at 5085H).
50A3
If the NZ FLAG is set (another hour), LOOP BACK to 509EH.
50A5
LD A,(4042H) 3A 42 40
Fetch the minutes of the clock from 4042H into Register A.
50A8
CP 00H FE 00
Self-Modifying Code
Compare Register A against the minutes given, the operand 50A9H (00H in the file, stored at 5093H).
50AA
If the NZ FLAG is set (another minute), LOOP BACK to 509EH.
50AC
LD A,(4041H) 3A 41 40
Fetch the seconds of the clock from 4041H into Register A.
50AF
CP 00H FE 00
Self-Modifying Code
Compare Register A against the seconds given, the operand 50B0H (00H in the file, stored at 509BH).
50B1
If the NZ FLAG is set (another second), LOOP BACK to 509EH.
50B3
JUMP to 4F4DH: the time has come; go on with the next line.
50B6H - The Table of Directives
Nine entries of 8 bytes, a name of 6 characters padded with spaces and the address of its routine, in alphabetical order, ended by 00H; searched by 5143H for the word after two slashes.
50B6-50BD
DEFM "ABORT " / DEFW 4E8CH 41 42 4F 52 54 20 8C 4E
Entry 1: //ABORT, routine 4E8CH: CHAINING ABORTED!, the end of the chaining.
50BE-50C5
DEFM "ALERT " / DEFW 4FCBH 41 4C 45 52 54 20 CB 4F
Entry 2: //ALERT, routine 4FCBH: units of sound and silence.
50C6-50CD
DEFM "DELAY " / DEFW 4F64H 44 45 4C 41 59 20 64 4F
Entry 3: //DELAY, routine 4F64H: a wait of n tenths of a second.
50CE-50D5
DEFM "EXIT " / DEFW 4E91H 45 58 49 54 20 20 91 4E
Entry 4: //EXIT, routine 4E91H: CHAINING COMPLETED, the end of the chaining.
50D6-50DD
DEFM "FLASH " / DEFW 504AH 46 4C 41 53 48 20 4A 50
Entry 5: //FLASH, routine 504AH: n flashes of the screen.
50DE-50E5
DEFM "KEYIN " / DEFW 4F7DH 4B 45 59 49 4E 20 7D 4F
Entry 6: //KEYIN, routine 4F7DH: a key from the keyboard chooses the block to run.
50E6-50ED
DEFM "PAUSE " / DEFW 4F6FH 50 41 55 53 45 20 6F 4F
Entry 7: //PAUSE, routine 4F6FH: the line shown, a wait for ENTER or BREAK.
50EE-50F5
DEFM "STOP " / DEFW 4F58H 53 54 4F 50 20 20 58 4F
Entry 8: //STOP, routine 4F58H: the end of the chaining, the keyboard takes over.
50F6-50FD
DEFM "WAIT " / DEFW 5076H 57 41 49 54 20 20 76 50
Entry 9: //WAIT, routine 5076H: a wait for a time of day.
50FE
DEFB 00H 00
The end of the table: 5150H stops when the first byte of an entry is 00H.
50FFH - Copy a Word
Register Pair HL = the text, Register Pair DE = the buffer, Register B = the most characters (6 from 4F39H). Letters and digits are copied, small letters made capital; letters and digits past the most are passed over. 03H, 0DH and an opening parenthesis end the word and are not passed over; any other character ends it and is passed over. 03H is stored after the word. Returns Register A = the character that ended the word and the NZ FLAG when no character was stored.
50FF
LD A,B 78
Copy Register B (the most characters) into Register A.
5100
LD (513FH),A 32 3F 51
Store Register A to 513FH, the operand of LD A,00H at 513EH: not 00H until a character is stored, so an empty word returns NZ.
5103
INC B 04
Increment Register B, since 512CH decrements it before each store.
5104
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
5105
CP 03H FE 03
Compare Register A against 03H, an end of text.
5107
If the Z FLAG is set (03H), JUMP to 513AH to end the word without passing over the character.
5109
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
510B
If the Z FLAG is set (0DH), JUMP to 513AH to end the word without passing over the character.
510D
CP 28H FE 28
Compare Register A against 28H, an opening parenthesis.
510F
If the Z FLAG is set (an opening parenthesis), JUMP to 513AH to end the word without passing over the character.
5111
INC HL 23
Increment Register Pair HL past the character. INC of a register pair does not change the flags.
5112
CP 30H FE 30
Compare Register A (the character) against 30H, the digit 0.
5114
If the C FLAG is set (below 0: a space, a comma, a period), JUMP to 513AH to end the word; the character is passed over.
5116
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9.
5118
If the C FLAG is set (a digit 0-9), JUMP to 512CH to store it.
511A
CP 41H FE 41
Compare Register A against 41H, the letter A.
511C
If the C FLAG is set (3AH-40H), JUMP to 513AH to end the word; the character is passed over.
511E
CP 5BH FE 5B
Compare Register A against 5BH, the character after Z.
5120
If the C FLAG is set (a capital letter A-Z), JUMP to 512CH to store it.
5122
CP 61H FE 61
Compare Register A against 61H, the small letter a.
5124
If the C FLAG is set (5BH-60H), JUMP to 513AH to end the word; the character is passed over.
5126
CP 7BH FE 7B
Compare Register A against 7BH, the character after z.
5128
If the NC FLAG is set (7BH and up), JUMP to 513AH to end the word; the character is passed over.
512A
SUB 20H D6 20
SUBtract 20H from Register A: the small letter becomes a capital one.
512C
DEC B 05
Decrement Register B, the room left in the word.
512D
If the Z FLAG is set (the word is full), JUMP to 5137H to pass over the character.
512F
LD (DE),A 12
Store Register A (the character) at Register Pair DE in the buffer.
5130
XOR A AF
Set Register A to 00H, the mark of a word that is not empty.
5131
LD (513FH),A 32 3F 51
Store Register A (00H) to 513FH, the operand of LD A,00H at 513EH: the word is not empty.
5134
INC DE 13
Increment Register Pair DE to the next place in the buffer.
5135
LOOP BACK to 5104H for the next character at Register Pair HL.
5137
INC B 04
Increment Register B back to 01H, so that every further letter or digit also finds the word full.
5138
LOOP BACK to 5104H for the next character at Register Pair HL.
513A
LD C,A 4F
Copy Register A (the character that ended the word) into Register C.
513B
LD A,03H 3E 03
Load Register A with 03H, the end of the word.
513D
LD (DE),A 12
Store Register A (03H) at Register Pair DE, after the last character copied.
513E
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the empty mark, the operand 513FH: the most characters (06H) when nothing was stored, 00H when a character was.
5140
OR A B7
OR Register A with itself: the NZ FLAG is set for an empty word.
5141
LD A,C 79
Copy Register C (the character that ended the word) into Register A. LD does not change the flags.
5142
RET C9
RETURN to the caller with the Z FLAG for a word, the NZ FLAG for an empty one.
5143H - Search the Table of Directives
Register Pair DE = the word (ended by 03H), Register Pair BC = the table. An entry matches when its first character equals the word's and its next 5 characters are equal too, or a space stands where the word has ended (03H or 0DH, or a character other than a letter or digit). Found: Register Pair DE = the entry's address word, Register A = 00H and the Z FLAG. Not found: Register A = 01H and the NZ FLAG. Register Pair HL is kept.
5143
PUSH HL E5
Save Register Pair HL (the caller's text pointer) to the stack.
5144
LD H,B 60
Copy Register B (the high byte of the table) into Register H.
5145
LD L,C 69
Copy Register C (the low byte of the table) into Register L: Register Pair HL = the first entry.
5146
LD A,(DE) 1A
Fetch the first character of the word from Register Pair DE into Register A.
5147
CP (HL) BE
Compare Register A against the first character of the entry at Register Pair HL.
5148
If the Z FLAG is set (the first characters are equal), JUMP to 5157H to compare the rest.
514A
PUSH BC C5
Save Register Pair BC to the stack (the table address before the first partial match; after 5157H Register B is a count, and nothing uses the pair again).
514B
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the length of an entry.
514E
ADD HL,BC 09
Add Register Pair BC (8) to Register Pair HL: the next entry.
514F
POP BC C1
Restore Register Pair BC from the stack, as saved at 514AH.
5150
LD A,(HL) 7E
Fetch the first byte of the next entry from Register Pair HL into Register A.
5151
OR A B7
OR Register A with itself: the Z FLAG is set at the end byte 00H.
5152
If the NZ FLAG is set (another entry), LOOP BACK to 5146H.
5154
POP HL E1
Restore Register Pair HL (the caller's text pointer) from the stack.
5155
INC A 3C
Increment Register A (00H) to 01H: the NZ FLAG, not found.
5156
RET C9
RETURN to the caller with Register A = 01H and the NZ FLAG: no entry matches.
5157
LD B,05H 06 05
Load Register B with 05H, the characters left to compare after the first.
5159
PUSH HL E5
Save Register Pair HL (the address of the entry) to the stack.
515A
PUSH DE D5
Save Register Pair DE (the address of the word) to the stack.
515B
INC DE 13
Increment Register Pair DE to the next character of the word.
515C
INC HL 23
Increment Register Pair HL to the next character of the entry.
515D
LD A,(DE) 1A
Fetch the character of the word from Register Pair DE into Register A.
515E
CP 03H FE 03
Compare Register A against 03H, the end of the word.
5160
If the Z FLAG is set (the word has ended), JUMP to 5187H: the entry must have a space here.
5162
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
5164
If the Z FLAG is set (the word has ended), JUMP to 5187H: the entry must have a space here.
5166
CP (HL) BE
Compare Register A against the character of the entry at Register Pair HL.
5167
If the NZ FLAG is set (they differ), JUMP to 5177H.
5169
Decrement Register B and LOOP BACK to 515BH until the 5 characters are compared.
516B
POP DE D1
Restore Register Pair DE from the stack: the address of the word.
516C
POP BC C1
Restore Register Pair BC from the stack: the address of the entry that matched.
516D
LD HL,0006H 21 06 00
Load Register Pair HL with 0006H, the offset of the address word in the entry.
5170
ADD HL,BC 09
Add Register Pair BC (the entry) to Register Pair HL: Register Pair HL = the entry's address word.
5171
LD E,(HL) 5E
Fetch the low byte of the address word from Register Pair HL into Register E.
5172
INC HL 23
Increment Register Pair HL to the high byte of the address word.
5173
LD D,(HL) 56
Fetch the high byte from Register Pair HL into Register D: Register Pair DE = the routine's address.
5174
POP HL E1
Restore Register Pair HL (the caller's text pointer) from the stack.
5175
XOR A AF
Set Register A to 00H and the Z FLAG (XOR A): the word was found.
5176
RET C9
RETURN to the caller with Register Pair DE = the routine and the Z FLAG.
5177
CP 30H FE 30
Compare Register A (the character of the word) against 30H, the digit 0. The word comes from 50FFH, so it holds only letters and digits here and 5177H-5185H always go on to 518CH.
5179
If the C FLAG is set (below 0), JUMP to 5187H: the word ends here.
517B
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9.
517D
If the C FLAG is set (a digit), JUMP to 518CH: a real difference.
517F
CP 41H FE 41
Compare Register A against 41H, the letter A.
5181
If the C FLAG is set (3AH-40H), JUMP to 5187H: the word ends here.
5183
CP 5BH FE 5B
Compare Register A against 5BH, the character after Z.
5185
If the C FLAG is set (a letter), JUMP to 518CH: a real difference.
5187
LD A,(HL) 7E
Fetch the character of the entry at Register Pair HL into Register A.
5188
CP 20H FE 20
Compare Register A against 20H, a space: the name of the entry ends where the word ends.
518A
If the Z FLAG is set (a space), JUMP to 516BH: the entry matches.
518C
POP DE D1
Restore Register Pair DE from the stack: the address of the word.
518D
POP HL E1
Restore Register Pair HL from the stack: the address of the entry.
518E
LOOP BACK to 514AH to try the next entry of the table at Register Pair HL.
5190H - Read a Decimal Number
Register Pair HL = the text. Digits are read into Register Pair BC (modulo 65536) up to the first character that is not a digit, where Register Pair HL stops; with no digit Register Pair BC = 0000H. Returns the CARRY FLAG for a character below 0, the NC FLAG for one above 9.
5190
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the number so far.
5193
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A.
5194
SUB 30H D6 30
SUBtract 30H from Register A: the value of a digit.
5196
RET C D8
If the C FLAG is set (below 0), RETURN with Register Pair BC = the number.
5197
CP 0AH FE 0A
Compare Register A (the character less 30H) against 0AH: the C FLAG for a digit.
5199
RET NC D0
If the NC FLAG is set (above 9), RETURN with Register Pair BC = the number.
519A
PUSH BC C5
Save Register Pair BC (the number so far) to the stack.
519B
EX (SP),HL E3
Exchange Register Pair HL with the word at the Stack Pointer: Register Pair HL = the number so far, the stack holds the text pointer.
519C
ADD HL,HL 29
Add Register Pair HL to itself: the number times 2.
519D
ADD HL,HL 29
Add Register Pair HL to itself: the number times 4.
519E
ADD HL,BC 09
Add Register Pair BC (the number) to Register Pair HL: the number times 5.
519F
ADD HL,HL 29
Add Register Pair HL to itself: the number times 10.
51A0
LD B,00H 06 00
Load Register B with 00H, the high byte of the digit's value.
51A2
LD C,A 4F
Copy Register A (the digit) into Register C: Register Pair BC = the digit.
51A3
ADD HL,BC 09
Add Register Pair BC (the digit) to Register Pair HL: the new number.
51A4
LD B,H 44
Copy Register H (the high byte) into Register B.
51A5
LD C,L 4D
Copy Register L (the low byte) into Register C: Register Pair BC = the new number.
51A6
POP HL E1
Restore Register Pair HL (the text pointer) from the stack.
51A7
INC HL 23
Increment Register Pair HL to the next character.
51A8
LOOP BACK to 5193H for the next character at Register Pair HL.
51AAH - The Word Buffer
Not in the file: the load blocks leave 51AAH-51B1H out.
51AA-51B1
DEFS 8
Not in the file. The word after two slashes, copied by 50FFH (at most 6 letters or digits and 03H) at 4F3BH and compared with the table by 5143H at 4F46H.
51B2H - Messages
The four texts, each shown by 447BH on a new line and written to the job log. 51D2H is the second part of the text at 51C5H.
51B2-51C4
DEFM "CHAINING COMPLETED" / DEFB 0DH 43 48 41 49 4E 49 4E 47 20 43 4F 4D 50 4C 45 54 45 44 0D
The end of the file, a byte 00H at the start of a line, or //EXIT (4E91H).
51C5-51D1
DEFM "INVALID JCL, " 49 4E 56 41 4C 49 44 20 4A 43 4C 2C 20
The start of the message of a bad //WAIT or //ALERT line (4F52H); it goes on at 51D2H.
51D2-51E3
DEFM "CHAINING ABORTED!" / DEFB 0DH 43 48 41 49 4E 49 4E 47 20 41 42 4F 52 54 45 44 21 0D
The abort exit 4030H while chaining and //ABORT (4E8CH); also the end of the text at 51C5H.
51E4-51FA
DEFM "MANUAL CHAINING ABORT!" / DEFB 0DH 4D 41 4E 55 41 4C 20 43 48 41 49 4E 49 4E 47 20 41 42 4F 52 54 21 0D
BREAK held down when a command has ended (4E74H).