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


4E00H - Entry Point - Process Routine Selection.

 
ORG 4E00H
4E00 S3ENTY
AND 0F0H
MASK the value of Register A against 0F0H (0000 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: TEST REQUEST VECTOR CODE
4E02
CP 90H
Compare the value held in Register A against 90H, which would be the "CLOSE" function call. Results: If Register A equals 90H, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: TEST REQUEST VECTOR
4E04
If the Z FLAG (Zero) is set, JUMP to 4E0FH.
Original Source Code Comment: DO CLOSE
4E06
CP 0A0H
Compare the value held in Register A against A0H, which would be the "KILL" function call. Results: If Register A equals 90H, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: (compare to VECT20)
4E08
If the Z FLAG (Zero) is set, JUMP to 4F61H.
Original Source Code Comment: (jump to SKILL if VECT20)
4E0B S3ABRT
LD A,1AH
LET Register A = 1AH to set up for a ILLEGAL COMMAND PARAMETER error.
Original Source Code Comment: FILE NOT OPEN ERROR
4E0D
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A. The NZ Flag will be set because we just put a 26H into Register A, so NZ will be set to indicate an error.
Original Source Code Comment: SET NZ FLAG
4E0E
RET
RETurn to the caller.
Original Source Code Comment: (return from abort)

4E0FH - SCLOSE - MAIN ROUTINE - "CLOSE" - Close an Open File.

4E0F SCLOSE
GOSUB to 4881H (from SYS00/SYS) to set up for closing a file.
Original Source Code Comment: SAVE CALLERS REGISTERS
4E12
RET NZ
If the NZ FLAG (Not Zero) is set then the prior CALL wound up with an error, RETurn to the caller.
Original Source Code Comment: FILE NOT OPEN
4E13
GOSUB to 4868H (from SYS00/SYS) to write the buffer out, if necessary.
Original Source Code Comment: DUMP OUT PARTIAL RECORD IF BLOCKED
4E16
If the Z FLAG (Zero) is set then the prior CALL had NO error so JUMP to 4E1FH.
Original Source Code Comment: CONTINUE IF GOOD WRITE
4E18
CP 1EH
Compare the value held in Register A against 1EH (the error code for NO MORE EXTENTS). Results: If Register A equals 1EH, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: NO MORE EXTENTS?
4E1A
If the Z FLAG (Zero) is set, meaning that the CALL returned an error code for NO MORE EXTENTS, JUMP to 4E1FH.
Original Source Code Comment: YES. IT'S OKAY
4E1C
CP 1BH
Compare the value held in Register A against 1BH (the error code for DISK FULL). Results: If Register A equals 1BH, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: DISK SPACE FULL?
4E1E
RET NZ
If the NZ FLAG (Not Zero) is set then the CALL did not result in a DISK FULL error, so RETurn to the caller.
Original Source Code Comment: NO, SOME OTHER ERROR
4E1F SCLOS1
LD B,(IX+07H)
Fetch the value stored at the memory location pointed to by IX+07H (i.e., the position in the DCB for the LOGICAL FILE NUMBER) and put it into Register B.
Original Source Code Comment: B = LFN (Logical File Number)
4E22
LD C,(IX+06H)
Fetch the value stored at the memory location pointed to by IX+06H (i.e., the position in the DCB for the DRIVE NUMBER) and put it into Register C.
Original Source Code Comment: C = DRIVE
4E25
LD A,(IX+0EH)
Fetch the value stored at the memory location pointed to by IX+0EH (i.e., the position in the DCB for the DISK SIDE NUMBER) and put it into Register A.
Original Source Code Comment: A = SIDE NUMBER
4E28
LD (4463H),ALD (CSIDE),A
Store the value held in Register A (i.e., the DISK SIDE NUMBER) into the memory location 4463H (i.e., the storage location for the old system disk side number).
Original Source Code Comment: SET IT IN DOS
4E2B
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 TABLE
4E2E
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: EXIT IF ERROR
4E2F
GOSUB to 4A67H.
NOTE: 4A67H is the SYS00/SYS routine to read the directory entry into RAM (Buffer at 4300H)
Original Source Code Comment: Read directory entry
4E32
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: DIR READ ERROR
4E33
LD (4F24H),HLLD (SAVEXP),HL
Store the value held in Register HL (i.e., the position of the entry) into the memory location 4F24H, which is in the middle of a LD HL,nnnn OPCODE.
Original Source Code Comment: SAVE THE DIRECTORY POINTER
4E36
BIT 3,(IX+01H)
Test Bit 3 of Register (IX+01H).
Original Source Code Comment: WAS THIS A READ FILE?
4E3A
If the Z FLAG (Zero) is set, the BIT 3 of DCB+01H was off, meaning that we were not requested to trim the file, so JUMP to 4F1BH.
Original Source Code Comment: YES, JUST RESET THE FILE NAME
4E3D
LD A,03H
LET Register A = 03H so as to allow us to move HL (i.e., the pointer to the current location in the directory entry) forward 3 bytes.
Original Source Code Comment: (set up pointer offset of 3)
4E3F
ADD A,L
ADD the value held in Register L to Register A (Results held in Register A).
Original Source Code Comment: (add offset to L)
4E40
LD L,A
LET Register L = Register A so that HL = HL + 3 now.
Original Source Code Comment: HL => DIR+3
4E41
PUSH HL
Save Register HL (i.e., the pointer to the current location in the directory entry) to the top of the stack.
Original Source Code Comment: SAVE HL
4E42
LD A,(IX+08H)
Fetch the value stored at the memory location pointed to by IX+08H (i.e., the position in the DCB for the EOF byte) and put it into Register A.
Original Source Code Comment: GET EOF BYTE
4E45
CP (HL)
Compare the value held in Register A (i.e., the position in the DCB for the EOF byte) against the value held in the memory location (HL) (i.e., the directory's EOF byte). Results: If Register A equals (HL), the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: CP TO DIR EOF
4E46
If the NZ FLAG (Not Zero) is set, then the EOF bytes didn't match, so we need to update the the directory --- JUMP to 4E5DH.
Original Source Code Comment: JR IF EOF BYTE MOVED
4E48
LD A,11H
LET Register A = 11H (Decimal: 20) so as to allow us to move HL (i.e., the pointer to the current location in the directory entry) forward 20 bytes (to the directory sector EOF).
Original Source Code Comment: (set up pointer offset of 17 decimal)
4E4A
ADD A,L
ADD the value held in Register L to Register A (Results held in Register A).
Original Source Code Comment: (add offset to L)
4E4B
LD L,A
LET Register L = Register A.
Original Source Code Comment: HL => DIR+20
4E4C
LD A,(IX+0CH)
Fetch the value stored at the memory location pointed to by IX+0CH (i.e., the position in the DCB for the NMSB OF THE LAST RECORD) and put it into Register A.
Original Source Code Comment: ERN (PHYSICAL) — End Record Number LSB
4E4F
CP (HL)
Compare the value held in Register A (i.e., the DCB sector EOF) against the value held in the memory location (HL) (i.e., the EOF byte in the directory). Results: If Register A equals (HL), the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: (compare ERN LSB to directory)
4E50
If the NZ FLAG (Not Zero) is set then the DCB and directory EOF's didn't match, so we need to update the directory by JUMPing to 4E5DH.
Original Source Code Comment: JR IF EOF PRN (LSB) ALTERED
4E52
INC L
Bump the value stored in Register L by 1 to point to the next position in the directory entry.
Original Source Code Comment: (bump to MSB)
4E53
LD A,(IX+0DH)
Fetch the value stored at the memory location pointed to by IX+0DH (i.e., the position in the DCB for the MSB OF THE LAST RECORD) and put it into Register A.
Original Source Code Comment: GET EOF MSB — End Record Number MSB
4E56
CP (HL)
Compare the value held in Register A against the value held in the memory location (HL). Results: If Register A equals (HL), the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: (compare ERN MSB to directory)
4E57
If the NZ FLAG (Not Zero) is set then we need to update the directory, so JUMP to 4E5DH.
Original Source Code Comment: JR IF EOF PRN (MSB) ALTERED
4E59
POP AF
Restore Register Pair AF from the top of the STACK.
Original Source Code Comment: CLEAN STACK
4E5A
JUMP to 4F07H to continue the routine.
Original Source Code Comment: AND EXIT

4E5DH - CLOSE1 - Continuation of the CLOSE routine. This routine will update the the directory.

4E5D CLOSE1
POP HL
Restore Register Pair HL (i.e., the pointer to the current location in the directory entry) from the top of the STACK.
Original Source Code Comment: HL => DIR+3
4E5E
LD A,(IX+08H)
Fetch the value stored at the memory location pointed to by IX+08H (i.e., the position in the DCB for the EOF byte) and put it into Register A.
Original Source Code Comment: (get EOF byte from DCB)
4E61
LD (HL),A
Store the value held in Register A (i.e., EOF byte from the DCB) into the memory location pointed to by Register Pair HL (i.e., the pointer to the EOF byte in the directory entry).
Original Source Code Comment: UPDATE THE EOF BYTE
4E62
INC HL
Bump the value stored in Register Pair HL by 1 to point to the next byte in the directory entry.
Original Source Code Comment: BUMP TO LRL
4E63
LD A,(IX+09H)
Fetch the value stored at the memory location pointed to by IX+09H (i.e., the position in the DCB for the LOGICAL RECORD LENGTH) and put it into Register A.
Original Source Code Comment: GET IT — Logical Record Length
4E66
LD (HL),A
Store the value held in Register A (i.e., the LOGICAL RECORD LENGTH in the DCB) into the memory location pointed to by Register Pair HL (i.e., the position in the directory entry for the LRL byte).
Original Source Code Comment: INTO THE DIRECTORY
4E67
LD A,10H
LET Register A = 10H so we can move HL to point to the directory entry for the SECTOR EOF.
Original Source Code Comment: (set up pointer offset of 16)
4E69
ADD A,L
ADD the value held in Register L to Register A (Results held in Register A).
Original Source Code Comment: (add offset to L)
4E6A
LD L,A
LET Register L = Register A, so now HL points to the directory entry for the SECTOR EOF.
Original Source Code Comment: HL => DIR+20
4E6B
LD A,(IX+0CH)
Fetch the value stored at the memory location pointed to by IX+0CH (i.e., the position in the DCB for the NMSB OF THE LAST RECORD) and put it into Register A.
Original Source Code Comment: NEW ERN (LSB) — new End Record Number
4E6E
LD (HL),A
Store the value held in Register A (i.e., the NMSB OF THE LAST RECORD in the DCB) into the memory location pointed to by Register Pair HL (i.e., the position in the directory entry for the NMSB of the last record).
Original Source Code Comment: UPDATE IT
4E6F
INC L
Bump the value stored in Register L by 1 so that HL now points to the position in the directory entry for the MSB of the last record).
Original Source Code Comment: (bump to MSB)
4E70
LD A,(IX+0DH)
Fetch the value stored at the memory location pointed to by IX+0DH (i.e., the position in the DCB for the MSB OF THE LAST RECORD) and put it into Register A.
Original Source Code Comment: ERN (MSB)
4E73
LD (HL),A
Store the value held in Register A (i.e., the MSB OF THE LAST RECORD in the DCB) into the memory location pointed to by Register Pair HL (i.e., the position in the DCB for the MSB OF THE LAST RECORD).
Original Source Code Comment: (update MSB in directory)
4E74
INC L
Bump the value stored in Register L by 1 so that HL now points to the next position in the directory entry.
Original Source Code Comment: HL => BEGIN OF EXTENTS
4E75
LD DE,0010H
LET Register Pair DE = 0010H (Decimal: 16).
Original Source Code Comment: OFFSET TO BEGIN OF EXTENSIONS
4E78
PUSH IX
Save Register IX (i.e., DCB + 00H) to the top of the stack.
Original Source Code Comment: SAVE DCB POINTER
4E7A
ADD IX,DE
ADD the value held in Register Pair DE (i.e., 16 bytes) to Register Pair IX, so that IX = IX + 16 bytes (to point to the extents).
Original Source Code Comment: ADD TO THE DCB POINTER
4E7C
PUSH IX
Save Register IX (i.e., the pointer in the DCB to the extents) to the top of the stack.
Original Source Code Comment: MOVE IT TO DE (via PUSH IX/POP DE)
4E7E
POP DE
Restore the pointer in the DCB to the extents into Register Pair DE.
Original Source Code Comment: (POP DE = IX+EXTBEG)
4E7F
POP IX
Restore the DCB + 00H (from the top of the stack) into Register Pair IX.
Original Source Code Comment: GET DCB POINTER BACK
4E81
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the current working position in the directory entry) with the value stored in Register Pair DE (i.e., the pointer in the DCB to the extents).
Original Source Code Comment: HL=> DCB EXT, DE=> DIR EXT
4E82
PUSH DE
Save Register DE (i.e., the current working position in the directory entry) to the top of the stack.
Original Source Code Comment: SAVE THE DIR POINTER
4E83
LD BC,001AH
LET Register Pair BC = 001AH (Decimal: 26) to prepare to move 26 bytes via a LDIR.
Original Source Code Comment: NUMBER OF BYTES IN EXT (NUMSEG = 001AH = 26 bytes)
4E86
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: MOVE IT INTO THE DIRECTORY
4E88
LD C,(IX+06H)
Fetch the value stored at the memory location pointed to by IX+06H (i.e., the position in the DCB for the DRIVE NUMBER) and put it into Register C.
Original Source Code Comment: GET THE DRIVE NUMBER
4E8B
LD B,(IX+07H)
Fetch the value stored at the memory location pointed to by IX+07H (i.e., the position in the DCB for the LOGICAL FILE NUMBER) and put it into Register B.
Original Source Code Comment: GET THE FILE NUMBER
4E8E
LD A,(IX+0EH)
Fetch the value stored at the memory location pointed to by IX+0EH (i.e., the position in the DCB for the DISK SIDE NUMBER) and put it into Register A.
Original Source Code Comment: GET THE SIDE NUMBER
4E91
LD (4463H),ALD (CSIDE),A
Store the value held in Register A (i.e., the DISK SIDE NUMBER from the DCB) into the memory location 4463H.
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: Set CSIDE in DOS
4E94
GOSUB to 4A7BH (from SYS00/SYS) to write the directory entry from the copy in RAM to the diskette.
Original Source Code Comment: WRITE NEW DIR RECORD
4E97
POP HL
Restore the current working position in the directory entry (held at the top of the stack) into Register Pair HL.
Original Source Code Comment: RESTORE POINTER
4E98
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine (to write the directory from the copy in RAM) returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: DIR WRITE ERROR
4E99 CLOSE2
DEC L
DECrement the value stored in Register L by 1 so that HL now points to the directory entry byte which is 1 byte before the EXTENTS.
Original Source Code Comment: (DEC L to set up for INC L — effectively a no-op to align)
4E9A
INC L
Bump the value stored in Register L by 1 so that HL now points to the directory entry byte for the EXTENTS.
Original Source Code Comment: HL => 1ST SEG DESC
4E9B
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the pointer in the directory entry for the EXTENTS) with the value stored in Register Pair DE.
Original Source Code Comment: DE = SEG POINTER
4E9C
LD L,(IX+0CH)
Fetch the value stored at the memory location pointed to by IX+0CH (i.e., the position in the DCB for the NMSB OF THE LAST RECORD/EOF) and put it into Register L.
Original Source Code Comment: GET THE END RECORD NUMBER (LSB)
4E9F
LD H,(IX+0DH)
Fetch the value stored at the memory location pointed to by IX+0DH (i.e., the position in the DCB for the MSB OF THE LAST RECORD/EOF) and put it into Register H.
Original Source Code Comment: (ERN MSB)
4EA2
INC HL
Bump the value stored in Register Pair HL (i.e., the EOF location) by 1.
Original Source Code Comment: CORRECT FOR 1'S OFFSET
4EA3
LD A,03H
LET Register A = 03H to prepare to divide that EOF by 3, so as to calculate the number of GRANs
Original Source Code Comment: NUMBER OF RECORDS PER GRAN (DGRAN = 3)
4EA5
GOSUB to 4451H to divide Register Pair HL by Register A; result in Register A.
Original Source Code Comment: HL = NUMBER OF GRANS FOR THIS FILE
4EA8
OR A
Set FLAGS based on the contents of Register A.
Original Source Code Comment: WAS THERE A REMAINDER?
4EA9
If the Z FLAG (Zero) is set then there is no remainder, so skip the next instruction and JUMP to 4EACH.
Original Source Code Comment: NO, CONTINUE
4EAB
INC HL
Bump the value stored in Register Pair HL by 1 so that the gran count includes the remainder as a whole number.
Original Source Code Comment: BUMP FOR THE REMAINDER
4EAC CLOS21
LD A,0CH
LET Register A = 0CH (Decimal: 13) in preparation for a loop to skip over all 13 extents.
Original Source Code Comment: GET THE MAX NUMBER OF EXTENTS (MAXEXT-1 = 12 decimal)
4EAE
LD (4EC5H),ALD (CLOCNT),A
Store the value held in Register A (which will be the counter of the extents) into the memory location 4EC5H which is in the middle of a LD A,nn OPCode.
Original Source Code Comment: SET A COUNTER
4EB1 CLOSE3
INC E
Bump the value stored in Register E by 1 so that Register Pair DE points to the next extent in the directory entry.
Original Source Code Comment: BUMP PAST TRACK NUMBER
4EB2
LD A,(DE)
Fetch the value stored at memory location pointed to by Register Pair DE (i.e., the pointer in the directory entry for the next extent) and put it into Register A.
Original Source Code Comment: GET THE ALLOCATION BYTE
4EB3
CP 0FEH
Compare the value held in Register A (i.e., the next extent) against 0FEH. Results:
  • If Register A equals 0FEH, the Z FLAG is set.
  • If A < 0FEH, the CARRY FLAG will be set.
  • if A >= 0FEH, the NO CARRY FLAG will be set.

