;************************************************************************** ; 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 ==============================