Browse Source

Fix IDE Detection on Spinning Disks

Prior improvement to IDE device detection broke detection of spinning hard disks.  IDE registers cannot be used prior to device init completion (spin up).  Not a problem for CF, but special steps required to ensure devices are fully initialized before register testing.
pull/351/head v3.3.0-dev.6
Wayne Warthen 3 years ago
parent
commit
ad3c533145
  1. 76
      Source/HBIOS/ide.asm
  2. 64
      Source/HBIOS/ppide.asm
  3. 2
      Source/ver.inc
  4. 2
      Source/ver.lib

76
Source/HBIOS/ide.asm

@ -937,42 +937,6 @@ IDE_RESET:
PRTS(" RESET$")
#ENDIF
;
;#IF (IDEMODE == IDEMODE_RC)
;
; OLDER CF CARDS DO NOT SEEM TO SET THE
; REGISTERS ON RESET, SO HERE WE FAKE THINGS BY
; SETTING THEM AS A RESET WOULD. SO WE ALWAYS
; DO THE FAKE.
;LD A,(IY+IDE_MODE) ; GET MODE
;CP IDEMODE_RC ; RCBUS?
;JR NZ,IDE_RESET2 ; IF NOT, BYPASS
;
; RCBUS CANNOT ADDRESS THE DEVICE CONTROL PORT AND
; HAS NO WAY TO PERFORM A HARD RESET FROM SOFTWARE,
; SO FAKE IT BY SETTING THE REGISTERS TO THE SAME
; VALUES THAT A RESET WOULD CAUSE.
#IF (IDETRACE >= 3)
PRTS(" FAKE$")
#ENDIF
XOR A
;OUT (IDE_IO_CYLLO),A
CALL IDE_OUT
.DB IDE_REG_CYLLO
;OUT (IDE_IO_CYLHI),A
CALL IDE_OUT
.DB IDE_REG_CYLHI
INC A
;OUT (IDE_IO_COUNT),A
CALL IDE_OUT
.DB IDE_REG_COUNT
;OUT (IDE_IO_SECT),A
CALL IDE_OUT
.DB IDE_REG_SECT
;
IDE_RESET2:
;
;#ENDIF
;
;#IF (IDEMODE == IDEMODE_MK4)
;
LD A,(IY+IDE_MODE) ; GET MODE
@ -1106,6 +1070,14 @@ IDE_SELUNIT2:
;
;
IDE_PROBE:
;
; PROBE FOR A DRIVE ON THE INTERFACE (EITHER MASTER OR SLAVE).
; IDEALLY, THIS IS BEING CALLED IMMEDIATELY AFTER A HARD OR SOFT
; INTERFACE RESET. HOWEVER, THERE ARE SOME HARDWARE IMPLEMENTATTIONS
; WHICH ARE NOT CAPABLE OF EITHER A HARD NOR SOFT RESET. SO THIS
; CODE SHOULD TRY TO HANDLE THE SCENARIO WHERE NO INTERFACE RESET
; HAS OCCURRED.
;
#IF (IDETRACE >= 3)
CALL IDE_PRTPREFIX
PRTS(" PROBE$") ; LABEL FOR IO ADDRESS
@ -1120,14 +1092,31 @@ IDE_PROBE:
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
CALL DELAY ; DELAY ~16US
;
; IF WE GET HERE AND THE INTERFACE IS STILL INITIALIZING, WE NEED TO
; WAIT UNTIL THE INTERFACE IS READY. PER SPEC, THE STATUS REGISTER
; WILL BE EXACTLY $80 IN THIS SCENARIO. SINCE $80 IS UNLIKELY
; FOR A FLOATING PORT VALUE, WE INTERPRET THIS VALUE TO MEAN HARDWARE
; IS THERE AND INIT IS IN PROGRESS, SO IT WILL BE IMPOSSIBLE TO
; INTERROGATE REGISTERS YET. SINCE WE NOW BELIEVE THAT SOME HARDWARE
; IS RESPONDING, IT IS SAFE (AND NECESSARY) TO WAIT FOR BUSY TO
; CLEAR.
;
CALL IDE_IN
.DB IDE_REG_STAT
#IF (IDETRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
CP $80 ; INIT IN PROGRESS?
CALL Z,IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
;
; TEST FOR PRESENCE OF IDE REGISTERS. USE LBA0/1 TO SEE
; IF VALUE CAN BE PERSISTED. THE USE OF BOTH LBA0 AND LBA1
; IS TO MAINTAIN CONSISTENCY WITH TGHE THE PPIDE DRIVER BECAUSE
; IS TO MAINTAIN CONSISTENCY WITH THE THE PPIDE DRIVER BECAUSE
; PPI ITSELF WILL PERSIST THE LAST VALUE WRITTEN, SO WE USE
; MULTIPLE REGISTERS TO WORK AROUND THIS FALSE POSITIVE.
; MULTIPLE REGISTERS TO WORK AROUND THIS.
;
; $AA -> LBA0
LD A,$AA
@ -1163,15 +1152,17 @@ IDE_PROBE:
CALL IDE_REGDUMP
#ENDIF
;
;JR IDE_PROBE1 ; *DEBUG*
;
IDE_PROBE0:
CALL IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
JP NZ,IDE_NOMEDIA ; CONVERT TIMEOUT TO NO MEDIA AND RETURN
;
#IF (IDETRACE >= 3)
CALL IDE_REGDUMP
#ENDIF
;
; IF THE INTERFACE HAS A MASTER AND NO SLAVE, THEN THE ABOVE CHECKS
; MAY ALL SUCCEED WHEN PROBING FOR THE SLAVE. HOWEVER, THE STATUS
; BYTE FOR THE SLAVE WILL REMAIN $00, SO WE LOOK FOR THAT VALUE AS A
; FINAL WAY TO DETECT NO MEDIA.
;
; CHECK STATUS
;IN A,(IDE_IO_STAT) ; GET STATUS
@ -1184,7 +1175,6 @@ IDE_PROBE0:
OR A ; SET FLAGS TO TEST FOR ZERO
JP Z,IDE_NOMEDIA
;
IDE_PROBE1:
; ASSUME ATA DEVICE FOR NOW, RECORD TYPE AND RETURN SUCCESS
LD A,IDE_TYPEATA ; TYPE = ATA
LD (IY+IDE_TYPE),A ; SET IT IN INSTANCE DATA

