;************************************************************************** ; Hardware Independent Floppy Drive Routines ; ; This module uses information from HSTDPH/HSTDPB and other HST values to ; access Floppy drives. It establishes physical parameters, performs ; logical to physical mapping of Track/Sector/Head information and links ; to Physical Read/Write routines in module FDC-xx. ; ; 1.4 - 23 Aug 01 - Cleaned up for GPL release. HFB ; 1.3 - 6 Aug 95 - Mod to handle Kaypro4 (Double-sided, continuous ; Sector #s w/Head = 0 on both side's Gap records. HFB ; 7 Jan 95 - Correct calcs for reversed Side 1 (Ken Owen fix) HFB ; 3 Jul 92 - First General Release. HFB ; 8 Jul 91 - Initial test release HFB ;************************************************************************** IF BANKED COMMON /BANK2/ ELSE CSEG ENDIF ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Read/Write Host Buffer ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Physical Write of "HSTSIZ" bytes from HSTBUF. Return Error Flag in ERFLAG ; and in Registers AF. This routine assumes that parameters are set as: ; HSTDSK = Host Disk #, HSTTRK = Host Track #, HSTSEC = Host Sect #. FWRITE: XOR A ; Get Write Clear value & RDOP Write Value LD (HSTWRT),A ; say there is no pending Write JR FRWHST ; and link with common code below ; Physical Read of "HSTSIZ" bytes from HSTBUF. Return Error Flag in ERFLAG ; and in Registers AF. This routine assumes that parameters are set as: ; HSTDSK = Host Disk #, HSTTRK = Host Track #, HSTSEC = Host Sect #. FREAD: LD A,1 ; Set Read Value for RDOP ; Linkage to FDC Dependent routines FRWHST: LD (RDOP),A CALL FSETHD ; Sort out track, sector, and head JP FHDRW ; Jump to hardware dependent r/w code PAGE ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; FSETHD - Routine to set the Head Number, Sector and Track for FDC ; Operation. This routine uses the "HST" values and DPH in order to ; set things up. This routine is Hardware Independent. ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: IF BANKED COMMON /BANK2/ ELSE CSEG ENDIF FSETHD: LD C,0 ; Set head to 0 for now LD HL,(HSTDPB) ; Get DPB pointer DEC HL LD B,(HL) ; Get # tracks per side DEC HL ; Point to physical SPT LD A,(HL) LD (FDPSPT),A ; Save for FDC DEC HL LD A,(HL) LD (FDSOFF),A ; Save sector offset LD (FDS1OF),A ; For side 1 also DEC HL DEC HL ; Point to format byte 1 BIT 7,(HL) CALL SETTFZ ; Get high speed flag LD (FDSPD),A ; Set speed for FDC LD A,00000111B ; Mask for Sector Size AND (HL) LD (FDSECS),A ; Set Sector Size for FDC DEC HL ; Point to Format Byte 0 BIT 7,(HL) ; Test for Single-Density format CALL SETTFZ LD (FDSDEN),A ; Save Single-Density flag LD A,(HSTTRK) ; Max track is 160 AND A ; Set flags if Track 0 LD E,A ; Put in E JR NZ,FSETH1 ; If not Track 0 (always side 0) BIT 6,(HL) JR Z,FSETH1 ; Test for Track 0 Single-Density LD A,0FFH LD (FDSDEN),A ; Set to Single-Density if Trk 0 is SD INC A LD (FDSECS),A ; And force 128 byte sectors FSETH1: LD A,(HSTSEC) LD D,A ; So stick sector in D LD A,00111000B ; Mask for Double-Side mode AND (HL) JR Z,SETHTS ; Skip if 1-sided CP 00100000B ; Select Side-by-Sector? JR C,SBYSEC ; ..jump if Yes CP 00110000B ; Select by Track LSB? JR Z,SBYTLS ; ..jump if Yes CP 00101000B ; Select Side by Track MSB. Is Side 2 Reversed? JR Z,REVTS2 ; ..jump if Yes SUB 00010000B ; Select Side by Sector, Cont, Hd always 0? LD (TSBSCF),A ; 0 if So (Save as flag in FDC-xx) LD A,E ; Get Track SUB B ; Is it Side 0? JR C,SETHTS ; ..jump if Side 0 UPTRK: LD E,A ; Else update Track UPTRK1: DEC C ; Set Head 1 JR SETHTS ; ..and exit REVTS2: LD A,E ; Get Track SUB B ; Is it Side 0? JR C,SETHTS ; ..jump if so ;; - Change from 2's complement to 1's complement per Ken Owen (Chameleon) ;; NEG ; Make Track negative CPL ; Make Track Negative (1's complement) ADD A,B ; Add to Tracks/Side to flip JR UPTRK ; Update Head and Track, exit SBYTLS: SRL E ; Divide Track by 2, Carry is Head JR NC,SETHTS ; ..jump if Head 0 JR UPTRK1 ; Else set to Head 1 and exit SBYSEC: SUB 00010000B ; Test for Cont Sctr Numbers CALL SETTFZ ; A=0 if Continuous, FF if Same LD B,A ; save same Sect # front and back flag INC HL INC HL INC HL INC HL ; Point to physical SPT SRL E ; Divide Track by 2 w/LSB going to Carry JR NC,SETHTS ; ..jump if Head 0 (Even tracks) DEC C ; Indicate Head 1 INC B ; Test if Sector # Ok JR Z,SETHTS ; ..jump if Sector Numbers same on both sides ; Else Side 1 continues from Side 0 Sctr #s LD A,(FDSOFF) ; Get starting Sector for Side 0 ADD A,(HL) ; Add number of sectors on Side 0 LD (FDS1OF),A ; save as first Sector on Side 1 ; Track (E), Side(Head in C), and Sector(D) are now sorted out, Command the FDC SETHTS: LD HL,(HSTDPH) DEC HL ; Point to Unit ID for drive LD A,4 AND C ; Mask head OR (HL) ; Or with unit number CALL STHDRV ; Set Head and Drive (and HDR variable) DEC HL DEC HL ; Point to Drive Type Byte LD A,DBLSTP AND (HL) ; Set NZ if Double-Step Enabled LD (STEP2),A ; save in FDC module LD A,E ; Get Track # LD (TTRK),A ; save in FDC module LD A,(FDS1OF) ; Get sector offset LD B,A ; Save for later IF CALCSK ADD A,D ; Offset the Sector ELSE LD A,D ; Get Sector - already offset ENDIF PUSH AF ; Save Desired Sector # for more work LD A,(FDPSPT) ; Get Sectors/Track (SPT) DEC B ; Adjust SPT to Base 0 ADD A,B ; .add sector Offset LD E,A ; Save Last Sector number LD A,(FDSECS) ; Get Sector Size LD D,A POP AF ; restore desired Sector # CALL STSECT ; Set all Sector data LD A,00000111B AND (HL) ; Mask for Drive size LD E,A BIT 5,(HL) ; Test for motor required CALL SETTFZ LD D,A ; Save motor flag LD A,(FDSPD) CALL STSIZE ; Let FDC know Speed, Size, and Motor LD A,(FDSDEN) ; Get SD/DD Mode CALL STMODE ; set in FDC module ;..fall thru to following and return to caller ; Gather parameters for this physical drive and set FDC module accordingly DOSPEC: LD A,(HDR) ; Get drive in lower 3 bits PUSH DE ; save regs needed elsewhere CALL SPCIFY ; and load registers for Specify command CALL SPEC ; Set Step, Head Load and Unload times POP DE RET ;..... ; Get drive parameters for Specify Command. ; Enter: Drive in bits 0,1 ; Exit : A = Step rate & Disk Size (B7=1 for 8", 0 for 5") ; D = Head Unload Time ; E = Head Load Time SPCIFY: CALL PHYSCL ; Get the physical Block for this drive LD A,(HL) ; Get drive byte AND 0111B ; mask for Drive size DEC A ; set Zero flag if 8" INC HL ; Advance to Step Rate LD A,(HL) ; fetch RES 7,A ; insure MSB clear for 5/3" JR NZ,SPCIF0 ; Jump if Not 8" SET 7,A ; else set MSB of Step for 8" SPCIF0: INC HL LD E,(HL) ; get HLT INC HL LD D,(HL) ; and HUT RET ;..... ; Index to proper Floppy Configuration bytes. Uses AF,HL. ; Enter with Physical Drive # in Bits 0,1 CSEG ; Must be in Common Memory PHYSCL: AND 0011B ; Mask out all but drive bits LD L,A ; save copy for *5 calc ADD A,A ; Calc table index *2 ADD A,A ; *4 ADD A,L ; *5 LD HL,FDCSPEC ; Set table base addr ;..fall thru to.. ; Routine to Add A to HL ADDAHL: ADD A,L ; Add A to LSB LD L,A RET NC ; Exit if no H adjustment INC H ; Else had Carry, so add 1 to MSB RET ; And exit IF BANKED AND NOT INROM COMMON /B2RAM/ ELSE DSEG ENDIF FDSECS: DEFS 1 ; FDC sector size 0=128,1=256,2=512,3=1024 FDSDEN: DEFS 1 ; FDC single density flag FDSPD: DEFS 1 ; FDC high speed flag FDPSPT: DEFS 1 ; FDC physical Sectors/Track FDSOFF: DEFS 1 ; FDC first sector number offset side 0 FDS1OF: DEFS 1 ; FDC first sector number offset side 1 sbscflg: DEFS 1 ; Flag for SBSC operation ;=========================== End of FLOPPY ================================