Original Source Code Comment: END OF FILE?
4EB5
If the NC FLAG (No Carry) is set then A >= 0FEH meaning that we reached the end of the extents, so JUMP to 4F07H to avoid continuing to parse the extents.
Original Source Code Comment: YES, EXIT
4EB7
AND 1FH
MASK the value of Register A against 1FH (0001 1111). This has the effect of turning off bits 7, 6, 5, leaving only bits 4, 3, 2, 1, 0 active, which will be the number of GRANS in that extent.
Original Source Code Comment: MASK OFF STARTING GRAN
4EB9
LD C,A
LET Register C = Register A (i.e., the number of GRANs in the current extent).
Original Source Code Comment: INTO BC
4EBA
LD B,00H
LET Register B = 00H, so now Register Pair BC = the number of GRANs in the current extent.
Original Source Code Comment: (B=0, so BC = number of grans)
4EBC
OR A
Set FLAGS based on the contents of Register A, but most notedly, clear the CARRY FLAG as we are about to use it.
Original Source Code Comment: CLEAR CARRY
4EBD
SBC HL,BC
Subtracts the value stored in Register Pair BC (i.e., the number of GRANs in the current extent) and the carry flag from the value stored in Register Pair HL (i.e., the EOF).
Original Source Code Comment: SUB THE GRANS IN THIS SEG FROM TOTAL
4EBF
If the Z FLAG (Zero) is set then the EOF = 0, so JUMP to 4EF3H.
Original Source Code Comment: WE'RE AT 0 SEE IF ANY FURTHER SEG DESC
4EC1
If the C FLAG (Carry) is set then the EOF < 0 so JUMP to 4ECEH.
Original Source Code Comment: WENT TOO FAR. THERE'S SOME IN THIS ONE
4EC3
INC E
Bump the value stored in Register E by 1 so that Register Pair DE points to the next extent in the directory entry.
Original Source Code Comment: BUMP TO NEXT TRACK NUMBER
4EC4
LD A,nn
LET Register A = nn (i.e., the value in 4EC5H), which is the current counter of extents left to process.
Original Source Code Comment: REMAINING NUMBER OF EXTENTS HERE (self-modifying: CLOCNT)
4EC6
DEC A
DECrement the value stored in Register A by 1 to indicate one less extent to process.
Original Source Code Comment: SUBTRACT ONE
4EC7
LD (4EC5H),ALD (CLOCNT),A
Store the value held in Register A (i.e., the number of extents left to process) into the memory location 4EC5H.
Original Source Code Comment: SAVE FOR NEXT TIME
4ECA
If the NZ FLAG (Not Zero) is set then we still have more extents to process, so LOOP BACK to 4EB1H.
Original Source Code Comment: CONTINUE IF NOT OUT OF EXTENTS
4ECC
JUMP to 4F07H to continue once all 13 extents have been checked.
Original Source Code Comment: EXIT. NOTHING DONE

