4E00H - Entry Point - Process Routine Selection.
Original Source Code Comment: TEST REQUEST VECTOR CODE
Original Source Code Comment: TEST REQUEST VECTOR
Original Source Code Comment: DO CLOSE
Original Source Code Comment: (compare to VECT20)
Original Source Code Comment: (jump to SKILL if VECT20)
Original Source Code Comment: FILE NOT OPEN ERROR
Original Source Code Comment: SET NZ FLAG
Original Source Code Comment: (return from abort)
4E0FH - SCLOSE - MAIN ROUTINE - "CLOSE" - Close an Open File.
Original Source Code Comment: SAVE CALLERS REGISTERS
Original Source Code Comment: FILE NOT OPEN
Original Source Code Comment: DUMP OUT PARTIAL RECORD IF BLOCKED
Original Source Code Comment: CONTINUE IF GOOD WRITE
Original Source Code Comment: NO MORE EXTENTS?
Original Source Code Comment: YES. IT'S OKAY
Original Source Code Comment: DISK SPACE FULL?
Original Source Code Comment: NO, SOME OTHER ERROR
Original Source Code Comment: B = LFN (Logical File Number)
Original Source Code Comment: C = DRIVE
Original Source Code Comment: A = SIDE NUMBER
Original Source Code Comment: SET IT IN DOS
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
Original Source Code Comment: EXIT IF ERROR
NOTE: 4A67H is the SYS00/SYS routine to read the directory entry into RAM (Buffer at 4300H)
Original Source Code Comment: Read directory entry
Original Source Code Comment: DIR READ ERROR
Original Source Code Comment: SAVE THE DIRECTORY POINTER
Original Source Code Comment: WAS THIS A READ FILE?
Original Source Code Comment: YES, JUST RESET THE FILE NAME
Original Source Code Comment: (set up pointer offset of 3)
Original Source Code Comment: (add offset to L)
Original Source Code Comment: HL => DIR+3
Original Source Code Comment: SAVE HL
Original Source Code Comment: GET EOF BYTE
Original Source Code Comment: CP TO DIR EOF
Original Source Code Comment: JR IF EOF BYTE MOVED
Original Source Code Comment: (set up pointer offset of 17 decimal)
Original Source Code Comment: (add offset to L)
Original Source Code Comment: HL => DIR+20
Original Source Code Comment: ERN (PHYSICAL) — End Record Number LSB
Original Source Code Comment: (compare ERN LSB to directory)
Original Source Code Comment: JR IF EOF PRN (LSB) ALTERED
Original Source Code Comment: (bump to MSB)
Original Source Code Comment: GET EOF MSB — End Record Number MSB
Original Source Code Comment: (compare ERN MSB to directory)
Original Source Code Comment: JR IF EOF PRN (MSB) ALTERED
Original Source Code Comment: CLEAN STACK
4E5DH - CLOSE1 - Continuation of the CLOSE routine. This routine will update the the directory.
Original Source Code Comment: HL => DIR+3
Original Source Code Comment: (get EOF byte from DCB)
Original Source Code Comment: UPDATE THE EOF BYTE
Original Source Code Comment: BUMP TO LRL
Original Source Code Comment: GET IT — Logical Record Length
Original Source Code Comment: INTO THE DIRECTORY
Original Source Code Comment: (set up pointer offset of 16)
Original Source Code Comment: (add offset to L)
Original Source Code Comment: HL => DIR+20
Original Source Code Comment: NEW ERN (LSB) — new End Record Number
Original Source Code Comment: UPDATE IT
Original Source Code Comment: (bump to MSB)
Original Source Code Comment: ERN (MSB)
Original Source Code Comment: (update MSB in directory)
Original Source Code Comment: HL => BEGIN OF EXTENTS
Original Source Code Comment: OFFSET TO BEGIN OF EXTENSIONS
Original Source Code Comment: SAVE DCB POINTER
Original Source Code Comment: ADD TO THE DCB POINTER
Original Source Code Comment: MOVE IT TO DE (via PUSH IX/POP DE)
Original Source Code Comment: (POP DE = IX+EXTBEG)
Original Source Code Comment: GET DCB POINTER BACK
Original Source Code Comment: HL=> DCB EXT, DE=> DIR EXT
Original Source Code Comment: SAVE THE DIR POINTER
Original Source Code Comment: NUMBER OF BYTES IN EXT (NUMSEG = 001AH = 26 bytes)
Original Source Code Comment: MOVE IT INTO THE DIRECTORY
Original Source Code Comment: GET THE DRIVE NUMBER
Original Source Code Comment: GET THE FILE NUMBER
Original Source Code Comment: GET THE SIDE NUMBER
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: Set CSIDE in DOS
Original Source Code Comment: WRITE NEW DIR RECORD
Original Source Code Comment: RESTORE POINTER
Original Source Code Comment: DIR WRITE ERROR
Original Source Code Comment: (DEC L to set up for INC L — effectively a no-op to align)
Original Source Code Comment: HL => 1ST SEG DESC
Original Source Code Comment: DE = SEG POINTER
Original Source Code Comment: GET THE END RECORD NUMBER (LSB)
Original Source Code Comment: (ERN MSB)
Original Source Code Comment: CORRECT FOR 1'S OFFSET
Original Source Code Comment: NUMBER OF RECORDS PER GRAN (DGRAN = 3)
Original Source Code Comment: HL = NUMBER OF GRANS FOR THIS FILE
Original Source Code Comment: WAS THERE A REMAINDER?
Original Source Code Comment: NO, CONTINUE
Original Source Code Comment: BUMP FOR THE REMAINDER
Original Source Code Comment: GET THE MAX NUMBER OF EXTENTS (MAXEXT-1 = 12 decimal)
Original Source Code Comment: SET A COUNTER
Original Source Code Comment: BUMP PAST TRACK NUMBER
Original Source Code Comment: GET THE ALLOCATION BYTE
- 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?
Original Source Code Comment: YES, EXIT
Original Source Code Comment: MASK OFF STARTING GRAN
Original Source Code Comment: INTO BC
Original Source Code Comment: (B=0, so BC = number of grans)
Original Source Code Comment: CLEAR CARRY
Original Source Code Comment: SUB THE GRANS IN THIS SEG FROM TOTAL
Original Source Code Comment: WE'RE AT 0 SEE IF ANY FURTHER SEG DESC
Original Source Code Comment: WENT TOO FAR. THERE'S SOME IN THIS ONE
Original Source Code Comment: BUMP TO NEXT TRACK NUMBER
Original Source Code Comment: REMAINING NUMBER OF EXTENTS HERE (self-modifying: CLOCNT)
Original Source Code Comment: SUBTRACT ONE
Original Source Code Comment: SAVE FOR NEXT TIME
Original Source Code Comment: CONTINUE IF NOT OUT OF EXTENTS
Original Source Code Comment: EXIT. NOTHING DONE
4ECEH - CHKEND - Continuation from the "CLOSE" routine; jumped to if the EOF < 0.
Original Source Code Comment: GET THE NUM OF GRANS THIS SEG TO RELEASE
Original Source Code Comment: FLIP IT (negate)
Original Source Code Comment: BACK INTO L FOR THE MOMENT
Original Source Code Comment: GET THE SEG DESCRIP
Original Source Code Comment: SUBTRACT THAT NUMBER FROM IT
Original Source Code Comment: STORE NEW DESCRIPTOR
Original Source Code Comment: SAVE HL
Original Source Code Comment: PLACE TO RETURN TO (CHKDON = 4EF3H)
Original Source Code Comment: PUT IT ON THE STACK
Original Source Code Comment: SAVE THE REGISTERS
Original Source Code Comment: (push DE)
Original Source Code Comment: (push BC)
Original Source Code Comment: SET THE NUMBER INTO (C) FOR COUNTER
Original Source Code Comment: HL => SEG DESCRIPTORS
Original Source Code Comment: GET THE DESCRIPTOR
Original Source Code Comment: SAVE IT
Original Source Code Comment: MASK THE STARTING GRAN
Original Source Code Comment: SET AS OFFSET COUNTER
Original Source Code Comment: GET THE SEG DESC BACK
Original Source Code Comment: MASK OF NUMBER OF GRANS
4EE8
4EE9
RLCA
RLCA
Original Source Code Comment: MOVE IT TO THE LSB (3 RLCAs)
Original Source Code Comment: SAVE IT
Original Source Code Comment: BACK UP TO THE TRACK NUMBER
Original Source Code Comment: GET IT
Original Source Code Comment: HL => THIS TRACK'S GAT BYTE (BUFF2.HIGH. = 4DH)
Original Source Code Comment: GET STARTING GRAN BACK
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.
Original Source Code Comment: (CHKDON entry) — check for more extents
Original Source Code Comment: BUMP TO NEXT TRACK
Original Source Code Comment: GET THE TRACK NUMBER
- 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?
Original Source Code Comment: YES, WRITE OUT THE BUFFERS
Original Source Code Comment: GET THE TRACK NUMBER
Original Source Code Comment: RELEASE THE TRACK (mark 0FFH)
Original Source Code Comment: BUMP TO SEG DESC
Original Source Code Comment: GET IT
Original Source Code Comment: RELEASE THE GRANS (mark 0FFH)
Original Source Code Comment: BUMP TO NEXT TRACK
Original Source Code Comment: RELEASE THE GRANS
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.
Original Source Code Comment: GET THE FILE NUMBER (LFN)
Original Source Code Comment: AND THE DRIVE NUMBER
Original Source Code Comment: GET THE SIDE NUMBER
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: SET IT IN DOS (CSIDE)
Original Source Code Comment: WRITE OUT THE ALLOCATION TABLE (WRGAT)
Original Source Code Comment: EXIT IF ERROR
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)
Original Source Code Comment: EXIT IF ERROR
Original Source Code Comment: Get drive number from DCB
Original Source Code Comment: CONVERT DRIVE TO ASCII
Original Source Code Comment: AND SAVE IT (self-modifying RESDRV at 4F59H)
Original Source Code Comment: DIR REC BUFFER POINTER STORED HERE (self-modifying SAVEXP)
Original Source Code Comment: OFFSET TO NAME (DNAME = 5)
Original Source Code Comment: HL => NAME
Original Source Code Comment: SAVE HL
Original Source Code Comment: (PUSH IX — DCB pointer)
Original Source Code Comment: DE => DCB
Original Source Code Comment: (loop 8 chars for filename)
Original Source Code Comment: (get character from directory)
Original Source Code Comment: JR IF SHORT FILE NAME (space = end)
Original Source Code Comment: (skip if space found)
Original Source Code Comment: RESTORE THE FILE NAME (copy char to DCB)
Original Source Code Comment: (next source char)
Original Source Code Comment: (next dest position)
Original Source Code Comment: (loop for 8 chars)
Original Source Code Comment: (restore HL to directory pointer)
Original Source Code Comment: (prepare to skip 8 chars to extension)
Original Source Code Comment: (add 8 to L)
Original Source Code Comment: HL => DIR+13 (extension)
Original Source Code Comment: (check first char of extension)
Original Source Code Comment: JR IF NOT EXTENSION (space = no ext)
Original Source Code Comment: (jump if no extension)
Original Source Code Comment: DELIMIT THE EXT (slash separator)
Original Source Code Comment: (store slash in DCB)
Original Source Code Comment: (bump DE)
Original Source Code Comment: (loop 3 chars for extension)
Original Source Code Comment: (get extension char)
Original Source Code Comment: JR IF SHORT EXTENSION
Original Source Code Comment: (skip if space found)
Original Source Code Comment: RESTORE THE EXTENSION
Original Source Code Comment: (next source char)
Original Source Code Comment: (next dest position)
Original Source Code Comment: (loop for 3 chars)
Original Source Code Comment: DELIMIT THE DRIVE (colon)
Original Source Code Comment: (store colon in DCB)
Original Source Code Comment: (bump DE)
Original Source Code Comment: GET THE DRIVE (self-modifying RESDRV — ASCII drive number)
Original Source Code Comment: PLACE IN FILE SPEC
Original Source Code Comment: (bump DE)
Original Source Code Comment: TERMINATE THE FILE SPEC (03H = end-of-text marker)
Original Source Code Comment: (store terminator)
Original Source Code Comment: (XOR A — clear A and flags for no error)
Original Source Code Comment: (return — close/reset complete)
4F61H - SKILL - MAIN ROUTINE - "KILL" - Delete a file from the directory.
Original Source Code Comment: SAVE CALLERS REGISTERS
Original Source Code Comment: FILE IS NOT OPEN
Original Source Code Comment: (get protection/access byte from DCB)
Original Source Code Comment: (mask to low 3 bits — access level)
- 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)
Original Source Code Comment: JR IF IT WAS GRANTED
Original Source Code Comment: ILLEGAL ACCESS ATTEMPTED (EFAD error code)
Original Source Code Comment: (set NZ for error)
Original Source Code Comment: (return with error)
4F72H - KILL1 - Continuation of "KILL" Routine. Jumped here if we have access to kill the file.
Original Source Code Comment: C = DRIVE NUM
Original Source Code Comment: B = LFN
Original Source Code Comment: GET THE SIDE NUMBER
NOTE: 4463H is the storage location for the old system disk side number.
Original Source Code Comment: SET IT IN DOS (CSIDE)
NOTE: 4ABAH is the SYS00/SYS routine to read the HIT sector into RAM.
Original Source Code Comment: READ IN HASH INDEX TABLE (RDHIT)
Original Source Code Comment: (return if error)
Original Source Code Comment: HL => THIS HIT CODE
Original Source Code Comment: CLEAR IT OUT
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)
Original Source Code Comment: EXIT IF ERROR
NOTE: 4A93H is the SYS00/SYS routine to READ THE GAT sector into RAM (Buffer at 4D00H).
Original Source Code Comment: (read GAT — RDGAT)
Original Source Code Comment: (return if error)
NOTE: 4A67H is the SYS00/SYS routine to read the directory entry into RAM (Buffer at 4300H)
Original Source Code Comment: (read directory — RDDIR)
Original Source Code Comment: (return if error)
Original Source Code Comment: SAVE POINTER TO FRONT OF THIS DIR (self-modifying SAVPNT at 4FACH)
Original Source Code Comment: Offset to extents (DSEG = 22 = 16H)
Original Source Code Comment: (add to L)
Original Source Code Comment: HL => DIR+22
Original Source Code Comment: SAVE LFN AND DRIVE NUMBER
Original Source Code Comment: GET THE MAXIMUM NUMBER OF EXTENTS (MAXEXT = 0DH = 13)
Original Source Code Comment: Get segment descriptor pair — track byte
Original Source Code Comment: (bump to allocation byte)
Original Source Code Comment: Get allocation byte into D
Original Source Code Comment: (copy E for comparison)
- 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)
Original Source Code Comment: (jump if end of extents)
Original Source Code Comment: (bump past allocation byte)
Original Source Code Comment: SAVE THE COUNTER
Original Source Code Comment: RELEASE THIS SEGMENT (call RELEAS)
Original Source Code Comment: GET THE COUNTER BACK
Original Source Code Comment: (loop through all extents via DJNZ)
Original Source Code Comment: FRONT OF DIR REC SAVED HERE (self-modifying SAVPNT)
Original Source Code Comment: CLEAR OUT THE DIR REC
Original Source Code Comment: (save DE)
4FB2
LD D,H
Original Source Code Comment: GET HL INTO DE
Original Source Code Comment: PROPAGATE THE X'00' THRU DIR REC (INC DE for LDIR)
Original Source Code Comment: SIZDIR-1 = 002FH (47 bytes)
Original Source Code Comment: CLEAR THE DIR REC
Original Source Code Comment: (restore DE)
Original Source Code Comment: RESTORE REGS
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)
Original Source Code Comment: (return if error)
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)
Original Source Code Comment: (return if error)
4FC5
POP HL
Original Source Code Comment: (PUSH IX / POP HL = HL = IX = DCB pointer)
Original Source Code Comment: Loop counter: EXTBEG = 10H = 16 bytes
Original Source Code Comment: (XOR A = zero)
Original Source Code Comment: (zero out DCB byte)
Original Source Code Comment: (next byte)
Original Source Code Comment: (loop until 16 bytes cleared)
Original Source Code Comment: (return — kill complete)
4FCEH - RELEAS - SUBroutine to De-Allocate Space.
Original Source Code Comment: SAVE THE REGISTERS
Original Source Code Comment: (push DE)
Original Source Code Comment: (push BC)
Original Source Code Comment: HL => 1ST GAT BYTE OF SEGMENT
Original Source Code Comment: (H = BUFF2.HIGH. = 4DH — GAT buffer high byte)
Original Source Code Comment: A = ALLOCATION BYTE
Original Source Code Comment: MASK OFF STARTING GRAN
Original Source Code Comment: SAVE NUMBER OF GRANS IN C
Original Source Code Comment: A = STARTING GRAN (XOR isolates high bits)
4FDA
4FDB
RLCA
RLCA
Original Source Code Comment: SHIFT IT TO LSB (3 RLCAs — A = 1ST GRAN # WITHIN SEGMENT)
Original Source Code Comment: SET A OFFSET COUNTER
Original Source Code Comment: SAVE STARTING GRAN
Original Source Code Comment: SAVE BUFFER POINTER
Original Source Code Comment: ADD THE COUNTER TO STARTING GRAN
Original Source Code Comment: PUT IT INTO HL
Original Source Code Comment: (H=0 so HL = A)
Original Source Code Comment: NUMBER OF GRANS PER TRACK (NGRAN = 6)
Original Source Code Comment: (divide: RET A=BIT NUMBER, L=TRACK OFFSET)
Original Source Code Comment: SAVE THE BIT NUMBER
Original Source Code Comment: GET THE TRACK OFFSET
Original Source Code Comment: GET THE GAT POINTER BACK
Original Source Code Comment: SAVE IT
Original Source Code Comment: ADD IN THE TRACK OFFSET
Original Source Code Comment: INTO HL => GAT BYTE TO RELEASE
Original Source Code Comment: GET THE BIT NUMBER BACK
Original Source Code Comment: B=GAT BYTE
Original Source Code Comment: RELEASE ONE GRAN (call CLRBIT)
Original Source Code Comment: (store modified GAT byte back)
Original Source Code Comment: GET GAT POINTER BACK
Original Source Code Comment: (restore AF)
Original Source Code Comment: (increment offset counter)
Original Source Code Comment: DEC C — loop counter for grans
Original Source Code Comment: JR IF MORE TO BE RELEASED
Original Source Code Comment: (restore BC)
Original Source Code Comment: (restore DE)
Original Source Code Comment: (restore HL)
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...
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.
5002
5003
RLCA
RLCA
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.
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.
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
Original Source Code Comment: AND EXECUTE IT (self-modified RES nn,B instruction)
Original Source Code Comment: (return from CLRBIT)