Files
RomWBW/Source/BPBIOS/hardsim.z80
2015-03-23 01:50:45 +00:00

291 lines
8.7 KiB
Z80 Assembly
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;::::::::::::::::::::::::::::::::::::::::::::::::**************************
; 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