4ECEH - CHKEND - Continuation from the "CLOSE" routine; jumped to if the EOF < 0.

4ECE CHKEND
LD A,L
LET Register A = Register L (i.e., the number of extra bytes).
Original Source Code Comment: GET THE NUM OF GRANS THIS SEG TO RELEASE
4ECF
NEG
NEGate Register A so now it is the NEGATIVE number of extra bytes.
Original Source Code Comment: FLIP IT (negate)
4ED1
LD L,A
LET Register L = Register A (i.e., the NEGATIVE number of extra bytes).
Original Source Code Comment: BACK INTO L FOR THE MOMENT
4ED2
LD A,(DE)
Fetch the value stored at memory location pointed to by Register Pair DE (i.e., the pointer in the directory entry) and put it into Register A.
Original Source Code Comment: GET THE SEG DESCRIP
4ED3
SUB L
SUBtract the value held in Register L from Register A so trim off the extra GRANs from the extent.
Original Source Code Comment: SUBTRACT THAT NUMBER FROM IT
4ED4
LD (DE),A
Store the value held in Register A (i.e., the reduced/trimmed GRAN count) into the memory location pointed to by Register Pair DE.
Original Source Code Comment: STORE NEW DESCRIPTOR
4ED5
PUSH HL
Save Register HL (i.e., the numebr of extra GRANs) to the top of the stack.
Original Source Code Comment: SAVE HL
4ED6
LD HL,4EF3HLD HL,CHKDON
LET Register Pair HL = 4EF3H to set a RETURN address.
Original Source Code Comment: PLACE TO RETURN TO (CHKDON = 4EF3H)
4ED9
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the return address of 4EF3H) with the value stored in Register Pair (SP).
Original Source Code Comment: PUT IT ON THE STACK
4EDA
PUSH HL
Save Register HL to the top of the stack.
Original Source Code Comment: SAVE THE REGISTERS
4EDB
PUSH DE
Save Register DE to the top of the stack.
Original Source Code Comment: (push DE)
4EDC
PUSH BC
Save Register BC to the top of the stack.
Original Source Code Comment: (push BC)
4EDD
LD C,L
LET Register C = Register L (i.e., the number of extra GRANs).
Original Source Code Comment: SET THE NUMBER INTO (C) FOR COUNTER
4EDE
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
Original Source Code Comment: HL => SEG DESCRIPTORS
4EDF
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the extra element) and put it into Register A.
Original Source Code Comment: GET THE DESCRIPTOR
4EE0
PUSH AF
Save Register AF to the top of the stack.
Original Source Code Comment: SAVE IT
4EE1
AND 1FH
MASK the value of Register A against 1FH (0001 1111) to isolate the number of GRANs. This has the effect of turning off bits 7, 6, 5, leaving only bits 4, 3, 2, 1, 0 active.
Original Source Code Comment: MASK THE STARTING GRAN
4EE3
LD E,A
LET Register E = Register A (i.e., the number of GRANs).
Original Source Code Comment: SET AS OFFSET COUNTER
4EE4
POP AF
Restore Register Pair AF (i.e., the extent) from the top of the STACK.
Original Source Code Comment: GET THE SEG DESC BACK
4EE5
AND 0E0H
MASK the value of Register A against E0H (1110 0000) to isolate the offset in the track. This has the effect of turning off bits 4, 3, 2, 1, 0, leaving only bits 7, 6, 5 active.
Original Source Code Comment: MASK OF NUMBER OF GRANS
4EE7
4EE8
4EE9
RLCA
RLCA
RLCA
Rotate the bits in A so that bits 7, 6, and 5, aare now bits 2, 1, and 0.
Original Source Code Comment: MOVE IT TO THE LSB (3 RLCAs)
4EEA
PUSH AF
Save Register AF (which is the offset in the track) to the top of the stack.
Original Source Code Comment: SAVE IT
4EEB
DEC HL
DECrement the value stored in Register Pair HL by 1 to back up 1 byte to the TRACK NUMBER byte.
Original Source Code Comment: BACK UP TO THE TRACK NUMBER
4EEC
LD L,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the TRACK NUMBER) and put it into Register L.
Original Source Code Comment: GET IT
4EED
LD H,4DH
LET Register H = 4DH so that Register Pair HL now points to the appropriate GAT ENTRY in RAM.
Original Source Code Comment: HL => THIS TRACK'S GAT BYTE (BUFF2.HIGH. = 4DH)
4EEF
POP AF
Restore Register Pair AF (i.e., the offset) from the top of the STACK.
Original Source Code Comment: GET STARTING GRAN BACK
4EF0
JUMP to 4FDEH to deallocate that GRAN.
Original Source Code Comment: DO THE RELEASE (JP REL1)

