Browse Source

Refactor IDE driver

- Dynamic detection of devices
- Significant code clean up
pull/3/head
Wayne Warthen 11 years ago
parent
commit
31d58909ce
  1. 10
      Source/HBIOS/Config/mk4_std.asm
  2. 586
      Source/HBIOS/ide.asm
  3. 61
      Source/HBIOS/util.asm

10
Source/HBIOS/Config/mk4_std.asm

@ -85,11 +85,11 @@ HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB)
;
PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD
PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE)
KBDENABLE .EQU TRUE ; TRUE FOR PS/2 KEYBOARD ON I8242
KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242
KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE)
;
TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT
ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT
TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT
ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT
ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE)
;
BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS)
@ -99,8 +99,8 @@ BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT
; 18.432MHz OSC @ FULL SPEED, 38.4Kbps
;
Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .EQU 3 ; MEMORY WAIT STATES TO INSERT (0-3)
Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3)
Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3)
Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3)
Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT
Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT
;

586
Source/HBIOS/ide.asm

@ -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
;
;

61
Source/HBIOS/util.asm

@ -221,6 +221,67 @@ PRTHEXBUF1:
DJNZ PRTHEXBUF1
RET
;
; PRINT A BLOCK OF MEMORY NICELY FORMATTED
; DE=BUFFER ADDRESS
;
DUMP_BUFFER:
CALL NEWLINE
PUSH DE
POP HL
INC D
INC D
DB_BLKRD:
PUSH BC
PUSH HL
POP BC
CALL PRTHEXWORD ; PRINT START LOCATION
POP BC
CALL PC_SPACE ;
LD C,16 ; SET FOR 16 LOCS
PUSH HL ; SAVE STARTING HL
DB_NXTONE:
LD A,(HL) ; GET BYTE
CALL PRTHEXBYTE ; PRINT IT
CALL PC_SPACE ;
DB_UPDH:
INC HL ; POINT NEXT
DEC C ; DEC. LOC COUNT
JR NZ,DB_NXTONE ; IF LINE NOT DONE
; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP
DB_PCRLF:
CALL PC_SPACE ; SPACE IT
LD C,16 ; SET FOR 16 CHARS
POP HL ; GET BACK START
DB_PCRLF0:
LD A,(HL) ; GET BYTE
AND 060H ; SEE IF A 'DOT'
LD A,(HL) ; O.K. TO GET
JR NZ,DB_PDOT ;
DB_DOT:
LD A,2EH ; LOAD A DOT
DB_PDOT:
CALL COUT ; PRINT IT
INC HL ;
LD A,D ;
CP H ;
JR NZ,DB_UPDH1 ;
LD A,E ;
CP L ;
JP Z,DB_END ;
;
;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE
DB_UPDH1:
DEC C ; DEC. CHAR COUNT
JR NZ,DB_PCRLF0 ; DO NEXT
DB_CONTD:
CALL NEWLINE ;
JP DB_BLKRD ;
DB_END:
RET ;
;
; OUTPUT A '$' TERMINATED STRING
;
WRITESTR:

Loading…
Cancel
Save