TRS-80 DOS - TRSDOS v1.3 - SYS14/SYS Disassembled

General:

SYS14/SYS handles the FILE POINTER ($FILPTR) and RAM DIRECTORY ($RAMDIR) functions — the two TRSDOS 1.3 supervisor calls used by an application to query directory data without having to read raw disk records itself. The overlay is loaded into the SYSLOW overlay area at 4E00H by the supervisor when either SVC is dispatched.

On entry the upper nibble of Register A selects the function: VECT00 (80H) returns the open file's drive number and logical file number for the DCB pointed to by DE; VECT10 (90H) uses Register C as a switch (00H = whole directory, 01H–60H = a specific record, FFH = used/free space totals), Register B as the drive number, and Register Pair HL as a pointer to the user's RAM buffer. Each VECT10 call writes one or more 22-byte file records to the buffer (filename/ext:D 0–14, attribute byte 15, EOF byte 16, LRL byte 17, end-record-number 18–19, granules-allocated 20–21) and terminates the entire list with a “++” sentinel.

Memory Map

Address RangeLabelContents
4E00HSTARTFunction dispatch — masks A to its upper nibble and routes to VECT00 (FILPTR) or VECT10 (RAMDIR).
4E0AH–4E25HGETLFNVECT00 handler — returns drive number and LFN from a DCB.
4E26H–4E5BHGETDIRVECT10 entry — validates the drive, decodes the C-register switch, and dispatches to DIRALL, GETFRE, or SETIT.
4E5CH–4E9FHDIRALL“Whole directory” branch — reads HIT, then loops through 80 LFNs invoking SETIT for each.
4EA0H–4EE2HGETFRE“Free-space” branch — reads GAT, walks 40 tracks of allocation bytes, writes used and free granule counts to the user buffer.
4EE3H–4F9BHSETITPer-file worker — reads a directory entry, formats name/ext:D + attribute + EOF + LRL + ERN + grans into 22 buffer bytes, and updates the buffer pointer.
4F9CH–4FACHCLEARSYSTEM-file blocker — zeros BUFF1 and returns 19H (FILE ACCESS DENIED).
4FADH–4FB4HRAMM…RECCNTLocal workspace (DEFS storage) for the overlay's five self-modifying variables.
4300HBUFF1SYS0-resident 256-byte disk buffer (sector 1) used for HIT/directory record reads.
4D00HBUFF2SYS0-resident 256-byte disk buffer (sector 2) used for HIT copy and GAT reads.

Variables (self-modifying workspace)

AddressLabelSizeDescription
4FADHRAMM2USER'S RAM POINTER — current write position in the caller-supplied buffer; advanced as records are formatted.
4FAFHDDRV1USER SUPPLIED DRIVE NUMBER — saved at routine entry and reused by SETIT/DIRALL/GETFRE.
4FB0HDDIR2INTERNAL DIRECTORY POINTER — pointer to the front of the directory entry returned by RDDIR.
4FB2HHITPTR2HIT TABLE POINTER — walking pointer through the 80-entry HIT during a whole-directory pass.
4FB4HRECCNT1INTERNAL RECORD COUNTER — down-counter from MAXFIL (80) for the DIRAL1 loop.

Per project convention these self-modifying variables live inside the SYS14 overlay code space and are not added to the global RAM-addresses JSON — they are overwritten the moment any other SYSLOW overlay (SYS1–SYS5, SYS10) loads.

Major Routines

AddressLabelFunction / Entry-Exit
4E00HSTARTEntry point. Masks A to its upper nibble and dispatches to VECT00 or VECT10. Exits with NZ if the function code isn't supported.
4E0AHGETLFNFILPTR. Entry: DE ⇒ DCB. Exit: B = drive number, C = LFN, Z if good or A = error code (26H = file not open) and NZ.
4E20HLFNER1FILPTR error tail — sets A to EFNYO (26H, FILE NOT OPEN).
4E22HLFNEXTFILPTR common exit — restores IX and returns.
4E26HGETDIRRAMDIR entry. Validates B against MAXDRV and dispatches on C: 0 ⇒ DIRALL, FFH (negative) ⇒ GETFRE, otherwise per-file via SETIT.
4E4DHDIRER1RAMDIR error — sets A to EDNS (02H, DRIVE NOT IN SYSTEM).
4E51HDIRER2RAMDIR error — sets A to EFAD (19H, FILE ACCESS DENIED). Unreachable in this build but reserved for future use; defined in the source for completeness.
4E55HDIRER3RAMDIR error — sets A to ELFN (10H, ILLEGAL FILE NUMBER).
4E57HDIREXTRAMDIR common exit — sets flags from A, pops HL/DE/BC, and returns.
4E5CHDIRALLWhole-directory branch — reads HIT into BUFF2 and loops MAXFIL (80) times calling SETIT.
4E7AHDIRAL1Top of the DIRALL loop — fetches the next HIT byte and decides whether to call SETIT.
4E8CHNXTFILDIRALL inner increment — advances HITPTR and decrements RECCNT.
4EA0HGETFREFree-space branch — reads the GAT, walks 40 tracks × 6 grans per track, writes 4 bytes (used LSB/MSB then free LSB/MSB) to the user buffer.
4EB9HGETFR1Top of the GETFRE outer (per-track) loop.
4EBEHGETFR2Top of the GETFRE inner (per-gran) loop — RRA tests one allocation bit at a time, accumulating used into HL and free into IY.
4EE3HSETITFormat-one-entry worker. Entry: B = LFN. Calls RDDIR, rejects SYSTEM files via CLEAR, builds NAME/EXT:D into the user buffer, then attribute, EOF, LRL, ERN low, ERN high, plus a 16-bit total-grans value derived by walking the 13 extents.
4F04HSETIT0Inner LDI loop copying up to 8 filename bytes until a SPACE is hit.
4F0EHSETIT2Extension processing entry — if extension non-blank, emits the “/” separator.
4F21HSETIT3Inner LDI loop copying up to 3 extension bytes.
4F2BHSETIT4Drive-specifier emit — “:D” (colon plus ASCII drive digit).
4F41HSETIT5Pads remaining unused name/ext:D slots with SPACE.
4F76HSETIT6Top of the extent-summing loop (13 iterations) — walks the directory entry's extent list adding each per-extent gran count to HL.
4F8AHSETIT7Extent-summing exit — stores total grans (DE) into the user buffer, writes the “+” delimiter, advances RAMM.
4F9CHCLEARSYSTEM-file rejector — zeros BUFF1 (256 bytes), sets A = EFAD (19H), and returns NZ.