4EF3H - CHKDON - Continuation from the "CLOSE" routine; jumped to if the EOF = 0, meaning that no trimming need be done. Just set the appropriate bytes to indicate that we have hit the end of the extents.

4EF3 CHKDON
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE (the pointer to the directory entry in RAM).
Original Source Code Comment: (CHKDON entry) — check for more extents
4EF4
INC HL
Bump the value stored in Register Pair HL by 1 so that HL points to the next extent in the directory entry in RAM.
Original Source Code Comment: BUMP TO NEXT TRACK
4EF5 CHKDO1
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the TRACK NUMBER) and put it into Register A.
Original Source Code Comment: GET THE TRACK NUMBER
4EF6
CP 0FEH
Compare the value held in Register A (i.e., the TRACK NUMBER) against 0FEH. Results:
  • If Register A equals 0FEH, the Z FLAG is set.
  • If A < 0FEH, the CARRY FLAG will be set.
  • if A >= 0FEH, the NO CARRY FLAG will be set.

Original Source Code Comment: WE DONE WITH THIS FILE?
4EF8
If the NC FLAG (No Carry) is set then we have reached the end of the extents so JUMP to 4F07H.
Original Source Code Comment: YES, WRITE OUT THE BUFFERS
4EFA
LD E,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the TRACK NUMBER) and put it into Register E.
Original Source Code Comment: GET THE TRACK NUMBER
4EFB
LD (HL),0FFH
Store a 0FFH into the memory location pointed to by Register Pair HL to indicate that we have reached the end of the extents.
Original Source Code Comment: RELEASE THE TRACK (mark 0FFH)
4EFD
INC HL
Bump the value stored in Register Pair HL by 1.
Original Source Code Comment: BUMP TO SEG DESC
4EFE
LD D,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the number of GRANs plus the offset) and put it into Register D.
Original Source Code Comment: GET IT
4EFF
LD (HL),0FFH
Store a 0FFH into the memory location pointed to by Register Pair HL to indicate that we have reached the end of the extents.
Original Source Code Comment: RELEASE THE GRANS (mark 0FFH)
4F01
INC HL
Bump the value stored in Register Pair HL by 1.
Original Source Code Comment: BUMP TO NEXT TRACK
4F02
GOSUB to 4FCEH to deallocate the space.
Original Source Code Comment: RELEASE THE GRANS
4F05
LOOP BACK to 4EF5H until all extents have been tested.
Original Source Code Comment: AND LOOP TILL END OF EXTENTS

4F07H - CHKDO2 - Continuation from the "CLOSE" routine if the directory did NOT need to be updated.

