From ad3c533145d936dd32594ec2712f7b9643cd4c99 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sun, 23 Apr 2023 18:47:43 -0700 Subject: [PATCH] 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. --- Source/HBIOS/ide.asm | 76 ++++++++++++++++++------------------------ Source/HBIOS/ppide.asm | 64 ++++++++++++++++++++--------------- Source/ver.inc | 2 +- Source/ver.lib | 2 +- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/Source/HBIOS/ide.asm b/Source/HBIOS/ide.asm index afd3869e..5268b447 100644 --- a/Source/HBIOS/ide.asm +++ b/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 diff --git a/Source/HBIOS/ppide.asm b/Source/HBIOS/ppide.asm index 271b1d72..f3f2fe6a 100644 --- a/Source/HBIOS/ppide.asm +++ b/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 diff --git a/Source/ver.inc b/Source/ver.inc index d5e9990c..1abda088 100644 --- a/Source/ver.inc +++ b/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 diff --git a/Source/ver.lib b/Source/ver.lib index 845f0f6b..65d94bf3 100644 --- a/Source/ver.lib +++ b/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