mirror of https://github.com/wwarthen/RomWBW.git
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.
240 lines
7.1 KiB
240 lines
7.1 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 ; BANKED
|
|
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 (1=Floppy,
|
|
; 2=Hard drive & 3=Memory drive)
|
|
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 ==============================
|
|
|