4F07 CHKDO2
LD B,(IX+07H)
Fetch the value stored at the memory location pointed to by IX+07H (i.e., the position in the DCB for the LOGICAL FILE NUMBER) and put it into Register B.
Original Source Code Comment: GET THE FILE NUMBER (LFN)
4F0A
LD C,(IX+06H)
Fetch the value stored at the memory location pointed to by IX+06H (i.e., the position in the DCB for the DRIVE NUMBER) and put it into Register C.
Original Source Code Comment: AND THE DRIVE NUMBER
4F0D
LD A,(IX+0EH)
Fetch the value stored at the memory location pointed to by IX+0EH (i.e., the position in the DCB for the DISK SIDE NUMBER) and put it into Register A.
Original Source Code Comment: GET THE SIDE NUMBER
4F10
LD (4463H),ALD (CSIDE),A
Store the value held in Register A into the memory location 4463H.
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: SET IT IN DOS (CSIDE)
4F13
GOSUB to 4A9BH to write the GAT sector from the appropriate RAM buffer.
Original Source Code Comment: WRITE OUT THE ALLOCATION TABLE (WRGAT)
4F16
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: EXIT IF ERROR
4F17
GOSUB to 4A7BH.
NOTE: 4A7BH is the SYS00/SYS routine to to write the directory entry from the copy in RAM to the diskette.
Original Source Code Comment: WRITE OUT THE DIR RECORD (WRDIR)
4F1A
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: EXIT IF ERROR
4F1B RESET
LD A,(IX+06H)
Fetch the value stored at the memory location pointed to by IX+06H (i.e., the position in the DCB for the DRIVE NUMBER) and put it into Register A.
Original Source Code Comment: Get drive number from DCB
4F1E
ADD A,30H
ADD the value 30H to Register A (Results held in Register A) so as to convert a number in to the ASCII value for that number.
Original Source Code Comment: CONVERT DRIVE TO ASCII
4F20
LD (4F59H),ALD (RESDRV),A
Store the value held in Register A (i.e., the ASCII version of the drive number) into the memory location 4F59H which is in the middle of a LD A,nn OPCode.
Original Source Code Comment: AND SAVE IT (self-modifying RESDRV at 4F59H)
4F23
LD HL,nnnn
LET Register Pair HL = nnnn, which was placed in 4F24H-4F25H elsewhere.
Original Source Code Comment: DIR REC BUFFER POINTER STORED HERE (self-modifying SAVEXP)
4F26
LD DE,0005H
LET Register Pair DE = 0005H, which is the offset to HL to then point to the filespec in the directory entry.
Original Source Code Comment: OFFSET TO NAME (DNAME = 5)
4F29
ADD HL,DE
ADD the value held in Register Pair DE to Register Pair HL. The results are held in Register Pair HL, so HL now points to the filespec in the directory entry.
Original Source Code Comment: HL => NAME
4F2A
PUSH HL
Save Register HL (i.e., the pointer to the filespec in the directory entry) to the top of the stack.
Original Source Code Comment: SAVE HL
4F2B
PUSH IX
Save Register IX (i.e., the DCB) to the top of the stack.
Original Source Code Comment: (PUSH IX — DCB pointer)
4F2D
POP DE
Restore Register Pair DE (i.e., the DCB) from the top of the STACK.
Original Source Code Comment: DE => DCB
4F2E
LD B,08H
LET Register B = 08H to prepare for a DJNZ loop of 8 iterations.
Original Source Code Comment: (loop 8 chars for filename)
4F30 RESET1
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., a character of the filespec in the directory entry) and put it into Register A.
Original Source Code Comment: (get character from directory)
4F31
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE which would indicate that we have run out of letters in the filespec before 8. Results: If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: JR IF SHORT FILE NAME (space = end)
4F33
If the Z FLAG (Zero) is set, meaning we hit a space, JUMP to 4F3AH as we do not need to keep parsing filespec characters.
Original Source Code Comment: (skip if space found)
4F35
LD (DE),A
Store the value held in Register A (i.e., the current filespec character) into the memory location pointed to by Register Pair DE.
Original Source Code Comment: RESTORE THE FILE NAME (copy char to DCB)
4F36
INC HL
Bump the value stored in Register Pair HL by 1 so that HL now points to the next character in the filespec in the directory entry.
Original Source Code Comment: (next source char)
4F37
INC DE
Bump the value stored in Register Pair DE by 1 so that DE now points to the next space in the DCB.
Original Source Code Comment: (next dest position)
4F38
DJNZ 4F30HDJNZ RESET1
LOOP back to 4F30H until Register B is ZERO and the entire filespec has been copied from the directory entry in RAM to the DCB.
Original Source Code Comment: (loop for 8 chars)
4F3A RESET2
POP HL
Restore the pointer to the filespec in the directory entry from the top of the stack into Register Pair HL.
Original Source Code Comment: (restore HL to directory pointer)
4F3B
LD A,L
LET Register A = Register L so as to prepare to move 8 characters foward, to leave Register Pair HL pointing to the extension in the filename in the directory.
Original Source Code Comment: (prepare to skip 8 chars to extension)
4F3C
ADD A,08H
ADD the value 08H to Register A (Results held in Register A).
Original Source Code Comment: (add 8 to L)
4F3E
LD L,A
LET Register L = Register A, so now Register Pair HL points to the extension in the filename in the directory.
Original Source Code Comment: HL => DIR+13 (extension)
4F3F
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the first character of the extension in the filename in the directory) and put it into Register A.
Original Source Code Comment: (check first char of extension)
4F40
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE) to see if it is empty. Results: If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: JR IF NOT EXTENSION (space = no ext)
4F42
If the Z FLAG (Zero) is set then there is no extension, so JUMP to 4F54H.
Original Source Code Comment: (jump if no extension)
4F44
LD A,2FH
LET Register A = 2FH (ASCII: /).
Original Source Code Comment: DELIMIT THE EXT (slash separator)
4F46
LD (DE),A
Store the value held in Register A (i.e., a /) into the memory location pointed to by Register Pair DE (i.e., the space in the DCB following the filespec).
Original Source Code Comment: (store slash in DCB)
4F47
INC DE
Bump the value stored in Register Pair DE by 1 so that DE now points to the space after the / in the DCB.
Original Source Code Comment: (bump DE)
4F48
LD B,03H
LET Register B = 08H to prepare for a DJNZ loop of 3 iterations (for the extension).
Original Source Code Comment: (loop 3 chars for extension)
4F4A RESET3
LD A,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., a character of the extension in the directory entry) and put it into Register A.
Original Source Code Comment: (get extension char)
4F4B
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE) which would indicate that we have run out of letters in the extension before 3. Results: If Register A equals 20H, the Z FLAG is set; otherwise the NZ FLAG is set.
Original Source Code Comment: JR IF SHORT EXTENSION
4F4D
If the Z FLAG (Zero) is set, meaning we hit a space, JUMP to 4F54H as we do not need to keep parsing extension characters.
Original Source Code Comment: (skip if space found)
4F4F
LD (DE),A
Store the value held in Register A (i.e., the current extension character) into the memory location pointed to by Register Pair DE.
Original Source Code Comment: RESTORE THE EXTENSION
4F50
INC HL
Bump the value stored in Register Pair HL by 1 so that HL now points to the next character in the filespec in the directory entry.
Original Source Code Comment: (next source char)
4F51
INC DE
Bump the value stored in Register Pair DE by 1 so that DE now points to the next space in the DCB.
Original Source Code Comment: (next dest position)
4F52
DJNZ 4F4AHDJNZ RESET3
LOOP back to 4F4AH until Register B is ZERO and the entire extension has been copied from the directory entry in RAM to the DCB.
Original Source Code Comment: (loop for 3 chars)
4F54 RESET4
LD A,3AH
LET Register A = 3AH (ASCII: :).
Original Source Code Comment: DELIMIT THE DRIVE (colon)
4F56
LD (DE),A
Store the value held in Register A (i.e., a :) into the memory location pointed to by Register Pair DE (i.e., the space in the DCB following the filespec).
Original Source Code Comment: (store colon in DCB)
4F57
INC DE
Bump the value stored in Register Pair DE by 1 so that DE now points to the space after the : in the DCB.
Original Source Code Comment: (bump DE)
4F58
LD A,nn
LET Register A = nn. This is the ASCII value of a DRIVE NUMBER and it was placed in (4F59H) by other instructions.
Original Source Code Comment: GET THE DRIVE (self-modifying RESDRV — ASCII drive number)
4F5A
LD (DE),A
Store the value held in Register A (i.e., the ASCII version of the DRIVE NUMBER) into the memory location pointed to by Register Pair DE.
Original Source Code Comment: PLACE IN FILE SPEC
4F5B
INC DE
Bump the value stored in Register Pair DE by 1 so that DE now points to the next space in the DCB.
Original Source Code Comment: (bump DE)
4F5C
LD A,03H
LET Register A = 03H, which is a terminator character
Original Source Code Comment: TERMINATE THE FILE SPEC (03H = end-of-text marker)
4F5E
LD (DE),A
Store the value held in Register A (i.e., the terminator character) into the memory location pointed to by Register Pair DE.
Original Source Code Comment: (store terminator)
4F5F
XOR A
Set Register A to ZERO and clear all Flags to signify NO ERROR.
Original Source Code Comment: (XOR A — clear A and flags for no error)
4F60
RET
RETurn to the caller.
Original Source Code Comment: (return — close/reset complete)