DCB / Directory-Entry Field Reference

SYS14 reaches into the system DCB and the directory-entry buffer through IX-indexed loads. The relevant offsets, taken from SYS0.GBL:

OffsetLabelUsed by
IX+00HTYPE / DATTRBGETLFN reads it as TYPE (open-file flag); SETIT reads it as DATTRB (attribute byte) once IX has been pointed at the directory entry.
IX+03HDEOFSETIT — EOF byte (last-record byte count).
IX+04HDLRLSETIT — logical record length.
IX+05HDNAMEOffset to filename inside the directory entry (used as a 16-bit immediate, not an IX+d operand).
IX+06HDRVNUMGETLFN — drive number from the DCB.
IX+07HLFNGETLFN — logical file number from the DCB.
IX+0DHDEXTOffset to extension inside the directory entry.
IX+14HDERNSETIT — end-record-number low byte (DERN+1 is the high byte).
IX+16HDSEGOffset to extent area inside the directory entry.

Function-Code Dispatch

The opening AND/CP sequence at START decodes the upper nibble of the SVC byte:

MaskEquateBranch
90HVECT10JP Z,GETDIR (4E26H) — RAMDIR.
80HVECT00Falls through to GETLFN (4E0AH) — FILPTR.
otherRET NZ — unsupported.

Disassembly:

 
ORG 4E00H
4E00START
AND 0F0H
MASK off the SYSTEM NUMBER from the byte passed to this OVERLAY by masking against F0H (1111 0000). This has the effect of turning off bits 3, 2, 1, 0, leaving only bits 7, 6, 5, 4 active.
Original Source Code Comment: MASK OFF ALL BUT FUNCTION NUMBER
4E02
CP 90HCP VECT10
Compare the remainder of Register A against 90H, which would be the RAMDIR function call. If the masked value is 90H, then ...
Original Source Code Comment: GET FULL DIRECTORY?
4E04
... JUMP to 4E26H.
Original Source Code Comment: YES, DO IT
4E07
CP 080HCP VECT00
Compare the remainder of Register A against 80H, which would be the FILPTR function call. If the masked value is NOT 80H then we didn't get a valid parameter ...
Original Source Code Comment: GET DRIVE & LFN?
4E09
RET NZ
... so return to caller with NZ FLAG set.
Original Source Code Comment: NO, NOTHING SUPPORTED

4E0AH - GETLFN - "FILPTR" Routine - Returns File Pointers to a USER PROGRAM.

4E0AGETLFN
PUSH IX
Save the contents of Special Index Register IX to the top of the stack.
Original Source Code Comment: SAVE IX
4E0C
4E0D
PUSH DE
POP IX
Let Special Index Register IX = DE (which is a DCB).
Original Source Code Comment: MOVE THE DCB POINTER TO IX
4E0F
LD A,(IX+00H)LD A,(IX+TYPE)
Check to see if the file is open by Fetching the value held in the memory location pointed to by Special Index Register Pair IX+00H and store it into Register A.
Note: IX+00H = the position in the DCB for the TYPE of FCB byte. Bit 0: 1=Read Only, Bit 1: 1=Write Only, Bit 4: 1=The next 2 bytes are simply the address of another FCB, Bit 7=1: Then the next 50 bytes are the description of an open file.
Original Source Code Comment: GET THE FILE TYPE
4E12
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).
Original Source Code Comment: FILE OPEN?
4E13
If the PARITY FLAG has been set then the file is NOT open, so exit with an error by JUMPing to 4E20H.
Original Source Code Comment: NO FILE NOT OPEN
4E16
LD B,(IX+06H)LD B,(IX+DRVNUM)
Fetch the DRIVE NUMBER (held in the memory location pointed to by Special Index Register Pair IX+06H) and store it into Register B.
Original Source Code Comment: GET THE DRIVE NUMBER INTO (B)
4E19
LD C,(IX+07H)LD C,(IX+LFN)
Fetch the LOGICAL FILE NUMBER [the directory entry number] (held in the memory location pointed to by Special Index Register Pair IX+07H) and store it into Register C.
Original Source Code Comment: GET THE FILE NUMBER INTO (C)
4E1C
INC C
INCrement the LOGICAL FILE NUMBER (stored in Register C) by 1.
Original Source Code Comment: CORRECT IT FOR GEORGE
4E1D
XOR A
Clear all Flags.
Original Source Code Comment: SET 'Z'
4E1E
Skip over the next instruction by JUMPing to 4E22H to continue.
Original Source Code Comment: AND EXIT

4E20H - LFNER1 - "FILPTR" Routine - All done!.

4E20LFNER1
LD A,26HLD A,EFNYO
Let Register A equal 26H to return an error for "FILE NOT OPEN".
Original Source Code Comment: FILE NOT OPEN
4E22LFNEXT
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).
Original Source Code Comment: SET Z/NZ
4E23
POP IX
Restore Special Register Pair IX from the top of the stack, and then remove the entry from the stack.
Original Source Code Comment: GET IX BACK
4E25
RET
RETurn to the caller, either with 00H set, or a "FILE NOT OPEN" error.
Original Source Code Comment: DONE

4E26H - GETDIR - "RAMDIR" Routine - Process the Disk Directory in RAM.

On entry: B = Drive Number, HL = RAM Storage Buffer, and C = a switch to denote what is being processed. 0=All unprotected directory records, 1-96=A specific directory record, FF=Used and Free Space only.

On exit: HL = RAM Storage Buffer. Z FLAG indicates GOOD DIRECTORY READ IN RAM

The buffer is structured: Bytes 0-14=Filename, 15=Attrib, 16=EOF Byte, 17=LRL Byte, 18-19=End Record Number, 20-21=Number of grans allocated.

