Files
RomWBW/Source/BPBIOS/selrwd.z80
2015-08-19 17:34:42 +00:00

239 lines
7.0 KiB
Z80 Assembly
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;**************************************************************************
; 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 ==============================