4F61H - SKILL - MAIN ROUTINE - "KILL" - Delete a file from the directory.

4F61 SKILL
GOSUB to 4881H (from SYS00/SYS) to set up for closing a file.
Original Source Code Comment: SAVE CALLERS REGISTERS
4F64
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: FILE IS NOT OPEN
4F65
LD A,(IX+01H)
Fetch the value stored at the memory location pointed to by IX+01H (i.e., the position in the DCB for the OPTIONS byte) and put it into Register A.
Original Source Code Comment: (get protection/access byte from DCB)
4F68
AND 07H
MASK the value of Register A against 07H (0000 0111) to isolate the access level. This has the effect of turning off bits 7, 6, 5, 4, 3, leaving only bits 2, 1, 0 active.
Original Source Code Comment: (mask to low 3 bits — access level)
4F6A
CP 02H
Compare the value held in Register A against 02H to see if we have KILL access (or higher) to the file. Results:
  • If Register A equals 02H, the Z FLAG is set.
  • If A < 02H, the CARRY FLAG will be set.
  • if A >= 02H, the NO CARRY FLAG will be set.

Original Source Code Comment: (compare to level 2 — need KILL access or higher)
4F6C
If the C FLAG (Carry) is set, then we have KILL acces (or higher), so continue on at 4F72H.
Original Source Code Comment: JR IF IT WAS GRANTED
4F6E
LD A,1AH
LET Register A = 19H to set up for a FILE ACCESS DENIED error.
Original Source Code Comment: ILLEGAL ACCESS ATTEMPTED (EFAD error code)
4F70
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A. The NZ Flag will be set because we just put a 26H into Register A, so NZ will be set to indicate an error.
Original Source Code Comment: (set NZ for error)
4F71
RET
RETurn to the caller.
Original Source Code Comment: (return with error)

4F72H - KILL1 - Continuation of "KILL" Routine. Jumped here if we have access to kill the file.

4F72 KILL1
LD C,(IX+06H)
Fetch the value stored at the memory location pointed to by IX+06H (i.e., the position in the DCB for the DRIVE NUMBER) and put it into Register C.
Original Source Code Comment: C = DRIVE NUM
4F75
LD B,(IX+07H)
Fetch the value stored at the memory location pointed to by IX+07H (i.e., the position in the DCB for the LOGICAL FILE NUMBER) and put it into Register B.
Original Source Code Comment: B = LFN
4F78
LD A,(IX+0EH)
Fetch the value stored at the memory location pointed to by IX+0EH (i.e., the position in the DCB for the DISK SIDE NUMBER) and put it into Register A.
Original Source Code Comment: GET THE SIDE NUMBER
4F7B
LD (4463H),ALD (CSIDE),A
Store the value held in Register A into the memory location 4463H.
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: SET IT IN DOS (CSIDE)
4F7E
GOSUB to 4ABAH.
NOTE: 4ABAH is the SYS00/SYS routine to read the HIT sector into RAM.
Original Source Code Comment: READ IN HASH INDEX TABLE (RDHIT)
4F81
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: (return if error)
4F82
LD L,B
LET Register L = Register B, so that Register Pair HL will now point to the HIT ENTRY for the file to kill.
Original Source Code Comment: HL => THIS HIT CODE
4F83
LD (HL),00H
Store the value held in Register 00H into the memory location pointed to by Register Pair HL (i.e., the HIT ENTRY for the file to kill).
Original Source Code Comment: CLEAR IT OUT
4F85
GOSUB to 4AC2H.
NOTE: 4AC2H is the SYS00/SYS routine to write the HIT sector from RAM to diskette.
Original Source Code Comment: WRITE OUT THE HIT TABLE (WRHIT)
4F88
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: EXIT IF ERROR
4F89
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 GAT — RDGAT)
4F8C
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: (return if error)
4F8D KILL2
GOSUB to 4A67H.
NOTE: 4A67H is the SYS00/SYS routine to read the directory entry into RAM (Buffer at 4300H)
Original Source Code Comment: (read directory — RDDIR)
4F90
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: (return if error)
4F91
LD (4FACH),HLLD (SAVPNT),HL
Store the value held in Register HL (i.e., the pointer to the entry) into the memory location 4FACH (which is in the middle of a LD HL,nnnn OPCODE).
Original Source Code Comment: SAVE POINTER TO FRONT OF THIS DIR (self-modifying SAVPNT at 4FACH)
4F94
LD A,16H
LET Register A = 16H (Decimal: 22) for the number of bytes to skip to get to the extents in a directory entry of the file to kill.
Original Source Code Comment: Offset to extents (DSEG = 22 = 16H)
4F96
ADD A,L
ADD the value held in Register L to Register A (Results held in Register A).
Original Source Code Comment: (add to L)
4F97
LD L,A
LET Register L = Register A so now HL points to the extents in a directory entry of the file to kill.
Original Source Code Comment: HL => DIR+22
4F98
PUSH BC
Save Register BC (i.e., the DRIVE NUMBER and LOGICAL FILE NUMBER of the file to kill) to the top of the stack.
Original Source Code Comment: SAVE LFN AND DRIVE NUMBER
4F99
LD B,0DH
LET Register B = 0DH (Decimal: 13) to loop over the 13 extents.
Original Source Code Comment: GET THE MAXIMUM NUMBER OF EXTENTS (MAXEXT = 0DH = 13)
4F9B KILL3
LD E,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the TRACK NUMBER of the extent) and put it into Register E.
Original Source Code Comment: Get segment descriptor pair — track byte
4F9C
INC HL
Bump the value stored in Register Pair HL by 1 so that HL points to the next byte in the extent.
Original Source Code Comment: (bump to allocation byte)
4F9D
LD D,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the SIZE and OFFSET of the extent) and put it into Register D.
Original Source Code Comment: Get allocation byte into D
4F9E
LD A,E
LET Register A = Register E so that we can test Register E against 0FEH to determine if we have hit the end of the extents.
Original Source Code Comment: (copy E for comparison)
4F9F
CP 0FEH
Compare the value held in Register A against 0FEH, which would signify that we have reached the end of the extents. Results:
  • If Register A equals 0FEH, the Z FLAG is set.
  • If A < 0FEH, the CARRY FLAG will be set.
  • if A >= 0FEH, the NO CARRY FLAG will be set.