4E26GETDIR
PUSH BC
Save the contents of Register Pair BC (i.e., the drive number and the user selected routine switch) to the top of the stack.
4E27
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
4E28
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
4E29
LD (4FADH),HLLD (RAMM),HL
Store the RAM STORAGE BUFFER POINTER (held in Register Pair HL) into memory location 4FADH.
Original Source Code Comment: SAVE THE RAM POINTER

A "++" is put at the end of the buffer to signify the end of the buffer, just in case there are no entries to be found.

4E2C
LD (HL),2BHLD (HL),'+'
Store a 2BH (ASCII: +) into the memory location pointed to by Register Pair HL.
Original Source Code Comment: SET END IN CASE NO FILES
4E2E
INC HL
INCrement the RAM STORAGE BUFFER POINTER (held in Register Pair HL) by 1.
4E2F
LD (HL),2BHLD (HL),'+'
Store a 2BH (ASCII: +) into the memory location pointed to by Register Pair HL.

Next we save the drive number and test it.

4E31
LD A,B
Copy the DRIVE NUMBER (held in Register B) into Register A.
Original Source Code Comment: GET THE DRIVE NUMBER
4E32
LD (4FAFH),ALD (DDRV),A
Store the DRIVE NUMBER (Register A) into memory location 4FAFH.
Original Source Code Comment: SAVE IT
4E35
LD A,(4413H)LD A,(MAXDRV)
Fetch the value held in memory location 4413H and store it into Register A.
NOTE: 4413H is the storage location for the NUMBER OF DISK DRIVES in the system.
Original Source Code Comment: SEE IF GREATER THAN WHAT'S IN SYSTEM
4E38
CP B
Compare USER PROVIDED DRIVE NUMBER (held in Register B) and the NUMBER OF DISK DRIVES IN THE SYSTEM (traditionally held at 4413H). If the NUMBER OF DISK DRIVES is < the USER PROVIDED DRIVE NUMBER then we have a problem ...
4E39
... so JUMP to DIRER1.
Original Source Code Comment: YES, NO SUCH DRIVE NUMBER

The drive number has been validated, so next let us get the function switch from Register C.

4E3B
LD A,C
Copy the function switch (held in Register C on entry) into Register A.
Original Source Code Comment: GET THE SWITCH
4E3C
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).
Original Source Code Comment: GET ALL?
4E3D
If the FUNCTION SWITCH was 00H, then the user wants the WHOLE DIRECTORY, so JUMP to 4E5CH.
Original Source Code Comment: YES, DO ALL
4E3F
If the SIGN FLAG has been SET (meaning that Register C was FFH), then the user wants the FREE INFO, so JUMP to 4EA0H.
Original Source Code Comment: RETURN USED/FREE SPACE
4E42
DEC A
If neither of those flags were set then the user wants the DIRECTORY ENTRY and supplied the record number they want. First DECrement the USER REQUESTED LOGICAL FILE NUMBER (stored in Register A) by 1.
Original Source Code Comment: CORRECT FOR 1'S OFFSET
4E43
CP 51HCP MAXFIL+1
Compare the USER REQUESTED LOGICAL FILE NUMBER (stored in Register A) against 51H (Decimal: 81). If the LOGICAL FILE NUMBER >= 81, then we have an invalid LOGICAL FILE NUMBER (because 80 is the highest), so ...
Original Source Code Comment: LEGAL FILE NUMBER?
4E45
... JUMP to 4E55H.
Original Source Code Comment: NO, EXIT
4E47
LD B,A
The USER REQUESTED LOGICAL FILE NUMBER is valid, so store it in Register B.
Original Source Code Comment: PUT THE LFN INTO B
4E48
Fetch the DIRECTORY ENTRY for the USER REQUESTED LOGICAL FILE NUMBER (held in Register B) via a GOSUB to 4EE3H.
Original Source Code Comment: PUT IT INTO MEMORY
4E4B
EXIT via a JUMP to 4E57H.
Original Source Code Comment: AND EXIT

4E4DH - DIRER1 - Exit with a "DISK DRIVE NOT ON" Error.

4E4DDIRER1
LD A,02HLD A,EDNS
Let Register A equal 02H for a "DISK DRIVE NOT ON" error.
Original Source Code Comment: DRIVE NOT IN SYSTEM
4E4F
Display the error and exit via a JUMP to 4E57H.

4E51H - DIRER2 - Exit with a "FILE ACCESS DENIED" Error.

4E51DIRER2
LD A,19HLD A,EFAD
Let Register A equal 19H for a "FILE ACCESS DENIED" error.
Original Source Code Comment: FILE ACCESS DENIED
4E53
Display the error and exit via a JUMP to 4E57H.

4E55H - DIRER3 - Exit with a "BAD FILE NUMBER" Error.

4E55DIRER3
LD A,10HLD A,ELFN
Let Register A equal 10H for a "BAD FILE NUMBER" error..
Original Source Code Comment: ILLEGAL FILE NUMBER
4E57DIREXT
OR A
Set the flags based on the error (so NZ FLAG should be enabled).
Original Source Code Comment: SET Z/NZ
4E58
POP HL
Put the value held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
4E59
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.
4E5A
POP BC
Put the value held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
4E5B
RET
RETurn to the caller.

4E5CH - DIRALL - "RAMDIR" Routine - "Whole Directory" option was selected by the user.

