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.
 
 
 
 
 
 

252 lines
8.1 KiB

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