Original Source Code Comment: JR IF LINKED OR END (>= 0FEH)
4FA1
If the NC FLAG (No Carry) is set then we have reached the end of the extents so JUMP to 4FABH since we don't need to keep looping through the extents..
Original Source Code Comment: (jump if end of extents)
4FA3
INC L
Bump the value stored in Register L by 1 so that Register Pair HL points to the next byte in the extents.
Original Source Code Comment: (bump past allocation byte)
4FA4
PUSH BC
Save Register BC (i.e., the extent counter) to the top of the stack.
Original Source Code Comment: SAVE THE COUNTER
4FA5
GOSUB to 4FCEH to de-allocate the extent.
Original Source Code Comment: RELEASE THIS SEGMENT (call RELEAS)
4FA8
POP BC
Restore the extent counter from the top of the stack into Register Pair BC.
Original Source Code Comment: GET THE COUNTER BACK
4FA9
DJNZ 4F9BHDJNZ KILL3
LOOP back to 4F9BH until Register B is ZERO and all 13 extents have been handled (or we exited earlier).
Original Source Code Comment: (loop through all extents via DJNZ)
4FAB KILL4
LD HL,nnnn
LET Register Pair HL = nnnn (i.e., the directory entry of the filespec we want to kill), which was placed in 4FACH elsewhere in the DOS.
Original Source Code Comment: FRONT OF DIR REC SAVED HERE (self-modifying SAVPNT)
4FAE
LD (HL),00H
Store the value held in Register 00H into the memory location pointed to by Register Pair HL (i.e., the directory entry of the filespec we want to kill).
Original Source Code Comment: CLEAR OUT THE DIR REC
4FB0
PUSH DE
Save Register DE to the top of the stack.
Original Source Code Comment: (save DE)
4FB1
4FB2
LD D,H
LD D,H
LET Register Pair DE = Register HL (i.e., the directory entry of the filespec we want to kill).
Original Source Code Comment: GET HL INTO DE
4FB3
INC DE
Bump the value stored in Register Pair DE by 1 (i.e., the directory entry AFTER the directory entry of the filespec we want to kill).
Original Source Code Comment: PROPAGATE THE X'00' THRU DIR REC (INC DE for LDIR)
4FB4
LD BC,002FH
LET Register Pair BC = 002FH (Decimal: 47) so that we zero 47 bytes.
Original Source Code Comment: SIZDIR-1 = 002FH (47 bytes)
4FB7
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 THE DIR REC
4FB9
POP DE
Restore Register Pair DE from the top of the STACK.
Original Source Code Comment: (restore DE)
4FBA
POP BC
Restore Register Pair BC from the top of the STACK.
Original Source Code Comment: RESTORE REGS
4FBB
GOSUB to 4A7BH.
NOTE: 4A7BH is the SYS00/SYS routine to to write the directory entry from the copy in RAM to the diskette.
Original Source Code Comment: UPDATE DIRECTORY ENTRY (WRDIR)
4FBE
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: (return if error)
4FBF
GOSUB to 4A9BH.
NOTE: 4A9BH is the SYS00/SYS routine to to write the GAT sector from RAM to diskette.
Original Source Code Comment: WRITE OUT THE GAT (WRGAT)
4FC2
RET NZ
If the NZ FLAG (Not Zero) is set then that the prior CALL routine returned an ERROR, so RETurn to caller with the NZ FLAG set (to signify an error).
Original Source Code Comment: (return if error)
4FC3
4FC5
PUSH IX
POP HL
LET HL = IX (i.e., the DCB).
Original Source Code Comment: (PUSH IX / POP HL = HL = IX = DCB pointer)
4FC6
LD B,10H
LET Register B = 10H (Decimal: 16) for a DJNZ loop to clear 16 bytes.
Original Source Code Comment: Loop counter: EXTBEG = 10H = 16 bytes
4FC8
XOR A
Set Register A to ZERO and clear all Flags.
Original Source Code Comment: (XOR A = zero)
4FC9 KILL5
LD (HL),A
Store the value held in Register A into the memory location pointed to by Register Pair HL (i.e., the DCB).
Original Source Code Comment: (zero out DCB byte)
4FCA
INC HL
Bump the value stored in Register Pair HL by 1 so HL points to the next byte of the DCB.
Original Source Code Comment: (next byte)
4FCB
DJNZ 4FC9HDJNZ KILL5
LOOP back to 4FC9H until Register B is ZERO.
Original Source Code Comment: (loop until 16 bytes cleared)
4FCD
RET
RETurn to the caller.
Original Source Code Comment: (return — kill complete)

4FCEH - RELEAS - SUBroutine to De-Allocate Space.