4E5CDIRALL
LD A,(4FAFH)LD A,(DDRV)
Fetch the DRIVE NUMBER (held in memory location 4FAFH) and store it into Register A.
Original Source Code Comment: GET THE DRIVE NUMBER
4E5F
LD C,A
Copy the DRIVE NUMBER into Register C.
Original Source Code Comment: INTO C
4E60
GOSUB to 4ABAH.
NOTE: 4ABAH is the SYS00/SYS routine to read the HIT sector into RAM.
Original Source Code Comment: READ IN THE HASH TABLE
4E63
If that call resulted in an error then the NZ FLAG (Not Zero) will have been set. JUMP to 4E57H.
Original Source Code Comment: EXIT IF ERROR
4E66
LD HL,4300HLD HL,BUFF1
Let Register Pair HL equal 4300H, which is a memory buffer where the HIT contents are stored following a GOSUB to 4ABAH.
Original Source Code Comment: WHERE THE HIT IS
4E69
LD DE,4D00HLD DE,BUFF2
Let Register Pair DE equal 4D00H.
NOTE: 4D00H is a memory buffer (referred to as Memory Buffer 2) where diskette contents are stored in RAM.
Original Source Code Comment: WHERE WE'RE GOING TO PUT IT
4E6C
LD (4FB2H),DELD (HITPTR),DE
Store the START OF BUFFER 2 (held in Register Pair DE) into memory location 4FB2H.
Original Source Code Comment: SAVE THE POINTER
4E70
LD BC,0100HLD BC,SECTOR
Let Register Pair BC equal 0100H (Decimal: 256) to move 256 bytes.
Original Source Code Comment: NUMBER OF BYTES
4E73
LDIR
Copy the HIT sector to the buffer at 4D00H via LDIR which transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
Original Source Code Comment: MOVE IT TO BUFFER 2
4E75
LD A,50HLD A,MAXFIL
Let Register A equal 50H (Decimal: 96) to work through the maximum of 96 HIT entries.
Original Source Code Comment: SET A COUNTER
4E77
LD (4FB4H),ALD (RECCNT),A
Store the HIT ENTRIES STILL TO PROCESS COUNTER (held in Register A) into memory location 4FB4H.

Start of a loop to process 96 HIT entries.

