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.
 
 
 
 
 
 

239 lines
7.0 KiB

;**************************************************************************
; SELRWD - Select Physical Driver for Disk IO
;
; 1.4 - 23 Aug 01 - Cleaned up for GPL release. HFB
; 1.3 - 6 Aug 95 - Set flag in FDC-xx if Side-By-Sctr Continuous as
; special case where Head is 0 on both sides. HFB
; 1.1 - 7 May 94 - Corrected PWR2MSK to return B=0 if A=0. HFB
; 1.0 - 3 Jul 92 - First General Release. HFB
; 0.0 - 12 Jun 91 - Initial Test Release. HFB
;**************************************************************************
CSEG
SELDSK:
IF BANKED
CALL BIOSTK
CALL GOSYSB
JP SELDKV
COMMON /BANK2/
SELDKV:
ENDIF
LD A,C ; Set disk to seek
LD (SEKDSK),A
PUSH DE ; Save new mount flag
CALL GETDPH ; Return DPH pointer in DE
EX DE,HL ; Xfer to HL
POP DE ; (return DE in case bad select)
LD A,H
OR L ; Any drive defined here?
RET Z ; ..Return w/Select Error if not
PUSH DE ; New Mount back to stack
LD (SEKDPH),HL ; Save for future use
DEC HL
LD A,(HL)
LD (SEKPDN),A ; Save physical drive number
DEC HL ; advance to Driver Type (Hard/Floppy/RAM)
LD A,(HL) ; and Get it
DEC HL ; Now advance to Drive Type Byte
CP 1 ; Is this a Floppy Drive?
LD A,(HL) ; (get Type Byte in case)
JR NZ,SELDK0 ; ..jump if Not Floppy
DEC HL ; Back down to LOCKED flag
LD E,(HL) ; fetch
INC HL ; (restore ptr)
INC E ; (FF -> 00) Is the Format Locked?
JR Z,SELDK0 ; ..jump if so
PUSH HL ; Else save pointer
LD A,(SEKPDN) ; Get physical drive back
CALL PHYSCL ; Point to Physical Drive Config bytes
LD E,(HL) ; Get Characteristics for This Drive to E
POP HL ; and ptr to Drive Type Byte
LD A,(HL) ; Get the Byte again
AND 90H ; mask all but Double-Step & Double Dens
OR E ; Add in Physical characteristics
LD (HL),A ; Save back in DPH
SELDK0: LD (SEKDVT),A ; Save Drive Type Byte locally
POP DE ; Restore new mount flag
BIT 0,E ; New mount?
JR NZ,SETPARMS ; Set params if old mount
; We are selecting a probably-changed disk. Be sure the Host Buffer is
; updated with the latest stuff.
LD A,(HSTDSK)
SUB C ; See if this disk is in the host buffer
JR NZ,SELDSK0 ; If it isn't, keep what's there active
LD HL,HSTACT
LD (HL),A ; Else mark host buffer as unused
INC HL
LD (HL),A ; And cancel any pending writes
; Note: this will never happen from DOS as the directory write during file
; Close will properly flush the buffer. However, programs doing direct BIOS
; calls could exit with a write still pending. This is also true if DOS had
; a write file open and warm booted for any reason. the only safe thing to do
; in either case is to cancel the write on The assumption the disk has changed.
; Links to Physical Drivers
SELDSK0: XOR A ; Offset for select
DEFB 21H ; Trash HL and fall thru
READHST: LD A,2 ; Offset to read
DEFB 21H ; Trash HL and fall thru
WRITEHST:
LD A,4 ; Offset to write
AND A ; Test if seek or host drive required
LD HL,(HSTDPH) ; Assume host drive for now
JR NZ,SELDSK1 ; Go if we assumed correctly
LD HL,(SEKDPH)
SELDSK1: DEC HL
DEC HL
LD B,(HL) ; Save driver number
LD HL,DVRVCT ; Point to vector table
CALL ADDAHL ; Offset to routine
LD A,B ; Get driver number
ADD A,A ; *2
ADD A,B ; *3
ADD A,A ; *6 to index to proper entry
PUSH HL ; Save HL on Stack for return
JP VECTA
; Routine Vector Table
DVRVCT: DEFW SELERR ; Driver 0 Select
DEFW ISTRUE ; Driver 0 Read
DEFW ISTRUE ; Driver 0 Write
DEFW SELFLP ; Driver 1 Select (Floppy)
DEFW FREAD ; Driver 1 Read
DEFW FWRITE ; Driver 1 Write
IF HARDDSK
DEFW SELHD ; Driver 2 Select (Hard Drive)
DEFW HDREAD ; Driver 2 Read
DEFW HDWRIT ; Driver 2 Write
ENDIF ; harddsk
IF [RAMDSK AND NOT HARDDSK]
DEFW SELERR ; Driver 2 Select (Dummy if No Hard Drive)
DEFW ISTRUE ; Driver 2 Read
DEFW ISTRUE ; Driver 2 Write
ENDIF ;ramdsk & not harddsk
IF RAMDSK
DEFW SELRAM ; Driver 3 Select (RAM Drive)
DEFW RAMRD ; Driver 3 Read
DEFW RAMWR ; Driver 3 Write
ENDIF ;ramdsk
SELERR: LD HL,0 ; Send null DPH pointer back to caller
RET
;.....
; Set parameters for currently selected drive on Old or New mount.
; Set: CPMSPT, SEKSD, SEKSPD, SECSHF, SECMSK, UCOUNT, SEKFMT,
; Skew pointer in DPH
; Info source is DPB for drive obtained via DPHTBL
SETPARMS: LD A,(SEKDSK) ; Get Logical Drive being selected
CALL GETDPH ; Return DPH pointer in DE
LD HL,0AH ; Get offset to DPB pointer in DPH
ADD HL,DE
LD A,(HL)
INC HL
LD H,(HL) ; Fetch DPB pointer for selected format
LD L,A
PUSH HL ; Save DPB pointer
IF CALCSK
LD BC,-4 ; Point to Skew Factor
ELSE
LD BC,0FH ; Point to Skew Table at end of DPB
ENDIF
ADD HL,BC ; Point to skew
EX DE,HL ; Put DPH pointer in HL
LD (HL),E
INC HL
LD (HL),D ; Save as Skew Table pointer in DPH
DEC HL
EX DE,HL ; DPH pointer back to DE
POP HL ; Restore DPB pointer
LD A,(HL) ; Fetch logical Records per Track
LD (CPMSPT),A ; Save for deblocking logic
LD (SEKDPH),DE
LD (SEKDPB),HL
LD BC,-5 ; Back up
ADD HL,BC ; to Format Byte 1
LD A,(HL) ; Get it.
DEC HL
LD L,(HL) ; get Format Byte 0 also
LD H,A
PUSH AF ; (save Format Byte 1)
LD A,L ; Move Format Byte 0
AND 00111000B ; mask
SUB 00010000B ; Set special case of 0=Side-by-Sctr Cont
LD (TSBSCF),A ; save in FDC-xx
POP AF ; (restore byte 1)
AND 00111B ; Mask for Physical Sector Size
LD (SECSHF),A ; Save as Sector Shift count
CALL PWR2MSK ; Convert to 2 ** N-1 mask
LD (SECMSK),A ; Save result as Sector Mask
LD A,00111000B ; Mask for Alloc Size
AND H
RRA
RRA
RRA ; Put into low nibble
CALL PWR2MSK ; Calculate 2 ** N-1
INC A ; Now 2 ** N = Number of K per Alloc
RLA
RLA
RLA ; Mult by 8 records/K
LD (UCOUNT),A ; Save number of Records per Alloc Block
EX DE,HL ; Put DPH address back in HL
RET ; And return to caller
;.....
; Routine to set the A register to True (0FFH) or False (0)
; Depending on the state of the Z-Flag
SETTFZ: LD A,0 ; Load logical false
RET Z ; Return if false
DEC A ; Else set true to 0FFH
RET ; And exit
;.....
; Routine to create mask of 2**N-1, where N is passed in A. Returns
; Mask in A, B=0.
PWR2MSK: AND A ; Screen case of a=0
LD B,A ; (Use Shift Count to create mask)
RET Z ; Done if a=0
XOR A ; Clear mask
SPRM1: SCF ; Get a set bit to roll in
RLA ; Shift into LSB of Mask
DJNZ SPRM1 ; Loop until required bits set
RET
;.....
; Routine to return the DPH Pointer in DE for the Logical drive in A
GETDPH: ADD A,A ; Form table index value
LD HL,DPHTBL ; Point to DPH header table
CALL ADDAHL ; Index into table
LD E,(HL)
INC HL
LD D,(HL) ; DPH pointer for logical drive in DE
RET
IF BANKED
COMMON /B2RAM/
ELSE
DSEG
ENDIF
; RAM Storage
SEKPDN: DEFS 1 ; Physical drive number to use
SEKDVT: DEFS 1 ; Drive type byte for selected drive
;============================= End of SELRWD ==============================