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.
 
 
 
 
 
 

730 lines
16 KiB

;
;==================================================================================================
; IDE DISK DRIVER
;==================================================================================================
;
#IF (IDETRACE >= 2)
#DEFINE DCALL CALL
#ELSE
#DEFINE DCALL \;
#ENDIF
;
; IO PORT ADDRESSES
;
#IF (IDEMODE == IDEMODE_MK4)
IDEBASE .EQU MK4_IDE
#ELSE
IDEBASE .EQU $20
#ENDIF
#IF ((IDEMODE == IDEMODE_DIO) | (IDEMODE == IDEMODE_MK4))
#IF (IDE8BIT)
IDEDATA .EQU $IDEBASE + $00 ; DATA PORT (8 BIT)
#ELSE
IDEDATALO .EQU $IDEBASE + $00 ; DATA PORT (16 BIT LO BYTE)
IDEDATAHI .EQU $IDEBASE + $08 ; DATA PORT (16 BIT HI BYTE)
IDEDATA .EQU IDEDATALO
#ENDIF
#ENDIF
;
#IF (IDEMODE == IDEMODE_DIDE)
#IF (IDE8BIT)
IDEDATA .EQU $IDEBASE + $00 ; DATA PORT (8 BIT OR 16 BIT PIO LO/HI BYTES)
#ELSE
IDEDATA .EQU $IDEBASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES)
IDEDMA .EQU $IDEBASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES)
#ENDIF
#ENDIF
;
IDEERR .EQU $IDEBASE + $01 ; READ: ERROR REGISTER; WRITE: PRECOMP
IDESECTC .EQU $IDEBASE + $02 ; SECTOR COUNT
IDESECTN .EQU $IDEBASE + $03 ; SECTOR NUMBER
IDECYLLO .EQU $IDEBASE + $04 ; CYLINDER LOW
IDECYLHI .EQU $IDEBASE + $05 ; CYLINDER HIGH
IDEDEVICE .EQU $IDEBASE + $06 ; DRIVE/HEAD
IDESTTS .EQU $IDEBASE + $07 ; READ: STATUS; WRITE: COMMAND
IDECTRL .EQU $IDEBASE + $0E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL
IDEADDR .EQU $IDEBASE + $0F ; DRIVE ADDRESS (READ ONLY)
;
;
;
IDECMD_RECAL .EQU $10
IDECMD_READ .EQU $20
IDECMD_WRITE .EQU $30
IDECMD_IDDEV .EQU $EC
IDECMD_SETFEAT .EQU $EF
;
IDE_RCOK .EQU 0
IDE_RCCMDERR .EQU 1
IDE_RCRDYTO .EQU 2
IDE_RCBUFTO .EQU 3
IDE_RCBSYTO .EQU 4
;
; UNIT CONFIGURATION
;
IDE_DEVICES:
IDE_DEVICE0 .DB %11100000 ; LBA, MASTER DEVICE
IDE_DEVICE1 .DB %11110000 ; LBA, SLAVE DEVICE
;
;
;
IDE_INIT:
PRTS("IDE:$") ; LABEL FOR IO ADDRESS
;
#IF (IDEMODE == IDEMODE_DIO)
PRTS(" MODE=DIO$")
#ENDIF
#IF (IDEMODE == IDEMODE_DIDE)
PRTS(" MODE=DIDE$")
#ENDIF
#IF (IDEMODE == IDEMODE_MK4)
PRTS(" MODE=MK4$")
#ENDIF
; PRINT IDE INTERFACE PORT ADDRESS
PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS
LD A,IDEDATA ; GET IO ADDRESS
CALL PRTHEXBYTE ; PRINT IT
;
; RESET INTERFACE
CALL IDE_RESET ; INTERFACE RESET
CALL DELAY ; SMALL DELAY
;
; SET GLOBAL STATUS TO OK (ZERO)
XOR A ; STATUS OK
LD (IDE_STAT),A ; INITIALIZE IT
;
; PROBE FOR DEVICE(S)
LD A,(IDE_DEVICE0) ; DEVICE 0
DCALL PC_SPACE ; IF DEBUGGING, PRINT A SPACE
DCALL PC_LBKT ; IF DEBUGGING, PRINT LEFT BRACKET
CALL IDE_PROBE ; PROBE FOR DEVICE 0 PRESENCE
DCALL PC_RBKT ; IF DEBUGGING, PRINT A RIGHT BRACKET
JR NZ,IDE_INIT1 ; IF DEVCIE 0 NOT PRESENT, SKIP DEVICE 1 PROBE
LD HL,IDE_UNITCNT ; POINT TO UNIT COUNT
INC (HL) ; INCREMENT IT
LD A,(IDE_DEVICE1) ; DEVICE 1
DCALL PC_SPACE ; IF DEBUGGING, PRINT A SPACE
DCALL PC_LBKT ; IF DEBUGGING, PRINT A LEFT BRACKET
CALL IDE_PROBE ; PROBE FOR DEVICE 1 PRESENT
DCALL PC_RBKT ; IF DEBUGGING, PRINT A RIGHT BRACKET
JR NZ,IDE_INIT1 ; IF DEVICE 1 NOT PRESENT, SKIP
LD HL,IDE_UNITCNT ; POINT TO UNIT COUNT
INC (HL) ; INCREMENT IT
;
IDE_INIT1:
; RESTORE DEFAULT DEVICE SELECTION (DEVICE 0)
LD A,(IDE_DEVICE0) ; DEVICE 0
OUT (IDEDEVICE),A ; SELECT IT
CALL DELAY ; SMALL DELAY AFTER SELECT
;
; PRINT UNIT COUNT
PRTS(" UNITS=$") ; PRINT LABEL FOR UNIT COUNT
LD A,(IDE_UNITCNT) ; GET UNIT COUNT
CALL PRTDECB ; PRINT IT IN DECIMAL
;
; CHECK FOR ZERO DEVICES AND BAIL OUT IF SO
LD A,(IDE_UNITCNT) ; GET UNIT COUNT
OR A ; SET FLAGS
RET Z ; IF ZERO, WE ARE DONE
;
; DEVICE SETUP LOOP
LD B,A ; LOOP ONCE PER UNIT
LD C,0 ; C IS UNIT INDEX
IDE_INIT2:
PUSH BC ; SAVE LOOP CONTROL
CALL IDE_INIT3 ; HANDLE THE NEXT UNIT
POP BC ; RESTORE LOOP CONTROL
INC C ; INCREMENT UNIT INDEX
DJNZ IDE_INIT2 ; LOOP UNTIL DONE
RET ; INIT FINISHED
;
IDE_INIT3: ; SUBROUTINE TO QUERY A DEVICE
; PRINT PREFIX FOR UNIT INFO "IDE#:"
CALL NEWLINE ; FORMATTING: START A NEW LINE
LD DE,IDESTR_PREFIX ; POINT TO STRING "IDE"
CALL WRITESTR ; PRINT STRING
LD A,C ; UNIT NUMBER TO ACCUM
LD (IDE_CURUNIT),A ; SAVE THE CURRENT UNIT
CALL PRTDECB ; PRINT IT IN DECIMAL
CALL PC_COLON ; PRINT THE ENDING COLON
;
LD A,C ; UNIT NUMBER TO ACCUM
CALL IDE_SELECT ; SELECT THE CORRECT DEVICE
;
#IF (IDE8BIT)
PRTS(" 8BIT$")
CALL IDE_SET8BIT ; SET 8BIT TRANSFER FEATURE
RET NZ ; BAIL OUT ON ERROR
#ENDIF
;
CALL IDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND
RET NZ ; BAIL OUT ON ERROR
;
LD DE,(DIOBUF) ; POINT TO BUFFER
DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
;
; PRINT LBA/NOLBA
CALL PC_SPACE ; SPACING
LD HL,(DIOBUF) ; POINT TO BUFFER START
LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG
ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS
LD A,(HL) ; GET THE BYTE
BIT 1,A ; CHECK THE LBA BIT
LD DE,IDESTR_NO ; POINT TO "NO" STRING
CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED
PRTS("LBA$") ; PRINT "LBA" REGARDLESS
;
; PRECOMPUTE LOC TO STORE 32-BIT CAPACITY
LD HL,IDE_CAPLIST ; POINT TO CAPACITY ARRAY
LD A,(IDE_CURUNIT) ; GET CUR UNIT NUM
RLCA ; MULTIPLY BY 4
RLCA ; ... TO OFFSET BY DWORDS
CALL ADDHLA ; ADD OFFSET TO POINTER
PUSH HL ; SAVE POINTER
;
; GET, SAVE, AND PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
LD HL,(DIOBUF) ; POINT TO BUFFER START
LD DE,120 ; OFFSET OF SECGTOR COUNT
ADD HL,DE ; POINT TO ADDRESS OF SECTOR COUNT
CALL LD32 ; LOAD IT TO DE:HL
POP BC ; RECOVER POINTER TO CAPACITY ARRAY ENTRY
CALL ST32 ; SAVE CAPACITY
CALL PRTHEX32 ; PRINT HEX VALUE
;
; PRINT STORAGE SIZE IN MB
PRTS(" SIZE=$") ; PRINT FIELD LABEL
LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB
CALL SRL32 ; RIGHT SHIFT
CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED)
PRTS("MB$") ; PRINT SUFFIX
;
RET
;
;
;
IDE_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F
JR Z,IDE_READ
DEC A
JR Z,IDE_WRITE
DEC A
JR Z,IDE_STATUS
DEC A
JR Z,IDE_MEDIA
CALL PANIC
;
;
;
IDE_READ:
LD A,IDECMD_READ
LD (IDE_CMD),A
CALL IDE_RW
RET NZ
CALL IDE_BUFRD
RET
;
;
;
IDE_WRITE:
LD A,IDECMD_WRITE
LD (IDE_CMD),A
CALL IDE_RW
RET NZ
CALL IDE_BUFWR
RET
;
;
;
IDE_STATUS:
LD A,(IDE_STAT) ; LOAD STATUS
OR A ; SET FLAGS
RET
;
; IDE_MEDIA
;
IDE_MEDIA:
LD A,C ; GET THE DEVICE/UNIT
AND $0F ; ISOLATE UNIT
LD HL,IDE_UNITCNT ; POINT TO UNIT COUNT
CP (HL) ; COMPARE TO UNIT COUNT
LD A,MID_HD ; ASSUME WE ARE OK
RET C ; RETURN
XOR A ; NO MEDIA
RET ; AND RETURN
;
;
;
IDE_RW:
; SELECT DEVICE
LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT
AND $0F
CALL IDE_SELECT
CALL IDE_SETUP ; SETUP CYL, TRK, HEAD
JR IDE_RUNCMD ; RETURN THRU RUNCMD
;
;
;
IDE_RUNCMD:
; CLEAR RESULTS
XOR A ; A = 0
LD (IDE_STAT),A ; CLEAR DRIVER STATUS CODE
LD (IDE_STTS),A ; CLEAR SAVED STTS
LD (IDE_ERRS),A ; CLEAR SAVED ERR
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY
RET NZ ; BAIL OUT ON TIMEOUT
LD A,(IDE_CMD) ; GET THE COMMAND
OUT (IDESTTS),A ; SEND IT (STARTS EXECUTION)
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY (COMMAND DONE)
RET NZ ; BAIL OUT ON TIMEOUT
CALL IDE_CHKERR ; CHECK FOR ERRORS
RET NZ ; BAIL OUT ON TIMEOUT
DCALL IDE_PRT ; PRINT COMMAND IF DEBUG ENABLED
XOR A ; SET RESULT
RET ; DONE
;
;
;
IDE_ERRCMD:
LD A,IDE_RCCMDERR
JR IDE_ERR
;
IDE_ERRRDYTO:
LD A,IDE_RCRDYTO
JR IDE_ERR
;
IDE_ERRBUFTO:
LD A,IDE_RCBUFTO
JR IDE_ERR
;
IDE_ERRBSYTO:
LD A,IDE_RCBSYTO
JR IDE_ERR
;
IDE_ERR:
LD (IDE_STAT),A ; SAVE ERROR AS STATUS
#IF (IDETRACE >= 1)
PUSH AF ; SAVE ACCUM
CALL IDE_PRT ; PRINT COMMAND SUMMARY
POP AF ; RESTORE ACCUM
#ENDIF
OR A ; MAKE SURE FLAGS ARE SET
RET ; DONE
;
; SOFT RESET OF ALL DEVICES
;
IDE_RESET:
LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES
OUT (IDECTRL),A
LD DE,16 ; DELAY ~250US
CALL VDELAY
LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET
OUT (IDECTRL),A
XOR A
LD (IDE_STAT),A ; STATUS OK
RET ; SAVE IT
;
; SELECT DEVICE IN A
;
IDE_SELECT:
LD HL,IDE_DEVICES
CALL ADDHLA
LD A,(HL) ; LOAD DEVICE
LD (IDE_DEVICE),A ; SHADOW REGISTER
CALL IDE_WAITBSY
RET NZ
LD A,(IDE_DEVICE) ; RECOVER DEVICE VALUE
OUT (IDEDEVICE),A ; SELECT DEVICE
; DELAY???
RET
;
;
;
IDE_PROBE:
OUT (IDEDEVICE),A ; SELECT IT
CALL DELAY
IN A,(IDESECTC)
DCALL PRTHEXBYTE
CP $01
RET NZ
DCALL PC_SPACE
IN A,(IDESECTN)
DCALL PRTHEXBYTE
CP $01
RET NZ
DCALL PC_SPACE
IN A,(IDECYLLO)
DCALL PRTHEXBYTE
CP $00
RET NZ
DCALL PC_SPACE
IN A,(IDECYLHI)
DCALL PRTHEXBYTE
CP $00
RET NZ
DCALL PC_SPACE
IN A,(IDESTTS)
DCALL PRTHEXBYTE ; PRINT STATUS
CP 0
JR NZ,IDE_PROBE1
OR $FF ; SIGNAL ERROR
RET
IDE_PROBE1:
XOR A ; SIGNAL SUCCESS
RET
;
;
;
IDE_SET8BIT:
; DEVICE *MUST* ALREADY BE SELECTED!
LD A,IDECMD_SETFEAT
LD (IDE_CMD),A
LD A,$01 ; $01 ENABLES 8-BIT XFR FEATURE
OUT (IDEERR),A ; SET FEATURS VALUE
JP IDE_RUNCMD ; EXIT THRU RUNCMD
;
;
;
IDE_IDENTIFY:
; DEVICE *MUST* ALREADY BE SELECTED!
LD A,IDECMD_IDDEV
LD (IDE_CMD),A
CALL IDE_RUNCMD
RET NZ
JP IDE_BUFRD ; EXIT THRU BUFRD
;
;
;
IDE_WAITRDY:
LD B,15 ; ~15 SECOND TIMEOUT?
IDE_WAITRDY1:
LD DE,-1 ; ~1 SECOND INNER LOOP
IDE_WAITRDY2:
IN A,(IDESTTS) ; READ STATUS
LD (IDE_STTS),A ; SAVE IT
AND %11000000 ; ISOLATE BUSY AND RDY BITS
XOR %01000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1
;JR Z,IDE_WAITRPT ; DIAGNOSTIC
RET Z ; ALL SET, RETURN WITH Z SET
CALL DELAY ; DELAY 16US
DEC DE
LD A,D
OR E
JR NZ,IDE_WAITRDY2 ; INNER LOOP RETURN
DJNZ IDE_WAITRDY1 ; OUTER LOOP RETURN
JP IDE_ERRRDYTO ; EXIT WITH RDYTO ERR
;
;
;
IDE_WAITBUF:
LD B,3 ; ~3 SECOND TIMEOUT???
IDE_WAITBUF1:
LD DE,-1 ; ~1 SECOND INNER LOOP
IDE_WAITBUF2:
IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER
LD (IDE_STTS),A ; SAVE IT
AND %10001000 ; TO FILL (OR READY TO FILL)
XOR %00001000
;JR Z,IDE_WAITRPT ; DIAGNOSTIC
RET Z
CALL DELAY ; DELAY 16US
DEC DE
LD A,D
OR E
JR NZ,IDE_WAITBUF2
DJNZ IDE_WAITBUF1
JP IDE_ERRBUFTO ; EXIT WITH BUFTO ERR
;
;
;
IDE_WAITBSY:
LD B,3 ; ~3 SECOND TIMEOUT???
IDE_WAITBSY1:
LD DE,-1 ; ~1 SECOND INNER LOOP
IDE_WAITBSY2:
IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER
LD (IDE_STTS),A ; SAVE IT
AND %10000000 ; TO FILL (OR READY TO FILL)
;JR Z,IDE_WAITRPT ; DIAGNOSTIC
RET Z
CALL DELAY ; DELAY 16US
DEC DE
LD A,D
OR E
JR NZ,IDE_WAITBSY2
DJNZ IDE_WAITBSY1
JP IDE_ERRBSYTO ; EXIT WITH BSYTO ERR
;
;
;
IDE_WAITRPT:
PUSH AF
CALL PC_SPACE
LD A,B
CALL PRTHEXBYTE
LD A,D
CALL PRTHEXBYTE
LD A,E
CALL PRTHEXBYTE
POP AF
RET
;
;
;
IDE_CHKERR:
IN A,(IDESTTS) ; GET STATUS
LD (IDE_STTS),A ; SAVE IT
AND %00000001 ; ERROR BIT SET?
RET Z ; NOPE, RETURN WITH ZF
;
IN A,(IDEERR) ; READ ERROR REGISTER
LD (IDE_ERRS),A ; SAVE IT
JP IDE_ERRCMD ; EXIT VIA ERRCMD
;
;
;
IDE_BUFRD:
CALL IDE_WAITBUF ; WAIT FOR BUFFER READY
RET NZ ; BAIL OUT IF TIMEOUT
LD HL,(DIOBUF)
LD B,0
#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE))
LD C,IDEDATA
INIR
INIR
#ELSE
LD C,IDEDATAHI
IDE_BUFRD1:
IN A,(IDEDATALO) ; READ THE LO BYTE
LD (HL),A ; SAVE IN BUFFER
INC HL ; INC BUFFER POINTER
INI ; READ AND SAVE HI BYTE, INC HL, DEC B
JP NZ,IDE_BUFRD1 ; LOOP AS NEEDED
#ENDIF
JP IDE_CHKERR ; RETURN THRU CHKERR
;
;
;
IDE_BUFWR:
CALL IDE_WAITBUF ; WAIT FOR BUFFER READY
RET NZ ; BAIL OUT IF TIMEOUT
LD HL,(DIOBUF)
LD B,0
#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE))
LD C,IDEDATA
OTIR
OTIR
#ELSE
LD C,IDEDATAHI
IDE_BUFWR1:
LD A,(HL) ; GET THE LO BYTE AND KEEP IT IN A FOR LATER
INC HL ; BUMP TO NEXT BYTE IN BUFFER
OUTI ; WRITE HI BYTE, INC HL, DEC B
OUT (IDEDATALO),A ; NOW WRITE THE SAVED LO BYTE TO LO BYTE
JP NZ,IDE_BUFWR1 ; LOOP AS NEEDED
#ENDIF
JP IDE_CHKERR ; RETURN THRU CHKERR
;
;
;
IDE_SETUP:
LD A,1
OUT (IDESECTC),A
; SEND 3 BYTES OF LBA T:SS -> CYL:SEC (CC:S)
LD A,(HSTLBAHI) ; LBA HIGH LSB
LD (IDE_CYLHI),A ; SAVE IT
OUT (IDECYLHI),A ; -> CYLINDER HI
LD A,(HSTLBALO + 1) ; LBA LOW MSB
LD (IDE_CYLLO),A ; SAVE IT
OUT (IDECYLLO),A ; -> CYLINDER LO
LD A,(HSTLBALO) ; LBA LOW LSB
LD (IDE_SEC),A ; SAVE IT
OUT (IDESECTN),A ; -> SECTOR NUM
#IF (DSKYENABLE)
CALL IDE_DSKY
#ENDIF
RET
;
;
;
#IF (DSKYENABLE)
IDE_DSKY:
LD HL,DSKY_HEXBUF
LD A,(IDE_DEVICE)
LD (HL),A
INC HL
LD A,(IDE_CYLHI)
LD (HL),A
INC HL
LD A,(IDE_CYLLO)
LD (HL),A
INC HL
LD A,(IDE_SEC)
LD (HL),A
CALL DSKY_HEXOUT
RET
#ENDIF
;
;
;
IDE_PRT:
CALL NEWLINE
LD DE,IDESTR_PREFIX
CALL WRITESTR
CALL PC_COLON
CALL PC_SPACE
LD DE,IDESTR_CMD
CALL WRITESTR
LD A,(IDE_CMD)
CALL PRTHEXBYTE
CALL PC_SPACE
CALL PC_LBKT
LD A,(IDE_CMD)
LD DE,IDESTR_READ
CP IDECMD_READ
JP Z,IDE_PRTCMD
LD DE,IDESTR_WRITE
CP IDECMD_WRITE
JP Z,IDE_PRTCMD
LD DE,IDESTR_SETFEAT
CP IDECMD_SETFEAT
JP Z,IDE_PRTCMD
LD DE,IDESTR_IDDEV
CP IDECMD_IDDEV
JP Z,IDE_PRTCMD
LD DE,IDESTR_RECAL
CP IDECMD_RECAL
JP Z,IDE_PRTCMD
LD DE,IDESTR_UNKCMD
IDE_PRTCMD:
CALL WRITESTR
CALL PC_RBKT
CALL PC_SPACE
LD A,(IDE_DEVICE)
CALL PRTHEXBYTE
LD A,(IDE_CYLHI)
CALL PRTHEXBYTE
LD A,(IDE_CYLLO)
CALL PRTHEXBYTE
LD A,(IDE_SEC)
CALL PRTHEXBYTE
CALL PC_SPACE
LD DE,IDESTR_ARROW
CALL WRITESTR
CALL PC_SPACE
IN A,(IDESTTS)
CALL PRTHEXBYTE
CALL PC_SPACE
IN A,(IDEERR)
CALL PRTHEXBYTE
CALL PC_SPACE
LD DE,IDESTR_RC
CALL WRITESTR
LD A,(IDE_STAT)
CALL PRTHEXBYTE
CALL PC_SPACE
CALL PC_LBKT
LD A,(IDE_STAT)
LD DE,IDESTR_RCOK
CP IDE_RCOK
JP Z,IDE_PRTRC
LD DE,IDESTR_RCCMDERR
CP IDE_RCCMDERR
JP Z,IDE_PRTRC
LD DE,IDESTR_RCRDYTO
CP IDE_RCRDYTO
JP Z,IDE_PRTRC
LD DE,IDESTR_RCBUFTO
CP IDE_RCBUFTO
JP Z,IDE_PRTRC
LD DE,IDESTR_RCBSYTO
CP IDE_RCBSYTO
JP Z,IDE_PRTRC
LD DE,IDESTR_RCUNK
IDE_PRTRC:
CALL WRITESTR
CALL PC_RBKT
RET
;
;
;
IDESTR_PREFIX .TEXT "IDE$"
IDESTR_CMD .TEXT "CMD=$"
IDESTR_RC .TEXT "RC=$"
IDESTR_ARROW .TEXT "-->$"
IDESTR_READ .TEXT "READ$"
IDESTR_WRITE .TEXT "WRITE$"
IDESTR_SETFEAT .TEXT "SETFEAT$"
IDESTR_IDDEV .TEXT "IDDEV$"
IDESTR_RECAL .TEXT "RECAL$"
IDESTR_UNKCMD .TEXT "UNKCMD$"
IDESTR_RCOK .TEXT "OK$"
IDESTR_RCCMDERR .TEXT "COMMAND ERROR$"
IDESTR_RCRDYTO .TEXT "READY TIMEOUT$"
IDESTR_RCBUFTO .TEXT "BUFFER TIMEOUT$"
IDESTR_RCBSYTO .TEXT "BUSY TIMEOUT$"
IDESTR_RCUNK .TEXT "UNKNOWN ERROR$"
IDESTR_NO .TEXT "NO$"
;
;==================================================================================================
; IDE DISK DRIVER - DATA
;==================================================================================================
;
IDE_UNITCNT .DB 0
IDE_CURUNIT .DB 0
IDE_STAT .DB 0
;
IDE_CMD .DB 0
IDE_DEVICE .DB 0
IDE_CYLHI .DB 0
IDE_CYLLO .DB 0
IDE_SEC .DB 0
IDE_STTS .DB 0
IDE_ERRS .DB 0
;
IDE_CAPLIST .FILL 2 * 4,0 ; CAPACITY OF EACH UNIT IN BLOCKS, 1 DWORD PER UNIT
;
;
;
;
; Error Register (ERR bit being set in the Status Register)
;
; Bit 7: BBK (Bad Block Detected) Set when a Bad Block is detected.
; Bit 6: UNC (Uncorrectable Data Error) Set when Uncorrectable Error is encountered.
; Bit 5: MC (Media Changed) Set to 0.
; Bit 4: IDNF (ID Not Found) Set when Sector ID not found.
; Bit 3: MCR (Media Change Request) Set to 0.
; Bit 2: ABRT (Aborted Command) Set when Command Aborted due to drive error.
; Bit 1: TKONF (Track 0 Not Found) Set when Executive Drive Diagnostic Command.
; Bit 0: AMNF (Address mark Not Found) Set in case of a general error.
;
; Status Register (When the contents of this register are read by the host, the IREQ# bit is cleared)
;
; Bit 7: BSY (Busy) Set when the drive is busy and unable to process any new ATA commands.
; Bit 6: DRDY (Data Ready) Set when the device is ready to accept ATA commands from the host.
; Bit 5: DWF (Drive Write Fault) Always set to 0.
; Bit 4: DSC (Drive Seek Complete) Set when the drive heads have been positioned over a specific track.
; Bit 3: DRQ (Data Request) Set when device is ready to transfer a word or byte of data to or from the host and the device.
; Bit 2: CORR (Corrected Data) Always set to 0.
; Bit 1: IDX (Index) Always set to 0.
; Bit 0: ERR (Error) Set when an error occurred during the previous ATA command.