4E7ADIRAL1
LD HL,(4FB2H)LD HL,(HITPTR)
Fetch the HIT ENTRY stored in the HIT ENTRY POINTER memory location of 4FB2H and store it into Register Pair HL.
Original Source Code Comment: GET THE HIT TABLE POINTER
4E7D
LD A,(HL)
Fetch the actual HIT ENTRY (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: ANY FILE HERE?
4E7E
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).
4E7F
If the Z FLAG (Zero) has been set then the HIT ENTRY pointed to by HL is empty, so move to the next HIT ENTRY by JUMPing to 4E8CH.
Original Source Code Comment: NO, TRY NEXT ONE
4E81
LD B,L
Copy the LOGICAL FILE NUMBER (held in Register L) into Register B.
Original Source Code Comment: SET IT AS THE LFN COUNTER
4E82
Get the directory entry of the LOGICAL FILE NUMBER held in Register B via a GOSUB to 4EE3H.
Original Source Code Comment: SET IT TO USER RAM
4E85
If the Z FLAG (Zero) has been set then the CALL resulted in success, so continue via a JUMP to 4E8CH.
Original Source Code Comment: GOOD READ. CONTINUE
4E87
CP 19HCP EFAD
Compare the drive response code (held in Register A) against 19H (Error: "FILE ACCESS DENIED"). If it was not for a "FILE ACCESS DENIED" error ...
Original Source Code Comment: FILE ACCESS DENIED?
4E89
.... JUMP to 4E57H.
Original Source Code Comment: NO, SOME OTHER ERROR. EXIT
4E8CNXTFIL
LD HL,(4FB2H)LD HL,(HITPTR)
Fetch the POINTER TO THE ENTRY TO PROCESS stored in the HIT ENTRY POINTER memory location of 4FB2H and store it into Register Pair HL.
Original Source Code Comment: GET THE POINTER
4E8F
INC HL
Move to the next HIT ENTRY by INCrementing the HIT ENTRY POINTER (stored in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT RECORD
4E90
LD (4FB2H),HLLD (HITPTR),HL
Store HIT ENTRY POINTER (held in Register Pair HL) into the HIT ENTRY TRACKING memory location of 4FB2H.
Original Source Code Comment: SAVE IT
4E93
LD A,(4FB4H)LD A,(RECCNT)
Fetch the HIT ENTRIES STILL TO PROCESS from the HIT ENTRIES STILL TO PROCESS COUNTER (held in memory location 4FB4H) and store it into Register A.
Original Source Code Comment: GET NUMBER OF RECORDS TO DO
4E96
DEC A
DECrement the HIT ENTRIES STILL TO PROCESS COUNTER by 1.
Original Source Code Comment: DEC FOR THIS ONE
4E97
LD (4FB4H),ALD (RECCNT),A
Store the new HIT ENTRIES STILL TO PROCESS COUNTER (held in Register A) into memory location 4FB4H.
Original Source Code Comment: SAVE IT
4E9A
If the NZ FLAG (Not Zero) has been set then there are still HIT ENTRIES TO PROCESS, so LOOP BACK to 4E7AH.
Original Source Code Comment: LOOP IF NOT DONE

End of the loop to process 96 HIT entries.

4E9C
XOR A
If we are here then all 96 HIT entries were processed. Set Register A to ZERO to indicate NO ERROR and clear all Flags.
Original Source Code Comment: SET 'Z'
4E9D
Exit via a JUMP to 4E57H.
Original Source Code Comment: EXIT. ALL DONE

4EA0H - GETFRE - "RAMDIR" Routine - "FREE INFO" option was selected by the user.

4EA0GETFRE
LD A,(4FAFH)LD A,(DDRV)
Fetch the DRIVE NUMBER (held in memory location 4FAFH) and store it into Register A.
Original Source Code Comment: GET THE DRIVE NUMBER
4EA3
LD C,A
Copy the DRIVE NUMBER into Register C.
Original Source Code Comment: INTO C
4EA4
GOSUB to 4A93H.
NOTE: 4A93H is the SYS00/SYS routine to READ THE GAT sector into RAM (Buffer at 4D00H).
Original Source Code Comment: READ IN THE GAT
4EA7
If that call resulted in an error then the NZ FLAG (Not Zero) will have been set. JUMP to 4E57H.
4EAA
LD IX,4D00HLD IX,BUFF2
Let Special Index Register IX equal 4D00H, which is the start of the RAM BUFFER where the GAT ENTRY was stored from the CALL to 4A93H.
Original Source Code Comment: WHERE THE GAT IS
4EAE
LD IY,0000HLD IY,0
Let Special Index Register Pair IY equal 0000H to act as the UNUSED TOTAL COUNTER. It will be tracking the FREE SPACE.
Original Source Code Comment: CLEAR A TOTAL COUNTER
4EB2
LD HL,0000HLD HL,0
Let Register Pair HL equal 0000H to act as the USED TOTAL COUNTER. It will be tracking the USED SPACE.
Original Source Code Comment: CLEAR A USED COUNTER
4EB5
LD D,H
Set Register D = 0 (since H is 00H).
Original Source Code Comment: CLEAR DE ALSO
4EB6
LD E,H
Set Register E = 0 (since H is 00H).
4EB7
LD C,28HLD C,MAXTRK
Let Register C equal 28H (Decimal: 40), as the highest track to scan.
Original Source Code Comment: NUMBER OF TRACK PER DISK

Top of Loop of 40 Tracks.

4EB9GETFR1
LD A,(IX+00H)LD A,(IX)
Fetch the ALLOCATION BYTE of the GAT (which is the first byte of the GAT) held in the memory location pointed to by Special Index Register Pair IX+00H and store it into Register A.
Note: IX+00H = the position in the DCB for the TYPE of FCB byte. Bit 0: 1=Read Only, Bit 1: 1=Write Only, Bit 4: 1=The next 2 bytes are simply the address of another FCB, Bit 7=1: Then the next 50 bytes are the description of an open file.
Original Source Code Comment: GET AN ALLOCATION BYTE
4EBC
LD B,06HLD B,NGRAN
Let Register B equal 06H since there are 6 grans per track.
Original Source Code Comment: NUMBER OF GRANS PER TRACK

Top of a DJNZ Loop to run through 6 grans in the track (18 sectors in a track / 3 Sectors Per Gran = 6 Grans per track)

4EBEGETFR2
RRA
Rotate the contents of A right one bit position, with BIT 0 being copied to the CARRY FLAG and to BIT 7.
4EBF
PUSH AF
Save the CARRY FLAG to the top of the stack.
Original Source Code Comment: SAVE THE CARRY FLAG
4EC0
ADC HL,DE
If that BIT is 1, then add 1 to the USED COUNTER (held in Register Pair HL).
Original Source Code Comment: ADD TO USED COUNTER
4EC2
POP AF
Put the value held at the top of the STACK into Register Pair AF, and then remove the entry from the stack.
Original Source Code Comment: GET THE CARRY FLAG BACK
4EC3
CCF
Invert the gran status (which is being held in the CARRY).
4EC4
RL E
Rotate Left Register E, so that Register Pair DE now holds the number of free grans.
4EC6
ADD IY,DE
LET Register Pair IY = the cumulative UNUSED grans so far (IY) + the additional free grans (DE).
4EC8
LD E,00H
Let Register E equal 00H.
4ECA
LOOP back through all grans by jumping to 4EBEH, 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.
Original Source Code Comment: LOOP FOR ALL GRANS

End of DJNZ Loop

4ECC
INC IX
Bump IX to point to the next byte (i.e. track) in the GAT.
Original Source Code Comment: BUMP TO NEXT ALLOCATION BYTE
4ECE
DEC C
DECrement the track counter (stored in Register C) by 1.
Original Source Code Comment: DEC THE TRACK COUNT
4ECF
If the NZ FLAG (Not Zero) has been set then there are still tracks to analyze, so LOOP BACK to 4EB9H.
Original Source Code Comment: GO GET ANOTHER TRACK

End of Loop of 40 Tracks.

4ED1
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the TOTAL USED GRANS) with the value stored in Register Pair DE.
Original Source Code Comment: DE = USED GRANS
4ED2
4ED4
PUSH IY
POP BC
Let BC = IY (i.e., UNUSED GRAN COUNTER).
4ED5
LD HL,(4FADH)LD HL,(RAMM)
Fetch the BUFFER POINTER (held in memory location 4FADH) and store it into Register Pair HL.
Original Source Code Comment: USER'S SPECIFIED AREA
4ED8
LD (HL),E
Store the LSB of the amount of TOTAL USED GRANS (held in Register E) into the memory location pointed to by Register Pair HL.
Original Source Code Comment: SET USED GRANS
4ED9
INC HL
INCrement the BUFFER POINTER (stored in Register Pair HL) by 1.
4EDA
LD (HL),D
Store the MSB of the amount of TOTAL USED GRANS (held in Register D) into the memory location pointed to by Register Pair HL.
4EDB
INC HL
INCrement the BUFFER POINTER (stored in Register Pair HL) by 1.
4EDC
LD (HL),C
Store the LSB of the amount of TOTAL UNUSED GRANS (held in Register C) into the memory location pointed to by Register Pair HL.
Original Source Code Comment: SET REMAINING GRANS
4EDD
INC HL
INCrement the BUFFER POINTER (stored in Register Pair HL) by 1.
4EDE
LD (HL),B
Store the MSB of the amount of TOTAL UNUSED GRANS (held in Register B) into the memory location pointed to by Register Pair HL.
4EDF
XOR A
Indicate success by setting Register A to ZERO and clear all Flags.
Original Source Code Comment: CLEAR A
4EE0
Exit via a JUMP to 4E57H.
Original Source Code Comment: AND EXIT

4EE3H - SETIT - "RAMDIR" Routine - Subroutine to fetch the DIRECTORY ENTRY at the LOGICAL FILE NUMBER held in Register B.

