|
|
|
@ -3,6 +3,12 @@ |
|
|
|
; IDE DISK DRIVER |
|
|
|
;================================================================================================== |
|
|
|
; |
|
|
|
#IF (IDETRACE >= 2) |
|
|
|
#DEFINE DCALL CALL |
|
|
|
#ELSE |
|
|
|
#DEFINE DCALL \; |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
; IO PORT ADDRESSES |
|
|
|
; |
|
|
|
#IF (IDEMODE == IDEMODE_MK4) |
|
|
|
@ -13,97 +19,159 @@ IDEBASE .EQU $20 |
|
|
|
|
|
|
|
#IF ((IDEMODE == IDEMODE_DIO) | (IDEMODE == IDEMODE_MK4)) |
|
|
|
#IF (IDE8BIT) |
|
|
|
IDEDATA: .EQU $IDEBASE + $00 ; DATA PORT (8 BIT) |
|
|
|
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 |
|
|
|
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) |
|
|
|
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) |
|
|
|
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) |
|
|
|
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_READ .EQU 020H |
|
|
|
IDECMD_WRITE .EQU 030H |
|
|
|
IDECMD_SETFEAT .EQU 0EFH |
|
|
|
IDECMD_RECAL .EQU $10 |
|
|
|
IDECMD_READ .EQU $20 |
|
|
|
IDECMD_WRITE .EQU $30 |
|
|
|
IDECMD_IDDEV .EQU $EC |
|
|
|
IDECMD_SETFEAT .EQU $EF |
|
|
|
; |
|
|
|
IDERC_OK .EQU 0 |
|
|
|
IDERC_CMDERR .EQU 1 |
|
|
|
IDERC_RDYTO .EQU 2 |
|
|
|
IDERC_BUFTO .EQU 3 |
|
|
|
IDE_RCOK .EQU 0 |
|
|
|
IDE_RCCMDERR .EQU 1 |
|
|
|
IDE_RCRDYTO .EQU 2 |
|
|
|
IDE_RCBUFTO .EQU 3 |
|
|
|
IDE_RCBSYTO .EQU 4 |
|
|
|
; |
|
|
|
; UNIT CONFIGURATION |
|
|
|
; |
|
|
|
IDE0_DEVICE .DB 11100000B ; LBA, MASTER DEVICE |
|
|
|
IDE1_DEVICE .DB 11110000B ; LBA, SLAVE DEVICE |
|
|
|
IDE_DEVLIST: |
|
|
|
IDE_DEVICE0 .DB %11100000 ; LBA, MASTER DEVICE |
|
|
|
IDE_DEVICE1 .DB %11110000 ; LBA, SLAVE DEVICE |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
IDE_INIT: |
|
|
|
PRTS("IDE: IO=0x$") |
|
|
|
LD A,IDEDATA |
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
|
|
CALL IDE_RESET ; INTERFACE RESET |
|
|
|
CALL DELAY |
|
|
|
|
|
|
|
XOR A ; STATUS OK |
|
|
|
LD (IDE_STAT),A ; INITIALIZE IT |
|
|
|
|
|
|
|
LD A,(IDE_DEVICE0) ; DEVICE 0 |
|
|
|
DCALL PC_SPACE |
|
|
|
DCALL PC_LBKT |
|
|
|
CALL IDE_PROBE |
|
|
|
DCALL PC_RBKT |
|
|
|
JR NZ,IDE_INIT1 |
|
|
|
LD HL,IDE_UNITCNT |
|
|
|
INC (HL) |
|
|
|
LD A,(IDE_DEVICE1) ; DEVICE 1 |
|
|
|
DCALL PC_SPACE |
|
|
|
DCALL PC_LBKT |
|
|
|
CALL IDE_PROBE |
|
|
|
DCALL PC_RBKT |
|
|
|
JR NZ,IDE_INIT1 |
|
|
|
LD HL,IDE_UNITCNT |
|
|
|
INC (HL) |
|
|
|
; |
|
|
|
IDE_INIT1: |
|
|
|
LD A,(IDE_DEVICE0) ; DEVICE 0 |
|
|
|
OUT (IDEDEVICE),A ; SELECT IT |
|
|
|
CALL DELAY |
|
|
|
|
|
|
|
PRTS(" UNITS=$") |
|
|
|
LD A,(IDE_UNITCNT) |
|
|
|
CALL PRTDECB |
|
|
|
; |
|
|
|
LD A,(IDE_UNITCNT) ; GET UNIT COUNT |
|
|
|
OR A ; SET FLAGS |
|
|
|
RET Z ; IF ZERO, WE ARE DONE |
|
|
|
; |
|
|
|
LD B,A ; LOOP ONCE PER UNIT |
|
|
|
LD C,0 ; C IS INDEX TO DEVICE LIST |
|
|
|
IDE_INIT2: |
|
|
|
PUSH BC |
|
|
|
CALL IDE_INIT3 |
|
|
|
POP BC |
|
|
|
INC C |
|
|
|
DJNZ IDE_INIT2 |
|
|
|
RET |
|
|
|
; |
|
|
|
IDE_INIT3: |
|
|
|
CALL NEWLINE |
|
|
|
LD DE,IDESTR_PREFIX |
|
|
|
CALL WRITESTR |
|
|
|
LD A,C |
|
|
|
CALL PRTDECB |
|
|
|
CALL PC_COLON |
|
|
|
; |
|
|
|
LD A,C |
|
|
|
CALL IDE_SELECT |
|
|
|
#IF (IDE8BIT) |
|
|
|
PRTS(" 8BIT$") |
|
|
|
CALL IDE_SET8BIT |
|
|
|
RET NZ |
|
|
|
#ENDIF |
|
|
|
CALL IDE_IDENTIFY |
|
|
|
RET NZ |
|
|
|
LD DE,(DIOBUF) |
|
|
|
DCALL DUMP_BUFFER |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
IDE_DISPATCH: |
|
|
|
LD A,B ; GET REQUESTED FUNCTION |
|
|
|
AND $0F |
|
|
|
JR Z,IDE_RD |
|
|
|
JR Z,IDE_READ |
|
|
|
DEC A |
|
|
|
JR Z,IDE_WR |
|
|
|
JR Z,IDE_WRITE |
|
|
|
DEC A |
|
|
|
JR Z,IDE_ST |
|
|
|
JR Z,IDE_STATUS |
|
|
|
DEC A |
|
|
|
JR Z,IDE_MED |
|
|
|
JR Z,IDE_MEDIA |
|
|
|
CALL PANIC |
|
|
|
; |
|
|
|
IDE_RD: |
|
|
|
JP IDE_READ |
|
|
|
IDE_WR: |
|
|
|
JP IDE_WRITE |
|
|
|
IDE_ST: |
|
|
|
JP IDE_STATUS |
|
|
|
IDE_MED: |
|
|
|
JP IDE_MEDIA |
|
|
|
; |
|
|
|
; IDE_MEDIA |
|
|
|
; |
|
|
|
IDE_MEDIA: |
|
|
|
LD A,C ; GET THE DEVICE/UNIT |
|
|
|
AND $0F ; ISOLATE UNIT |
|
|
|
CP IDECNT ; NUM UNITS |
|
|
|
LD A,MID_HD ; ASSUME WE ARE OK |
|
|
|
RET C ; RETURN |
|
|
|
XOR A ; NO MEDIA |
|
|
|
RET ; AND RETURN |
|
|
|
; |
|
|
|
IDE_READ: |
|
|
|
LD A,IDECMD_READ |
|
|
|
LD (IDE_CMD),A |
|
|
|
CALL IDE_RW |
|
|
|
RET NZ |
|
|
|
CALL IDE_BUFRD |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
IDE_INIT: |
|
|
|
PRTS("IDE: IO=0x$") |
|
|
|
LD A,IDEDATA |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=$") |
|
|
|
LD A,IDECNT |
|
|
|
CALL PRTDECB |
|
|
|
; |
|
|
|
CALL IDE_RESET |
|
|
|
XOR A |
|
|
|
DEC A ; INITIAL STATUS IS NOT READY $FF |
|
|
|
LD (IDE_STAT),A ; SAVE IT |
|
|
|
IDE_WRITE: |
|
|
|
LD A,IDECMD_WRITE |
|
|
|
LD (IDE_CMD),A |
|
|
|
CALL IDE_RW |
|
|
|
RET NZ |
|
|
|
CALL IDE_BUFWR |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
@ -113,184 +181,255 @@ IDE_STATUS: |
|
|
|
OR A ; SET FLAGS |
|
|
|
RET |
|
|
|
; |
|
|
|
; IDE_MEDIA |
|
|
|
; |
|
|
|
; |
|
|
|
IDE_READ: |
|
|
|
LD A,IDECMD_READ |
|
|
|
LD (IDE_CMD),A |
|
|
|
JP IDE_RW |
|
|
|
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_WRITE: |
|
|
|
LD A,IDECMD_WRITE |
|
|
|
LD (IDE_CMD),A |
|
|
|
JP IDE_RW |
|
|
|
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_RW: |
|
|
|
IDE_RUNCMD: |
|
|
|
; CLEAR RESULTS |
|
|
|
XOR A ; A = 0 |
|
|
|
LD (IDE_RC),A ; CLEAR RETURN CODE |
|
|
|
LD (IDE_STAT),A ; CLEAR DRIVER STATUS CODE |
|
|
|
LD (IDE_STTS),A ; CLEAR SAVED STTS |
|
|
|
LD (IDE_ERRS),A ; CLEAR SAVED ERR |
|
|
|
|
|
|
|
; INIT REQUIRED? |
|
|
|
LD A,(IDE_STAT) ; GET CURRENT STATUS |
|
|
|
OR A ; SET FLAGS |
|
|
|
JR Z,IDE_RW0 ; IF STATUS OK, BYPASS RESET |
|
|
|
|
|
|
|
CALL IDE_RESET ; DO THE RESET |
|
|
|
|
|
|
|
#IF (IDE8BIT) |
|
|
|
CALL IDE_WAITRDY |
|
|
|
|
|
|
|
LD A,01H |
|
|
|
OUT (IDEERR),A |
|
|
|
LD A,IDECMD_SETFEAT |
|
|
|
OUT (IDESTTS),A |
|
|
|
CALL IDE_WAITRDY |
|
|
|
JP NC,IDE_ERR |
|
|
|
CALL IDE_CHKERR ; CHECK FOR ERRORS |
|
|
|
JP NC,IDE_ERR |
|
|
|
#IF (IDETRACE >= 2) |
|
|
|
CALL IDE_PRT |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
IDE_RW0: |
|
|
|
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY |
|
|
|
JP NC,IDE_ERR |
|
|
|
CALL IDE_SETUP ; SETUP CYL, TRK, HEAD |
|
|
|
LD A,(IDE_CMD) |
|
|
|
OUT (IDESTTS),A |
|
|
|
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY |
|
|
|
JP NC,IDE_ERR |
|
|
|
CALL IDE_CHKERR ; CHECK FOR ERRORS |
|
|
|
JP NC,IDE_ERR |
|
|
|
CALL IDE_WAITBUF ; WAIT FOR BUFFER READY |
|
|
|
JP NC,IDE_ERR |
|
|
|
|
|
|
|
LD A,(IDE_CMD) ; DISPATCH TO READ OR WRITE SPECIFIC LOGIC |
|
|
|
CP IDECMD_WRITE |
|
|
|
JP Z,IDE_RW1 |
|
|
|
|
|
|
|
CALL IDE_BUFRD ; READ BUFFER |
|
|
|
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY |
|
|
|
JP NC,IDE_ERR |
|
|
|
CALL IDE_CHKERR ; CHECK FOR ERRORS |
|
|
|
JP NC,IDE_ERR |
|
|
|
JP IDE_OK |
|
|
|
|
|
|
|
IDE_RW1: |
|
|
|
CALL IDE_BUFWR ; WRITE BUFFER |
|
|
|
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY |
|
|
|
JP NC,IDE_ERR |
|
|
|
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 |
|
|
|
JP NC,IDE_ERR |
|
|
|
JP IDE_OK |
|
|
|
|
|
|
|
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: |
|
|
|
XOR A |
|
|
|
DEC A ; A = $FF TO SIGNAL ERROR |
|
|
|
LD (IDE_STAT),A ; SAVE IT |
|
|
|
LD (IDE_STAT),A ; SAVE ERROR AS STATUS |
|
|
|
#IF (IDETRACE >= 1) |
|
|
|
PUSH AF |
|
|
|
CALL IDE_PRT |
|
|
|
POP AF |
|
|
|
#ENDIF |
|
|
|
RET |
|
|
|
|
|
|
|
IDE_OK: |
|
|
|
#IF (IDETRACE >= 2) |
|
|
|
CALL IDE_PRT |
|
|
|
PUSH AF ; SAVE ACCUM |
|
|
|
CALL IDE_PRT ; PRINT COMMAND SUMMARY |
|
|
|
POP AF ; RESTORE ACCUM |
|
|
|
#ENDIF |
|
|
|
XOR A |
|
|
|
RET |
|
|
|
; |
|
|
|
OR A ; MAKE SURE FLAGS ARE SET |
|
|
|
RET ; DONE |
|
|
|
; |
|
|
|
; SOFT RESET OF ALL DEVICES |
|
|
|
; |
|
|
|
IDE_RESET: |
|
|
|
LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES |
|
|
|
LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES |
|
|
|
OUT (IDECTRL),A |
|
|
|
LD DE,16 ; DELAY ~250US |
|
|
|
CALL VDELAY |
|
|
|
LD A,000001010B ; NO INTERRUPTS, DEASSERT RESET |
|
|
|
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_DEVLIST |
|
|
|
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_WAITRDY: |
|
|
|
LD DE,0 ; TIMEOUT IS 250us * 65536 = 15 SECONDS |
|
|
|
IDE_WBSY: |
|
|
|
PUSH DE |
|
|
|
LD DE,16 ; INNER LOOP DELAY IS ~250us (16us * 16) |
|
|
|
CALL VDELAY |
|
|
|
POP DE |
|
|
|
DEC DE |
|
|
|
LD A,D |
|
|
|
OR E |
|
|
|
JP Z,IDE_TO |
|
|
|
IN A,(IDESTTS) ; READ STATUS |
|
|
|
LD (IDE_STTS),A ; SAVE IT |
|
|
|
AND 011000000b ; ISOLATE BUSY AND RDY BITS |
|
|
|
XOR 001000000b ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 |
|
|
|
JP NZ,IDE_WBSY |
|
|
|
SCF ; CARRY 1 = OK |
|
|
|
; |
|
|
|
; |
|
|
|
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_TO: |
|
|
|
LD A,IDERC_RDYTO |
|
|
|
LD (IDE_RC),A |
|
|
|
XOR A ; CARRY 0 = TIMEOUT |
|
|
|
|
|
|
|
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_CHKERR: |
|
|
|
IN A,(IDESTTS) ; GET STATUS |
|
|
|
; |
|
|
|
; |
|
|
|
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 000000001B ; ERROR BIT SET? |
|
|
|
SCF ; ASSUME NO ERR |
|
|
|
RET Z ; NO ERR, RETURN WITH CF SET |
|
|
|
|
|
|
|
IN A,(IDEERR) ; READ ERROR FLAGS |
|
|
|
LD (IDE_ERRS),A ; SAVE IT |
|
|
|
|
|
|
|
LD A,IDERC_CMDERR ; COMMAND ERROR |
|
|
|
LD (IDE_RC),A ; SAVE IT |
|
|
|
|
|
|
|
OR A ; CLEAR CF TO SIGNAL ERROR |
|
|
|
RET |
|
|
|
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 DE,0 |
|
|
|
IDE_WDRQ: |
|
|
|
CALL DELAY |
|
|
|
INC DE |
|
|
|
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 |
|
|
|
JP Z,IDE_TO2 |
|
|
|
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 000001000B ; TO FILL (OR READY TO FILL) |
|
|
|
JP Z,IDE_WDRQ |
|
|
|
SCF ; CARRY 1 = OK |
|
|
|
RET |
|
|
|
IDE_TO2: |
|
|
|
LD A,IDERC_BUFTO |
|
|
|
LD (IDE_RC),A |
|
|
|
XOR A ; CARRY 0 = TIMED OUT |
|
|
|
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 |
|
|
|
|
|
|
|
@ -307,11 +446,14 @@ IDE_BUFRD1: |
|
|
|
INI ; READ AND SAVE HI BYTE, INC HL, DEC B |
|
|
|
JP NZ,IDE_BUFRD1 ; LOOP AS NEEDED |
|
|
|
#ENDIF |
|
|
|
RET |
|
|
|
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 |
|
|
|
|
|
|
|
@ -328,7 +470,7 @@ IDE_BUFWR1: |
|
|
|
OUT (IDEDATALO),A ; NOW WRITE THE SAVED LO BYTE TO LO BYTE |
|
|
|
JP NZ,IDE_BUFWR1 ; LOOP AS NEEDED |
|
|
|
#ENDIF |
|
|
|
RET |
|
|
|
JP IDE_CHKERR ; RETURN THRU CHKERR |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
@ -336,25 +478,6 @@ IDE_SETUP: |
|
|
|
LD A,1 |
|
|
|
OUT (IDESECTC),A |
|
|
|
|
|
|
|
LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT |
|
|
|
AND 0FH |
|
|
|
CP 0 |
|
|
|
JP Z,IDE_SETUP_UNIT0 |
|
|
|
CP 1 |
|
|
|
JP Z,IDE_SETUP_UNIT1 |
|
|
|
CALL NC,PANIC |
|
|
|
IDE_SETUP_UNIT0: |
|
|
|
LD A,(IDE0_DEVICE) |
|
|
|
; LD DE,(IDE0_OFFSET) |
|
|
|
JP IDE_SETUP1 |
|
|
|
IDE_SETUP_UNIT1: |
|
|
|
LD A,(IDE1_DEVICE) |
|
|
|
; LD DE,(IDE1_OFFSET) |
|
|
|
JP IDE_SETUP1 |
|
|
|
IDE_SETUP1: |
|
|
|
LD (IDE_DEVICE),A |
|
|
|
OUT (IDEDEVICE),A |
|
|
|
|
|
|
|
; SEND 3 BYTES OF LBA T:SS -> CYL:SEC (CC:S) |
|
|
|
LD A,(HSTLBAHI) ; LBA HIGH LSB |
|
|
|
LD (IDE_CYLHI),A ; SAVE IT |
|
|
|
@ -365,11 +488,9 @@ IDE_SETUP1: |
|
|
|
LD A,(HSTLBALO) ; LBA LOW LSB |
|
|
|
LD (IDE_SEC),A ; SAVE IT |
|
|
|
OUT (IDESECTN),A ; -> SECTOR NUM |
|
|
|
|
|
|
|
#IF (DSKYENABLE) |
|
|
|
CALL IDE_DSKY |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
@ -399,6 +520,7 @@ IDE_PRT: |
|
|
|
|
|
|
|
LD DE,IDESTR_PREFIX |
|
|
|
CALL WRITESTR |
|
|
|
CALL PC_COLON |
|
|
|
|
|
|
|
CALL PC_SPACE |
|
|
|
LD DE,IDESTR_CMD |
|
|
|
@ -415,6 +537,15 @@ IDE_PRT: |
|
|
|
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 |
|
|
|
@ -445,23 +576,26 @@ IDE_PRTCMD: |
|
|
|
CALL PC_SPACE |
|
|
|
LD DE,IDESTR_RC |
|
|
|
CALL WRITESTR |
|
|
|
LD A,(IDE_RC) |
|
|
|
LD A,(IDE_STAT) |
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
|
|
CALL PC_SPACE |
|
|
|
CALL PC_LBKT |
|
|
|
LD A,(IDE_RC) |
|
|
|
LD A,(IDE_STAT) |
|
|
|
LD DE,IDESTR_RCOK |
|
|
|
CP IDERC_OK |
|
|
|
CP IDE_RCOK |
|
|
|
JP Z,IDE_PRTRC |
|
|
|
LD DE,IDESTR_RCCMDERR |
|
|
|
CP IDERC_CMDERR |
|
|
|
CP IDE_RCCMDERR |
|
|
|
JP Z,IDE_PRTRC |
|
|
|
LD DE,IDESTR_RCRDYTO |
|
|
|
CP IDERC_RDYTO |
|
|
|
CP IDE_RCRDYTO |
|
|
|
JP Z,IDE_PRTRC |
|
|
|
LD DE,IDESTR_RCBUFTO |
|
|
|
CP IDERC_BUFTO |
|
|
|
CP IDE_RCBUFTO |
|
|
|
JP Z,IDE_PRTRC |
|
|
|
LD DE,IDESTR_RCBSYTO |
|
|
|
CP IDE_RCBSYTO |
|
|
|
JP Z,IDE_PRTRC |
|
|
|
LD DE,IDESTR_RCUNK |
|
|
|
IDE_PRTRC: |
|
|
|
@ -472,32 +606,36 @@ IDE_PRTRC: |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
IDESTR_PREFIX .TEXT "IDE:$" |
|
|
|
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$" |
|
|
|
; |
|
|
|
;================================================================================================== |
|
|
|
; IDE DISK DRIVER - DATA |
|
|
|
;================================================================================================== |
|
|
|
; |
|
|
|
IDE_UNITCNT .DB 0 |
|
|
|
IDE_STAT .DB 0 |
|
|
|
IDE_RC .DB 0 |
|
|
|
; |
|
|
|
IDE_CMD: .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_CYLHI .DB 0 |
|
|
|
IDE_CYLLO .DB 0 |
|
|
|
IDE_SEC .DB 0 |
|
|
|
IDE_STTS .DB 0 |
|
|
|
IDE_ERRS .DB 0 |
|
|
|
; |
|
|
|
; |
|
|
|
|