forked from MirrorRepos/RomWBW
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.
291 lines
8.7 KiB
291 lines
8.7 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
|
|
LD A,(SEKPDN)
|
|
LD (HDSK_DEVICE),A
|
|
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 (HSTACT),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)
|
|
IF NOWAIT
|
|
;WTSAVE: DEFS 1 ; Storage for Entry Wait State Setting
|
|
ENDIF
|
|
;======================= 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 A,HDSK_CMDREAD
|
|
JR HDSK_RW
|
|
;
|
|
;
|
|
;
|
|
HDSK_WRITE:
|
|
; CALL PRTSTRD
|
|
; DEFB '[HDSK WRITE]$'
|
|
LD A,HDSK_CMDWRITE
|
|
JR HDSK_RW
|
|
;
|
|
;
|
|
;
|
|
HDSK_RW:
|
|
LD (HDSK_CMD),A
|
|
|
|
; CLEAR RESULTS
|
|
XOR A ; A = 0
|
|
LD (HDSK_RC),A ; CLEAR RETURN CODE
|
|
|
|
; INIT IF NEEDED
|
|
LD A,(HDSK_STAT) ; GET CURRENT STATUS
|
|
OR A ; SET FLAGS
|
|
CALL NZ,HDSK_RESET ; RESET IF NOT READY
|
|
|
|
; ; SET SECTOR (IGNORES MSB)
|
|
; LD A,(HSTSEC)
|
|
; LD (HDSK_SEC),A
|
|
|
|
; ; SET TRACK
|
|
; LD BC,(HSTTRK)
|
|
; LD (HDSK_TRK),BC
|
|
|
|
; BPBIOS DEFINES 16 SECTORS PER TRACK
|
|
; CONVERT TO 256 SECTORS PER TRACK FOR SIMH DEFINITION
|
|
; FIRST, DIVIDE TRACKS BY 16 SAVING REMAINDER IN TOP NIBBLE OF A
|
|
LD HL,(HSTTRK)
|
|
XOR A ; CLEAR A
|
|
LD B,4 ; ROTATE 4 BITS TO DIVIDE BY 4
|
|
HDSK_RW0:
|
|
SRL H
|
|
RR L
|
|
RR A
|
|
DJNZ HDSK_RW0
|
|
LD (HDSK_TRK),HL ; SAVE MODIFIED TRACK FOR HDSK I/O CALL
|
|
LD HL,HSTSEC ; POINT TO INCOMING SECTOR
|
|
OR (HL) ; COMBINE WITH SECTOR VALUE PASSED IN
|
|
LD (HDSK_SEC),A ; SAVE IT FOR HDSK I/O CALL
|
|
|
|
; SET TRANSFER ADDRESS
|
|
LD BC,HSTBUF
|
|
LD (HDSK_DMA),BC
|
|
|
|
; EXECUTE COMMAND
|
|
LD B,7 ; SIZE OF PARAMETER BLOCK
|
|
LD HL,HDSK_PARMBLK ; START ADDRESS OF PARAMETER BLOCK
|
|
HDSK_RW1:
|
|
LD A,(HL) ; GET BYTE OF PARAMETER BLOCK
|
|
OUT (0FDH),A ; SEND IT TO PORT
|
|
INC HL ; POINT TO NEXT BYTE
|
|
DJNZ HDSK_RW1
|
|
|
|
IN A,(0FDH) ; GET RESULT CODE
|
|
LD (HDSK_RC),A
|
|
OR A
|
|
JR Z,HDSK_OK
|
|
JR HDSK_ERR
|
|
|
|
HDSK_ERR:
|
|
XOR A
|
|
DEC A ; A=$FF TO SIGNAL ERROR
|
|
LD (HDSK_STAT),A ; SAVE IT
|
|
RET
|
|
|
|
HDSK_OK:
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
HDSK_RESET:
|
|
LD B,32
|
|
LD A,HDSK_CMDRESET
|
|
HDSK_RESET1:
|
|
OUT (0FDH),A
|
|
DJNZ HDSK_RESET1
|
|
|
|
XOR A ; STATUS = OK
|
|
LD (HDSK_STAT),A ; SAVE IT
|
|
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; HDSK DISK DRIVER - DATA
|
|
;==================================================================================================
|
|
;
|
|
IF BANKED
|
|
COMMON /B2RAM/
|
|
ELSE
|
|
DSEG
|
|
ENDIF
|
|
|
|
HDSK_STAT DEFB 0
|
|
HDSK_RC DEFB 0
|
|
;
|
|
HDSK_PARMBLK:
|
|
HDSK_CMD DEFB 0 ; COMMAND (HDSK_READ, HDSK_WRITE, ...)
|
|
HDSK_DEVICE DEFB 0 ; 0..7, HARD DISK UNIT
|
|
HDSK_SEC DEFB 0 ; 0..255 SECTOR
|
|
HDSK_TRK DEFW 0 ; 0..2047 TRACK
|
|
HDSK_DMA DEFW 0 ; DEFINES WHERE RESULT IS PLACED IN MEMORY
|
|
|
|
|
|
|
|
|
|
|