General:
SYS10/SYS handles DISPLAY DIR ($DSPDIR) and BASIC Error Messages.
Disassembly:
“START”
4E00
AND 0F0H
On entry, every overlay has a routine request in Register A, which is routinely masked to retain only the high nybble. MASK the value of Register A against 0F0H (1111 0000) to leaving only bits 7, 6, 5, 4 active.
4E02
CP 90H
Compare the value held in Register A against 90H to see if this was a request to display an error message. If Register A equals 90H, the Z FLAG is set; otherwise the NZ FLAG is set.
4E04
If the entry call was 90H, then the Z FLAG (Zero) will have been set, meaning that this Overlay was involked to display an error; JUMP to 4EF0H to handle it.
“DODIR”
4E07
XOR A
Set Register A to ZERO and clear all Flags so that we can set the overlay flag to indicate that SYS06/SYS is NOT in memory.
4E08
LD (442BH),A
Store the 0 held in Register A into memory location 442BH.
4E0B
LD A,(4271H)
Fetch the drive number from memory location 4271H and store it into Register A.
4E0E
AND 03H
The first two bits of Register A hold the drive number, so MASK the value of Register A against 03H to keep only bits 1-0.
“DIRGET”
4E10
LD (DRIVE),A
Store the drive number (held in Register A) into memory location 4EDAH.
4E13
Clear the screen via a GOSUB to 01C9H.
NOTE: 01C9H is the Model III ROM routine to to CLEAR THE SCREEN and RETurn.
4E16
LD A,0EH
Let Register A equal 0EH which is the ASCII code for CURSOR ON.
4E18
Turn the cursor on via a GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4E1B
LD A,(DRIVE)
Fetch the drive number (held in memory location 4EDAH) and store it into Register A.
4E1E
LD B,A
Copy the drive number from Register A into Register B.
4E1F
LD A,(4413H)
Fetch the highest drive number in the system from memory location 4413H and store it into Register A.
NOTE: 4413H is the storage location for the NUMBER OF DISK DRIVES in the system.
4E22
CP B
Make sure we actually have the drive by comparing the highest drive number in the system(held in Register A) against the drive number supplied (held in Register B). If if the maximum drive number (A) >= the requested drive number (B), the NO CARRY FLAG will be set.
4E23
If the drive number is valid, then the NC FLAG (No Carry) will have been set, so continue via JUMP to 4E2AH.
4E25
LD A,0C2H
Let Register A equal 0C2H to set up for a DRIVE NOT IN SYSTEM error.
4E27
JUMP to 4409H, which is the SYS00/SYS routine to process DOS errors.
4E2AH – Read the directory track into a Buffer in RAM.
LD A,(DRIVE)
Fetch the drive number (held in memory location 4EDAH) and store it into Register A.
4E2D
PUSH AF
Save the drive number to the top of the stack.
4E2E
GOSUB to 4B3EH.
NOTE: 4B3EH is the SYS00/SYS routine to identify the track number of the directory. Routine exits with the director track number in Register D.
4E31
LD A,D
Copy the directory track number for the given drive (held in Register D) into Register A.
4E32
LD (SAVTRK),A
Store the directory track number for the given drive into memory location 4E56H, which is in the middle of a LD D,0 OPCODE.
4E35
POP AF
Restore the drive number from the top of the stack.
4E36
ADD A,30H
LET Register A = Register A + 30H. Note: Adding 30H to from Register A will convert decimal number 0-9 into its ASCII equivalent (i.e., 6 + 30H = 36H, which, in ASCII, is 6.
4E38
LD (DRV),A
Store the ASCII rendition of the drive number (held in Register A) into the middle of the DRIVE MESSAGE at memory location 4EE3H.
4E3B
LD A,01H
Let Register A equal 01H.
4E3D
LD (NUM),A
Store a 1 into memory location 4EEFH as the starter value for how many filenames have been displayed on the current screen line.
4E40
LD HL,DRVMSG
Let Register Pair HL equal 4EDCH to point to the drive number message.
4E43
GOSUB to 021BH.
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
“DIRLO1”
4E46
LD A,02H
Let Register A equal 02H to point to Sector 2.
4E48
LD (S10SEC),A
Store the sector number (held in Register A) into memory location 4EEEH.
LD HL,S10SEC
Let Register Pair HL equal to the track pointed to at 4EEEH.
4E4E
LD A,(HL)
Fetch the sector number (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4E4F
INC (HL)
INCrement the value stored in the memory location pointed to by Register Pair HL by 1 to point to the next sector.
4E50
LD E,A
Copy the sector number into Register E to prepare for the next call.
4E51
LD A,(DRIVE)
Fetch the current drive number (held in memory location 4EDAH) and store it into Register A.
4E54
LD C,A
Copy the contents of Register A into Register C for the CALL.
4E55
LD D,(**SAVTRK**)
Let Register D equal the directory track (placed into 4E56H at 4E32H).
4E57
LD HL,4300H
Let Register Pair HL equal 4300H.
NOTE: 4300H is a memory buffer (referred to as Memory Buffer 1) where diskette contents are stored in RAM.
NOTE: 4300H is the storage location for the 256 Byte Storage Area for Disk I/O.
4E5A
Read the directory track into the buffer via a GOSUB to 4675H.
4E5D
If the Z FLAG (Zero) has been set then there was no error, so JUMP to 4E64H.
4E5F
OR 0C0H
If we’re here then there was an error reading that track. OR Register A against 0C0H (1100 0000) to prepare to set error codes to detailed messages instead of just numbers.
4E61
JUMP to 4409H.
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.
4E64H – Process the directory track now in RAM to find the filename.
LD HL,4300H
Let Register Pair HL equal 4300H.
NOTE: 4300H is a memory buffer (referred to as Memory Buffer 1) where diskette contents are stored in RAM.
NOTE: 4300H is the storage location for the 256 Byte Storage Area for Disk I/O.
4E67
LD (SAVE3),HL
Store the buffer pointer (held in Register Pair HL) into memory location 4EECH.
LD HL,(SAVE3)
Fetch the current pointer to the current buffer (held in memory location 4EECH) and store it into Register Pair HL.
4E6D
LD A,(HL)
Fetch a character from the buffer (which is a character from the directory) and store it into Register A.
4E6E
OR A
We need to see if that first character of the directory entry is 0. Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4E6F
If the Z FLAG (Zero) has been set, then we have a blank file, so JUMP to 4EBFH to skip the file processing.
4E71
AND 48H
If we’re here then we found a file, but now need to see if it is a SYSTEM or INVISIBLE file. MASK the value of Register A against 48H (0100 1000) leaving only bits 6 and 3 active.
4E73
If the NZ FLAG (Not Zero) has been set, then we have either a SYSTEM or an INVISIBLE file, so JUMP to 4EBFH to skip the file processing.
4E75
LD B,08H
Let Register B equal the maximum length of a filename (i.e., 08H).
4E77
LD C,0FH
Let Register C equal the maximum length of a full filespec (i.e., 0FH or 15 characters).
4E79
4E7A
4E7C
LD A,L
ADD A,05H
LD L,A
LET Register Pair HL = Register Pair HL + 05H so as to push HL to the beginning of the filename.
LD A,(HL)
Fetch a character from the filename (which is what HL is pointing to in the directory in the buffer).
4E7E
INC HL
Bump the buffer to point to the next character in the filename.
4E7F
CP 20H
We need to see if we are at the end of the filename, so compare that character against a SPACE. Results: If it is a SPACE, the Z FLAG will be set.
4E81
If it is a SPACE, then we are done processing filename characters so JUMP to 4E89H.
4E83
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4E86
DEC C
DECrement the filespec character counter stored in Register C by 1.
4E87
Keep processing characters by LOOPing back to 4E7DH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
LD A,B
Copy the filename counter (held in Register B as the counter for the DJNZ loop) into Register A.
4E8A
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4E8B
If B was zero, then we don’t need to fill the remaining characters of a filename (i.e., we got 8), so JUMP to 4E91H.
4E8D
DEC HL
Back up the pointer in the directory sector (value stored in Register Pair HL) by 1 in preparation for the following loop which starts by INCrementing it right back.
INC HL
INCrement the value stored in Register Pair HL by 1.
4E8F
Keep skipping spaces by LOOPing back to 4E8EH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
At this point, HL is now positioned at the file’s EXTENSION in the directory sector.
LD A,(HL)
Fetch the first character of where the file’s extension is supposed to be in the directory entry held in RAM (pointed to by Register Pair HL) and store it into Register A.
4E92
CP 20H
Compare the value held in Register A against a SPACE). Results: If Register A equals SPACE, the Z FLAG is set; otherwise the NZ FLAG is set.
4E94
If that very first character is a SPACE, then we know that there is no extension present; so skip processing the extension by JUMPing to 4EA6H.
4E96
LD A,2FH
We know that there is an extension, so we need to display a /. Let Register A equal 2FH (ASCII: /).
4E98
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4E9B
DEC C
DECrement the total filespec counter (stored in Register C) by 1.
4E9C
LD B,03H
Let Register B equal 03H for the length of an extension.
LD A,(HL)
Fetch a character of where the file’s extension is supposed to be in the directory entry held in RAM (pointed to by Register Pair HL) and store it into Register A.
4E9F
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next character in the extension.
4EA0
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4EA3
DEC C
DECrement the total filespec counter (stored in Register C) by 1.
4EA4
Display the entire extension by LOOPing back to 4E9EH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
LD B,C
Copy the total number of characters left into Register B.
LD A,20H
Let Register A equal 20H so that we can display the appropriate number of SPACE‘s.
4EA9
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4EAC
LOOP back to 4EA7H, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
4EAE
LD A,(NUM)
Fetch the number of filenames that have already been displayed on the same line on screen (held in memory location 4EEFH) and store it into Register A.
4EB1
INC A
INCrement the value stored in Register A by 1 to indicate that one more was just displayed.
4EB2
CP 04H
Compare the value held in Register A against 04H to see if we already have 4. If A < 04H, the CARRY FLAG will be set.
4EB4
If we are less than 4, then we can keep displaying on this line, so JUMP down to 4EBCH.
If we are here, then we have already displayed 4 filenames on a line, so we need to end that line and reset everything that monitors that count and start again.
4EB6
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
4EB8
GOSUB to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
4EBB
XOR A
Set Register A to ZERO in preparation for resetting the “how many filenames have appeared on screen on this line” tracker.
LD (NUM),A
Store the value held in Register A into the “how many filenames have appeared on screen on this line” tracker (held in memory location 4EEFH).
LD HL,(SAVE3)
Fetch the BUFFER starting location (held in memory location 4EECH) and store it into Register Pair HL.
4EC2
LD A,L
ADD A,30H
LD L,A
Let Register Pair HL point to the next filename in the buffer in RAM by advancing it 30H more bytes.
4EC6
LD (SAVE3),HL
Store the revised pointer to the directory sector in RAM into memory location 4EECH.
4EC9
CP 0F0H
Compare the value held in Register A against 0F0H, which is the delimeter for the last entry in a directory sector. If A < 0F0H, the CARRY FLAG will be set.
4ECB
If the C FLAG (Carry) has been set, then we are not yet at the end of the sector, so JUMP back to 4E6AH to process the next filename.
If we are here, then we have exhausted all filenames in the current sector, and need to move to the next sector of the directory.
4ECD
LD A,(S10SEC)
Fetch the sector number of the directory which we just worked on from memory location 4EEEH.
4ED0
CP 13H
Compare the value held in Register A against 13H (Decimal: 19) to see if we have run out of sectors. If the sector we are on (held in Register A) < 19 sectors, the CARRY FLAG will be set.
4ED2
If the C FLAG (Carry) has been set then we have not yet hit sector 19, so loop back to 4E4BH to get the next directory sector.
4ED5
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
4ED7
JUMP to 0033H.
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.
4EDAH – BYTE STORAGE.
“DRIVE”
4EDA
DEFB 00H
Storage byte for the DRIVE NUMBER being worked on.
“TRK”
4EDB
DEFB 00H
Storage byte for the DIRECTORY TRACK of the disk in the DRIVE.
“DRVMSG”
4EDC
DEFM ‘DRIVE :’
“SAVE3”
4EEC
DEFW 0000H
Location of the current pointer in the Directory Buffer in RAM
“S10SEC”
4EEE
DEFB 00H
The sector number in the directory being worked on.
“NUM”
4EEF
DEFB 00H
Number of filenames which have already appeared on screen on the current line.
4EF0H – Process an Error.
LD A,E
Copy the error code (held in Register E) into Register A.
4EF1
CP 8BH
Compare the value held in Register A against 8BH (Decimal: 139), which is the highest possible error code. If A >= 8BH, the NO CARRY FLAG will be set.
4EF3
If the requested error code is higher than the highest possible error code then the NC FLAG (No Carry) will have been set, JUMP to 4EFDH to handle an UNPRINTABLE ERROR.
4EF5
CP 63H
Compare the value held in Register A against 63H (Decimal: 99), which is the start of the DISK ERRORs. If A >= 63H, the NO CARRY FLAG will be set.
4EF7
If the requested error code is equal to or higher than 63H, then we have a disk error, so JUMP to 4EFFH.
4EF9
CP 2FH
Compare the value held in Register A against 2FH (Decimal: 47). If A < 2FH, the CARRY FLAG will be set.
4EFB
If the C FLAG (Carry) has been set, JUMP to 4F01H.
If we pass through, then we wind up at the UNPRINTABLE ERROR jump point. How clever!
LD A,5AH
As a jump point, this processes an UNPRINTABLE ERROR. Let Register A equal 5AH (Decimal: 90) to set up to force an UNPRINTABLE ERROR after all the math that’s coming up.
SUB 34H
As a jump point, this processes disk errors. SUBtract the value 34H (Decimal: 52) from Register A. If passed through, then A now equals 5AH-34H=26H (Decimal 38). If jumped, A is between 63H-34H=2F (Decimal 47) and 8AH-34H=56H (Decimal 86).
RRCA
As a jump point, this is for errors 2EH (46 decimal) and below. Rotate the bits in A right, with Bit 0 being copied to both the CARRY FLAG and Bit 7. If passed from START 1, then 00100110 rotated to 00010011 (13H / 19).
4F02
INC A
INCrement the adjusted error code (stored in Register A) by 1. If this was from START 1, then A now is 20, meaning the 20th error. This is, in fact, 505AH which is UNPRINTABLE ERROR.
4F03
LD B,A
Copy the contents of Register A into Register B.
4F04
LD HL,ERRSTR
Let Register Pair HL equal 4F11H to point to the ERROR MESSAGE TABLE.
At this point, Register B is holding the number of error messages we need to skip before we get to the one we want.
LD A,(HL)
Fetch a character from the error message table (the memory location pointed to by Register Pair HL) and store it into Register A.
4F08
INC HL
Point the to next character in the error message table by INCrementing the value stored in Register Pair HL by 1.
OR A
Set FLAGS based on the contents of Register A.
4F0A
If we have no 0, then we have not yet reached the end of the error message, so LOOP back to START4.
We fall through to here when an entire error message has been read and its time to move to the next one.
4F0C
LOOP back to 4F07H, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.
4F0E
JUMP to the error handler at 1A01H.
4F11H – ERROR MESSAGE STORAGE AREA.
“ERRSTR”
4F11
DEFB 00H
Delimeter
4F12
DEFM ‘NEXT without FOR’
4F30
DEFM ‘RETURN without GOSUB’
4F51
DEFM ‘Illegal function call’
4F7E
DEFM ‘Undefined line number’
4F94
DEFM ‘Subscript out of range’
4FAB
DEFM ‘Redimensioned array’
4FBF
DEFM ‘Division by zero’
4FD0
DEFM ‘Illegal direct’
4FED
DEFM ‘Out of string space’
5001
DEFM ‘String too long’
5011
DEFM ‘String formula too complex’
502C
DEFM ‘Can’t Continue’
5045
DEFM ‘RESUME without error’
505A
DEFM ‘Unprintable error’
506C
DEFM ‘Missing operand’
508A
DEFM ‘Disk Basic Feature’
509D
DEFM ‘Undefined User Function’
50B5
DEFM ‘FIELD overflow’
50C4
DEFM ‘Internal error’
50D3
DEFM ‘Bad field number’
50E3
DEFM ‘File not found’
5100
DEFM ‘File already open’
5114
DEFM ‘Disk I/O error’
5123
DEFM ‘File already exists’
5145
DEFM ‘Input past end’
5154
DEFM ‘Bad record number’
5182
DEFM ‘Direct statement in file’
519B
DEFM ‘Too many files’
51AA
DEFM ‘Disk write protected’
51BF
DEFM ‘File access DENIED’