4EE3SETIT
LD A,(4FAFH)LD A,(DDRV)
Fetch the DRIVE NUMBER (held in memory location 4FAFH) and store it into Register A.
Original Source Code Comment: GET THE DRIVE NUMBER
4EE6
LD C,A
Copy the DRIVE NUMBER into Register C.
Original Source Code Comment: INTO C
4EE7
GOSUB to 4A67H.
NOTE: 4A67H is the SYS00/SYS routine to read the directory entry into RAM (Buffer at 4300H)
Original Source Code Comment: GET POINTER TO THE FILE
4EEA
RET NZ
If the NZ FLAG (Not Zero) has been set then that CALL returned with an error, so RETurn to the caller.
Original Source Code Comment: EXIT IF DISK ERROR
4EEB
BIT 6,(HL)BIT SYSTEM,(HL)
Check for a SYSTEM FILE by testing Bit Number 6 of Register HL. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
Original Source Code Comment: SYSTEM FILE?
4EED
If the file was a SYSTEM FILE then the NZ FLAG (Not Zero) will have been set. JUMP to 4F9CH to zero out all the buffers and return with "FILE ACCESS DENIED" error.
Original Source Code Comment: YES, CLEAR OUT ENTERY AND SET NZ
4EF0
LD (4FB0H),HLLD (DDIR),HL
Store the POINTER TO THE DIRECTORY ENTRY IN RAM (held in Register Pair HL) into memory location 4FB0H.
Original Source Code Comment: SAVE POINTER TO FRONT OF FILE
4EF3
LD DE,0005HLD DE,DNAME
Since the filename starts 5 bytes into a directory entry, set Register Pair DE equal to 0005H.
Original Source Code Comment: OFFSET TO BEGIN OF NAME
4EF6
ADD HL,DE
Point the POINTER TO THE DIRECTORY ENTRY IN RAM (HL) at the FILENAME by adding 5.
Original Source Code Comment: HL => FRONT OF NAME
4EF7
LD DE,(4FADH)LD DE,(RAMM)
Fetch the pointer to the USER BUFFER (held in memory location 4FADH) and store it into Register Pair DE.
Original Source Code Comment: GET THE RAM POINTER
4EFB
LD BC,0008HLD BC,8
Set Register Pair BC equal to 0008H since there are up to 8 bytes in a filename.
Original Source Code Comment: NUMBER OF BYTES IN NAME
4EFE
LD IX,000EHLD IX,14
Set Special Index Register Pair IX equal 000EH (Decimal: 14) since a filespec can be up to 14 bytes (i.e., NNNNNNNN/EEE:D).
Original Source Code Comment: TOTAL NUMBER OF BYTES IN NAME/EXT:D + 1 SPACE
4F02
LD A,20HLD A,' '
Let Register A equal 20H (ASCII: SPACE).
Original Source Code Comment: SPACE

Top of a loop.

4F04SETIT0
CP (HL)
Compare a SPACE (held in Register A) against the character at the memory location pointed to by the POINTER TO THE DIRECTORY ENTRY IN RAM (Register Pair HL). If it's a SPACE ....
Original Source Code Comment: SPACE?
4F05
... exit this loop via a JUMP to 4F0EH.
Original Source Code Comment: YES, EXIT
4F07
DEC IX
DECrement the amount of characters left in the filespec (tracked in Special Index Register IX) by 1.
Original Source Code Comment: DEC THE COUNTER
4F09
LDI
Move to the 2nd character of both HL and DE via LDI command; which copies BC number of characters from (HL) to (DE), dropping BC each time. When BC hits 0, the PE flag is reset.
Original Source Code Comment: NO, MOVE A BYTE
4F0B
If the PARITY/OVERFLOW FLAG has been SET then we are not yet done processing characters, so LOOP BACK to 4F04H.
Original Source Code Comment: LOOP TILL DONE

Bottom of a loop.

4F0ESETIT2
LD HL,(4FB0H)LD HL,(DDIR)
Fetch the POINTER TO THE DIRECTORY ENTRY IN RAM (held in memory location 4FB0H) and store it into Register Pair HL.
Original Source Code Comment: PICK UP THE BEGIN OF DIRECTORY
4F11
LD BC,000DHLD BC,DEXT
Let Register Pair BC equal 000DH (Decimal: 13), which will be an offset to HL to get to the filename extension.
Original Source Code Comment: OFFSET TO EXTENSION
4F14
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC, so that HL now points to the extension.
Original Source Code Comment: HL => DIRECTORY EXTENSION
4F15
LD BC,0003HLD BC,3
Since an extension is maximum 3 characters, set Register Pair BC equal 0003H.
Original Source Code Comment: NUMBER OF BYTES IN EXT
4F18
CP (HL)
Compare the value held in Register A (which should be a SPACE) against the FIRST CHARACTER OF THE EXTENSION (held in the memory location pointed to by the value held in Register Pair HL). Results: If Register A equals the value held in Register HL, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: ANY EXTENSION?
4F19
If the Z FLAG (Zero) has been set, then we hit a space and there is no extension, so stop processing extension characters via a JUMP to 4F2BH.
Original Source Code Comment: NO, CONTINUE
4F1B
PUSH AF
If we're here then we know we have at least 1 character of an extension, so save the SPACE (held in Register A) to the top of the stack.
Original Source Code Comment: SAVE THE SPACE
4F1C
LD A,2FHLD A,'/'
Let Register A equal 2FH (ASCII: /).
Original Source Code Comment: SET EXTENSION SPECIFIER
4F1E
LD (DE),A
Store a / into the memory location pointed to by Register Pair DE.
Original Source Code Comment: INTO USER'S RAM
4F1F
INC DE
Since we just filled a character, move the pointer by INCrementing the value stored in Register Pair DE by 1.
Original Source Code Comment: BUMP TO NEXT SLOT
4F20
POP AF
Restore the SPACE from the top of the stack into Register A.

Top of a loop to process the 2nd and 3rd characters of the filename extension, if any.

4F21SETIT3
CP (HL)
Compare the value held in the memory location pointed to by the value held in Register Pair HL against a SPACE. If the byte is a SPACE ...
Original Source Code Comment: SPACE?
4F22
... JUMP to 4F2BH.
Original Source Code Comment: YES, EXIT
4F24
DEC IX
DECrement the amount of space left in the filespec (tracked in Special Index Register IX) by 1.
Original Source Code Comment: DEC THE COUNTER
4F26
LDI
Move to the 2nd character of both HL and DE via LDI command; which copies BC number of characters from (HL) to (DE), dropping BC each time. When BC hits 0, the PE flag is reset.
Original Source Code Comment: TRANSFER A BYTE
4F28
If the PARITY/OVERFLOW FLAG has been SET then there are more characters to test, so LOOP BACK to 4F21H.
Original Source Code Comment: LOOP FOR COUNT

Bottom of the loop to process the 2nd and 3rd characters of the filename extension, if any.