64
Source/HBIOS/ppide.asm

@ -989,27 +989,6 @@ PPIDE_RESET:
CALL PPIDE_PRTPREFIX
PRTS(" RESET$")
#ENDIF
;
; OLDER CF CARDS DO NOT SEEM TO SET THE
; REGISTERS ON RESET, SO HERE WE FAKE THINGS BY
; SETTING THEM AS A RESET WOULD
#IF (PPIDETRACE >= 3)
PRTS(" FAKE$")
#ENDIF
XOR A
;OUT (IDE_IO_CYLLO),A
CALL PPIDE_OUT
.DB PPIDE_REG_CYLLO
;OUT (IDE_IO_CYLHI),A
CALL PPIDE_OUT
.DB PPIDE_REG_CYLHI
INC A
;OUT (IDE_IO_COUNT),A
CALL PPIDE_OUT
.DB PPIDE_REG_COUNT
;OUT (IDE_IO_SECT),A
CALL PPIDE_OUT
.DB PPIDE_REG_SECT
;
; SETUP PPI TO READ
LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ
@ -1034,6 +1013,9 @@ PPIDE_RESET:
#ENDIF
;
; PULSE IDE RESET LINE
#IF (IDETRACE >= 3)
PRTS(" HARD$")
#ENDIF
LD A,PPIDE_CTL_RESET
;OUT (PPIDE_IO_CTL),A
LD C,(IY+PPIDE_CTL) ; SET IDE ADDRESS
@ -1057,6 +1039,10 @@ PPIDE_RESET:
#ENDIF
#ENDIF
;
; CONFIGURE OPERATION
#IF (PPIDETRACE >= 3)
PRTS(" CONFIG$")
#ENDIF
LD A,%00001010 ; SET ~IEN, NO INTERRUPTS
;OUT (PPIDE_REG_CTRL),A
CALL PPIDE_OUT
@ -1122,6 +1108,14 @@ PPIDE_SELUNIT2:
;
;
PPIDE_PROBE:
;
; PROBE FOR A DRIVE ON THE INTERFACE (EITHER MASTER OR SLAVE).
; IDEALLY, THIS IS BEING CALLED IMMEDIATELY AFTER A HARD OR SOFT
; INTERFACE RESET. HOWEVER, THERE ARE SOME HARDWARE IMPLEMENTATTIONS
; WHICH ARE NOT CAPABLE OF EITHER A HARD NOR SOFT RESET. SO THIS
; CODE SHOULD TRY TO HANDLE THE SCENARIO WHERE NO INTERFACE RESET
; HAS OCCURRED.
;
#IF (PPIDETRACE >= 3)
CALL PPIDE_PRTPREFIX
PRTS(" PROBE$") ; LABEL FOR IO ADDRESS
@ -1136,9 +1130,26 @@ PPIDE_PROBE:
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
;
CALL DELAY ; DELAY ~16US
;
; IF WE GET HERE AND THE INTERFACE IS STILL INITIALIZING, WE NEED TO
; WAIT UNTIL THE INTERFACE IS READY. PER SPEC, THE STATUS REGISTER
; WILL BE EXACTLY $80 IN THIS SCENARIO. SINCE $80 IS UNLIKELY
; FOR A FLOATING PORT VALUE, WE INTERPRET THIS VALUE TO MEAN HARDWARE
; IS THERE AND INIT IS IN PROGRESS, SO IT WILL BE IMPOSSIBLE TO
; INTERROGATE REGISTERS YET. SINCE WE NOW BELIEVE THAT SOME HARDWARE
; IS RESPONDING, IT IS SAFE (AND NECESSARY) TO WAIT FOR BUSY TO
; CLEAR.
;
CALL PPIDE_IN
.DB PPIDE_REG_STAT
#IF (PPIDETRACE >= 3)
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
CP $80 ; INIT IN PROGRESS?
CALL Z,PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
;
; TEST FOR PRESENCE OF IDE REGISTERS. USE LBA0/1 TO SEE
; IF VALUE CAN BE PERSISTED. THE USE OF BOTH LBA0 AND LBA1
; IS TO MAINTAIN CONSISTENCY WITH TGHE THE PPIDE DRIVER BECAUSE
@ -1179,15 +1190,17 @@ PPIDE_PROBE:
CALL PPIDE_REGDUMP
#ENDIF
;
;JR PPIDE_PROBE1 ; *DEBUG*
;
PPIDE_PROBE0:
CALL PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
JP NZ,PPIDE_NOMEDIA ; CONVERT TIMEOUT TO NO MEDIA AND RETURN
;
#IF (PPIDETRACE >= 3)
CALL PPIDE_REGDUMP
#ENDIF
;
; IF THE INTERFACE HAS A MASTER AND NO SLAVE, THEN THE ABOVE CHECKS
; MAY ALL SUCCEED WHEN PROBING FOR THE SLAVE. HOWEVER, THE STATUS
; BYTE FOR THE SLAVE WILL REMAIN $00, SO WE LOOK FOR THAT VALUE AS A
; FINAL WAY TO DETECT NO MEDIA.
;
; CHECK STATUS
; IN A,(PPIDE_REG_STAT) ; GET STATUS
@ -1200,7 +1213,6 @@ PPIDE_PROBE0:
OR A ; SET FLAGS TO TEST FOR ZERO
JP Z,PPIDE_NOMEDIA ; CONTINUE IF NON-ZERO
;
PPIDE_PROBE1:
; ASSUME ATA DEVICE FOR NOW, RECORD TYPE AND RETURN SUCCESS
LD A,PPIDE_TYPEATA ; TYPE = ATA
LD (IY+PPIDE_TYPE),A ; SET IT IN INSTANCE DATA

2
Source/ver.inc

@ -2,7 +2,7 @@
#DEFINE RMN 3
#DEFINE RUP 0
#DEFINE RTP 0
#DEFINE BIOSVER "3.3.0-dev.5"
#DEFINE BIOSVER "3.3.0-dev.6"
#define rmj RMJ
#define rmn RMN
#define rup RUP

2
Source/ver.lib

@ -3,5 +3,5 @@ rmn equ 3
rup equ 0
rtp equ 0
biosver macro
db "3.3.0-dev.5"
db "3.3.0-dev.6"
endm

Loading…
Cancel
Save