You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

417 lines
10 KiB

;**************************************************************************
; DEBLOCK - Disk Deblocking Buffer Routines. (Based on CP/M Example code)
;
; 1.1 - 14 Jun 16 - eliminated unnecessary disk accessess WW
; 1.0 - 3 Jul 92 - First General Release. HFB
; 0.0 - 8 Jul 91 - Initial Test Release. HFB
;**************************************************************************
CSEG
;.....
; Set DMA address given by registers B and C
SETDMA:
LD (DMAADR),BC ; Save the address
; CALL PRTSTRD
; DEFB '[SETDMA',']$'
RET
;.....
; Set track given by BC. While the entire word is saved here, only the
; lower byte is used in Floppy, SCSI and RAM Drivers.
SETTRK:
LD (SEKTRK),BC
; CALL PRTSTRD
; DEFB '[SETTRK$'
; CALL PRTHEXWORD
; CALL PRTSTRD
; DEFB ']$'
RET
;.....
; Set sector given by register C. This Sector number is the physical number
; of the desired sector and assumes that SECTRAN has been called. This value
; should reflect the Sector Number returned from SECTRAN. While the entire
; word is saved here, only the lower byte is used in Floppy, SCSI and RAM.
SETSEC:
LD (SEKSEC),BC
; CALL PRTSTRD
; DEFB '[SETSEC$'
; CALL PRTHEXWORD
; CALL PRTSTRD
; DEFB ']$'
RET
;.....
; Home the selected drive
HOME:
; CALL PRTSTRD
; DEFB '[HOME]$'
RET ; Done by SELDSK
;.....
; Flush the host buffer to disk if any writes pending
FLUSH:
; CALL PRTSTRD
; DEFB '[FLUSH]$'
LD A,(HSTWRT) ; Write pending?
OR A
RET Z ; ..quit if nothing pending
IF BANKED
CALL BIOSTK
CALL GOSYSB
ENDIF
JP WRITEHST ; Write host buffer to disk if so
;.....
; Sector blocking and de-blocking routines. Drive numbers used in these
; routines are logical drives.
READ:
; CALL PRTSTRD
; DEFB '[READ]$'
IF BANKED
CALL BIOSTK
CALL GOSYSB
JP JBREAD
COMMON /BANK2/
ENDIF
BREAD: LD A,1 ; Non-zero
LD (READOP),A ; Read operation
INC A ; Treat as un-allocated (=wrual)
LD (WRTYPE),A ; Save it
; JR ALLOC ; Go to common code
JP ALLOC ; Go to common code
CSEG
WRITE:
; PUSH AF
; LD A,C
; CALL PRTSTRD
; DEFB '[WRITE($'
; CALL PRTHEXBYTE
; CALL PRTSTRD
; DEFB ')]$'
; POP AF
IF BANKED
CALL BIOSTK
CALL GOSYSB
JP JBWRT
COMMON /BANK2/
ENDIF
BWRT: XOR A
LD (READOP),A ; Write operation
LD A,C ; Get write type from dos
; CALL PRTHEXBYTE
LD (WRTYPE),A ; Save it
CP WRUAL ; Unallocated write?
JR NZ,CHKUNA ; ..jump if Not. check for unallocated sector
; Write to un-allocated sector, set parameters
; CALL PRTSTRD
; DEFB '[SETPARMS]$'
LD A,(UCOUNT) ; Records/allocation group
; CALL PRTHEXBYTE
LD (UNACNT),A ; Unallocated count
LD HL,SEKDSK ; Selcted disk, track & sector for us
LD DE,UNADSK ; (unadsk=sekdsk)
LD BC,4 ; (unatrk=sektrk)
LDIR ; (unasec=cpmsec)
CHKUNA:
; CALL PRTSTRD
; DEFB '[TP0]$'
LD A,(UNACNT) ; Any unallocated records remaining?
OR A
JR Z,ALLOC ; ..jump if none remain
; CALL PRTSTRD
; DEFB '[TP1]$'
; More unallocated records remain. Check for any change.
DEC A ; Decrement unallocated count
LD (UNACNT),A ; And save it
LD B,4 ; Compare four bytes
LD HL,UNADSK ; Compare Old Disk, Track & Sector
LD DE,SEKDSK ; .to New Disk, Track & Sector
SLP0: LD A,(DE)
; CALL PRTHEXBYTE
CP (HL) ; Same?
; LD A,(HL) ; WW
; CALL PRTHEXBYTE
JR NZ,ALLOC ; ..jump if not
INC HL ; Else advance to next
INC DE
DJNZ SLP0 ; ..and loop til done
; Everything matches, anticipate the next sector
; CALL PRTSTRD
; DEFB '[MATCH]$'
;**********************
DEC HL ; **** WW ****
;**********************
INC (HL) ; Unasec+1
LD A,(CPMSPT) ; Max sectors per track
CP (HL) ; Compare them
JR NZ,NOOVF ; ..jump if not ready for new track yet
; Overflow to next track
LD (HL),0 ; Unasec = 0
LD HL,(UNATRK)
INC HL
LD (UNATRK),HL ; Unatrk+1
; Match found. Pre-read not necessary.
NOOVF: XOR A ; Indicate no pre-read required
JR ALLOC1 ; ..and jump to common code
; Not an unallocated record. Requires pre-read
ALLOC:
; CALL PRTSTRD
; DEFB '[ALLOC]$'
XOR A ; Clear acc
LD (UNACNT),A ; Start over
INC A
ALLOC1: LD (RSFLAG),A ; Force pre-read if a=1
; Read/Write common code
XOR A ; Clear acc
LD (ERFLAG),A ; Start with no errors
LD A,(SEKSEC) ; Get logical sector number
CALL PHYSEC ; Get physical sector
LD (SEKHST),A ; Physical sector (rel 0)
; Check host active
LD HL,HSTACT ; Host active flag
LD A,(HL) ; Get it
LD (HL),1 ; Set it in any case
OR A ; Set flags
JR Z,FILHST ; Flush Host Buffer if needed, then Read
; Host buffer is active. Same as seek buffer?
LD B,3 ; Loop compare of Disk and Track
LD HL,HSTDSK ; Compare Old Logical Disk & Trk
LD DE,SEKDSK ; .to New Logical Disk & Trk
SLP1: LD A,(DE)
CP (HL) ; Same?
JR NZ,FILHST ; ..jump if not same
INC HL ; Else advance to next
INC DE
DJNZ SLP1 ; ..loop til done
; Same track. Same host sector?
LD A,(SEKHST) ; New physical sector
CP (HL)
JR Z,MATCH ; The same
; Not a match.
FILHST: CALL FLUSH ; Empty hstbuf if write pending
; Fill the host buffer if necessary.
LD HL,SEKDSK ; Hstdsk=sekdsk
LD DE,HSTDSK ; Hsttrk=sektrk
LD BC,3
LDIR ; Move it
LD A,(SEKHST) ; Move the Sector too
LD (DE),A
INC DE
INC HL
INC HL ; Skip over logical sector
LD C,4 ; B=0 from above
LDIR ; Set Host DPH and DPB, physical sector
LD A,(RSFLAG) ; Pre-read necessary?
OR A
CALL NZ,READHST ; Read a sector if so.
XOR A ; Clear acc
LD (HSTWRT),A ; Clear write pending flag
; We have a match.
MATCH: LD A,(SECMSK) ; Get the sector mask
LD B,A ; Save it
LD A,(SEKSEC) ; Get new sector
AND B ; Mask off the high bits
RRA
LD H,A ; *128 MSB
LD L,0
RR L ; And LSB
; HL now has relative host buffer address of seksec
IF HBIOS
;
; Modified to use HBIOS host buffer
;
LD A,BID_HB ; HSTBUF is in HBIOS
LD C,A
IF BANKED
LD A,(DMABNK) ; Set Read Destination Bank
ELSE
LD A,(TPABNK) ; Set Read Destination Bank
ENDIF
LD B,A
LD A,(READOP) ; Direction?
OR A
JR NZ,OKBNKS ; ..jump if read
LD A,B ; Else reverse banks
LD B,C
LD C,A
OKBNKS: CALL HBX_XCOPY ; Set source & destination banks
; LD DE,HBBUF ; Host buffer address in HBIOS bank
LD DE,(HB_DSKBUF) ; Host buffer address in HBIOS bank
ADD HL,DE ; Point to the sector
LD DE,(DMAADR) ; User's buffer
LD BC,128 ; Number of bytes to transfer
LD A,(READOP) ; Direction?
OR A ; Set flags
JR NZ,RWMOVE ; ..jump if Read
; Must be Write. Mark and change direction.
INC A ; A = 1
LD (HSTWRT),A ; Set write pending flag
EX DE,HL ; Swap source and destination
; Move the data
RWMOVE: CALL HBX_COPY ; Handle possible inter-bank move
ELSE ; HBIOS
IF BANKED
IF INROM
LD A,(TPABNK) ; If bank in ROM, HSTBUF is in TPA
LD C,A
ELSE
LD A,(SYSBNK) ; If bank in RAM, HSTBUF is in System Bank
LD C,A
ENDIF ;INROM
LD A,(DMABNK) ; Set Read Destination Bank
LD B,A
LD A,(READOP) ; Direction?
OR A
JR NZ,OKBNKS ; ..jump if read
LD A,B ; Else reverse banks
LD B,C
LD C,A
OKBNKS: CALL XMOVE ; Set source & destination banks
ENDIF ;BANKED
LD DE,HSTBUF ; Host buffer address
ADD HL,DE ; Point to the sector
LD DE,(DMAADR) ; User's buffer
LD BC,128 ; Number of bytes to transfer
LD A,(READOP) ; Direction?
OR A ; Set flags
JR NZ,RWMOVE ; ..jump if Read
; Must be Write. Mark and change direction.
INC A ; A = 1
LD (HSTWRT),A ; Set write pending flag
EX DE,HL ; Swap source and destination
; Move the data
RWMOVE: CALL MOVE ; Handle possible inter-bank move
ENDIF ; HBIOS
; Data has been moved
LD A,(WRTYPE)
DEC A ; Directory write? set zero flag
LD A,(ERFLAG) ; In case of error
RET NZ ; ..go home if not a directory write
; This was a Directory Write. Write it now!
OR A ; Check error flag
RET NZ ; ..exit here if any error
LD (HSTWRT),A ; Clear write pending flag
CALL WRITEHST ; Write to disk
LD A,(ERFLAG) ; .Load resulting status
RET ; ..return it to caller
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Blocking/De-blocking variables
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DSEG ; These variables must ALWAYS be visable, so put here
;.....
; Parameters relating to what we need in the Buffer Next
SEKSEC: DEFS 2 ; New skewed logical sector to seek
; --- The Following Variables MUST be kept in this order ---
SEKDSK: DEFS 1 ; New disk
SEKTRK: DEFS 2 ; New track
CPMSEC: DEFS 2 ; New logical sector
SEKDPB: DEFS 2 ; DPB for host
SEKDPH: DEFS 2 ; DPH for host
SEKHST: DEFS 1 ; New host physical sector to seek
;-----------------------------------------------------------
; Parameters relating to what's in the Buffer Now
; --- The Following Variables MUST be kept in this order ---
HSTDSK: DEFS 1 ; Current disk
HSTTRK: DEFS 2 ; Current track
HSTSEC: DEFS 1 ; Current physical sector
HSTDPB: DEFS 2 ; DPB for host
HSTDPH: DEFS 2 ; DPH for host
HSTACT: DEFS 1 ; Host buffer active flag
HSTWRT: DEFS 1 ; Host buffer write pending flag
;-----------------------------------------------------------
UCOUNT: DEFS 1 ; Number of logical records per alloc block
CPMSPT: DEFS 2 ; Logical sectors per track (byte)
SECSHF: DEFS 1 ; Sector shift factor
SECMSK: DEFS 1 ; Sector mask
DMAADR: DEFS 2 ; User's DMA buffer
IF BANKED AND NOT INROM
COMMON /B2RAM/ ; These values only used internally, bank them!
ENDIF
RSFLAG: DEFS 1 ; Read sector flag 0=skip, 1=read
READOP: DEFS 1 ; Read operation flag 1=read, 0=write
WRTYPE: DEFS 1 ; Write type 0=allocated, 1=dir, 2=unallocated
;.....
; Parameters to track Pre-Read Requirements
; --- The Following Variables MUST be kept in this order ---
UNADSK: DEFS 1 ; Current disk
UNATRK: DEFS 2 ; Current track
UNASEC: DEFS 1 ; Current record
;-----------------------------------------------------------
UNACNT: DEFS 1 ; Unallocated record count
;========================= End of DEBLOCK =================================