4F2BSETIT4
LD A,3AHLD A,':'
So now the filename, the "/" (if necessary), and the extension (if any) have been placed into RAM (tracked by DE). Move to the DRIVE NUMBER next. Let Register A equal 3AH (ASCII: :).
Original Source Code Comment: DRIVE SPECIFIER
4F2D
LD (DE),A
Store the : into the LOCATION IN THE USER BUFFER pointed to by Register Pair DE.
Original Source Code Comment: INTO USER RAM
4F2E
INC DE
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair DE) by 1 to point after the :
Original Source Code Comment: BUMP TO NEXT SLOT
4F2F
LD A,(4FAFH)LD A,(DDRV)
Fetch the DRIVE NUMBER (held in memory location 4FAFH) and store it into Register A.
Original Source Code Comment: GET THE DRIVE NUMBER
4F32
AND 07HAND 7
MASK the value of Register A against 07H (0000 0111) to leave only 2, 1, 0 active.
Original Source Code Comment: FORCE TO BINARY
4F34
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.
Original Source Code Comment: MAKE IT ASCII
4F36
LD (DE),A
Store the DRIVE NUMBER IN ASCII (held in Register A) into the memory location in the LOCATION IN THE USER BUFFER pointed to by Register Pair DE.
Original Source Code Comment: SET THE DRIVE NUMBER
4F37
INC DE
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair DE) by 1 to point after the DRIVE NUMBER IN ASCII.

So now the complete filespec (filename/ext:drive) is in RAM with DE pointing to the drive number. Time to start processing the other information.

4F38
4F3A
DEC IX
DEC IX
DECrement the amount of space left in the filespec (tracked in Special Index Register IX) by 2 as the ":D" has been added.
Original Source Code Comment: FOR THE ':'
4F3C
4F3E
PUSH IX
POP BC
Let Register Pair BC = the amount of space left in the filespec.
Original Source Code Comment: MOVE COUNTER TO BC
4F3F
LD B,C
Prepare for a DJNZ loop by copying the LSB of the amount of space left unfilled in the filespec (held in BC) into Register B.
Original Source Code Comment: PUT THE COUNT INTO B
4F40
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LOCATION IN THE DIRECTORY ENTRY IN RAM) with the value stored in Register Pair DE (i.e., the LOCATION IN THE USER BUFFER).
Original Source Code Comment: USER RAM TO HL

Top of a loop to fill the excess characters in the USER BUFFER with SPACES.

4F41SETIT5
LD (HL),20HLD (HL),' '
Store a : into the USER BUFFER at the memory location pointed to by Register Pair HL.
Original Source Code Comment: PAD REST WITH SPACES
4F43
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F44
LOOP back to 4F41H, 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.
Original Source Code Comment: LOOP FOR COUNT

Bottom of a loop.

4F46
LD IX,(4FB0H)LD IX,(DDIR)
Fetch the RAM POINTER IN THE DIRECTORY ENTRY (held in memory location 4FB0H) and store it into Special Index Register Pair IX.
Original Source Code Comment: GET THE DIRECTORY POINTER
4F4A
LD A,(IX+00H)LD A,(IX+DATTRB)
Fetch the ATTRIBUTE BYTE (held in the memory location pointed to by Special Index Register Pair IX+00H) and store it into Register A.
Original Source Code Comment: GET THE ATTRIB BYTE
4F4D
AND 07HAND 7
MASK the value of Register A against 07H (0000 0111) to keep only the protection/access level bits active.
Original Source Code Comment: MASK OFF STATUS BITS
4F4F
LD (HL),A
Store the protection level (held in Register A) into the USER BUFFER memory location pointed to by Register Pair HL.
Original Source Code Comment: INTO USERS BUFFER
4F50
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F51
LD A,(IX+03H)LD A,(IX+DEOF)
Fetch the EOF BYTE (held in the memory location pointed to by Special Index Register Pair IX+03H) and store it into Register A.
Original Source Code Comment: GET THE EOF BYTE
4F54
LD (HL),A
Store the EOF BYTE into the USER BUFFER memory location pointed to by Register Pair HL.
Original Source Code Comment: INTO USER RAM
4F55
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F56
LD A,(IX+04H)LD A,(IX+DLRL)
Fetch the LOGICAL RECORD LENGTH (held in the memory location pointed to by Special Index Register Pair IX+04H) and store it into Register A.
Original Source Code Comment: GET THE LRL
4F59
LD (HL),A
Store the LOGICAL RECORD LENGTH into the USER BUFFER memory location pointed to by Register Pair HL.
Original Source Code Comment: INTO USER RAM
4F5A
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F5B
LD A,(IX+14H)LD A,(IX+DERN)
Fetch the LSB of the END OF FILE SECTOR NUMBER (held in the memory location pointed to by Special Index Register Pair IX+14H) and store it into Register A.
Original Source Code Comment: GET THE END RECORD NUMBER (LSB)
4F5E
LD (HL),A
Store the LSB of the END OF FILE SECTOR NUMBER into the USER BUFFER memory location pointed to by Register Pair HL.
4F5F
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F60
LD A,(IX+15H)LD A,(IX+DERN+1)
Fetch the MSB of the END OF FILE SECTOR NUMBER (stored in memory location pointed to by Special Index Register Pair IX+15H) and store it into Register A.
Original Source Code Comment: GET THE MSB
4F63
LD (HL),A
Store the LSB of the END OF FILE SECTOR NUMBER into the USER BUFFER memory location pointed to by Register Pair HL.
Original Source Code Comment: INTO USER BUFFER
4F64
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT GUY
4F65
LD (4FADH),HLLD (RAMM),HL
Store the LOCATION IN THE USER BUFFER (held in Register Pair HL) into memory location 4FADH.
Original Source Code Comment: SAVE THE POINTER
4F68
LD IX,(4FB0H)LD IX,(DDIR)
Fetch the RAM POINTER IN THE DIRECTORY ENTRY (held in memory location 4FB0H) and store it into Special Index Register Pair IX.
Original Source Code Comment: GET THE FRONT POINTER AGAIN
4F6C
LD DE,0016HLD DE,DSEG
Let Register Pair DE equal 0016H for a byte offset into the directory entry to point to the file extents.
Original Source Code Comment: OFFSET TO EXTENTS
4F6F
ADD IX,DE
Set Register Pair IX to point to the EXTENTS by letting IX = Register Pair IX + 22 (i.e., Register DE).
Original Source Code Comment: IX => BEGIN OF EXTENTS
4F71
LD B,0DHLD B,MAXEXT
Let Register B equal 0DH (Decimal: 13) to loop through the 13 extents in each directory entry.
Original Source Code Comment: NUMBER OF EXTENTS IN FILE
4F73
LD HL,0000HLD HL,0
Let Register Pair HL equal 0000H to be an accumulator for the number of grans in the extent.
Original Source Code Comment: CLEAR A 16 BIT ACCUMULATOR

