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.
 
 
 
 
 
 

234 lines
7.6 KiB

;::::::::::::::::::::::::::::::::::::::::::::::::**************************
; Hard disk routines as implemented for ** Hardware Dependent **
; SIMH Altair80 ** for exact interface **
; D-X Designs Pty Ltd P112. **************************
;--------------------------------------------------------------------------
; This file uses modifications of the definitions in ICFG-xx to reflect
; Physical and/or logical definitions for HBIOS drives. A controller type of
; 8xH signifies IDE/ATA drives, in which case the Drive byte at HDRVx is:
; 7 6 5 4 3 2 1 0
; | | | | | | | +- Unit Number (0 = Master, 1 = Slave)
; | | | | +-+-+--- (reserved)
; | | | +--------- 1 = Active, 0 = Inactive
; +-+-+----------- (reserved)
; Additionally, the first byte of the Reduced Write Cylinder word is re-
; defined to be the number of physical/logical Sectors-Per-Track.
; These parameters are used to convert the Track & 16 Sector/Track format
; assumed in the B/P Bios definitions for Hard Drives into Track/Sector/Head
; Sector Number needed for IDE/ATA Data accesses. Direct driver IO routines
; to Select (SELHD), Read (HDREAD) and Write (HDWRIT) are all included here.
;--------------------------------------------------------------------------
; 1.0 - 26 Aug 01 - Cleaned up source and included fixes from SCSI. HFB
; 0.2 - 28 Jun 97 - Added Home Drive, Retry Disable bit handling. HFB
; 0.1 - 25 Apr 97 - Initial Test Release HFB
;***************************************************************************
IF BANKED
COMMON /BANK2/
ELSE
CSEG
ENDIF
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Function 0 - Set User Data Area Adress for Direct Disk IO, Return
; Number of Bytes in the driver Command Block (SCSI-"like")
; For IDE, a minimum of 6 Bytes is needed (Comnd,Trk(2),Sctr,Head,Drive)
; Enter: DE = Address of User Data Area
; Exit : A = Number of bytes available in the Command Block
; Uses : A,HL
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
HDVALS: LD (DATADR),DE ; Save the Users Data Area
LD A,CMDSIZ
RET
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Function 1 - Set Drive bit Command Block from A
; Enter: A = Drive Byte
; Exit : A = Drive Bit in LSB (00/01H, for Master/Slave)
; Uses : AF
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
HDSLCT: AND 01H ; Strip any garbage
LD (hdUnit),A ; save in Command Block
RET
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Function 2 - Direct SCSI driver. This routine performs the function
; described by the command in the HD Command Block with Data area
; addressed by DE. At the end of the function, 512 bytes of data are
; transferred from the Bios IO Buffer to the Users Space set by Fcn 0.
;
; Enter: DE = Pointer to User Command Descriptor Block
; HDCOMD contains pre-filled SCSI Command Block
; A = 0 if No Data to be Written, FF if User-supplied data to write
; Exit : H = Message Byte value
; L = Status Byte value
; A = Status byte, Flags set accordingly.
; Uses : AF,BC,DE,HL
; NOTE : Routine assumes the Command Block is properly configured for the
; desired function and device. Errors in phasing result in program
; exit and Warm Boot function, while Timeout returns 0FFH.
; For external access, It assumes the user has used Functions 0 and 1 to
; set the data transfer source/dest address and logical & physical drive.
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
HD_RW: CALL PANIC ; NOT IMPLEMENTED!!!!
RET
;========================================================================
; Select Hard Disk (Unit 0/1, Master/Slave) < Internal Bios routine >
SELHD: ; SET DEVICE
; CALL PRTSTRD
; DEFB '[SELHD]$'
JP SETPARMS ; then set parameters for DPH/DPB
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Write to Hard Disk Drive < Internal BIOS Routine >
; Writes from HSTBUF using HSTTRK and HSTSEC to build Block Number.
; NOTE: This routine uses physical drive characteristics from ICFG-xx.
HDWRIT:
XOR A
LD (HSTWRT),A ; Show no active writes pending
JP HDSK_WRITE ; ..continue
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Read from Hard Disk Drive < Internal BIOS Routine >
; Reads to HSTBUF using HSTTRK and HSTSEC to build Block Number.
; NOTE: This routine uses physical drive characteristics from ICFG-xx.
; The routine computes a sequential block number (as with SCSI) with
; the algorithm; Trk * 16 + Sector, then computes Head, Sector and Track
; using Physical characteristics (hdHds = Number_of_Heads,
; hdSPT = Sectors_per_Track) according to the algorithm:
;
; Sector := (Block# MOD hdSPT)+1 (* Quotient1 := Block# DIV hdSPT *)
; Head := Quotient1 MOD hdHds (* Quotient2 := Quotient1 DIV hdHds *)
; Track := Quotient2
HDREAD:
JP HDSK_READ
IF BANKED
COMMON /B2RAM/
ELSE
DSEG
ENDIF
HRTrys: DEFS 1 ; Retry counter storage
hdUnit: DEFS 1 ; IDE Drive (0 = Master, 1 = Slave)
hdTrks: DEFS 2 ; Number of Tracks on IDE Drive
hdHds: DEFS 1 ; Number of Heads on IDE Drive
hdSPT: DEFS 1 ; Number of Sectors-Per-Track on IDE Drive
; IDE Command Block for User Direct Driver Access
hdComd: DEFS 1 ; Command Byte
hdBMap: DEFS 1 ; Bit Map (B6..0) of Following Bytes to Set
hdHead: DEFS 1 ; Head Number/Number of Heads in B3..0
hdTrkH: DEFS 1 ; Hi-Track (Cylinder) Byte
hdTrkL: DEFS 1 ; Lo-Track (Cylinder) Byte
hdSec: DEFS 1 ; Sector Number
hdSCnt: DEFS 1 ; Sector Count
hdErr: DEFS 1 ; Error Reg Value
hdDigO: DEFS 1 ; Digital Output Reg Value
CMDSIZ EQU $-hdComd ; Size of Command Block
DATADR: DEFS 2 ; Pointer to User Buffer Space (user bank)
;======================= End of HARDIDE ===========================
IF BANKED
COMMON /BANK2/
ELSE
CSEG
ENDIF
;
;==================================================================================================
; HDSK DISK DRIVER
;==================================================================================================
;
; IO PORT ADDRESSES
;
HDSK_IO EQU 0FDH
;
HDSK_CMDNONE EQU 0
HDSK_CMDRESET EQU 1
HDSK_CMDREAD EQU 2
HDSK_CMDWRITE EQU 3
HDSK_CMDPARAM EQU 4
;
; STATUS
;
HDSKRC_OK EQU 0
;
;
;
HDSK_READ:
; CALL PRTSTRD
; DEFB '[HDSK READ]$'
LD B,10H ; $10 IS HBIOS DISK READ
JR HDSK_RW
;
;
;
HDSK_WRITE:
; CALL PRTSTRD
; DEFB '[HDSK WRITE]$'
LD B,11H ; $11 IS HBIOS DISK WRITE
JR HDSK_RW
;
;
;
HDSK_RW:
LD HL,(HSTDPH) ; GET ACTIVE DPH POINTER
DEC HL ; ADJUST TO POINT TO UNIT NUMBER
LD C,(HL) ; LOAD IT IN C FOR HBIOS CALL LATER
PUSH BC ; SAVE FUNCTION AND DEVICE FOR LATER
LD DE,(HSTTRK)
LD HL,0
LD B,4 ; PREPARE TO LEFT SHIT BY 4 BITS
HDSK_RW1:
SLA E ; SHIFT DE LEFT BY 4 BITS
RL D
RL L
RL H
DJNZ HDSK_RW1 ; LOOP TILL ALL BITS DONE
LD A,(HSTSEC) ; GET THE SECTOR INTO A
AND 0FH ; GET RID OF TOP NIBBLE FOR SAFETY
OR E ; COMBINE WITH E
LD E,A ; BACK IN E
POP BC ; RECOVER FUNCTION AND DEVICE
CALL HBX_INVOKE
OR A
RET Z ; DONE IF NO ERROR
XOR A
DEC A ; A=$FF TO SIGNAL ERROR
RET
;
;==================================================================================================
; HDSK DISK DRIVER - DATA
;==================================================================================================
;
IF BANKED
COMMON /B2RAM/
ELSE
DSEG
ENDIF
HDSK_PDN DEFS 1 ; PHYSICAL DEVICE