4BC8H - The Overlay Length (Data)
Every system file from SYS1/SYS to SYS12/SYS carries a load block for the two bytes 4BC8H-4BC9H in the resident area of SYS0/SYS. They hold the length of the file's part in the overlay area: for SYS11/SYS 03FCH, the 1020 bytes 4E00H-51FBH (5181H-5186H among them, which the file does not load). In the file this block is the last load block, after the blocks of 4E00H-5180H and 5187H-51FBH and before the transfer address record (4E00H). The two bytes are data, not instructions.
4BC8-4BC9
DEFW 03FCH FC 03
4BC8H-4BC9H: 03FCH (1020), the number of bytes from 4E00H that SYS11/SYS takes up (4E00H-51FBH). Loading SYS11/SYS puts it over the length the system file loaded before it left here.
4E00H - The Five Requests
The supervisor dispatcher loads SYS11/SYS into 4E00H and calls it with the request code in Register A; it drops the return address of the RST itself, so the stack above holds the chain of calls that issued the request. Bits 6-4 select the function. 9DH (10H): DO (SYS6/SYS) starts the job file it has compiled. ADH (20H) and BDH (30H): while a job runs, @EXIT (402DH) and @ABORT (4030H) issue these, so a command that ends comes back here. CDH (40H): @DOKEY (42B5H), the keyboard driver while a job runs, asks for a key. DDH (50H): @DOKEY while the INPUT directive hands the keyboard to the operator. Every entry first clears bit 2 of KFLAG$ (429FH), the ENTER key held, so that a directive waits for a new press.
4E00
PUSH HL E5
Save Register Pair HL to the stack while Register Pair HL points at KFLAG$.
4E01
LD HL,429FH 21 9F 42
Point Register Pair HL to 429FH, KFLAG$, the keyboard flags of the interrupt routine.
4E04
RES 2,(HL) CB 96
Clear bit 2 of KFLAG$ at Register Pair HL, set while ENTER is held: the directives that wait for ENTER see only a new press.
4E06
POP HL E1
Restore the caller's Register Pair HL from the stack; Register A still holds the request code.
4E07
AND 70H E6 70
Keep bits 6-4 of Register A, the request code (AND 70H): the function.
4E09
CP 20H FE 20
Compare Register A (the function) against 20H, request ADH: a command of the job ended through @EXIT.
4E0B
If the Z FLAG is set (ADH), JUMP to 4E60H to take the next line of the job.
4E0D
CP 40H FE 40
Compare Register A (the function) against 40H, request CDH: @DOKEY asks for a key.
4E0F
If the Z FLAG is set (CDH), JUMP to 4ECFH to answer from the job file.
4E12
CP 50H FE 50
Compare Register A (the function) against 50H, request DDH: @DOKEY during INPUT.
4E14
If the Z FLAG is set (DDH), JUMP to 50C8H to take the key from the keyboard.
4E17
CP 30H FE 30
Compare Register A (the function) against 30H, request BDH: a command of the job ended through @ABORT.
4E19
If the Z FLAG is set (BDH), JUMP to 4E8AH to end the job with Job aborted.
4E1B
CP 10H FE 10
Compare Register A (the function) against 10H, request 9DH: start a job.
4E1D
RET NZ C0
RETurn with the NZ FLAG for any other function: the request only loads SYS11/SYS.
4E1EH - Start the Job
Request 9DH from DO, with the compiled job file open in JFCB$ (4265H). Bit 5 of SFLAG$ (442BH) is set while a job runs. Unless a job already runs (a DO inside a job), the keyboard driver address (4016H-4017H) is kept in KIJCL$ (42BEH) and the six bytes that DO left at 406BH-4070H (LD A,ADH / RST 28H and LD A,BDH / RST 28H) are copied over @EXIT and @ABORT (402DH-4032H); DO has already saved the six bytes it found there at 4065H-406AH. The first line of the job is read with 4E5AH as the keyboard driver, which takes each byte straight from the job file, and run through @CMNDI; from then on the keyboard driver is @DOKEY (42B5H), so every key a command asks for comes to 4ECFH.
4E1E
DI F3
Disable interrupts while the keyboard driver and the vectors are changed.
4E1F
LD HL,429FH 21 9F 42
Point Register Pair HL to 429FH, KFLAG$, the keyboard flags of the interrupt routine.
4E22
RES 0,(HL) CB 86
Clear bit 0 of KFLAG$ at Register Pair HL, the BREAK key pressed: a BREAK from before the job does not end it.
4E24
LD HL,442BH 21 2B 44
Point Register Pair HL to 442BH, SFLAG$, the system flags.
4E27
BIT 5,(HL) CB 6E
Test bit 5 of SFLAG$ at Register Pair HL, set while a job runs: the NZ FLAG when this job starts inside another.
4E29
SET 5,(HL) CB EE
Set bit 5 of SFLAG$ at Register Pair HL: a job runs. SET does not change the flags.
4E2B
If the NZ FLAG is set (a job already ran), JUMP to 4E39H: the keyboard driver and the vectors are already the job's.
4E2D
LD HL,(4016H) 2A 16 40
Fetch the keyboard driver address from 4016H-4017H, KIDCB$ +01H-+02H, into Register Pair HL.
4E30
LD (42BEH),HL 22 BE 42
Store Register Pair HL (the keyboard driver) at 42BEH-42BFH, KIJCL$, to put back when the job ends and to pass keys on to.
4E33
LD HL,406BH 21 6B 40
Point Register Pair HL to 406BH, where DO put LD A,ADH / RST 28H and LD A,BDH / RST 28H.
4E36
GOSUB to 4EC6H to copy the six bytes at Register Pair HL over 402DH-4032H: @EXIT now issues request ADH and @ABORT request BDH.
4E39
LD SP,41E5H 31 E5 41
Load the Stack Pointer with 41E5H, the stack of the command level: what was on the stack is dropped.
4E3C
EI FB
Enable interrupts: the keyboard driver and the vectors are the job's now.
4E3D
LD DE,4265H 11 65 42
Point Register Pair DE to 4265H, JFCB$, the control block of the job file.
4E40
GOSUB to 4458H (@CKEOF) to test whether the job file is at its end: Register A = 00H with the Z FLAG before the end, else 1CH or an error number with the NZ FLAG.
4E43
If the NZ FLAG is set (the job file is empty, or an error), JUMP to 4409H (@ERROR) with the error number in Register A.
4E46
LD DE,4E5AH 11 5A 4E
Point Register Pair DE to 4E5AH, the routine that takes the next byte of the job file.
4E49
LD (4016H),DE ED 53 16 40
Store Register Pair DE (4E5AH) at 4016H-4017H: it is the keyboard driver while the first line is read.
4E4D
GOSUB to 4E82H to read the first line of the job into INBUF$ (4225H) through the keyboard driver, that is from the job file.
4E50
LD DE,42B5H 11 B5 42
Point Register Pair DE to 42B5H, @DOKEY (LD A,0CDH / RST 28H).
4E53
LD (4016H),DE ED 53 16 40
Store Register Pair DE (42B5H) at 4016H-4017H: from now on every key asked for issues request CDH.
4E57
JUMP to 4299H (@CMNDI) to run the line at Register Pair HL (INBUF$) as a command; when it ends, @EXIT issues request ADH (4E60H).
4E5A
LD DE,4265H 11 65 42
The keyboard driver for the first line: point Register Pair DE to 4265H, JFCB$, the job file.
4E5D
JUMP to the ROM at 0013H to get the next byte of the job file at Register Pair DE into Register A; its RET is the driver's.
4E60H - A Command of the Job Has Ended: the Next Line
Request ADH from @EXIT. The stack is set back to 41E5H. BREAK pressed (bit 0 of KFLAG$) ends the job with Job aborted, unless BREAK is disabled (bit 4 of SFLAG$). At the end of the job file the job ends with Job done; otherwise the next line is read into INBUF$ and run through @CMNDI. The line is read by the ROM's line input routine through @DOKEY, so its bytes come from 4ECFH, which also carries out the directive lines it meets on the way.
4E60
LD SP,41E5H 31 E5 41
Load the Stack Pointer with 41E5H, the stack of the command level: the ended command's stack is dropped.
4E63
EI FB
Enable interrupts while the next line of the job is taken.
4E64
LD HL,442BH 21 2B 44
Point Register Pair HL to 442BH, SFLAG$, the system flags.
4E67
BIT 4,(HL) CB 66
Test bit 4 of SFLAG$ at Register Pair HL, set when BREAK is disabled.
4E69
If the NZ FLAG is set (BREAK disabled), JUMP to 4E74H without looking at the BREAK key.
4E6B
LD A,(429FH) 3A 9F 42
Fetch KFLAG$, the keyboard flags, from 429FH into Register A.
4E6E
RRCA 0F
Rotate Register A right (RRCA): bit 0, the BREAK key pressed, goes into the CARRY FLAG.
4E6F
LD HL,51A0H 21 A0 51
Point Register Pair HL to 51A0H, the message Job aborted. LD does not change the flags.
4E72
If the CARRY FLAG is set (BREAK was pressed), JUMP to 4E8DH to end the job with Job aborted through @ABORT.
4E74
LD DE,4265H 11 65 42
Point Register Pair DE to 4265H, JFCB$, the control block of the job file.
4E77
GOSUB to 4458H (@CKEOF): the Z FLAG before the end of the job file.
4E7A
If the NZ FLAG is set (the end of the job file), JUMP to 4EA3H to end the job with Job done.
4E7C
GOSUB to 4E82H to read the next line of the job into INBUF$ (4225H) through @DOKEY.
4E7F
JUMP to 4299H (@CMNDI) to run the line at Register Pair HL (INBUF$) as a command.
4E82
LD HL,4225H 21 25 42
Point Register Pair HL to 4225H, INBUF$, the command line buffer.
4E85
LD B,3FH 06 3F
Load Register B with 3FH, the 63 characters a line may hold.
4E87
JUMP to the ROM at 0040H to read a line of up to Register B characters into the buffer at Register Pair HL through the keyboard driver; its RET goes back to the caller of 4E82H with Register Pair HL = the buffer.
4E8AH - End the Job
4E8AH (ABORT, request BDH, BREAK) ends the job with Job aborted and goes on to @ABORT; 4EA3H (EXIT, the end of the job file) with Job done and @EXIT. The message is shown and sent to the job log (@LOGOT), bit 5 of SFLAG$ is cleared, JFCB$ +00H is cleared (the job file is closed), the keyboard driver kept in KIJCL$ is put back and given a control call, and the six bytes of @EXIT and @ABORT saved at 4065H-406AH are put back. The RET then goes to the vector pushed first, with interrupts off. 4E92H is the test the waiting directives make: BREAK ends the job here; it returns the NZ FLAG while ENTER is held. 4EC6H is the copy of six bytes at Register Pair HL to 402DH that the start uses too.
4E8A
LD HL,51A0H 21 A0 51
Point Register Pair HL to 51A0H, the message Job aborted, and the end of the BREAK key, @ABORT and the ABORT directive.
4E8D
LD DE,4030H 11 30 40
Point Register Pair DE to 4030H, @ABORT, where the end goes after the job is undone.
4E90
JUMP to 4EA9H to undo the job and go on to @ABORT.
4E92
LD A,(442BH) 3A 2B 44
Fetch SFLAG$ from 442BH into Register A. The directives that wait call here on each turn.
4E95
BIT 4,A CB 67
Test bit 4 of Register A (SFLAG$), set when BREAK is disabled.
4E97
LD A,(429FH) 3A 9F 42
Fetch KFLAG$ from 429FH into Register A. LD does not change the flags.
4E9A
If the NZ FLAG is set (BREAK disabled), JUMP to 4EA0H to look at ENTER only.
4E9C
BIT 0,A CB 47
Test bit 0 of Register A (KFLAG$), set when BREAK was pressed.
4E9E
If the NZ FLAG is set (BREAK), JUMP to 4E8AH to end the job with Job aborted.
4EA0
BIT 2,A CB 57
Test bit 2 of Register A (KFLAG$), set while ENTER is held.
4EA2
RET C9
RETurn with the NZ FLAG while ENTER is held, the Z FLAG otherwise.
4EA3
LD HL,51ACH 21 AC 51
Point Register Pair HL to 51ACH, the message Job done: the end of the job file and the EXIT directive.
4EA6
LD DE,402DH 11 2D 40
Point Register Pair DE to 402DH, @EXIT, where the end goes after the job is undone.
4EA9
PUSH DE D5
Save Register Pair DE (@EXIT or @ABORT) to the stack: the RET at 4ECEH goes there.
4EAA
GOSUB to 428AH (@LOGOT) to display the message at Register Pair HL and send it to the job log.
4EAD
DI F3
Disable interrupts while the keyboard driver and the vectors are put back. STOP (4F65H) calls here.
4EAE
LD HL,442BH 21 2B 44
Point Register Pair HL to 442BH, SFLAG$, the system flags.
4EB1
RES 5,(HL) CB AE
Clear bit 5 of SFLAG$ at Register Pair HL: no job runs.
4EB3
XOR A AF
Set Register A to 00H (XOR A), the value for JFCB$ +00H and the control call.
4EB4
LD (4265H),A 32 65 42
Store Register A (00H) at 4265H, JFCB$ +00H: the job file's control block no longer describes an open file.
4EB7
LD HL,(42BEH) 2A BE 42
Fetch the keyboard driver kept at 42BEH-42BFH, KIJCL$, into Register Pair HL.
4EBA
LD (4016H),HL 22 16 40
Store Register Pair HL at 4016H-4017H, KIDCB$ +01H-+02H: the keyboard has its own driver again.
4EBD
LD DE,4015H 11 15 40
Point Register Pair DE to 4015H, KIDCB$, the keyboard's device control block.
4EC0
GOSUB to the ROM at 0023H to give the keyboard driver at Register Pair DE a control call, with Register A = 00H.
4EC3
LD HL,4065H 21 65 40
Point Register Pair HL to 4065H, where DO saved the six bytes of @EXIT and @ABORT.
4EC6
LD DE,402DH 11 2D 40
Point Register Pair DE to 402DH, @EXIT. 4E36H calls here with Register Pair HL = 406BH.
4EC9
LD BC,0006H 01 06 00
Load Register Pair BC with 0006H, the six bytes 402DH-4032H.
4ECC
LDIR ED B0
Copy (DE) = (HL) for Register Pair BC bytes, HL and DE counting up (LDIR): @EXIT and @ABORT get the six bytes at Register Pair HL.
4ECE
RET C9
RETurn: to 4E39H after the start, to 4F68H after STOP, else to @EXIT or @ABORT as pushed at 4EA9H.
4ECFH - Answer a Key Request from the Job File
Request CDH from @DOKEY. The stack holds the chain that asked for the key: the dispatcher's call to 4E00H, the four words the ROM's device routine pushes, the Register Pair BC that the ROM's input routine at 0013H saved, and the return address of the call that asked. When the word at the Stack Pointer +0EH is 05E3H, the request comes from the CALL 0049H at 05E0H in the ROM's line input routine, and the job answers it; Register Pair BC at +0AH is then that routine's count, Register C the length of the line allowed and Register B the room left, equal while no character of the line is taken. Any other request goes to the keyboard driver kept in KIJCL$ with the CARRY FLAG set (a byte is asked for). In the middle of a line the next byte of the job file is the key. At the start of a line the job file's sector is read again (@RREAD) and its first byte taken: 00H ends the job; a byte other than / is the key; a line that starts with / is read whole into INBUF$ (4225H) and carried out here (4F0AH), and the next line is taken in the same way.
4ECF
LD HL,000AH 21 0A 00
Load Register Pair HL with 000AH, the offset of the saved Register Pair BC from the Stack Pointer.
4ED2
ADD HL,SP 39
ADD the Stack Pointer to Register Pair HL: Register Pair HL = the Stack Pointer +0AH.
4ED3
LD C,(HL) 4E
Fetch the byte at Register Pair HL into Register C: the length of the line the ROM's line input allows.
4ED4
INC HL 23
INCrement Register Pair HL to the Stack Pointer +0BH.
4ED5
LD B,(HL) 46
Fetch the byte at Register Pair HL into Register B: the room left in the line.
4ED6
INC HL 23
INCrement Register Pair HL to the Stack Pointer +0CH, the return address of the ROM's CALL 002BH at 0049H.
4ED7
INC HL 23
INCrement Register Pair HL to the Stack Pointer +0DH.
4ED8
INC HL 23
INCrement Register Pair HL to the Stack Pointer +0EH, the return address of the call that asked for the key.
4ED9
LD E,(HL) 5E
Fetch the low byte of that return address at Register Pair HL into Register E.
4EDA
INC HL 23
INCrement Register Pair HL to the Stack Pointer +0FH.
4EDB
LD D,(HL) 56
Fetch the high byte of that return address at Register Pair HL into Register D: Register Pair DE = the caller's return address.
4EDC
LD HL,05E3H 21 E3 05
Load Register Pair HL with 05E3H, the return address of the CALL 0049H in the ROM's line input routine.
4EDF
SBC HL,DE ED 52
SUBtract Register Pair DE (the return address found) and the CARRY FLAG from Register Pair HL (05E3H); the ADD HL,SP leaves the CARRY FLAG clear unless the stack lies in the last ten bytes of memory: the Z FLAG when they are the same.
4EE1
If the Z FLAG is set (the ROM's line input asks), JUMP to 4EE8H to answer from the job file.
4EE3
LD HL,(42BEH) 2A BE 42
Fetch the keyboard driver kept at 42BEH-42BFH, KIJCL$, into Register Pair HL.
4EE6
SCF 37
Set the CARRY FLAG, which tells the driver that a byte is asked for.
4EE7
JP (HL) E9
JUMP to the keyboard driver at Register Pair HL: it answers the request from the keyboard.
4EE8
LD DE,4265H 11 65 42
Point Register Pair DE to 4265H, JFCB$, the job file. 4F5DH comes back here after a directive line.
4EEB
PUSH BC C5
Save Register Pair BC (Register C the length allowed, Register B the room left) to the stack.
4EEC
GOSUB to 4458H (@CKEOF): the Z FLAG before the end of the job file.
4EEF
POP BC C1
Restore Register Pair BC (Register C the length allowed, Register B the room left) from the stack. POP does not change the flags.
4EF0
If the NZ FLAG is set (the end of the job file), JUMP to 4EA3H to end the job with Job done.
4EF2
LD A,B 78
Copy Register B (the room left in the line) into Register A.
4EF3
CP C B9
Compare Register A against Register C (the length allowed): the Z FLAG when no character of the line has been taken.
4EF4
If the NZ FLAG is set (in the middle of a line), JUMP to the ROM at 0013H to get the next byte of the job file at Register Pair DE: that byte is the key.
4EF7
GOSUB to 445EH (@RREAD) to have the job file's current sector read again, since a command run in between may have used the memory: the Z FLAG on success.
4EFA
If the NZ FLAG is set (the sector could not be read), JUMP to 4409H (@ERROR) with the error number in Register A.
4EFD
GOSUB to the ROM at 0013H to get the first byte of the line from the job file at Register Pair DE into Register A.
4F00
OR A B7
Set the flags from Register A (OR A): the Z FLAG for 00H.
4F01
If the Z FLAG is set (a 00H byte, the end of the compiled job), JUMP to 4EA3H to end the job with Job done.
4F03
PUSH AF F5
Save Register Pair AF (Register A = the first byte) to the stack.
4F04
CP 2FH FE 2F
Compare Register A (the first byte) against 2FH, a slash.
4F06
If the Z FLAG is set (a line that starts with a slash), JUMP to 4F0AH to read the line here.
4F08
POP AF F1
Restore Register Pair AF (Register A = the first byte) from the stack.
4F09
RET C9
RETurn to the ROM with Register A = the first byte of the line: the key.
4F0A
POP AF F1
Remove the saved first byte from the stack into Register Pair AF: Register A = 2FH, the slash, stored first.
4F0B
PUSH BC C5
Save Register Pair BC (Register C the length allowed, Register B the room left) to the stack.
4F0C
PUSH DE D5
Save Register Pair DE (4265H, the job file) to the stack.
4F0D
LD B,3FH 06 3F
Load Register B with 3FH, the 63 bytes a line may hold.
4F0F
LD HL,4225H 21 25 42
Point Register Pair HL to 4225H, INBUF$, where the line is read.
4F12
PUSH HL E5
Save Register Pair HL (4225H, the start of the line) to the stack: the directives find it on top of the stack.
4F13
LD (HL),A 77
Store Register A (the byte) at Register Pair HL in INBUF$. 4F1CH loops back here.
4F14
INC HL 23
INCrement Register Pair HL to the next byte of INBUF$.
4F15
CP 0DH FE 0D
Compare Register A (the byte) against 0DH, the end of the line.
4F17
If the Z FLAG is set (0DH), JUMP to 4F20H: the line is read.
4F19
GOSUB to the ROM at 0013H to get the next byte of the job file at Register Pair DE into Register A.
4F1C
DECrement Register B and LOOP BACK to 4F13H to store it, while the line has room.
4F1E
JUMP to 4F5FH: no 0DH in 63 bytes, the job ends with Bad JCL, Job aborted.
4F20
POP HL E1
Restore Register Pair HL from the stack: 4225H, the start of the line.
4F21
PUSH HL E5
Save Register Pair HL (the start of the line) to the stack again.
4F22
INC HL 23
INCrement Register Pair HL to the second byte of the line.
4F23
LD A,(HL) 7E
Fetch the second byte of the line at Register Pair HL into Register A.
4F24
CP 2FH FE 2F
Compare Register A against 2FH, a slash: directive and label lines start with two slashes.
4F26
If the NZ FLAG is set (one slash only), JUMP to 4F5AH: the line is passed over and the next one taken.
4F28
INC HL 23
INCrement Register Pair HL to the third byte of the line.
4F29
SUB (HL) 96
SUBtract the third byte at Register Pair HL from Register A (2FH): the Z FLAG for a third slash.
4F2A
If the Z FLAG is set (three slashes, the end of a KEYIN choice), JUMP to 4FCCH with Register A = 00H.
4F2D
SUB F6H D6 F6
SUBtract F6H from Register A (2FH less the third byte): the result is 39H less the third byte, with the NO CARRY FLAG only for the digits 0-9.
4F2F
If the NO CARRY FLAG is set (two slashes and a digit, a KEYIN label), JUMP to 4FC8H with Register A = 39H less the digit.
4F32
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, the Stack Pointer unchanged: Register Pair HL = the start of the line, the third byte's address goes on the stack.
4F33
GOSUB to 428DH (@LOGER) to send the directive line at Register Pair HL to the job log.
4F36
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack again, the Stack Pointer unchanged: Register Pair HL = the third byte of the line, the start of the line back on top.
4F37
LD A,(HL) 7E
Fetch the byte at Register Pair HL into Register A. 4F3FH loops back here.
4F38
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4F3A
If the Z FLAG is set (no directive name), JUMP to 4F5AH to take the next line.
4F3C
CP 20H FE 20
Compare Register A (the byte of the line) against 20H, a space.
4F3E
INC HL 23
INCrement Register Pair HL to the next byte. INC of a pair does not change the flags.
4F3F
If the Z FLAG is set (a space), LOOP BACK to 4F37H to pass over it.
4F41
DEC HL 2B
DECrement Register Pair HL back to the first byte of the name.
4F42
LD DE,5181H 11 81 51
Point Register Pair DE to 5181H, where the name is copied (5181H-5186H, not loaded).
4F45
LD B,05H 06 05
Load Register B with 05H. 50DCH sets Register B again before it uses it.
4F47
GOSUB to 50DCH to copy the name at Register Pair HL to 5181H in capitals, ended by 03H: the NZ FLAG when there is no name.
4F4A
If the NZ FLAG is set (no name), JUMP to 4F5AH to take the next line.
4F4C
LD DE,5181H 11 81 51
Point Register Pair DE to 5181H, the name copied, for the table search.
4F4F
LD BC,51B5H 01 B5 51
Point Register Pair BC to 51B5H, the table of the directives.
4F52
GOSUB to 5125H to find the name in the table: the Z FLAG with Register Pair DE = the directive's routine; Register Pair HL = after the name.
4F55
If the NZ FLAG is set (not a directive), JUMP to 4F5AH to take the next line.
4F57
PUSH DE D5
Save Register Pair DE (the directive's routine) to the stack.
4F58
RET C9
RETurn into the directive's routine: the start of the line (4225H), then 4265H and Register Pair BC are on the stack, Register Pair HL is after the name.
4F59
POP BC C1
Remove the count FLASH keeps on the stack into Register Pair BC, when ENTER ends it (506DH).
4F5A
POP HL E1
Restore Register Pair HL from the stack: the start of the line. The directives end here.
4F5B
POP DE D1
Restore Register Pair DE (4265H, the job file) from the stack.
4F5C
POP BC C1
Restore Register Pair BC (Register C the length allowed, Register B the room left) from the stack.
4F5D
JUMP to 4EE8H to take the next line of the job file for the same key request.
4F5F
LD HL,5197H 21 97 51
Point Register Pair HL to 5197H, the message Bad JCL, Job aborted.
4F62
JUMP to 4E8DH to end the job through @ABORT with that message.
4F65H - The STOP, DELAY and PAUSE Directives
STOP ends the job without a message and gives the pending key request to the keyboard, so that the command that asked finishes from the operator's keys. DELAY n waits n times the time unit of 504CH (n counted in its low byte: 0 waits 256 units). PAUSE shows the line and waits for ENTER (or BREAK, which ends the job).
4F65
STOP: GOSUB to 4EADH to undo the job without a message: SFLAG$ bit 5 cleared, the job file closed, the keyboard driver and @EXIT and @ABORT put back; interrupts are left off.
4F68
POP HL E1
Restore Register Pair HL from the stack: the start of the line, no longer needed.
4F69
POP DE D1
Restore Register Pair DE (4265H) from the stack.
4F6A
POP BC C1
Restore Register Pair BC (the line input's count) from the stack.
4F6B
EI FB
Enable interrupts, which 4EADH turned off, before the keyboard is read.
4F6C
LD DE,4015H 11 15 40
Point Register Pair DE to 4015H, KIDCB$, the keyboard, which has its own driver again.
4F6F
JUMP to the ROM at 0013H to get the key from the keyboard at Register Pair DE: the answer to the pending request.
4F72
DELAY: GOSUB to 5167H to read the decimal number at Register Pair HL into Register Pair BC.
4F75
LD B,C 41
Copy Register C (the low byte of the number) into Register B, the count of the DJNZ.
4F76
GOSUB to 504CH to wait one time unit (two when FAST is on). 4F79H loops back here.
4F79
DECrement Register B and LOOP BACK to 4F76H until the units are waited.
4F7B
JUMP to 4F5AH to take the next line of the job.
4F7D
POP HL E1
PAUSE: Restore Register Pair HL from the stack: the start of the line, 4225H.
4F7E
PUSH HL E5
Save Register Pair HL (the start of the line) to the stack again, for 4F5AH.
4F7F
GOSUB to 4467H (@DSPLY) to display the line at Register Pair HL, ended by 0DH.
4F82
GOSUB to 4E92H: BREAK ends the job; the NZ FLAG while ENTER is held. 4F85H loops back here.
4F85
If the Z FLAG is set (ENTER not held), LOOP BACK to 4F82H to wait.
4F87
JUMP to 4F5AH to take the next line of the job.
4F89H - The KEYIN Directive and the Labels
KEYIN shows its line, waits for a key from the keyboard (KEYIN's request does not come from the line input routine, so 4ECFH passes it to the keyboard driver) and keeps it at 4FC9H, the operand of the CP at 4FC8H. Then the lines of the job file are read into INBUF$ and passed over up to a line of two slashes followed by that key, or by a third slash, which matches any key; that line is sent to the job log and the job goes on after it. A label line met in the normal course of the job comes to 4FC8H (two slashes and a digit, with Register A = 39H less the digit) or 4FCCH (three slashes, Register A = 00H): Register A is compared with the key kept, and when they differ the lines are passed over in the same way. The key kept becomes 00H at a line of three slashes.
4F89
POP HL E1
KEYIN: Restore Register Pair HL from the stack: the start of the line, 4225H.
4F8A
PUSH HL E5
Save Register Pair HL (the start of the line) to the stack again.
4F8B
LD A,(HL) 7E
Fetch the next byte of the line at Register Pair HL into Register A. 4F94H loops back here.
4F8C
INC HL 23
INCrement Register Pair HL to the byte after it.
4F8D
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4F8F
If the Z FLAG is set (the end), JUMP to 4F96H to wait for the key.
4F91
GOSUB to the ROM at 0033H to display Register A (the byte of the line) at the cursor.
4F94
LOOP BACK to 4F8BH for the next byte of the line.
4F96
GOSUB to the ROM at 0049H to wait for a key into Register A, from the keyboard driver (4ECFH passes this request on).
4F99
GOSUB to the ROM at 0033H to display Register A (the key).
4F9C
LD (4FC9H),A 32 C9 4F
Store Register A (the key) at 4FC9H, the operand of the CP at 4FC8H: the label to look for.
4F9F
LD A,0DH 3E 0D
Load Register A with 0DH, to end the displayed line.
4FA1
GOSUB to the ROM at 0033H to display Register A (0DH): the cursor goes to the next line.
4FA4
POP HL E1
Restore Register Pair HL from the stack: 4225H, INBUF$. 4FBDH, 4FC1H and 4FCAH loop back here for the next line.
4FA5
PUSH HL E5
Save Register Pair HL (4225H) to the stack again.
4FA6
LD DE,4265H 11 65 42
Point Register Pair DE to 4265H, JFCB$, the job file.
4FA9
GOSUB to 4458H (@CKEOF): the Z FLAG before the end of the job file.
4FAC
If the NZ FLAG is set (the end of the job file, no label found), JUMP to 4EA3H to end the job with Job done.
4FAF
GOSUB to the ROM at 0013H to get the next byte of the job file at Register Pair DE into Register A. 4FB6H loops back here.
4FB2
LD (HL),A 77
Store Register A (the byte) at Register Pair HL in INBUF$.
4FB3
INC HL 23
INCrement Register Pair HL to the next byte of INBUF$.
4FB4
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4FB6
If the NZ FLAG is set (not the end), LOOP BACK to 4FAFH for the next byte.
4FB8
POP HL E1
Restore Register Pair HL from the stack: 4225H, the start of the line just read.
4FB9
PUSH HL E5
Save Register Pair HL (4225H) to the stack again.
4FBA
LD A,(HL) 7E
Fetch the first byte of the line at Register Pair HL into Register A.
4FBB
CP 2FH FE 2F
Compare Register A (the first byte of the line) against 2FH, a slash.
4FBD
If the NZ FLAG is set (not a label), JUMP to 4FA4H to read the next line.
4FBF
INC HL 23
INCrement Register Pair HL to the second byte of the line.
4FC0
CP (HL) BE
Compare Register A (2FH) against the second byte at Register Pair HL.
4FC1
If the NZ FLAG is set (one slash only), JUMP to 4FA4H to read the next line.
4FC3
INC HL 23
INCrement Register Pair HL to the third byte of the line.
4FC4
SUB (HL) 96
SUBtract the third byte at Register Pair HL from Register A (2FH): 00H with the Z FLAG for a third slash.
4FC5
If the Z FLAG is set (three slashes: any key), JUMP to 4FCCH with Register A = 00H.
4FC7
LD A,(HL) 7E
Fetch the third byte of the line at Register Pair HL into Register A: the label.
4FC8
CP 00H FE 00
Compare Register A (the label, or 39H less the digit from 4F2FH) against the key kept, the operand at 4FC9H (00H in the file) stored by 4F9CH and 4FCCH.
4FCA
If the NZ FLAG is set (not this key), JUMP to 4FA4H to read the next line.
4FCC
LD (4FC9H),A 32 C9 4F
Store Register A (the label found, or 00H after three slashes) at 4FC9H, the key kept.
4FCF
POP HL E1
Restore Register Pair HL from the stack: 4225H, the label line.
4FD0
PUSH HL E5
Save Register Pair HL (4225H) to the stack again, for 4F5AH.
4FD1
GOSUB to 428DH (@LOGER) to send the label line at Register Pair HL to the job log.
4FD4
JUMP to 4F5AH to take the line after the label.
4FD6H - The ALERT Directive
ALERT n,n,... plays tones on the cassette output: the numbers stand in turn for a tone (tone n AND 7, 501FH) and a silence (n time units, 5044H), starting with a tone; the byte at 5006H, the operand of LD A at 5005H, is flipped between FFH and 00H for each number. Spaces and commas separate the numbers. A ( keeps the place after it at 4FF7H, the operand of the LD HL at 4FF6H, and a ) goes back there, so the numbers between them repeat until ENTER is held; a ) with no ( before it (4FF7H still 0000H, the value in the file) is Bad JCL. ENTER held ends ALERT after the number being played; 0DH ends it at the end of the line.
4FD6
XOR A AF
ALERT: Set Register A to 00H (XOR A), the state before the first number.
4FD7
LD (5006H),A 32 06 50
Store Register A (00H) at 5006H, the operand of the LD A at 5005H: the first number is a tone.
4FDA
LD A,(HL) 7E
Fetch the next byte of the line at Register Pair HL into Register A. 4FDEH, 4FE2H, 4FF4H, 4FFBH and 501DH come back here.
4FDB
INC HL 23
INCrement Register Pair HL to the byte after it.
4FDC
CP 20H FE 20
Compare Register A (the byte of the line) against 20H, a space.
4FDE
If the Z FLAG is set (a space), LOOP BACK to 4FDAH.
4FE0
CP 2CH FE 2C
Compare Register A (the byte of the line) against 2CH, a comma.
4FE2
If the Z FLAG is set (a comma), LOOP BACK to 4FDAH.
4FE4
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
4FE6
If the Z FLAG is set (the end), JUMP to 4F5AH to take the next line of the job.
4FE9
CP 29H FE 29
Compare Register A against 29H, a closing bracket.
4FEB
If the Z FLAG is set (a closing bracket), JUMP to 4FF6H to go back to the opening one.
4FED
CP 28H FE 28
Compare Register A against 28H, an opening bracket.
4FEF
If the NZ FLAG is set (not a bracket: a number), JUMP to 5000H to play it.
4FF1
LD (4FF7H),HL 22 F7 4F
Store Register Pair HL (the byte after the opening bracket) at 4FF7H-4FF8H, the operand of the LD HL at 4FF6H.
4FF4
LOOP BACK to 4FDAH for the byte after the opening bracket.
4FF6
LD HL,0000H 21 00 00
Load Register Pair HL with the place after the opening bracket, the operand at 4FF7H-4FF8H (0000H in the file) stored by 4FF1H.
4FF9
LD A,H 7C
Copy Register H (the high byte of that place) into Register A.
4FFA
OR L B5
OR Register L (the low byte) into Register A: the Z FLAG when it is 0000H, no opening bracket yet.
4FFB
If the NZ FLAG is set (an opening bracket was seen), LOOP BACK to 4FDAH to play the numbers after it again.
4FFD
JUMP to 4F5FH: a closing bracket with no opening one is Bad JCL.
5000
DEC HL 2B
DECrement Register Pair HL back to the first digit of the number.
5001
GOSUB to 5167H to read the decimal number at Register Pair HL into Register Pair BC.
5004
LD B,C 41
Copy Register C (the low byte of the number) into Register B.
5005
LD A,00H 3E 00
Load Register A with the last state, the operand at 5006H (00H at the start of ALERT).
5007
XOR FFH EE FF
Exclusive OR FFH into Register A: the state flips, FFH a tone, 00H a silence.
5009
LD (5006H),A 32 06 50
Store Register A (the new state) at 5006H for the next number.
500C
LD C,A 4F
Copy Register A (the state, FFH or 00H) into Register C for the two tests.
500D
BIT 0,C CB 41
Test bit 0 of Register C (the state): set for a tone.
500F
If the NZ FLAG is set (a tone), GOSUB to 501FH to play tone Register B AND 07H.
5012
BIT 0,C CB 41
Test bit 0 of Register C (the state) again: clear for a silence.
5014
If the Z FLAG is set (a silence), GOSUB to 5044H to wait Register B time units.
5017
GOSUB to 4E92H: BREAK ends the job; the NZ FLAG while ENTER is held.
501A
If the NZ FLAG is set (ENTER held), JUMP to 4F5AH to end ALERT and take the next line.
501D
LOOP BACK to 4FDAH for the next number of the line.
501FH - Tones and Time Units
501FH plays tone Register B AND 07H on the cassette output port FFH: the table at 5187H gives for each tone the count of a half period and the number of periods. With interrupts off, the port is set to 01H and then 02H for the half period each, the two output levels, as many times as the table says. 5044H waits Register B time units (none for 0). 504CH waits one time unit, the ROM's delay at 0060H with Register Pair BC = 199BH, and a second one when bit 3 of SFLAG$ (FAST) is set.
501F
PUSH BC C5
Save Register Pair BC (Register B = the number) to the stack.
5020
PUSH HL E5
Save Register Pair HL (the place in the line) to the stack.
5021
LD HL,5187H 21 87 51
Point Register Pair HL to 5187H, the table of the eight tones.
5024
LD A,B 78
Copy Register B (the number) into Register A.
5025
AND 07H E6 07
Keep bits 2-0 of Register A (AND 07H): the tone, 0-7.
5027
RLCA 07
Rotate Register A left one bit (RLCA): the tone times 2, the offset of its two bytes in the table.
5028
LD C,A 4F
Copy Register A (the offset) into Register C.
5029
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the offset.
502B
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the tone's entry in the table.
502C
LD C,(HL) 4E
Fetch the first byte of the entry at Register Pair HL into Register C: the count of a half period.
502D
INC HL 23
INCrement Register Pair HL to the second byte of the entry.
502E
LD L,(HL) 6E
Fetch the second byte at Register Pair HL into Register L: the number of periods to play.
502F
DI F3
Disable interrupts: a clock interrupt would lengthen a half period.
5030
LD B,C 41
Copy Register C (the count of a half period) into Register B. 503EH loops back here for each period.
5031
LD A,01H 3E 01
Load Register A with 01H, the first output level of the cassette port.
5033
OUT (FFH),A D3 FF
Write Register A (01H) to port FFH, the cassette output.
5035
DECrement Register B and LOOP BACK to 5035H: the first half period.
5037
LD B,C 41
Copy Register C (the count of a half period) into Register B again.
5038
INC A 3C
INCrement Register A: 02H, the second output level of the cassette port.
5039
OUT (FFH),A D3 FF
Write Register A (02H) to port FFH, the cassette output.
503B
DECrement Register B and LOOP BACK to 503BH: the second half period.
503D
DEC L 2D
DECrement Register L, the periods still to play.
503E
If the NZ FLAG is set (periods left), LOOP BACK to 5030H for the next period.
5040
EI FB
Enable interrupts again, now that the tone is played.
5041
POP HL E1
Restore Register Pair HL (the place in the line) from the stack.
5042
POP BC C1
Restore Register Pair BC (Register B = the number) from the stack.
5043
RET C9
RETurn to 5012H with the tone played and Register Pairs BC and HL kept.
5044
OR B B0
OR Register B (the time units left) into Register A: on the first turn Register A is 00H (the silence state), so the Z FLAG means 0 units. 5049H loops back here.
5045
RET Z C8
RETurn if the Z FLAG is set: a silence of 0 units, or the end of the units.
5046
GOSUB to 504CH to wait one time unit (two when FAST is on).
5049
DECrement Register B and LOOP BACK to 5044H until the units are waited.
504B
RET C9
RETurn with the units waited: Register B is 00H.
504C
LD A,(442BH) 3A 2B 44
Fetch SFLAG$, the system flags, from 442BH into Register A.
504F
BIT 3,A CB 5F
Test bit 3 of Register A (SFLAG$), set when FAST (the faster clock) is on.
5051
If the NZ FLAG is set (FAST), GOSUB to 5054H for one more wait, so that the unit lasts as long as at the normal speed.
5054
PUSH BC C5
Save Register Pair BC to the stack: the ROM's delay counts it down.
5055
LD BC,199BH 01 9B 19
Load Register Pair BC with 199BH, the count of the ROM's delay loop for one time unit.
5058
GOSUB to the ROM at 0060H to wait while Register Pair BC counts down to 0000H.
505B
POP BC C1
Restore the caller's Register Pair BC from the stack.
505C
RET C9
RETurn after one wait: to 5054H after the first of the two waits when FAST is on, else to the caller of 504CH.
505DH - The FLASH Directive
FLASH n shows the directive line, keeps it on the screen for 4000H turns of the test 4E92H, then moves the cursor up a line (1BH) and erases it (1EH) and waits one time unit; n times (n counted in its low byte: 0 gives 256). ENTER held ends it at once.
505D
FLASH: GOSUB to 5167H to read the decimal number at Register Pair HL into Register Pair BC.
5060
LD B,C 41
Copy Register C (the low byte of the number) into Register B, the count of the flashes.
5061
POP HL E1
Restore Register Pair HL from the stack: the start of the line, 4225H.
5062
PUSH HL E5
Save Register Pair HL (the start of the line) to the stack again, for 4F5AH.
5063
PUSH BC C5
Save Register Pair BC (Register B = the flashes left) to the stack. 5083H loops back here.
5064
GOSUB to 4467H (@DSPLY) to display the line at Register Pair HL, ended by 0DH.
5067
LD BC,4000H 01 00 40
Load Register Pair BC with 4000H, the turns the line stays on the screen.
506A
GOSUB to 4E92H: BREAK ends the job; the NZ FLAG while ENTER is held. 5073H loops back here.
506D
If the NZ FLAG is set (ENTER held), JUMP to 4F59H, which drops the count of flashes from the stack and takes the next line.
5070
DEC BC 0B
DECrement Register Pair BC, the turns the line stays on the screen.
5071
LD A,B 78
Copy Register B (the high byte of the turns left) into Register A.
5072
OR C B1
OR Register C (the low byte) into Register A: the Z FLAG when no turn is left.
5073
If the NZ FLAG is set (turns left), LOOP BACK to 506AH.
5075
LD A,1BH 3E 1B
Load Register A with 1BH, the display code that moves the cursor up a line.
5077
GOSUB to the ROM at 0033H to display Register A (1BH): the cursor goes back up to the line shown.
507A
LD A,1EH 3E 1E
Load Register A with 1EH, the display code that erases to the end of the line.
507C
GOSUB to the ROM at 0033H to display Register A (1EH): the line is erased.
507F
GOSUB to 504CH to wait one time unit with the line off.
5082
POP BC C1
Restore Register Pair BC (Register B = the flashes left) from the stack.
5083
DECrement Register B and LOOP BACK to 5063H for the next flash.
5085
JUMP to 4F5AH to take the next line of the job. WAIT (50B5H) ends here too.
5088H - The WAIT Directive
WAIT hh:mm:ss shows its line, then waits until TIME$ (4217H-4219H: seconds, minutes, hours) holds that time exactly, the three numbers kept at 5181H-5183H (hours, minutes, seconds). Each number ends at a character that is not a digit; the second and third must follow a colon. The instruction at 5092H is JP NZ,0AFEH; after @DSPLY the Z FLAG is always set, so it is not taken, and its last two bytes, entered from the DJNZ at 50A0H, are CP 0AH: the separator before the second and third numbers is tested against the colon (3AH less 30H). While it waits, BREAK ends the job; ENTER does not end WAIT.
5088
EX (SP),HL E3
WAIT: Exchange Register Pair HL with the word at the top of the stack, the Stack Pointer unchanged: Register Pair HL = the start of the line, and the place after the name goes on the stack.
5089
GOSUB to 4467H (@DSPLY) to display the line at Register Pair HL; it returns with the Z FLAG.
508C
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack again, the Stack Pointer unchanged: Register Pair HL = the place after the name, the start of the line back on top.
508D
LD DE,5181H 11 81 51
Point Register Pair DE to 5181H, where the three numbers are kept.
5090
LD B,03H 06 03
Load Register B with 03H, the three numbers: hours, minutes and seconds.
5092
JP NZ,0AFEH C2 FE 0A
JP NZ,0AFEH, never taken, since the Z FLAG is set after @DSPLY. The DJNZ at 50A0H enters its second byte, 5093H: CP 0AH compares Register A (the separator less 30H, from 5167H) against 0AH, the colon.
5095
If the NZ FLAG is set (the separator before the second or third number is not a colon), JUMP to 4F5FH: Bad JCL.
5098
PUSH BC C5
Save Register Pair BC (Register B = the numbers left) to the stack.
5099
GOSUB to 5167H to read the decimal number at Register Pair HL into Register Pair BC; Register Pair HL stops at the separator, Register A = the separator less 30H.
509C
LD (HL),C 71
Store Register C (the number) at Register Pair HL, over the separator in INBUF$, so that the LDI below can move it.
509D
LDI ED A0
Copy the byte at Register Pair HL (the number) to Register Pair DE (5181H-5183H), step Register Pairs HL and DE up and Register Pair BC down (LDI): Register Pair HL goes past the separator; Register Pair BC is put back below.
509F
POP BC C1
Restore Register Pair BC (Register B = the numbers left) from the stack.
50A0
DECrement Register B and LOOP BACK to 5093H, the CP 0AH inside the JP at 5092H, to test the separator before the next number.
50A2
GOSUB to 4E92H: BREAK ends the job. Its result is not tested, so ENTER does not end the wait. 50AFH loops back here.
50A5
LD HL,5181H 21 81 51
Point Register Pair HL to 5181H, the hours wanted.
50A8
LD DE,4219H 11 19 42
Point Register Pair DE to 4219H, the hours of TIME$.
50AB
LD B,03H 06 03
Load Register B with 03H, the three bytes to compare.
50AD
LD A,(DE) 1A
Fetch the byte of TIME$ at Register Pair DE into Register A (hours, then minutes, then seconds). 50B3H loops back here.
50AE
CP (HL) BE
Compare Register A against the number wanted at Register Pair HL.
50AF
If the NZ FLAG is set (not yet that time), JUMP to 50A2H to wait on.
50B1
INC HL 23
INCrement Register Pair HL to the next number wanted.
50B2
DEC DE 1B
DECrement Register Pair DE to the next byte of TIME$ (minutes at 4218H, seconds at 4217H).
50B3
DECrement Register B and LOOP BACK to 50ADH until all three are the same.
50B5
JUMP to 5085H, which goes on to 4F5AH: the time is reached.
50B7H - The INPUT Directive
INPUT shows its line and hands the keyboard to the operator for the rest of the key request: the keyboard driver kept in KIJCL$ goes into the CALL at 50C8H, and the request code at 42B6H, @DOKEY's operand, becomes DDH, so the keys come through 50C8H from the keyboard until ENTER (0DH) or BREAK (01H), which put CDH back. The first key answers the request that brought the directive line.
50B7
POP HL E1
INPUT: Restore Register Pair HL from the stack: the start of the line, 4225H.
50B8
GOSUB to 4467H (@DSPLY) to display the line at Register Pair HL.
50BB
LD HL,(42BEH) 2A BE 42
Fetch the keyboard driver kept at 42BEH-42BFH, KIJCL$, into Register Pair HL.
50BE
LD (50C9H),HL 22 C9 50
Store Register Pair HL (the keyboard driver) at 50C9H-50CAH, the operand of the CALL at 50C8H.
50C1
LD A,DDH 3E DD
Load Register A with DDH, the request code of SYS11/SYS's function 50H.
50C3
LD (42B6H),A 32 B6 42
Store Register A (DDH) at 42B6H, the operand of @DOKEY's LD A: the keys now come through request DDH.
50C6
POP DE D1
Restore Register Pair DE (4265H) from the stack.
50C7
POP BC C1
Restore Register Pair BC (the line input's count) from the stack: the return address of the key request is now on top.
50C8
GOSUB to the keyboard driver whose address 50BEH stored in the operand at 50C9H-50CAH (0000H in the file): Register A = the key. Request DDH comes here from 4E14H.
50CB
PUSH AF F5
Save Register Pair AF (Register A = the key) to the stack.
50CC
DEC A 3D
DECrement Register A: 00H with the Z FLAG for 01H, BREAK.
50CD
If the Z FLAG is set (BREAK), JUMP to 50D5H to end the input.
50CF
CP 0CH FE 0C
Compare Register A (the key less one) against 0CH: the Z FLAG for 0DH, ENTER.
50D1
If the Z FLAG is set (ENTER), JUMP to 50D5H to end the input.
50D3
POP AF F1
Restore Register Pair AF (Register A = the key) from the stack.
50D4
RET C9
RETurn with Register A = the key, the answer to the request.
50D5
LD A,CDH 3E CD
Load Register A with CDH, the request code of SYS11/SYS's function 40H.
50D7
LD (42B6H),A 32 B6 42
Store Register A (CDH) at 42B6H, @DOKEY's operand: the job answers the keys again.
50DA
POP AF F1
Restore Register Pair AF (Register A = ENTER or BREAK) from the stack.
50DB
RET C9
RETurn with Register A = the key that ended the input.
50DCH - Copy the Directive's Name
Register Pair HL = the first byte of the name in the line, Register Pair DE = 5181H. Letters and digits are copied, small letters made capitals, up to eight of them (more are passed over); the name ends at 03H, 0DH, an opening bracket or any other character that is not a letter or a digit, and 03H is stored after it. The buffer 5181H-5186H has room for five letters and the 03H; a name of six to eight characters runs on over the first bytes of the tone table at 5187H. The byte at 5113H, the operand of LD A at 5112H, starts as 08H and becomes 00H when a character is stored: the NZ FLAG on return means no name. Register A comes back as the character that ended the name.
50DC
LD B,08H 06 08
Load Register B with 08H, the most characters that are copied.
50DE
LD A,B 78
Copy Register B (08H) into Register A: the value of the flag while no character is stored.
50DF
LD (5113H),A 32 13 51
Store Register A (08H) at 5113H, the operand of the LD A at 5112H.
50E2
INC B 04
INCrement Register B to 09H: the DEC at 5100H leaves 8 places to store.
50E3
LD A,(HL) 7E
Fetch the next character of the name at Register Pair HL into Register A. 5109H and 510CH loop back here.
50E4
CP 03H FE 03
Compare Register A against 03H, the end of a text.
50E6
If the Z FLAG is set (03H), JUMP to 510EH to end the name.
50E8
CP 0DH FE 0D
Compare Register A against 0DH, the end of the line.
50EA
If the Z FLAG is set (0DH), JUMP to 510EH to end the name.
50EC
CP 28H FE 28
Compare Register A against 28H, an opening bracket.
50EE
If the Z FLAG is set (an opening bracket), JUMP to 510EH to end the name.
50F0
INC HL 23
INCrement Register Pair HL to the next character of the line.
50F1
GOSUB to 5117H: the NO CARRY FLAG for a digit or a capital letter.
50F4
If the NO CARRY FLAG is set (a digit or a capital), JUMP to 5100H to store it.
50F6
CP 61H FE 61
Compare Register A (the character) against 61H, a small a.
50F8
If the CARRY FLAG is set (below a small a: not a letter), JUMP to 510EH to end the name.
50FA
CP 7BH FE 7B
Compare Register A against 7BH, the character after a small z.
50FC
If the NO CARRY FLAG is set (above a small z), JUMP to 510EH to end the name.
50FE
RES 5,A CB AF
Clear bit 5 of Register A: the small letter becomes a capital.
5100
DEC B 05
DECrement Register B, the places left in the name.
5101
If the Z FLAG is set (eight characters stored already), JUMP to 510BH to pass over this one.
5103
LD (DE),A 12
Store Register A (the character) at Register Pair DE.
5104
XOR A AF
Set Register A to 00H (XOR A), the flag value for a character stored.
5105
LD (5113H),A 32 13 51
Store Register A (00H) at 5113H: a character of the name is stored.
5108
INC DE 13
INCrement Register Pair DE to the next place of the name.
5109
LOOP BACK to 50E3H for the next character of the name.
510B
INC B 04
INCrement Register B back to 01H, so that the next DEC again finds no place.
510C
LOOP BACK to 50E3H to pass over the rest of a long name.
510E
LD C,A 4F
Copy Register A (the character that ended the name) into Register C.
510F
LD A,03H 3E 03
Load Register A with 03H, the end of the name.
5111
LD (DE),A 12
Store Register A (03H) at Register Pair DE, after the name.
5112
LD A,00H 3E 00
Load Register A with the flag at 5113H (08H in the file, stored by 50DFH and 5105H): 00H when a character was stored.
5114
OR A B7
Set the flags from Register A (OR A): the NZ FLAG when the name is empty.
5115
LD A,C 79
Copy Register C (the character that ended the name) into Register A. LD does not change the flags.
5116
RET C9
RETurn with the NZ FLAG for no name, the Z FLAG for a name at 5181H.
5117
CP 30H FE 30
Compare Register A against 30H, the digit 0: the CARRY FLAG below it.
5119
RET C D8
RETurn with the CARRY FLAG for a character below 0.
511A
CP 3AH FE 3A
Compare Register A against 3AH, the character after 9: the CARRY FLAG for a digit.
511C
If the CARRY FLAG is set (a digit), JUMP to 5123H, whose CCF clears it.
511E
CP 41H FE 41
Compare Register A against 41H, a capital A: the CARRY FLAG between 9 and A.
5120
RET C D8
RETurn with the CARRY FLAG for a character between 9 and A.
5121
CP 5BH FE 5B
Compare Register A against 5BH, the character after a capital Z: the CARRY FLAG for a capital letter.
5123
CCF 3F
Complement the CARRY FLAG: the NO CARRY FLAG for a digit or a capital letter, the CARRY FLAG for any other character.
5124
RET C9
RETurn with the CARRY FLAG for a character that is neither a digit nor a capital letter.
5125H - Find the Directive in the Table
Register Pair DE = the name (5181H, ended by 03H), Register Pair BC = the table at 51B5H: ten entries of seven bytes, five characters (padded with spaces) and the address of the directive's routine, then 00H. The first character picks the entries to compare; the next four must be the same, and a name that ends early matches when the table has a space at that place. Found: the Z FLAG and Register Pair DE = the routine. Not found: the NZ FLAG. Register Pair HL is kept.
5125
PUSH HL E5
Save Register Pair HL (the place after the name in the line) to the stack.
5126
LD H,B 60
Copy Register B (the high byte of the table entry) into Register H.
5127
LD L,C 69
Copy Register C (the low byte) into Register L: Register Pair HL = the first entry.
5128
LD A,(DE) 1A
Fetch the name's first character at Register Pair DE into Register A. 5134H loops back here.
5129
CP (HL) BE
Compare Register A against the entry's first character at Register Pair HL.
512A
If the Z FLAG is set (the same), JUMP to 5139H to compare the rest.
512C
PUSH BC C5
Save Register Pair BC to the stack while Register Pair BC holds the size of an entry. 5165H comes back here.
512D
LD BC,0007H 01 07 00
Load Register Pair BC with 0007H, the size of an entry.
5130
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = the next entry.
5131
POP BC C1
Restore Register Pair BC (the first entry, kept for the next search) from the stack.
5132
LD A,(HL) 7E
Fetch the first byte of the next entry at Register Pair HL into Register A.
5133
OR A B7
Set the flags from Register A (OR A): the Z FLAG for 00H, the end of the table.
5134
If the NZ FLAG is set (another entry), LOOP BACK to 5128H.
5136
POP HL E1
Restore Register Pair HL (the place after the name) from the stack.
5137
INC A 3C
INCrement Register A from 00H to 01H: the NZ FLAG, not found.
5138
RET C9
RETurn with the NZ FLAG: the name is not a directive.
5139
LD B,04H 06 04
Load Register B with 04H, the four characters after the first.
513B
PUSH HL E5
Save Register Pair HL (the entry) to the stack.
513C
PUSH DE D5
Save Register Pair DE (the name) to the stack.
513D
INC DE 13
INCrement Register Pair DE to the name's next character. 514BH loops back here.
513E
INC HL 23
INCrement Register Pair HL to the entry's next character.
513F
LD A,(DE) 1A
Fetch the name's character at Register Pair DE into Register A.
5140
CP 03H FE 03
Compare Register A against 03H, the end of the name.
5142
If the Z FLAG is set (the name ends here), JUMP to 515EH to see whether the entry ends too.
5144
CP 0DH FE 0D
Compare Register A against 0DH, the end of a line.
5146
If the Z FLAG is set (0DH), JUMP to 515EH to see whether the entry ends too.
5148
CP (HL) BE
Compare Register A against the entry's character at Register Pair HL.
5149
If the NZ FLAG is set (they differ), JUMP to 5159H.
514B
DECrement Register B and LOOP BACK to 513DH for the next character.
514D
POP DE D1
Restore Register Pair DE (the name) from the stack: the name matches.
514E
POP BC C1
Restore Register Pair BC from the stack: the entry.
514F
LD HL,0005H 21 05 00
Load Register Pair HL with 0005H, the offset of the routine's address in an entry.
5152
ADD HL,BC 09
ADD Register Pair BC (the entry) to Register Pair HL: Register Pair HL = the routine's address in the entry.
5153
LD E,(HL) 5E
Fetch the low byte of the routine's address at Register Pair HL into Register E.
5154
INC HL 23
INCrement Register Pair HL to the high byte of the routine's address.
5155
LD D,(HL) 56
Fetch the high byte at Register Pair HL into Register D: Register Pair DE = the directive's routine.
5156
POP HL E1
Restore Register Pair HL (the place after the name) from the stack.
5157
XOR A AF
Set Register A to 00H (XOR A) with the Z FLAG: found.
5158
RET C9
RETurn with the Z FLAG and Register Pair DE = the directive's routine.
5159
GOSUB to 5117H: the NO CARRY FLAG when the name's character (Register A) is a digit or a capital.
515C
If the NO CARRY FLAG is set (a letter or digit that differs), JUMP to 5163H: not this entry.
515E
LD A,(HL) 7E
Fetch the entry's character at Register Pair HL into Register A.
515F
CP 20H FE 20
Compare Register A against 20H, the space that pads a short entry.
5161
If the Z FLAG is set (the entry ends here too), JUMP to 514DH: the name matches.
5163
POP DE D1
Restore Register Pair DE (the name) from the stack.
5164
POP HL E1
Restore Register Pair HL (the entry) from the stack.
5165
JUMP to 512CH to go on with the next entry of the table.
5167H - Read a Decimal Number
Register Pair HL = the first digit. The digits are read into Register Pair BC (times ten plus the digit, as 16 bits) until a character that is not a digit; Register Pair HL is left on it and Register A = that character less 30H, with the CARRY FLAG when it was below 0.
5167
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the number so far.
516A
LD A,(HL) 7E
Fetch the character at Register Pair HL into Register A. 517FH loops back here.
516B
SUB 30H D6 30
SUBtract 30H from Register A: the digits 0-9 become 00H-09H; a character below 0 borrows.
516D
RET C D8
RETurn with the CARRY FLAG for a character below 0: the number ends.
516E
CP 0AH FE 0A
Compare Register A against 0AH: the NO CARRY FLAG for a character above 9.
5170
RET NC D0
RETurn with the NO CARRY FLAG for a character above 9: the number ends.
5171
PUSH BC C5
Save Register Pair BC (the number so far) to the stack.
5172
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack, the Stack Pointer unchanged: Register Pair HL = the number so far, the place in the line on the stack.
5173
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 2.
5174
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 4.
5175
ADD HL,BC 09
ADD Register Pair BC (the number) to Register Pair HL: the number times 5.
5176
ADD HL,HL 29
ADD Register Pair HL to itself: the number times 10.
5177
LD B,00H 06 00
Load Register B with 00H, the high byte of the digit.
5179
LD C,A 4F
Copy Register A (the digit's value) into Register C.
517A
ADD HL,BC 09
ADD Register Pair BC (the digit) to Register Pair HL: the number times 10 plus the digit.
517B
LD B,H 44
Copy Register H (the high byte of the number) into Register B.
517C
LD C,L 4D
Copy Register L (the low byte of the number) into Register C: Register Pair BC = the number.
517D
POP HL E1
Restore Register Pair HL (the place in the line) from the stack.
517E
INC HL 23
INCrement Register Pair HL to the next character.
517F
LOOP BACK to 516AH for the next digit of the number.
5181H - The Name Buffer, the Tones, the Messages and the Directives
5181H-5186H are not in the file: the name of a directive (50DCH) or the three numbers of WAIT. Then the table of the eight tones of ALERT, the three messages (the second starts inside the first), and the table of the ten directives, 00H at its end.
5181-5186
DEFS 6
5181H-5186H, not in the file (the load blocks skip them): the directive's name copied by 50DCH, ended by 03H, or WAIT's hours, minutes and seconds (5181H-5183H).
5187-5188
DEFB 6BH, 9CH 6B 9C
Tone 0 of ALERT: a half period of 6BH (107) turns of the DJNZ, 9CH (156) periods.
5189-518A
DEFB 72H, 92H 72 92
Tone 1: a half period of 72H (114) turns, 92H (146) periods.
518B-518C
DEFB 79H, 89H 79 89
Tone 2: a half period of 79H (121) turns, 89H (137) periods.
518D-518E
DEFB 80H, 81H 80 81
Tone 3: a half period of 80H (128) turns, 81H (129) periods.
518F-5190
DEFB 87H, 7AH 87 7A
Tone 4: a half period of 87H (135) turns, 7AH (122) periods.
5191-5192
DEFB 8EH, 74H 8E 74
Tone 5: a half period of 8EH (142) turns, 74H (116) periods.
5193-5194
DEFB 95H, 6FH 95 6F
Tone 6: a half period of 95H (149) turns, 6FH (111) periods.
5195-5196
DEFB 99H, 6BH 99 6B
Tone 7: a half period of 99H (153) turns, 6BH (107) periods: the higher the number, the lower the tone, each about as long.
5197-519F
DEFM "Bad JCL, " 42 61 64 20 4A 43 4C 2C 20
5197H: the start of the message Bad JCL, Job aborted (4F5FH), which goes on into the next message.
51A0-51AB
DEFM "Job aborted" / DEFB 0DH 4A 6F 62 20 61 62 6F 72 74 65 64 0D
51A0H: Job aborted and 0DH, shown alone for BREAK, @ABORT and the ABORT directive (4E6FH, 4E8AH), and the end of Bad JCL, Job aborted.
51AC-51B4
DEFM "Job done" / DEFB 0DH 4A 6F 62 20 64 6F 6E 65 0D
51ACH: Job done and 0DH, shown at the end of the job file and for EXIT (4EA3H).
51B5-51BB
DEFM "ABORT" / DEFW 4E8AH 41 42 4F 52 54 8A 4E
The directive ABORT: end the job with Job aborted (4E8AH).
51BC-51C2
DEFM "ALERT" / DEFW 4FD6H 41 4C 45 52 54 D6 4F
The directive ALERT: tones and silences (4FD6H).
51C3-51C9
DEFM "DELAY" / DEFW 4F72H 44 45 4C 41 59 72 4F
The directive DELAY: wait n time units (4F72H).
51CA-51D0
DEFM "EXIT " / DEFW 4EA3H 45 58 49 54 20 A3 4E
The directive EXIT: end the job with Job done (4EA3H).
51D1-51D7
DEFM "FLASH" / DEFW 505DH 46 4C 41 53 48 5D 50
The directive FLASH: flash the line n times (505DH).
51D8-51DE
DEFM "KEYIN" / DEFW 4F89H 4B 45 59 49 4E 89 4F
The directive KEYIN: take a key and go on at its label (4F89H).
51DF-51E5
DEFM "PAUSE" / DEFW 4F7DH 50 41 55 53 45 7D 4F
The directive PAUSE: show the line and wait for ENTER (4F7DH).
51E6-51EC
DEFM "STOP " / DEFW 4F65H 53 54 4F 50 20 65 4F
The directive STOP: end the job and give the keyboard back (4F65H).
51ED-51F3
DEFM "WAIT " / DEFW 5088H 57 41 49 54 20 88 50
The directive WAIT: wait for a time of day (5088H).
51F4-51FA
DEFM "INPUT" / DEFW 50B7H 49 4E 50 55 54 B7 50
The directive INPUT: the operator types the rest of the line (50B7H).
51FB
DEFB 00H 00
51FBH: 00H, the end of the table of directives.