Top of a loop to parse all extents and accumulate the number of grans into HL.

4F76SETIT6
INC IX
INCrement IX to point to the next byte in the EXTENTS portion of the directory entry.
Original Source Code Comment: BUMP TO ALLOCATE BYTE
4F78
INC (IX+00H)INC (IX)
Test for a FFH in the current EXTENT by INCrementing the value stored in the memory location pointed to by Special Index Register IX+00H by 1.
Original Source Code Comment: END OF EXTENTS?
4F7B
If the Z FLAG (Zero) has been set, then the EXTENT was FFH (or empty), so JUMP to 4F8AH.
Original Source Code Comment: YES, EXIT
4F7D
LD A,(IX+00H)LD A,(IX)
Fetch a byte of the EXTENT (pointed to by IX+00H) and put it into Register A. THis should be the SIZE byte of the extent.
Original Source Code Comment: PICK UP THE ALLOCATE BYTE
4F80
AND 1FH
MASK the value of Register A against 1FH (0001 1111). This has the effect of turning off bits 7, 6, 5 (i.e., the starting gran), which are not needed for this calculation.
Original Source Code Comment: MASK OFF STARTING GRAN
4F82
4F83
LD E,A
LD D,00H
Let Register Pair DE = the number of grans in the extent (held in Register A).
Original Source Code Comment: INTO DE
4F85
ADD HL,DE
Add the number of grans in the extent (held in Register Pair DE) into the accumulator (held in Register Pair HL).
Original Source Code Comment: ADD TO EXISTING GRANS
4F86
INC IX
Bump Special Index Register IX to the next extent.
Original Source Code Comment: BUMP TO NEXT EXTENT
4F88
LOOP back to 4F76H, 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.
Original Source Code Comment: LOOP FOR COUNT

End of loop to parse all extents and accumulate the number of grans into HL.

4F8ASETIT7
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the total number of grans in the extents) with the value stored in Register Pair DE.
Original Source Code Comment: DE = TOTAL GRANS
4F8B
LD HL,(4FADH)LD HL,(RAMM)
Fetch LOCATION IN THE USER BUFFER (held in memory location 4FADH) and store it into Register Pair HL.
Original Source Code Comment: GET THE USER RAM POINTER
4F8E
LD (HL),E
Store the LSB of the number of grans in the file (held in Register E) into the memory location pointed to by Register Pair HL.
Original Source Code Comment: STORE IT
4F8F
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F90
LD (HL),D
Store the MSB of the number of grans in the file (held in Register D) into the memory location pointed to by Register Pair HL.
4F91
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F92
LD (HL),2BHLD (HL),'+'
Store a + delimiter into the LOCATION IN THE USER BUFFER (stored in Register Pair HL).
Original Source Code Comment: SPECIFY END OF DIR
4F94
LD (4FADH),HLLD (RAMM),HL
Store the LOCATION IN THE USER BUFFER (held in Register Pair HL) into memory location 4FADH.
Original Source Code Comment: SAVE FOR NEXT TIME
4F97
INC HL
INCrement the LOCATION IN THE USER BUFFER (stored in Register Pair HL) by 1.
4F98
LD (HL),2BHLD (HL),'+'
Store a + delimiter into the LOCATION IN THE USER BUFFER (stored in Register Pair HL).
Original Source Code Comment: SET THE SECOND ONE
4F9A
XOR A
Set Register A to ZERO and clear all Flags to show NO ERROR.
Original Source Code Comment: SET Z
4F9B
RET
RETurn to the caller.

4F9CH - CLEAR - Zero out all the buffers and return with "FILE ACCESS DENIED" error.

4F9CCLEAR
LD HL,4300HLD HL,BUFF1
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.
Original Source Code Comment: WHERE THE DIRECTORY RECORD IS
4F9F
LD DE,4301HLD DE,BUFF1 + 1
Let Register Pair DE equal 4301H.
4FA2
LD BC,00FFHLD BC,SECTOR-1
Let Register Pair BC equal 00FFH to clear 256 bytes.
Original Source Code Comment: NUMBER OF BYTES TO CLEAR
4FA5
LD (HL),00H
Zero out the memory location pointed to by Register Pair HL.
Original Source Code Comment: THE CLEAR BYTE
4FA7
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
Original Source Code Comment: CLEAR OUT THE BUFFER
4FA9
LD A,19HLD A,EFAD
Let Register A equal 19H to return a "FILE ACCESS DENIED" error.
Original Source Code Comment: FILE ACCESS DENIED
4FAB
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).
Original Source Code Comment: SET 'NZ'
4FAC
RET
RETurn to the caller.
Original Source Code Comment: EXIT

4FADH - RAMM - BYTE STORAGE AREA.

4FADRAMM
DEFS 2
RAM STORAGE BUFFER POINTER.
Original Source Code Comment: USER'S RAM POINTER
4FAFDDRV
DEFS 1
USER SUPPLIED DRIVE NUMBER.
Original Source Code Comment: USER SUPPLIED DRIVE NUMBER
4FB0DDIR
DEFS 2
INTERNAL DIRECTORY POINTER.
Original Source Code Comment: INTERNAL DIRECTORY POINTER
4FB2HITPTR
DEFS 2
HIT TABLE POINTER.
Original Source Code Comment: HIT TABLE POINTER
4FB4RECCNT
DEFS 1
INTERNAL RECORD COUNTER.
Original Source Code Comment: INTERNAL RECORD COUNTER
 
END 4E00H
That's it!