4D00H - Function Dispatcher
SYS9 is entered by the SYS0 RST 28H dispatcher (4BC2H) with Register A = the RST 28H code and the return address 4C20H on the stack. 2BH and 4BH add a *name routine to the list at 4051H or remove it (the SYS0 vectors 4461H and 4464H); CBH gives the SYS0 keyboard driver its next key from the chain file; EBH (function 7) takes a sub-function in Register C: 1 return from 4DD0H, 2 MDCOPY, 3 CHAIN and DO, 4 abort chaining after an error, 5 CHNON, 6 BASIC2, 7 run a *name routine, 8 PAUSE, 9 STMT, 0AH BOOT, 0BH DOS FATAL ERROR, 0CH 'RUN ONLY' STOPPED. Anything else returns error 2AH.
4D00
LD IY,4380H FD 21 80 43
Load Index Register IY with 4380H, the base of the SYS0 variables; nothing in SYS9 uses Index Register IY after this.
4D04
CP 2BH FE 2B
Compare Register A (the RST 28H code) against 2BH: function 1, enqueue a *name routine (from 4461H).
4D06
If the Z FLAG is set (code 2BH), JUMP to 5067H with Register Pair HL = the routine's block.
4D09
CP 4BH FE 4B
Compare Register A (the RST 28H code) against 4BH: function 2, dequeue a *name routine (from 4464H).
4D0B
If the Z FLAG is set (code 4BH), JUMP to 507EH with Register Pair HL = the routine's block.
4D0E
CP CBH FE CB
Compare Register A (the RST 28H code) against CBH: function 6, a key from the chain file (from the SYS0 keyboard driver at 451FH).
4D10
If the Z FLAG is set (code CBH), JUMP to 4E2BH.
4D13
CP EBH FE EB
Compare Register A (the RST 28H code) against EBH: function 7, with a sub-function in Register C.
4D15
If the NZ FLAG is set (no code SYS9 knows), JUMP to 4D42H for error 2AH.
4D17
DEC C 0D
Decrement Register C, the sub-function: the Z FLAG is set if it was 1.
4D18
If the Z FLAG is set (Register C was 1, the way back from 4DD0H), JUMP to 4DE2H.
4D1B
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 2.
4D1C
If the Z FLAG is set (Register C was 2, MDCOPY), JUMP to 4FE0H.
4D1F
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 3.
4D20
If the Z FLAG is set (Register C was 3, CHAIN or DO), JUMP to 4DE5H.
4D23
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 4.
4D24
If the Z FLAG is set (Register C was 4, from the SYS1 exit: an error while chaining), JUMP to 4EEBH.
4D27
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 5.
4D28
If the Z FLAG is set (Register C was 5, CHNON), JUMP to 4D72H.
4D2A
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 6.
4D2B
If the Z FLAG is set (Register C was 6, BASIC2), JUMP to 5051H.
4D2E
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 7.
4D2F
If the Z FLAG is set (Register C was 7, a command starting with *, from SYS1 4EA0H), JUMP to 508FH.
4D32
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 8.
4D33
If the Z FLAG is set (Register C was 8, PAUSE), JUMP to 4D52H.
4D35
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 9.
4D36
If the Z FLAG is set (Register C was 9, STMT), JUMP to 4D63H.
4D38
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 0AH.
4D39
If the Z FLAG is set (Register C was 0AH, BOOT), JUMP to 4DC6H.
4D3C
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 0BH.
4D3D
If the Z FLAG is set (Register C was 0BH, from the SYS1 exit when bit 2 of 436AH is set), JUMP to 4DACH.
4D3F
DEC C 0D
Decrement Register C, the sub-function, again: the Z FLAG is set if it was 0CH.
4D40
If the Z FLAG is set (Register C was 0CH, from the SYS1 exit: RUN-ONLY, option AB), JUMP to 4DB1H; any other sub-function falls into 4D42H.
4D42H - Error Exits
4D42H: error 2AH. 4D4CH: error 2FH. 4D4EH: the error in Register A through SYS0 4409H. 4D46H is used when the *name list is found damaged (50E8H): it pushes error 33H and calls SYS4 function 2 (code 46H), which sets bit 2 of 436AH and shows the error; the SYS1 exit then stops the system through sub-function 0BH.
4D42
LD A,2AH 3E 2A
Load Register A with 2AH, error code ILLEGAL DOS FUNCTION.
4D44
JUMP to 4D4EH to return the error in Register A.
4D46
LD A,33H 3E 33
Load Register A with 33H, error code DOS FATAL ERROR (from 50E8H: the *name list is damaged).
4D48
PUSH AF F5
Save Register Pair AF (Register A = 33H) on the stack, where SYS4 takes the error code.
4D49
LD A,46H 3E 46
Load Register A with 46H, the RST 28H code of SYS4 function 2.
4D4B
RST 28H EF
RST 28H with Register A = 46H: SYS4 function 2 shows the error on the stack and sets bit 2 of 436AH.
4D4C
LD A,2FH 3E 2F
Load Register A with 2FH, error code BAD PARAMETER(S) (also entered from 50A5H and 50C5H).
4D4E
OR A B7
OR Register A (the error code) with itself to set the NZ FLAG.
4D4F
JUMP to SYS0 4409H, the error exit, with the error code in Register A.
4D52H - PAUSE Command (Sub-Function 8)
PAUSE text: Register Pair HL = the text. It is shown (only in the case 4D63H describes), then PRESS 'ENTER' WHEN READY TO CONTINUE, and SYS9 waits for ENTER.
4D52
GOSUB to 4D63H to show the text at Register Pair HL if it is not already on the screen.
4D55
LD HL,4FBBH 21 BB 4F
Load Register Pair HL with 4FBBH, the message PRESS 'ENTER' WHEN READY TO CONTINUE and a carriage return.
4D58
GOSUB to SYS0 4467H to display the message at Register Pair HL.
WAIT FOR ENTER
Register A = each key read.
4D5B
GOSUB to ROM 0049H ($KEY), which waits for a key and returns it in Register A.
4D5E
SUB 0DH D6 0D
Subtract 0DH (ENTER) from Register A: the Z FLAG is set and Register A = 00H for ENTER.
4D60
If the NZ FLAG is set (not ENTER), LOOP back to 4D5BH.
4D62
RET C9
RETURN with Register A = 00H and the Z FLAG set: no error.
4D63H - STMT Command (Sub-Function 9)
STMT text only shows the text at Register Pair HL, and only when bit 6 of 436AH (a DOS-CALL is running) is set and chaining is off (4369H bit 5 clear). Also used by PAUSE.
4D63
LD BC,(4369H) ED 4B 69 43
Load Register Pair BC with the 16-bit value at 4369H: C = the flags at 4369H, B = the flags at 436AH.
4D67
BIT 6,B CB 70
Test bit 6 of Register B (436AH): set while a DOS-CALL is running.
4D69
If the Z FLAG is set (no DOS-CALL), JUMP to 4D70H without showing the text.
4D6B
BIT 5,C CB 69
Test bit 5 of Register C (4369H): set while chaining is on.
4D6D
If the Z FLAG is set (chaining off), GOSUB to SYS0 4467H to display the text at Register Pair HL.
4D70
XOR A AF
Load Register A with 00H (XOR A with itself), which also sets the Z FLAG: no error.
4D71
RET C9
RETURN with Register A = 00H and the Z FLAG set.
4D72H - CHNON Command (Sub-Function 5)
CHNON Y, N or D, with Register Pair HL = the parameter. It works only while a chain file is open (the chain FCB at 43E0H), otherwise error 26H. Anything else gives error 34H.
4D72
LD A,(43E0H) 3A E0 43
Load Register A with the byte at 43E0H, byte 0 of the chain FCB: bit 7 is set while the chain file is open.
4D75
RLCA 07
Rotate Register A left: bit 7 (open) goes into the CARRY FLAG.
4D76
LD A,26H 3E 26
Load Register A with 26H, error code FILE NOT OPEN. LD does not change the flags.
4D78
If the NO CARRY FLAG is set (no chain file open), JUMP to 4D4EH to return error 26H.
4D7A
GOSUB to 4D82H to read Y, N or D at Register Pair HL and set the flags at 4369H and 436AH.
4D7D
RET Z C8
If the Z FLAG is set (done), RETURN with Register A = 00H.
4D7E
LD A,34H 3E 34
Load Register A with 34H, error code ILLEGAL KEYWORD OR SEPARATOR OR TERMINATOR.
4D80
JUMP to 4D4EH to return error 34H in Register A.
4D82H - Read Y, N or D
Used by CHNON and by the 85H line of a chain file (4E87H), with Register Pair HL = the letter. N turns chaining off (4369H bit 5 clear), Y turns it on, D turns it on and also sets 436AH bit 4 when bit 6 (a DOS-CALL) is set. Only the end of the line may follow. Returns the Z FLAG with Register A = 00H, or the NZ FLAG (nothing stored) for anything else; Register B and Register C keep the new flags in either case.
4D82
LD BC,(4369H) ED 4B 69 43
Load Register Pair BC with the 16-bit value at 4369H: C = the flags at 4369H, B = the flags at 436AH.
4D86
RES 5,C CB A9
Clear bit 5 of Register C (4369H): chaining off.
4D88
RES 4,B CB A0
Clear bit 4 of Register B (the 436AH flags): D not in force.
4D8A
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the parameter's letter.
4D8B
GOSUB to SYS0 45B5H to make the letter in Register A upper case.
4D8E
CP 4EH FE 4E
Compare Register A against 4EH, the letter N.
4D90
If the Z FLAG is set (N), JUMP to 4DA1H with chaining off in Register C.
4D92
SET 5,C CB E9
Set bit 5 of Register C (4369H): chaining on.
4D94
CP 59H FE 59
Compare Register A against 59H, the letter Y.
4D96
If the Z FLAG is set (Y), JUMP to 4DA1H with chaining on in Register C.
4D98
CP 44H FE 44
Compare Register A against 44H, the letter D.
4D9A
RET NZ C0
If the NZ FLAG is set (not D), RETURN with the NZ FLAG: nothing is stored.
4D9B
BIT 6,B CB 70
Test bit 6 of Register B (436AH): set while a DOS-CALL is running.
4D9D
If the Z FLAG is set (no DOS-CALL), JUMP to 4DA1H.
4D9F
SET 4,B CB E0
Set bit 4 of Register B (the 436AH flags): D during a DOS-CALL.
4DA1
INC HL 23
Increment Register Pair HL past the letter to the next character.
4DA2
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the character after the letter.
4DA3
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return at the end of the line.
4DA5
RET NZ C0
If the NZ FLAG is set (something follows), RETURN with the NZ FLAG: nothing is stored.
4DA6
LD (4369H),BC ED 43 69 43
Store Register Pair BC (the new flags) at 4369H: Register C to 4369H, Register B to 436AH.
4DAA
XOR A AF
Load Register A with 00H (XOR A with itself), which also sets the Z FLAG.
4DAB
RET C9
RETURN with Register A = 00H and the Z FLAG set.
4DACH - DOS FATAL ERROR and 'RUN ONLY' STOPPED (Sub-Functions 0BH and 0CH)
Called by the SYS1 exit. 0BH when bit 2 of 436AH is set (by SYS4 function 2 after an error at reset or a damaged *name list); 0CH when a command has ended while option AB (RUN-ONLY, 436CH bit 6) is on and no chain file is running. Both show their message and !! KEY 'R' FOR RESET., wait for R and restart the system (4DC6H).
4DAC
LD HL,5113H 21 13 51
Sub-function 0BH: load Register Pair HL with 5113H, the message DOS FATAL ERROR.
4DAF
JUMP to 4DB4H to display the message at Register Pair HL.
4DB1
LD HL,5100H 21 00 51
Sub-function 0CH: load Register Pair HL with 5100H, the message 'RUN ONLY' STOPPED.
4DB4
GOSUB to SYS0 4467H to display the message at Register Pair HL.
4DB7
LD HL,5123H 21 23 51
Load Register Pair HL with 5123H, the message !! KEY 'R' FOR RESET. and a carriage return.
4DBA
GOSUB to SYS0 4467H to display the message at Register Pair HL.
WAIT FOR R
Register A = each key read.
4DBD
GOSUB to ROM 0049H ($KEY), which waits for a key and returns it in Register A.
4DC0
RES 5,A CB AF
Clear bit 5 of Register A: a lower case letter becomes upper case.
4DC2
CP 52H FE 52
Compare Register A against 52H, the letter R.
4DC4
If the NZ FLAG is set (not R), LOOP back to 4DBDH; R falls into BOOT at 4DC6H.
4DC6H - BOOT Command (Sub-Function 0AH)
Deselects the drives and executes HALT, which resets the Model I: the system boots again.
4DC6
XOR A AF
Load Register A with 00H (XOR A with itself): no drive bit set.
4DC7
LD (37E1H),A 32 E1 37
Store Register A (00H) at 37E1H, the Model I disk drive select latch: no drive selected.
4DCA
LD B,02H 06 02
Load Register B with 02H, the high byte of the delay count in Register Pair BC (Register C is 00H after the sub-function count when BOOT is called directly).
4DCC
GOSUB to ROM 0060H, the delay loop, which counts Register Pair BC down.
4DCF
HALT 76
HALT: on the Model I this resets the computer, and the system boots again.
4DD0H - Run an Overlay Function and Come Back
Used by MDCOPY, whose file buffer lies inside SYS9 and whose calls load other overlays. Pushes the word EB01H and 49D3H. With Register A not 00H it then jumps to 49DDH (RST 28H with code A); with Register A = 00H it jumps to the address in Register Pair HL' (4439H, set at 5006H). The function returns to SYS0 49D3H, which shows an error (NZ) or does RST 28H with EB01H: SYS9 function 7 sub-function 1 (reloaded if needed), which returns to the caller of 4DD0H.
4DD0
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set BC', DE' and HL'.
4DD1
LD BC,EB01H 01 01 EB
Load Register Pair BC' with EB01H: code EBH (SYS9, function 7) in the high byte, sub-function 1 in the low byte.
4DD4
LD DE,49D3H 11 D3 49
Load Register Pair DE' with 49D3H, the SYS0 return point for overlay functions.
4DD7
PUSH BC C5
Push Register Pair BC' (EB01H) on the stack, under the return address of this call.
4DD8
PUSH DE D5
Push Register Pair DE' (49D3H) on the stack, where the function will return.
4DD9
EXX D9
Exchange the alternate set back: Register Pairs BC, DE and HL are the caller's again.
4DDA
OR A B7
OR Register A with itself: the Z FLAG is set if Register A is 00H.
4DDB
If the NZ FLAG is set (Register A holds a code), JUMP to SYS0 49DDH, which does RST 28H with the code in Register A; the overlay returns to 49D3H.
4DDE
EXX D9
Register A = 00H: exchange Register Pairs BC, DE and HL with the alternate set.
4DDF
PUSH HL E5
Push Register Pair HL' (the routine to run, 4439H from 5006H) on the stack.
4DE0
EXX D9
Exchange the alternate set back: Register Pairs BC, DE and HL are the caller's again.
4DE1
RET C9
RETURN, which jumps to the routine at Register Pair HL'; it returns to 49D3H.
4DE2H - Sub-Function 1: Back to the Caller of 4DD0H
The stack holds the dispatcher's return address (4C20H) and then the return address of the CALL 4DD0H. 4C20H is discarded and Register Pair HL kept.
4DE2
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): HL = 4C20H, and the caller's Register Pair HL is saved there.
4DE3
POP HL E1
Restore Register Pair HL from the stack: the caller's value; 4C20H is gone.
4DE4
RET C9
RETURN to the caller of 4DD0H with its Register Pair HL.
4DE5H - CHAIN and DO Commands (Sub-Function 3)
SYS1 has opened the chain file (default extension /JCL) in the FCB at Register Pair DE and left the command line pointer on the stack. The FCB is copied to 43E0H-43FFH with its buffer at 5000H (inside SYS9). If a label follows the filespec it is searched for (4E0FH). Then chaining is turned on (4369H bit 5; 436AH bit 4 too when a DOS-CALL is running), and the SYS0 keyboard driver takes its keys from the file through code CBH.
4DE5
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the FCB SYS1 opened.
4DE6
LD DE,43E0H 11 E0 43
Load Register Pair DE with 43E0H, the chain FCB.
4DE9
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of an FCB.
4DEC
LDIR ED B0
Copy Register Pair BC (32) bytes from Register Pair HL (SYS1's FCB) to Register Pair DE (43E0H).
4DEE
LD HL,5000H 21 00 50
Load Register Pair HL with 5000H, the chain file's sector buffer (5000H-50FFH, over SYS9's own code).
4DF1
LD (43E3H),HL 22 E3 43
Store Register Pair HL (5000H) at 43E3H, the chain FCB's buffer address (FCB+3/4).
4DF4
POP AF F1
Restore Register Pair AF from the stack, discarding the dispatcher's return address (4C20H).
4DF5
POP HL E1
Restore Register Pair HL from the stack: the command line pointer left by SYS1.
4DF6
GOSUB to SYS0 4CD5H with Register Pair HL = the command line: the Z FLAG at the end of the line, the NO CARRY FLAG after a comma or spaces.
4DF9
RET C D8
If the CARRY FLAG is set (another character follows), RETURN with error 34H in Register A.
4DFA
If the NZ FLAG is set (a separator), GOSUB to 4E0FH to find the label named on the command line at Register Pair HL.
4DFD
RET NZ C0
If the NZ FLAG is set (not found, or a read error), RETURN with the error in Register A.
4DFE
LD HL,4369H 21 69 43
Load Register Pair HL with 4369H, the system flags.
4E01
SET 5,(HL) CB EE
Set bit 5 of the byte at Register Pair HL (4369H): chaining on.
4E03
INC HL 23
Increment Register Pair HL to 436AH, the next flag byte.
4E04
BIT 6,(HL) CB 76
Test bit 6 of the byte at Register Pair HL (436AH): set while a DOS-CALL is running.
4E06
If the Z FLAG is set (no DOS-CALL), JUMP to 4E0AH.
4E08
SET 4,(HL) CB E6
Set bit 4 of the byte at Register Pair HL (436AH).
4E0A
XOR A AF
Load Register A with 00H (XOR A with itself), which also sets the Z FLAG.
4E0B
LD (43A5H),A 32 A5 43
Store Register A (00H) at 43A5H, the character read ahead: none is pending.
4E0E
RET C9
RETURN with Register A = 00H and the Z FLAG set.
4E0FH - Find a Label in the Chain File
Register Pair HL points to the label (ended by a carriage return). The file is read from where it is: a label line starts with the code 80H (4F59H turns /./0 into 80H too), followed by the name (compared in upper case) and a carriage return. Returns the Z FLAG with the file positioned after the label line, or the NZ FLAG with the error in Register A (1CH at the end of the file).
4E0F
LD B,H 44
Load Register B with Register H, the label's address, high byte.
4E10
LD C,L 4D
Load Register C with Register L. Register Pair BC = the label's address, kept for each new try.
FIND A LABEL LINE
Register Pair HL = the label being compared, Register Pair BC = its start.
4E11
LD H,B 60
Load Register H with Register B, the label's address, high byte.
4E12
LD L,C 69
Load Register L with Register C. Register Pair HL = the start of the label again.
4E13
GOSUB to 4F59H to read a character of the chain file into Register A.
4E16
RET NZ C0
If the NZ FLAG is set (an error, or the end of the file), RETURN with the error in Register A.
4E17
CP 80H FE 80
Compare Register A against 80H, the label code.
4E19
If the NZ FLAG is set (not a label line), LOOP back to 4E13H.
COMPARE THE NAME
Register Pair HL steps through the label on the command line.
4E1B
GOSUB to 4F59H to read a character of the label line into Register A.
4E1E
RET NZ C0
If the NZ FLAG is set (an error), RETURN with the error in Register A.
4E1F
GOSUB to SYS0 45B5H to make the character in Register A upper case.
4E22
CP (HL) BE
Compare Register A with the byte at Register Pair HL, the label's character.
4E23
INC HL 23
Increment Register Pair HL to the label's next character. INC HL does not change the flags.
4E24
If the NZ FLAG is set (different), LOOP back to 4E11H for the next label line.
4E26
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends both names.
4E28
If the NZ FLAG is set (not the end), LOOP back to 4E1BH for the next character.
4E2A
RET C9
RETURN with the Z FLAG set: found, the file positioned after the label line.
4E2BH - Code CBH: The Next Key From the Chain File
Called by the SYS0 keyboard driver (4516H) when chaining is on (4369H bit 5 set, bits 3 and 6 clear). Returns the Z FLAG with the key in Register A, or the NZ FLAG to make the driver read the real keyboard. The first time after SYS9 is loaded, 4E2BH-4E35H mark the chain file's buffer as empty (FCB+1 bit 5), because the buffer at 5000H has just been overwritten by SYS9 itself, and turn 4E2BH into JR 4E37H. Unless option AT (436DH bit 7) is on, keys are given only to the ROM's line input: SYS9 looks on the stack for the ROM return address 03DDH (inside the driver entry CIO, 03C2H-03E2H) and, 12 bytes further up, 05E3H (inside the keyboard line input KEYIN, 05D9H-0618H).
4E2B
LD A,0AH 3E 0A
Self-Modifying Code
Load Register A with 0AH. As loaded the bytes are LD A,0AH; after the first call the opcode is 18H (stored at 4E2FH), and the bytes read JR 4E37H.
4E2D
LD A,18H 3E 18
Load Register A with 18H, the opcode of JR, for 4E2BH.
4E2F
LD (4E2BH),A 32 2B 4E
Self-Modifying Code
Store Register A (18H) at 4E2BH, the opcode above: from now on 4E2BH jumps to 4E37H.
4E32
LD HL,43E1H 21 E1 43
Load Register Pair HL with 43E1H, FCB+1 of the chain file.
4E35
SET 5,(HL) CB EE
Set bit 5 of the byte at Register Pair HL (FCB+1): the buffer does not hold the current sector, so it is read again.
4E37
LD A,(436DH) 3A 6D 43
Load Register A with the byte at 436DH, the option flags.
4E3A
BIT 7,A CB 7F
Test bit 7 of Register A (the 436DH options): option AT.
4E3C
If the NZ FLAG is set (option AT), JUMP to 4E60H: every keyboard read gets chain file keys.
4E3E
LD B,0AH 06 0A
Load Register B with 0AH: up to 9 words on the stack are looked at.
4E40
LD HL,FFFFH 21 FF FF
Load Register Pair HL with FFFFH (minus 1), to be added to the Stack Pointer.
4E43
ADD HL,SP 39
Add the Stack Pointer SP to Register Pair HL: HL = the Stack Pointer minus 1.
LOOK FOR 03DDH
Register Pair HL steps up the stack a word at a time; Register B counts the words.
4E44
DEC B 05
Decrement Register B, the words left to look at.
4E45
If the Z FLAG is set (not found), JUMP to 4E84H to return the NZ FLAG: the real keyboard.
4E47
INC HL 23
Increment Register Pair HL to the low byte of the next word on the stack.
4E48
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the word's low byte.
4E49
CP DDH FE DD
Compare Register A against DDH, the low byte of 03DDH.
4E4B
INC HL 23
Increment Register Pair HL to the word's high byte. INC HL does not change the flags.
4E4C
If the NZ FLAG is set (another low byte), LOOP back to 4E44H.
4E4E
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the word's high byte.
4E4F
CP 03H FE 03
Compare Register A against 03H: the Z FLAG is set if the word is 03DDH.
4E51
If the NZ FLAG is set (not 03DDH), LOOP back to 4E44H.
4E53
LD DE,000CH 11 0C 00
Load Register Pair DE with 000CH, 12 bytes: the distance to the next return address.
4E56
ADD HL,DE 19
Add Register Pair DE (12) to Register Pair HL: HL = the high byte of the word 12 bytes further up the stack.
4E57
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, that word's high byte.
4E58
CP 05H FE 05
Compare Register A against 05H, the high byte of 05E3H.
4E5A
DEC HL 2B
Decrement Register Pair HL to the word's low byte. DEC HL does not change the flags.
4E5B
RET NZ C0
If the NZ FLAG is set (not 05H), RETURN with the NZ FLAG: the real keyboard.
4E5C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the word's low byte.
4E5D
CP E3H FE E3
Compare Register A against E3H: the Z FLAG is set if the word is 05E3H.
4E5F
RET NZ C0
If the NZ FLAG is set (not 05E3H), RETURN with the NZ FLAG: the real keyboard.
4E60H - Give the Next Character
With option BC (436DH bit 6) the right arrow held pauses the chain file (4F0CH) and the up arrow aborts it (4EDCH). A character read ahead earlier (43A5H) is used first; otherwise the next one is read (4F59H). At the end of the file chaining ends and the keyboard is used.
4E60
LD A,(436DH) 3A 6D 43
Load Register A with the byte at 436DH, the option flags.
4E63
AND 40H E6 40
Mask Register A against 40H (0100 0000) to keep bit 6, option BC.
4E65
If the Z FLAG is set (no option BC), JUMP to 4E6FH.
4E67
LD A,(3840H) 3A 40 38
Load Register A with the byte at 3840H, keyboard row 6 (ENTER, CLEAR, BREAK and the arrows).
4E6A
AND 40H E6 40
Mask Register A against 40H (0100 0000) to keep bit 6, the right arrow.
4E6C
If the NZ FLAG is set (the right arrow is held), JUMP to 4F0CH to pause.
4E6F
GOSUB to 4EDCH: with option BC the up arrow aborts chaining (it does not return then).
4E72
LD A,(43A5H) 3A A5 43
Load Register A with the byte at 43A5H, the character read ahead (00H = none).
4E75
OR A B7
OR Register A with itself: the Z FLAG is set if there is none.
4E76
If the NZ FLAG is set (a character is waiting), JUMP to 4E99H with it in Register A.
4E78
GOSUB to 4F59H to read a character of the chain file into Register A.
4E7B
If the Z FLAG is set (a character was read), JUMP to 4E99H.
4E7D
CP 1CH FE 1C
Compare Register A (the error) against 1CH, END OF FILE ENCOUNTERED.
4E7F
If the NZ FLAG is set (any other error), JUMP to 4EE9H to abort with it.
4E81
The end of the chain (also 80H, from 4EA2H): GOSUB to 4ECEH to turn chaining off.
4E84
OR 01H F6 01
OR Register A with 01H to set the NZ FLAG: the keyboard driver reads the real keyboard.
4E86
RET C9
RETURN to the keyboard driver with the NZ FLAG set in Register Pair AF.
4E87H - A CHNON Line in the Chain File (85H)
The line read by 4F24H (at 4FE0H, Register Pair HL) is taken as CHNON's parameter Y, N or D; anything else aborts with error 01H. Then 513AH gives the character read ahead, if any, through 4E99H; the RET there comes back to 4E93H (the CALL at 4E90H is still on the stack), so that character is not handed to the keyboard driver and Register C then holds it rather than the 4369H flags. Without a character read ahead, if a DOS-CALL is running (436AH bit 6) without bit 4 the command ends at DOS READY (513AH); otherwise the chain goes on if it is still on.
4E87
GOSUB to 4D82H to read Y, N or D at Register Pair HL; Register B and Register C come back with the new 436AH and 4369H flags.
4E8A
If the NZ FLAG is set (not a valid parameter), JUMP to 4F37H to abort with error 01H.
4E8D
LD A,(43A5H) 3A A5 43
Load Register A with the byte at 43A5H, the character read ahead (00H = none).
4E90
GOSUB to 513AH: with a character in Register A it jumps to 4E99H, whose RET comes back to 4E93H; with none it may end the command at DOS READY under a DOS-CALL.
4E93
BIT 5,C CB 69
Test bit 5 of Register C: the 4369H flag chaining on, from 4D82H (or, after 4E99H has run, the character itself).
4E95
If the Z FLAG is set (chaining off), JUMP to 4E84H to return the NZ FLAG: the real keyboard.
4E97
JUMP to 4E60H for the next character of the chain file.
4E99H - Handle a Character or a Code
Register A = the character. Codes: 80H (a label) ends chaining, 81H-83H lines go to 4EF7H, 84H and 85H lines to 4F24H. An ordinary character is given to the keyboard driver after the next one has been read ahead (43A5H): if that is the end of the file or 80H, chaining ends now, so the command being read is the last; if it is 85H its line is handled before this character is given (4F1FH).
4E99
LD B,A 47
Load Register B with Register A, the character.
4E9A
LD C,A 4F
Load Register C with Register A, the character, as well.
4E9B
XOR A AF
Load Register A with 00H (XOR A with itself).
4E9C
LD (43A5H),A 32 A5 43
Store Register A (00H) at 43A5H, the character read ahead: nothing is pending any more.
4E9F
LD A,B 78
Load Register A with Register B, the character.
4EA0
SUB 80H D6 80
Subtract 80H from Register A: the codes 80H-85H become 00H-05H.
4EA2
If the Z FLAG is set (80H, a label: the end of this part of the file), JUMP to 4E81H to turn chaining off.
4EA4
CP 04H FE 04
Compare Register A against 04H: the CARRY FLAG is set for the codes 81H-83H.
4EA6
If the CARRY FLAG is set (81H-83H), JUMP to 4EF7H with the code in Register B.
4EA8
CP 06H FE 06
Compare Register A against 06H: the CARRY FLAG is set for the codes 84H and 85H.
4EAA
If the CARRY FLAG is set (84H or 85H), JUMP to 4F24H with the code in Register C.
4EAD
An ordinary character: GOSUB to 4F59H to read the next one into Register A.
4EB0
LD (43A5H),A 32 A5 43
Store Register A at 43A5H, the character read ahead (the error code when the read failed). LD does not change the flags.
4EB3
If the NZ FLAG is set (a read error), JUMP to 4EB9H.
4EB5
CP 80H FE 80
Compare Register A (the character read ahead) against 80H: the Z FLAG is set for a label line.
4EB7
JUMP to 4EBDH with the Z FLAG set if Register A is 80H.
4EB9
CP 1CH FE 1C
Compare Register A (the error) against 1CH, END OF FILE ENCOUNTERED.
4EBB
If the NZ FLAG is set (any other error), JUMP to 4EE9H to abort with it.
4EBD
If the Z FLAG is set (the end of the file, or 80H next), GOSUB to 4ECEH to turn chaining off now.
4EC0
CP 85H FE 85
Compare Register A (the character read ahead) against 85H, a CHNON line.
4EC2
If the Z FLAG is set (85H), JUMP to 4F1FH to handle that line first.
4EC5
LD A,B 78
Load Register A with Register B, the character to give.
4EC6
CP A BF
Compare Register A with itself to set the Z FLAG: a key is given.
4EC7
RET C9
RETURN with the key in Register A and the Z FLAG set.
4EC8H - CHAINING ABORTED and Turn Chaining Off
4EC8H shows CHAINING ABORTED. 4ECEH closes the chain (byte 0 of the chain FCB = 00H) and clears 4369H bit 5 and 436AH bit 4.
4EC8
LD HL,4FABH 21 AB 4F
Load Register Pair HL with 4FABH, the message ABORTED and a carriage return.
4ECB
GOSUB to 4F4EH to show CHAINING and then the message at Register Pair HL.
4ECE
LD HL,43E0H 21 E0 43
Load Register Pair HL with 43E0H, byte 0 of the chain FCB.
4ED1
LD (HL),00H 36 00
Store 00H at Register Pair HL (43E0H): the chain file is no longer open.
4ED3
LD HL,4369H 21 69 43
Load Register Pair HL with 4369H, the system flags.
4ED6
RES 5,(HL) CB AE
Clear bit 5 of the byte at Register Pair HL (4369H): chaining off.
4ED8
INC HL 23
Increment Register Pair HL to 436AH, the next flag byte.
4ED9
RES 4,(HL) CB A6
Clear bit 4 of the byte at Register Pair HL (436AH).
4EDB
RET C9
RETURN with the chain FCB at 43E0H closed and chaining off.
4EDCH - Abort With the Up Arrow
With option BC (436DH bit 6), the up arrow (keyboard row 6 bit 3) held aborts the chain file with no error code: it goes on at 4EE9H with Register A = 00H and never returns.
4EDC
LD A,(3840H) 3A 40 38
Load Register A with the byte at 3840H, keyboard row 6 (ENTER, CLEAR, BREAK and the arrows).
4EDF
AND 08H E6 08
Mask Register A against 08H (0000 1000) to keep bit 3, the up arrow.
4EE1
RET Z C8
If the Z FLAG is set (the up arrow is not held), RETURN.
4EE2
LD A,(436DH) 3A 6D 43
Load Register A with the byte at 436DH, the option flags.
4EE5
AND 40H E6 40
Mask Register A against 40H (0100 0000) to keep bit 6, option BC.
4EE7
RET Z C8
If the Z FLAG is set (no option BC in Register A), RETURN.
4EE8
XOR A AF
Load Register A with 00H (XOR A with itself): no error code; fall into 4EE9H.
4EE9H - Abort the Chain File
Register A = the error (00H = none). Shows CHAINING ABORTED, turns chaining off and ends the command: with Register A = 00H through SYS0 4030H (error already shown), otherwise with the error in Register A through 4409H. 4EEBH is sub-function 4, called by the SYS1 exit after an error while chaining: the stack then holds the dispatcher's return address and SYS1's Register Pair AF with the error.
4EE9
PUSH AF F5
Save Register Pair AF (Register A = the error code) on the stack.
4EEA
PUSH AF F5
Save Register Pair AF on the stack a second time, so the stack looks like the one sub-function 4 finds at 4EEBH.
4EEB
GOSUB to 4EC8H to show CHAINING ABORTED and turn chaining off.
4EEE
POP AF F1
Restore Register Pair AF from the stack, discarding a word (4C20H for sub-function 4).
4EEF
POP AF F1
Restore Register Pair AF from the stack: Register A = the error code.
4EF0
OR A B7
OR Register A with itself: the Z FLAG is set if there is no error code.
4EF1
If the Z FLAG is set (Register A = 00H), JUMP to SYS0 4030H: the error has been shown (or there is none), DOS READY.
4EF4
JUMP to SYS0 4409H, the error exit, with the error code in Register A.
4EF7H - Lines Marked 81H, 82H and 83H
Register B = the code. The rest of the line is read to its carriage return. With 81H and 83H it is displayed, with 82H (a comment) it is not. After an 81H line the chain file pauses (CHAINING PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE) until ENTER is pressed; the up arrow can abort (with option BC).
READ THE LINE
Register A = each character; Register B = the code.
4EF7
GOSUB to 4F59H to read a character of the chain file into Register A.
4EFA
If the NZ FLAG is set (a read error), JUMP to 4EE9H to abort with it.
4EFC
PUSH AF F5
Save Register Pair AF (Register A = the character) on the stack.
4EFD
BIT 0,B CB 40
Test bit 0 of Register B, the code: set for 81H and 83H, which display the line.
4EFF
If the NZ FLAG is set (81H or 83H), GOSUB to ROM 0033H ($DSP) to display the character in Register A.
4F02
POP AF F1
Restore Register Pair AF from the stack: Register A = the character.
4F03
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line.
4F05
If the NZ FLAG is set (not the end), LOOP back to 4EF7H.
4F07
LD A,B 78
Load Register A with Register B, the code of the line (81H-83H).
4F08
CP 81H FE 81
Compare Register A against 81H, the pause code.
4F0A
If the NZ FLAG is set (82H or 83H), JUMP to 4F1CH to go on with the file.
4F0C
LD HL,4FB3H 21 B3 4F
Load Register Pair HL with 4FB3H, the message PAUSE. PRESS 'ENTER' WHEN READY TO CONTINUE (4E6CH enters here for the right arrow).
4F0F
GOSUB to 4F4EH to show CHAINING and then the message at Register Pair HL.
WAIT FOR ENTER
The up arrow (with option BC) aborts while waiting.
4F12
GOSUB to 4EDCH: with option BC the up arrow aborts chaining.
4F15
LD A,(3840H) 3A 40 38
Load Register A with the byte at 3840H, keyboard row 6.
4F18
AND 01H E6 01
Mask Register A against 01H (0000 0001) to keep bit 0, ENTER.
4F1A
If the Z FLAG is set (ENTER is not pressed), LOOP back to 4F12H.
4F1C
JUMP to 4E60H for the next character of the chain file.
4F1FH - Lines Marked 84H and 85H
4F1FH: the character after an ordinary one is 85H; the ordinary character (Register B) is kept in 43A5H to be given afterwards. 4F24H reads the rest of the line, at most 32 characters, into 4FE0H (over MDCOPY's own code, not needed while chaining). 84H: go to the label named on the line: the file is rewound and the label searched for (4E0FH). 85H: the line is a CHNON parameter (4E87H). A line that is too long, a missing label or a read error aborts.
4F1F
LD C,A 4F
Load Register C with Register A, the code 85H.
4F20
LD A,B 78
Load Register A with Register B, the ordinary character.
4F21
LD (43A5H),A 32 A5 43
Store Register A (the ordinary character) at 43A5H, to be given after the 85H line.
4F24
LD B,20H 06 20
Load Register B with 20H, at most 32 characters.
4F26
LD HL,4FE0H 21 E0 4F
Load Register Pair HL with 4FE0H, the line buffer (over MDCOPY's code).
4F29
PUSH HL E5
Save Register Pair HL (the line's start) on the stack.
READ THE LINE
Register Pair HL = the buffer position, Register B = the room left.
4F2A
GOSUB to 4F59H to read a character of the chain file into Register A.
4F2D
If the NZ FLAG is set (a read error), JUMP to 4EE9H to abort with it.
4F2F
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line.
4F31
LD (HL),A 77
Store Register A (the character) at Register Pair HL, in the buffer. LD does not change the flags.
4F32
INC HL 23
Increment Register Pair HL to the next buffer position. INC HL does not change the flags.
4F33
If the Z FLAG is set (the carriage return), JUMP to 4F3BH.
4F35
Decrement Register B (the room left); if it is not 0, LOOP back to 4F2AH.
4F37
LD A,01H 3E 01
Too long (or a bad 85H line, from 4E8AH): load Register A with 01H, error code BAD FILE DATA.
4F39
JUMP to 4EE9H to abort with the error in Register A.
4F3B
POP HL E1
Restore Register Pair HL from the stack: the line's start (4FE0H).
4F3C
BIT 0,C CB 41
Test bit 0 of Register C, the code: set for 85H.
4F3E
If the NZ FLAG is set (85H), JUMP to 4E87H with Register Pair HL = the line.
4F41
LD DE,43E0H 11 E0 43
84H: load Register Pair DE with 43E0H, the chain FCB.
4F44
GOSUB to SYS0 443FH to rewind the file whose FCB is at Register Pair DE.
4F47
If the Z FLAG is set (rewound), GOSUB to 4E0FH to find the label at Register Pair HL.
4F4A
If the NZ FLAG is set (an error, or the label is not found), JUMP to 4EE9H to abort with the error in Register A.
4F4C
JUMP to 4F1CH to go on after the label line; Register Pair HL is not needed.
4F4EH - Show CHAINING and a Message
Register Pair HL = the message that follows CHAINING.
4F4E
PUSH HL E5
Save Register Pair HL (the message's address) on the stack.
4F4F
LD HL,4FA1H 21 A1 4F
Load Register Pair HL with 4FA1H, the message CHAINING (ended by 03H, no new line).
4F52
GOSUB to SYS0 4467H to display the message at Register Pair HL.
4F55
POP HL E1
Restore Register Pair HL from the stack: the message's address.
4F56
JUMP to SYS0 4467H to display the message at Register Pair HL and return from there.
4F59H - Read a Character From the Chain File
Returns the Z FLAG with the next byte that is not 00H in Register A, or the NZ FLAG with the error (1CH at the end of the file). The text /./ followed by 0-5 is returned as the code 80H-85H, so that a chain file made with an editor can hold the codes. If /, /. or /./ is followed by anything else, the file is moved back (SYS0 4445H with the record length at FCB+9 set to the number of extra bytes read) so that those bytes are read again one at a time, and the / is returned. Bytes 86H-FFH lose bit 7.
4F59
GOSUB to 4F95H to read a byte of the chain file into Register A.
4F5C
RET NZ C0
If the NZ FLAG is set (a read error), RETURN with the error in Register A.
4F5D
PUSH BC C5
Save Register Pair BC (the caller's value) on the stack; it is used as work space here.
4F5E
CP 2FH FE 2F
Compare Register A (the byte) against 2FH, a slash.
4F60
LD B,A 47
Load Register B with Register A, the byte. LD does not change the flags.
4F61
LD A,(43E5H) 3A E5 43
Load Register A with the byte at 43E5H, the position in the sector (FCB+5).
4F64
LD C,A 4F
Load Register C with Register A: the position after the first byte.
4F65
If the Z FLAG is set (a slash), GOSUB to 4F95H to read the next byte into Register A.
4F68
If the NZ FLAG is set (not a slash, or a read error), JUMP to 4F7FH.
4F6A
CP 2EH FE 2E
Compare Register A (the second byte) against 2EH, a period.
4F6C
If the Z FLAG is set (a period), GOSUB to 4F95H to read the next byte into Register A.
4F6F
If the NZ FLAG is set (not a period, or a read error), JUMP to 4F7FH.
4F71
CP B B8
Compare Register A (the third byte) with Register B, the slash.
4F72
If the Z FLAG is set (a slash), GOSUB to 4F95H to read the next byte into Register A.
4F75
If the NZ FLAG is set (not a slash, or a read error), JUMP to 4F7FH.
4F77
SUB 30H D6 30
Subtract 30H from Register A (the fourth byte): the digits 0-9 become 00H-09H.
4F79
CP 06H FE 06
Compare Register A against 06H: the CARRY FLAG is set for the digits 0-5.
4F7B
SET 7,A CB FF
Set bit 7 of Register A: 00H-05H becomes the code 80H-85H. SET does not change the flags.
4F7D
If the CARRY FLAG is set (a digit 0-5), JUMP to 4F92H to return the code in Register A.
4F7F
LD A,(43E5H) 3A E5 43
Load Register A with the byte at 43E5H, the position in the sector (FCB+5) now.
4F82
SUB C 91
Subtract Register C (the position after the first byte) from Register A: the number of extra bytes read.
4F83
LD (43E9H),A 32 E9 43
Store Register A (the extra bytes) at 43E9H, the chain FCB's record length (FCB+9).
4F86
If the NZ FLAG is set (extra bytes were read), GOSUB to SYS0 4445H to move back one record of that length: those bytes will be read again.
4F89
If the NZ FLAG is set (an error), JUMP to 4F93H to return it in Register A.
4F8B
LD A,B 78
Load Register A with Register B, the first byte.
4F8C
CP 86H FE 86
Compare Register A against 86H: the CARRY FLAG is set below 86H.
4F8E
If the CARRY FLAG is set, JUMP to 4F92H to return Register A as it is.
4F90
AND 7FH E6 7F
Mask Register A against 7FH (0111 1111) to take off bit 7 of 86H-FFH.
4F92
CP A BF
Compare Register A with itself to set the Z FLAG: a character is returned.
4F93
POP BC C1
Restore Register Pair BC from the stack: the caller's value.
4F94
RET C9
RETURN with the character (Z FLAG) or the error (NZ FLAG) in Register A.
4F95H - Read a Byte From the Chain File
Reads bytes through the ROM input routine at 0013H with Register Pair DE = the chain FCB (SYS0 4ADBH reads them from the file) and skips 00H bytes. Returns the Z FLAG with the byte in Register A or the NZ FLAG with the error.
SKIP 00H BYTES
Register Pair DE = the chain FCB.
4F95
LD DE,43E0H 11 E0 43
Load Register Pair DE with 43E0H, the chain FCB.
4F98
GOSUB to ROM 0013H ($GET), which reads one byte from the device or file whose control block is at Register Pair DE into Register A.
4F9B
RET NZ C0
If the NZ FLAG is set (an error), RETURN with the error in Register A.
4F9C
OR A B7
OR Register A with itself: the Z FLAG is set for a 00H byte.
4F9D
If the Z FLAG is set (00H), LOOP back to 4F95H to skip it.
4F9F
CP A BF
Compare Register A with itself to set the Z FLAG.
4FA0
RET C9
RETURN with the byte in Register A and the Z FLAG set.
4FA1H - Chaining Messages
4FA1-4FAA
DEFM "CHAINING ", 03H 43 48 41 49 4E 49 4E 47 20 03
The message CHAINING and a space, ended by 03H (no new line), shown by 4F4FH before the other two.
4FAB-4FB2
DEFM "ABORTED", 0DH 41 42 4F 52 54 45 44 0D
The message ABORTED and a carriage return, shown after CHAINING by 4EC8H.
4FB3-4FBA
DEFM "PAUSE. " 50 41 55 53 45 2E 20 20
The message PAUSE. and two spaces, shown by 4F0CH; 4467H goes on with the message after it.
4FBB-4FDF
DEFM "PRESS 'ENTER' WHEN READY TO CONTINUE", 0DH 50 52 45 53 53 20 27 45 4E 54 45 52 27 20 57 48 45 4E 20 52 45 41 44 59 20 54 4F 20 43 4F 4E 54 49 4E 55 45 0D
The message PRESS 'ENTER' WHEN READY TO CONTINUE and a carriage return, shown after PAUSE. (4F0CH) and by the PAUSE command (4D55H).
4FE0H - MDCOPY Command (Sub-Function 2)
MDCOPY source TO destination copies a file sector by sector; it can be used under MINI-DOS. SYS1 has opened the source in the FCB at 4480H and put the second filespec at 51E0H. Both FCBs use the sector buffer 4DE5H-4EE4H, inside SYS9, so 4317H is set to 00H after the calls that may load other overlays (SYS9 will be loaded again the next time it is needed). The destination is opened (new or existing, SYS2), positioned at the source's last sector and written there so that its space is allocated at once, rewound, then every source sector is read and written to it. Finally it gets the source's EOF, is read through once from the start and closed.
4FE0
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the destination filespec SYS1 left after the file.
4FE3
LD HL,4DE5H 21 E5 4D
Load Register Pair HL with 4DE5H, the sector buffer for both files (4DE5H-4EE4H, over SYS9's own code).
4FE6
LD (4483H),HL 22 83 44
Store Register Pair HL (4DE5H) at 4483H, the source FCB's buffer address (FCB+3/4); Register Pair HL = 4DE5H is also the buffer for the destination's open.
4FE9
LD A,44H 3E 44
Load Register A with 44H, the RST 28H code of SYS2's open new or existing.
4FEB
GOSUB to 4DD0H to run the open with Register Pair DE = the filespec and Register Pair HL = the buffer, and come back here.
4FEE
LD A,00H 3E 00
Load Register A with 00H, the value for no overlay in memory.
4FF0
LD (4317H),A 32 17 43
Store Register A (00H) at 4317H, the number of the overlay in memory: the buffer overlaps SYS9, so SYS9 is no longer taken as loaded.
4FF3
LD HL,(448CH) 2A 8C 44
Load Register Pair HL with the 16-bit value at 448CH, the source FCB's EOF sector (FCB+12/13).
4FF6
LD A,(4488H) 3A 88 44
Load Register A with the byte at 4488H, the source FCB's EOF byte in the last sector (FCB+8).
4FF9
OR A B7
OR Register A with itself: the Z FLAG is set if the file ends on a sector boundary.
4FFA
If the NZ FLAG is set (the last sector is partly used), JUMP to 4FFDH.
4FFC
DEC HL 2B
Decrement Register Pair HL: the file ends on a boundary, so its last sector is one less. Register Pair HL = the last sector of the file.
4FFD
LD A,H 7C
Load Register A with Register H, the last sector's high byte.
4FFE
AND L A5
AND Register A with Register L: Register A is FFH only if Register Pair HL is FFFFH.
4FFF
INC A 3C
Increment Register A: the Z FLAG is set if Register Pair HL was FFFFH (an empty file).
5000
If the Z FLAG is set (an empty file), JUMP to 502FH.
5002
LD (51EAH),HL 22 EA 51
Store Register Pair HL (the last sector) at 51EAH, the destination FCB's NEXT (FCB+10/11): it is positioned at that sector.
5005
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set BC', DE' and HL'.
5006
LD HL,4439H 21 39 44
Load Register Pair HL' with 4439H, the SYS0 write vector, for 4DD0H to run.
5009
EXX D9
Exchange the alternate set back: Register Pairs BC, DE and HL are the main ones again.
500A
XOR A AF
Load Register A with 00H (XOR A with itself): 4DD0H is to run the routine at Register Pair HL'.
500B
GOSUB to 4DD0H to write the destination's sector through 4439H (Register Pair DE = 51E0H) and come back: the file's space is allocated at once.
500E
LD A,00H 3E 00
Load Register A with 00H, the value for no overlay in memory.
5010
LD (4317H),A 32 17 43
Store Register A (00H) at 4317H, the number of the overlay in memory: SYS9 is no longer taken as loaded.
5013
GOSUB to SYS0 443FH to rewind the destination, whose FCB is at Register Pair DE (51E0H).
5016
RET NZ C0
If the NZ FLAG is set (an error), RETURN with the error in Register A.
COPY LOOP
Each source sector is read into 4DE5H and written from there.
5017
LD DE,4480H 11 80 44
Load Register Pair DE with 4480H, the source FCB.
501A
GOSUB to SYS0 4436H to read the next sector of the file at Register Pair DE.
501D
If the NZ FLAG is set (the end of the file, or an error), JUMP to 5028H with the code in Register A.
501F
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the destination FCB.
5022
GOSUB to SYS0 4439H to write the sector to the file at Register Pair DE.
5025
RET NZ C0
If the NZ FLAG is set (an error), RETURN with the error in Register A.
5026
LOOP back to 5017H for the next sector, with Register Pair DE set again.
5028
CP 1CH FE 1C
Compare Register A (the error) against 1CH, END OF FILE ENCOUNTERED.
502A
If the Z FLAG is set (1CH), JUMP to 502FH: the copy is done.
502C
CP 1DH FE 1D
Compare Register A (the error) against 1DH, PAST END OF FILE.
502E
RET NZ C0
If the NZ FLAG is set (any other error), RETURN with the error in Register A.
502F
LD HL,(448CH) 2A 8C 44
Load Register Pair HL with the 16-bit value at 448CH, the source FCB's EOF sector (FCB+12/13).
5032
LD (51ECH),HL 22 EC 51
Store Register Pair HL at 51ECH, the destination FCB's EOF sector (FCB+12/13).
5035
LD A,(4488H) 3A 88 44
Load Register A with the byte at 4488H, the source FCB's EOF byte (FCB+8).
5038
LD (51E8H),A 32 E8 51
Store Register A at 51E8H, the destination FCB's EOF byte (FCB+8).
503B
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, the destination FCB.
503E
GOSUB to SYS0 443FH to rewind the file at Register Pair DE.
5041
RET NZ C0
If the NZ FLAG is set (an error), RETURN with the error in Register A.
READ THROUGH
The destination at Register Pair DE is read to its end once.
5042
GOSUB to SYS0 4436H to read the next sector of the file at Register Pair DE.
5045
If the Z FLAG is set (read), LOOP back to 5042H until it stops.
5047
CP 1CH FE 1C
Compare Register A (the error) against 1CH, END OF FILE ENCOUNTERED.
5049
If the Z FLAG is set (1CH), JUMP to 504EH to close.
504B
CP 1DH FE 1D
Compare Register A (the error) against 1DH, PAST END OF FILE.
504D
RET NZ C0
If the NZ FLAG is set (any other error), RETURN with the error in Register A.
504E
JUMP to SYS0 4428H to close the file at Register Pair DE and return from there.
5051H - BASIC2 Command (Sub-Function 6)
Starts the ROM's Level II BASIC without the DOS: copies the ROM's table at 06D2H-0707H to 4000H-4035H, clears 4036H-405CH and jumps into the ROM's second stage of initialisation at 0075H.
5051
DI F3
Disable interrupts: the DOS's interrupt handling is about to be overwritten.
5052
LD BC,0036H 01 36 00
Load Register Pair BC with 0036H, the 54 bytes of the ROM's table.
5055
LD DE,4000H 11 00 40
Load Register Pair DE with 4000H, the start of the communication area.
5058
LD HL,06D2H 21 D2 06
Load Register Pair HL with 06D2H, the ROM's data to be moved to RAM at initialisation (06D2H-070AH).
505B
LDIR ED B0
Copy Register Pair BC (36H) bytes from Register Pair HL (06D2H) to Register Pair DE (4000H). Afterwards DE = 4036H and BC = 0000H.
505D
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = 4036H.
505E
LD B,27H 06 27
Load Register B with 27H, the 39 bytes 4036H-405CH to clear.
CLEAR 4036H-405CH
Register Pair HL = the byte, Register C = 00H, Register B counts.
5060
LD (HL),C 71
Store Register C (00H after the LDIR) at Register Pair HL.
5061
INC HL 23
Increment Register Pair HL to the next byte to clear.
5062
Decrement Register B (the bytes left); if it is not 0, LOOP back to 5060H.
5064
JP 0075H C3 75 00
JUMP to ROM 0075H (INIT2), the second stage of Level II BASIC's start-up.
5067H - Code 2BH: Enqueue a *name Routine
Register Pair HL = the address of the routine's block, which must be 5200H or higher. The block: +0/+1 a check word (set to the block address + 2), +2/+3 the link to the next block, +4 to +11 the name (8 characters), +12 the code. The block is put at the head of the list at 4051H. Error 35H if the name is already in the list, 2FH if the address is too low.
5067
GOSUB to 50C2H to check the address and look for the name: the Z FLAG with Register Pair HL = the name (block+4) if it is not in the list.
506A
RET NZ C0
If the NZ FLAG is set (found, error 35H in Register A), RETURN.
506B
DEC HL 2B
Decrement Register Pair HL to block+3, the link's high byte.
506C
LD DE,(4051H) ED 5B 51 40
Load Register Pair DE with the 16-bit value at 4051H, the list head: the first block, or 0000H.
5070
LD (HL),D 72
Store Register D (the old head, high byte) at Register Pair HL (block+3).
5071
DEC HL 2B
Decrement Register Pair HL to block+2, the link's low byte.
5072
LD (HL),E 73
Store Register E (the old head, low byte) at Register Pair HL (block+2): the link points to the old first block.
5073
LD D,H 54
Load Register D with Register H, block+2's high byte.
5074
LD E,L 5D
Load Register E with Register L. Register Pair DE = block+2, the check word's value.
5075
DEC HL 2B
Decrement Register Pair HL to block+1, the check word's high byte.
5076
LD (HL),D 72
Store Register D (the check word's high byte) at Register Pair HL (block+1).
5077
DEC HL 2B
Decrement Register Pair HL to block+0, the check word's low byte.
5078
LD (HL),E 73
Store Register E (the check word's low byte) at Register Pair HL (block+0).
5079
LD (4051H),HL 22 51 40
Store Register Pair HL (the block) at 4051H: the block is the new list head.
507C
XOR A AF
Load Register A with 00H (XOR A with itself), which also sets the Z FLAG.
507D
RET C9
RETURN with Register A = 00H and the Z FLAG set: no error.
507EH - Code 4BH: Dequeue a *name Routine
Register Pair HL = the block address. The block is found by its name and removed from the list; its check word is spoiled so that it is no longer taken as a block. Error 18H if the name is not in the list.
507E
GOSUB to 50C2H to look for the name: the NZ FLAG if found, with Register Pair HL = the block's link word (block+2) and Register Pair DE = the address of the link that points to the block.
5081
If the Z FLAG is set (not found), JUMP to 50BDH for error 18H.
5083
XOR A AF
Load Register A with 00H (XOR A with itself).
5084
DEC HL 2B
Decrement Register Pair HL to block+1, the check word's high byte.
5085
LD (HL),A 77
Store Register A (00H) at Register Pair HL (block+1): the check word is no longer valid.
5086
INC HL 23
Increment Register Pair HL to block+2, the link's low byte.
5087
LD C,(HL) 4E
Load Register C with the byte at Register Pair HL, the link's low byte.
5088
INC HL 23
Increment Register Pair HL to block+3, the link's high byte.
5089
LD B,(HL) 46
Load Register B with the byte at Register Pair HL. Register Pair BC = the next block's address (0000H at the end).
508A
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the link that points to this block.
508B
LD (HL),C 71
Store Register C (the next block, low byte) at Register Pair HL.
508C
INC HL 23
Increment Register Pair HL to the link's high byte.
508D
LD (HL),B 70
Store Register B (the next block, high byte) at Register Pair HL: the block is out of the list.
508E
RET C9
RETURN with Register A = 00H and the Z FLAG set (from 5083H): no error.
508FH - Sub-Function 7: Run a *name Routine
SYS1 calls this for a command that starts with *, with Register Pair HL at the *. The name (1-8 characters, up to a separator or the end of the line) is looked for in the list; the routine is entered at its block + 12 with Register Pair HL = the rest of the command line, through SYS0 4C20H. No name gives error 2FH, an unknown one 18H.
508F
LD DE,51E0H 11 E0 51
Load Register Pair DE with 51E0H, where the name is copied (after the file).
5092
LD B,09H 06 09
Load Register B with 09H: at most 8 characters, counted from 9.
5094
PUSH DE D5
Save Register Pair DE (51E0H, the start of the name's copy) on the stack.
COPY THE NAME
Register Pair HL steps through the command line, Register Pair DE through 51E0H.
5095
INC HL 23
Increment Register Pair HL past the * (then past each character).
5096
GOSUB to SYS0 4CD5H with Register Pair HL at the character: the NO CARRY FLAG at the end of the line or at a separator.
5099
If the NO CARRY FLAG is set (the name has ended), JUMP to 50A2H.
509B
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the name's character.
509C
LD (DE),A 12
Store Register A at Register Pair DE, in the copy at 51E0H.
509D
INC DE 13
Increment Register Pair DE to the next position of the copy.
509E
Decrement Register B (the room left); if it is not 0, LOOP back to 5095H.
50A0
LD B,09H 06 09
A ninth character: load Register B with 09H, the same as no name.
50A2
LD A,B 78
Load Register A with Register B, 9 minus the characters copied.
50A3
CP 09H FE 09
Compare Register A against 09H: the Z FLAG is set if no character was copied.
50A5
If the Z FLAG is set (no name), JUMP to 4D4CH for error 2FH.
PAD THE NAME
Register Pair DE = the next position, Register B = the characters to add.
50A8
LD A,20H 3E 20
Load Register A with 20H, a space, to pad the name.
50AA
LD (DE),A 12
Store Register A (a space) at Register Pair DE.
50AB
INC DE 13
Increment Register Pair DE to the next position.
50AC
Decrement Register B; if it is not 0, LOOP back to 50A8H: the name is 8 characters.
50AE
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): HL = 51E0H, the name, and the command line pointer is saved there.
50AF
GOSUB to 50CCH to look for the name at Register Pair HL: the NZ FLAG if found, with Register Pair HL = the block's link word (block+2).
50B2
LD DE,000AH 11 0A 00
Load Register Pair DE with 000AH, 10: from block+2 to block+12.
50B5
ADD HL,DE 19
Add Register Pair DE (10) to Register Pair HL: HL = block+12, the routine's code. ADD HL does not change the Z FLAG.
50B6
POP DE D1
Restore Register Pair DE from the stack: the command line pointer.
50B7
If the Z FLAG is set (not found), JUMP to 50BDH for error 18H.
50B9
EX (SP),HL E3
Exchange Register Pair HL with the word at the top of the stack (at the Stack Pointer SP): HL = the dispatcher's return address 4C20H, and the routine's address takes its place.
50BA
PUSH HL E5
Push Register Pair HL (4C20H) on the stack again, above the routine's address.
50BB
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the command line pointer after the name.
50BC
RET C9
RETURN to SYS0 4C20H, which clears 4369H bit 6 and returns into the routine with Register Pair HL = the rest of the line.
50BD
LD A,18H 3E 18
Load Register A with 18H, error code FILE NOT IN DIRECTORY (from 5081H and 50B7H).
50BF
JUMP to 4D4EH to return error 18H in Register A.
50C2H - Look for a *name Block
50C2H checks that the block at Register Pair HL is at 5200H or higher (else error 2FH) and points Register Pair HL to its name; 50CCH looks for the 8-character name at Register Pair HL. The list starts at 4051H and ends with a link of 0000H. A block whose check word is not its own address + 2 means the list is damaged: 4D46H. Returns the Z FLAG (not found) with Register Pair HL = the name, or the NZ FLAG with Register A = 35H, Register Pair HL = the block's link word (+2), Register Pair DE = the address of the link that points to the block, Register Pair BC = the name.
50C2
LD A,H 7C
Load Register A with Register H, the high byte of the block's address.
50C3
CP 52H FE 52
Compare Register A against 52H: the CARRY FLAG is set below 5200H.
50C5
If the CARRY FLAG is set (below 5200H), JUMP to 4D4CH for error 2FH.
50C8
INC HL 23
Increment Register Pair HL (the block's address) to block+1.
50C9
INC HL 23
Increment Register Pair HL (the block's address) to block+2.
50CA
INC HL 23
Increment Register Pair HL (the block's address) to block+3.
50CB
INC HL 23
Increment Register Pair HL to block+4, the name.
50CC
PUSH HL E5
Save Register Pair HL (the name's address) on the stack.
50CD
LD HL,4051H 21 51 40
Load Register Pair HL with 4051H, the list head: the first link to follow.
50D0
PUSH HL E5
Save Register Pair HL (4051H) on the stack, for the POP at 50D3H.
50D1
PUSH HL E5
Save Register Pair HL (4051H) on the stack again, for the POP at 50D2H to discard.
FOLLOW THE LIST
The stack holds a word to discard, the link to follow and the name's address.
50D2
POP BC C1
Restore Register Pair BC from the stack, discarding a word.
50D3
POP HL E1
Restore Register Pair HL from the stack: the address of the link to follow (4051H or a block+2).
50D4
LD B,H 44
Load Register B with Register H, the link's address, high byte.
50D5
LD C,L 4D
Load Register C with Register L. Register Pair BC = the address of the link.
50D6
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the link's low byte.
50D7
INC HL 23
Increment Register Pair HL to the link's high byte.
50D8
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the next block (0000H at the end).
50D9
LD A,D 7A
Load Register A with Register D, to test Register Pair DE for zero.
50DA
OR E B3
OR Register A with Register E: the Z FLAG is set for 0000H, the end of the list.
50DB
If the NZ FLAG is set (another block), JUMP to 50DFH.
50DD
POP HL E1
The end of the list: restore Register Pair HL from the stack, the name's address.
50DE
RET C9
RETURN with the Z FLAG set (not found) and Register Pair HL = the name.
50DF
EX DE,HL EB
Exchange Register Pairs DE and HL: HL = the block.
50E0
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the check word's low byte.
50E1
INC HL 23
Increment Register Pair HL to block+1, the check word's high byte.
50E2
LD D,(HL) 56
Load Register D with the byte at Register Pair HL. Register Pair DE = the check word.
50E3
INC HL 23
Increment Register Pair HL: HL = block+2, the block's link word.
50E4
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
50E5
SBC HL,DE ED 52
Subtract Register Pair DE (the check word) from Register Pair HL (block+2): the Z FLAG is set if they match.
50E7
POP HL E1
Restore Register Pair HL from the stack: the name's address. POP does not change the flags.
50E8
If the NZ FLAG is set (a wrong check word: the list is damaged), JUMP to 4D46H.
50EB
PUSH HL E5
Save Register Pair HL (the name's address) on the stack.
50EC
PUSH DE D5
Save Register Pair DE (block+2, the block's link word) on the stack.
50ED
PUSH BC C5
Save Register Pair BC (the address of the link that points to the block) on the stack.
50EE
INC DE 13
Increment Register Pair DE from block+2 to block+3.
50EF
INC DE 13
Increment Register Pair DE to block+4, the block's name.
50F0
LD B,08H 06 08
Load Register B with 08H, the 8 characters of a name.
COMPARE THE NAMES
Register Pair DE steps through the block's name, Register Pair HL through the name wanted.
50F2
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE, a character of the block's name.
50F3
SUB (HL) 96
Subtract the byte at Register Pair HL (the name wanted) from Register A: the Z FLAG is set if they match.
50F4
INC DE 13
Increment Register Pair DE to the block's next character. INC DE does not change the flags.
50F5
INC HL 23
Increment Register Pair HL to the next character wanted. INC HL does not change the flags.
50F6
If the NZ FLAG is set (different), LOOP back to 50D2H to follow this block's link.
50F8
Decrement Register B (the characters left); if it is not 0, LOOP back to 50F2H.
50FA
POP DE D1
Found: restore Register Pair DE from the stack, the address of the link that points to the block.
50FB
POP HL E1
Restore Register Pair HL from the stack: block+2, the block's link word.
50FC
POP BC C1
Restore Register Pair BC from the stack: the name's address.
50FD
OR 35H F6 35
OR Register A (00H after the last match) with 35H: Register A = 35H, error code FILE ALREADY EXISTS, and the NZ FLAG set.
50FF
RET C9
RETURN with the NZ FLAG set and Register A = 35H: found.
5100H - Stop Messages
5100-5112
DEFM "'RUN ONLY' STOPPED", 03H 27 52 55 4E 20 4F 4E 4C 59 27 20 53 54 4F 50 50 45 44 03
The message 'RUN ONLY' STOPPED, ended by 03H (no new line), shown by 4DB1H for sub-function 0CH.
5113-5122
DEFM "DOS FATAL ERROR", 03H 44 4F 53 20 46 41 54 41 4C 20 45 52 52 4F 52 03
The message DOS FATAL ERROR, ended by 03H (no new line), shown by 4DACH for sub-function 0BH.
5123-5139
DEFM "!! KEY 'R' FOR RESET.", 0DH 21 21 20 20 4B 45 59 20 27 52 27 20 46 4F 52 20 52 45 53 45 54 2E 0D
The message !! KEY 'R' FOR RESET. and a carriage return, shown after either of the two by 4DB7H.
513AH - After a CHNON Line
Called from 4E90H with Register A = the character read ahead and Register B = the new 436AH flags from 4D82H: if there is a character it is given now (JP 4E99H). Otherwise, if a DOS-CALL is running (436AH bit 6) and bit 4 is clear, the command ends at DOS READY (402DH).
513A
OR A B7
OR Register A (the character read ahead) with itself: the Z FLAG is set if there is none.
513B
If the NZ FLAG is set (a character is waiting), JUMP to 4E99H to give it; its RET comes back to 4E93H.
513E
LD A,B 78
Load Register A with Register B, the 436AH flags from 4D82H.
513F
AND 50H E6 50
Mask Register A against 50H (0101 0000) to keep bit 6 (a DOS-CALL) and bit 4.
5141
CP 40H FE 40
Compare Register A against 40H: the Z FLAG is set if bit 6 is set and bit 4 clear.
5143
If the Z FLAG is set, JUMP to SYS0 402DH: DOS READY, the DOS-CALL's command ends.
5146
RET C9
RETURN to 4E93H with Register A = the masked 436AH flags.
5147H - Unused Bytes
5147-51DF
NOP x 153 00 x 153
153 zero bytes to the end of the file (51DFH). Nothing in SYS9 reads or writes them; 51E0H-51FFH, after the file, holds the second filespec from SYS1 (MDCOPY) or the *name being looked for.