4FCE RELEAS
PUSH HL
Save Register HL to the top of the stack.
Original Source Code Comment: SAVE THE REGISTERS
4FCF
PUSH DE
Save Register DE to the top of the stack.
Original Source Code Comment: (push DE)
4FD0
PUSH BC
Save Register BC to the top of the stack.
Original Source Code Comment: (push BC)
4FD1
LD L,E
LET Register L = Register E.
Original Source Code Comment: HL => 1ST GAT BYTE OF SEGMENT
4FD2
LD H,4DH
LET Register H = 4DH, so that Register Pair HL now points to the GAT Entry in RAM
Original Source Code Comment: (H = BUFF2.HIGH. = 4DH — GAT buffer high byte)
4FD4
LD A,D
LET Register A = Register D and ...
Original Source Code Comment: A = ALLOCATION BYTE
4FD5
AND 1FH
... MASK the value of Register A against 1FH (0001 1111) to isolate the number of GRANs. This has the effect of turning off bits 7, 6, 5, leaving only bits 4, 3, 2, 1, 0 active.
Original Source Code Comment: MASK OFF STARTING GRAN
4FD7
LD C,A
LET Register C = Register A (i.e., the number of GRANs).
Original Source Code Comment: SAVE NUMBER OF GRANS IN C
4FD8
XOR D
eXclusive OR Register D against Register A which will then put the offset in the track into Register A.
Original Source Code Comment: A = STARTING GRAN (XOR isolates high bits)
4FD9
4FDA
4FDB
RLCA
RLCA
RLCA
Rotate the bits in A left so that the offset moves into bits 2, 1, and 0.
Original Source Code Comment: SHIFT IT TO LSB (3 RLCAs — A = 1ST GRAN # WITHIN SEGMENT)
4FDC
LD E,00H
LET Register E = 00H.
Original Source Code Comment: SET A OFFSET COUNTER
4FDE REL1
PUSH AF
Save Register AF to the top of the stack.
Original Source Code Comment: SAVE STARTING GRAN
4FDF
PUSH HL
Save Register HL to the top of the stack.
Original Source Code Comment: SAVE BUFFER POINTER
4FE0
ADD A,E
ADD the value held in Register E to Register A (Results held in Register A) to computer the number of grans offset.
Original Source Code Comment: ADD THE COUNTER TO STARTING GRAN
4FE1
LD L,A
LET Register L = Register A.
Original Source Code Comment: PUT IT INTO HL
4FE2
LD H,00H
LET Register H = 00H, so that Register Pair HL is the number of tracks to offset
Original Source Code Comment: (H=0 so HL = A)
4FE4
LD A,06H
LET Register A = 06H since we are going to need to divide by 6.
Original Source Code Comment: NUMBER OF GRANS PER TRACK (NGRAN = 6)
4FE6
GOSUB to 4451H to divide the number of grans by 6; Remainder in A.
Original Source Code Comment: (divide: RET A=BIT NUMBER, L=TRACK OFFSET)
4FE9
LD D,A
LET Register D = Register A (i.e., the remainder from that division).
Original Source Code Comment: SAVE THE BIT NUMBER
4FEA
LD A,L
LET Register A = Register L (i.e., the number of tracks offset).
Original Source Code Comment: GET THE TRACK OFFSET
4FEB
POP HL
Restore Register Pair HL from the top of the STACK.
Original Source Code Comment: GET THE GAT POINTER BACK
4FEC
PUSH HL
Save Register HL to the top of the stack.
Original Source Code Comment: SAVE IT
4FED
ADD A,L
ADD the value held in Register L (i.e., the number of tracks offset) to Register A (Results held in Register A).
Original Source Code Comment: ADD IN THE TRACK OFFSET
4FEE
LD L,A
LET Register L = Register A so that HL now points contains the number of tracks to offset.
Original Source Code Comment: INTO HL => GAT BYTE TO RELEASE
4FEF
LD A,D
LET Register A = Register D (i.e., the number of grans).
Original Source Code Comment: GET THE BIT NUMBER BACK
4FF0
LD B,(HL)
Fetch the value stored at memory location pointed to by Register Pair HL (i.e., the GAT Table Entry) and put it into Register B.
Original Source Code Comment: B=GAT BYTE
4FF1
GOSUB to 4FFFH to de-allocate the granule.
Original Source Code Comment: RELEASE ONE GRAN (call CLRBIT)
4FF4
LD (HL),B
Store the value held in Register B into the memory location pointed to by Register Pair HL (i.e., the GAT Table Entry).
Original Source Code Comment: (store modified GAT byte back)
4FF5
POP HL
Restore Register Pair HL from the top of the STACK.
Original Source Code Comment: GET GAT POINTER BACK
4FF6
POP AF
Restore Register Pair AF from the top of the STACK.
Original Source Code Comment: (restore AF)
4FF7
INC E
Bump the value stored in Register E by 1 so as to point to the nexy GRAN.
Original Source Code Comment: (increment offset counter)
4FF8 REL2
DEC C
DECrement the value stored in Register C by 1 to keep track of the loop.
Original Source Code Comment: DEC C — loop counter for grans
4FF9
If the NZ FLAG (Not Zero) is set then we have more iterations to go, so JUMP to 4FDEH.
Original Source Code Comment: JR IF MORE TO BE RELEASED
4FFB
POP BC
Restore Register Pair BC from the top of the STACK.
Original Source Code Comment: (restore BC)
4FFC
POP DE
Restore Register Pair DE from the top of the STACK.
Original Source Code Comment: (restore DE)
4FFD
POP HL
Restore Register Pair HL from the top of the STACK.
Original Source Code Comment: (restore HL)
4FFE
RET
RETurn to the caller.
Original Source Code Comment: (return from RELEAS)

4FFFH - CLRBIT - SUBroutine from the SUBroutine to de-allocate space.

This routine does a little bit of bit manipulation to form an OPCODE of RES nn,B

In summary, RES n,B is a set of OPCODES which are 80H (for bit 0), 88H (for bit 1), 90H (for bit 2), 98H (for bit 3), etc. These are conveniently "10xx x000" in binary, so they tick up based on bits 5, 4, and 3.

So if the value was 100 after the AND 07 in 4FFFH, then 3 lefts would make it, 00 100 000. Then the OR 80H makes it 10 100 000. 10100000 in Hex is A8H. The Z-80 OPCODE of CB A8 is RES 5,B. So 101 would be RES 5,B.

For purposes of this, I will track an example. Let's say Register A is 0DBH and we'll track that through...

4FFF CLRBIT
AND 07H
MASK the value of Register A against 07H (0000 0111). This has the effect of turning off bits 7, 6, 5, 4, 3, leaving only bits 2, 1, 0 active.
Original Source Code Comment: Mask to bits 2,1,0 (bit position 0-7)

07H is 0000 0111 and Register is 0DBH which is 1101 1011. If you AND them together, only the last 3 bits survive, so Register A becomes 0000 0011.

5001
5002
5003
RLCA
RLCA
RLCA
Rotate the bits in A left so that the offset moves bits 2, 1, and 0 to bits 5, 4, and 3 .
Original Source Code Comment: MOVE IT TO THE LSB (3 RLCAs — shift to bits 5,4,3)

Rotating 0000 0011 left 3 times, gives you 00 011 000.

5004
OR 80H
OR Register A against 80H (Binary: 1000 0000) to convert Register A (which is just bits 5, 4, and 3) into an appropriate RES OPCODE.
Original Source Code Comment: BIT 7 NEEDS TO BE ON (forms RES opcode)

80H is 1000 0000, so when you OR Register A (00 011 000) by 80H (1000 0000) you get 10 011 000. 10110000 in Hex is 0B0H.

5006
LD (500AH),ALD (CLRBT2),A
Store the value held in Register A into the memory location 500AH (i.e., the next opcode).
Original Source Code Comment: Store into self-modifying operand (CLRBT2 at 500AH)

Memory Location 500AH is in the middle of the next 2 instructions which are 0CB nn. Putting 0B0H in 500AH makes the next instruction 0CBH 0B0H, which is the Z-80 OPCODE for RES 6,B

5009
RES nn,B
RESet (i.e., set as 0) BIT (A) of Register B.
Original Source Code Comment: AND EXECUTE IT (self-modified RES nn,B instruction)
500B
RET
RETurn to the caller.
Original Source Code Comment: (return from CLRBIT)
 
END 4E00H