mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-07 06:53:13 -06:00
Compare commits
1 Commits
v3.3.0-dev
...
v3.3.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f71fe05aa |
@@ -35,8 +35,10 @@ Z180_CLKDIV .SET 1 ; Z180: CHK DIV: 0=OSC/2, 1=OSC, 2=OSC*2
|
||||
Z180_MEMWAIT .SET 0 ; Z180: MEMORY WAIT STATES (0-3)
|
||||
Z180_IOWAIT .SET 1 ; Z180: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3)
|
||||
;
|
||||
FPENABLE .SET TRUE ; ENABLES FRONT PANEL SWITCHES
|
||||
DIAGENABLE .SET TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT
|
||||
DIAGPORT .SET $00 ; DIAGNOSTIC PORT ADDRESS
|
||||
LEDENABLE .SET TRUE ; ENABLE STATUS LED (SINGLE LED)
|
||||
DIAGENABLE .SET FALSE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT
|
||||
;
|
||||
DSRTCENABLE .SET TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM)
|
||||
INTRTCENABLE .SET TRUE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM)
|
||||
|
||||
@@ -35,10 +35,10 @@ Z180_MEMWAIT .SET 0 ; Z180: MEMORY WAIT STATES (0-3)
|
||||
Z180_IOWAIT .SET 1 ; Z180: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3)
|
||||
;
|
||||
FPENABLE .SET TRUE ; ENABLES FRONT PANEL SWITCHES
|
||||
FPBASE .SET $A0 ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
FPBASE .SET $00 ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
LEDENABLE .SET TRUE ; ENABLE STATUS LED (SINGLE LED)
|
||||
DIAGENABLE .SET TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT
|
||||
DIAGPORT .SET $A0 ; DIAGNOSTIC PORT ADDRESS
|
||||
DIAGPORT .SET $00 ; DIAGNOSTIC PORT ADDRESS
|
||||
;
|
||||
DSRTCENABLE .SET TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM)
|
||||
INTRTCENABLE .SET TRUE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM)
|
||||
|
||||
@@ -35,10 +35,10 @@ Z180_MEMWAIT .SET 0 ; Z180: MEMORY WAIT STATES (0-3)
|
||||
Z180_IOWAIT .SET 1 ; Z180: I/O WAIT STATES TO ADD ABOVE 1 W/S BUILT-IN (0-3)
|
||||
;
|
||||
FPENABLE .SET TRUE ; ENABLES FRONT PANEL SWITCHES
|
||||
FPBASE .SET $A0 ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
FPBASE .SET $00 ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
LEDENABLE .SET TRUE ; ENABLE STATUS LED (SINGLE LED)
|
||||
DIAGENABLE .SET TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT
|
||||
DIAGPORT .SET $A0 ; DIAGNOSTIC PORT ADDRESS
|
||||
DIAGPORT .SET $00 ; DIAGNOSTIC PORT ADDRESS
|
||||
;
|
||||
DSRTCENABLE .SET TRUE ; DSRTC: ENABLE DS-1302 CLOCK DRIVER (DSRTC.ASM)
|
||||
INTRTCENABLE .SET TRUE ; ENABLE PERIODIC INTERRUPT CLOCK DRIVER (INTRTC.ASM)
|
||||
|
||||
@@ -67,7 +67,7 @@ SKZENABLE .EQU FALSE ; ENABLE SERGEY'S Z80-512K FEATURES
|
||||
WDOGMODE .EQU WDOG_NONE ; WATCHDOG MODE: WDOG_[NONE|EZZ80|SKZ]
|
||||
;
|
||||
FPENABLE .EQU FALSE ; ENABLES FRONT PANEL SWITCHES
|
||||
FPBASE .EQU $0D ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
FPBASE .EQU $00 ; FRONT PANEL I/O PORT BASE ADDRESS
|
||||
DIAGENABLE .EQU TRUE ; ENABLES OUTPUT TO 8 BIT LED DIAGNOSTIC PORT
|
||||
DIAGPORT .EQU $0D ; DIAGNOSTIC PORT ADDRESS
|
||||
DIAGDISKIO .EQU TRUE ; ENABLES DISK I/O ACTIVITY ON DIAGNOSTIC LEDS
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
;=============================================================================
|
||||
;
|
||||
; TODO:
|
||||
; - FIX SCALER CONSTANT
|
||||
; - GOPARTNER NEEDS TO HANDLE "NO PARTNER" CONDITION
|
||||
; - IMPLEMENT H/W PROBES FOR DIO AND DIDE
|
||||
;
|
||||
@@ -126,9 +125,13 @@ IDE_REG_DRVADR .EQU $0F ; DRIVE ADDRESS REGISTER (R)
|
||||
;
|
||||
; COMMAND BYTES
|
||||
;
|
||||
IDE_CIDE_NOP .EQU $00
|
||||
IDE_CIDE_DEVRES .EQU $08
|
||||
IDE_CIDE_RECAL .EQU $10
|
||||
IDE_CIDE_READ .EQU $20
|
||||
IDE_CIDE_WRITE .EQU $30
|
||||
IDE_CIDE_DEVDIAG .EQU $90
|
||||
IDE_CIDE_IDPKTDEV .EQU $A1
|
||||
IDE_CIDE_IDDEV .EQU $EC
|
||||
IDE_CIDE_SETFEAT .EQU $EF
|
||||
;
|
||||
@@ -153,6 +156,7 @@ IDE_STIOERR .EQU -4
|
||||
IDE_STRDYTO .EQU -5
|
||||
IDE_STDRQTO .EQU -6
|
||||
IDE_STBSYTO .EQU -7
|
||||
IDE_STNOTSUP .EQU -8
|
||||
;
|
||||
; DRIVE SELECTION BYTES (FOR USE IN DRIVE/HEAD REGISTER)
|
||||
;
|
||||
@@ -290,15 +294,18 @@ IDE_DEV2S: ; DEVICE 2, SLAVE
|
||||
;
|
||||
; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL
|
||||
; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING
|
||||
; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES
|
||||
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
|
||||
; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY
|
||||
; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO
|
||||
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
|
||||
; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS.
|
||||
; ON THE SITUATION. THE SLOW TIMEOUT IS USED TO WAIT FOR A DEVICE TO
|
||||
; BECOME READY AFTER A HARD RESET (SPIN UP, ETC.). THE NORMAL TIMEOUT
|
||||
; IS USED DURING NORMAL OPERATION FOR ALL I/O OPERATIONS WHICH SHOULD
|
||||
; OCCUR PRETTY FAST. NOTE THAT THE ATA SPEC ALLOWS UP TO 30 SECONDS
|
||||
; FOR DEVICES TO RESPOND. WE ARE USING MUCH MORE AGGRESSIVE VALUES
|
||||
; BASED ON REAL WORLD EXPERIENCE.
|
||||
; THE PICO TIMEOUT (TOPICO) IS A SPECIAL TIMEOUT FOR THE RC2014 SD
|
||||
; PICO TO WAIT FOR THE PICO DEVICE TO INITIALIZE.
|
||||
;
|
||||
IDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS
|
||||
IDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
|
||||
IDE_TOSLOW .EQU 200 ; SLOW TIMEOUT IS 20 SECS
|
||||
IDE_TONORM .EQU 5 ; NORMAL TIMEOUT IS 0.55 SECS
|
||||
IDE_TOPICO .EQU 50 ; RC2014 SD PICO (5 SECONDS)
|
||||
;
|
||||
;=============================================================================
|
||||
; INITIALIZATION ENTRY POINT
|
||||
@@ -306,9 +313,12 @@ IDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
|
||||
;
|
||||
IDE_INIT:
|
||||
; COMPUTE CPU SPEED COMPENSATED TIMEOUT SCALER
|
||||
; AT 1MHZ, THE SCALER IS 218 (50000US / 229TS = 218)
|
||||
; SCALER IS THEREFORE 218 * CPU SPEED IN MHZ
|
||||
LD DE,961 ; LOAD SCALER FOR 1MHZ
|
||||
; ONE INTERNAL LOOP IN WAITBSY IS 180TS. ON A 1 MHZ CPU, 1 TS
|
||||
; TAKES 1NS. SO 1/10 SECOND IS 100000 TS ON A 1 MHZ CPU.
|
||||
; SINCE 1 INTERNAL LOOP IS 180 TS, IT TAKES 100000 / 180 = 556
|
||||
; INTERNAL LOOPS FOR 1/10 SECOND. SO, WE WANT TO USE
|
||||
; 523 * CPU MHZ FOR INTERNAL LOOP COUNT.
|
||||
LD DE,556 ; LOAD SCALER FOR 1MHZ
|
||||
LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
|
||||
CALL MULT8X16 ; HL := DE * A
|
||||
LD (IDE_TOSCALER),HL ; SAVE IT
|
||||
@@ -359,7 +369,7 @@ IDE_INIT2A:
|
||||
LD DE,IDE_STR_NOHW ; NOT PRESENT MESSAGE
|
||||
CALL WRITESTR ; DISPLAY IT
|
||||
JR IDE_INIT4 ; SKIP CFG ENTRY
|
||||
;
|
||||
;
|
||||
IDE_INIT3:
|
||||
CALL IDE_RESET ; RESET THE BUS
|
||||
CALL IDE_INIT5 ; DETECT/INIT MASTER
|
||||
@@ -367,7 +377,7 @@ IDE_INIT3:
|
||||
CALL IDE_GOPARTNER ; SWITCH IY TO PARTNER CFG
|
||||
CALL IDE_INIT5 ; DETECT/INIT SLAVE
|
||||
POP IY ; RESTORE CFG PTR
|
||||
;
|
||||
;
|
||||
IDE_INIT4:
|
||||
LD DE,IDE_CFGSIZ ; SIZE OF CFG TABLE ENTRY
|
||||
ADD IY,DE ; BUMP POINTER
|
||||
@@ -385,13 +395,28 @@ IDE_INIT5:
|
||||
PUSH IY ; CFG ENTRY POINTER
|
||||
POP DE ; COPY TO DE
|
||||
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
|
||||
;
|
||||
; START PRINTING DEVICE INFO
|
||||
CALL IDE_PRTPREFIX ; PRINT DEVICE PREFIX
|
||||
LD A,(IY+IDE_TYPE)
|
||||
LD DE,IDE_STR_TYPEATA
|
||||
CP IDE_TYPEATA
|
||||
CALL Z,WRITESTR
|
||||
LD DE,IDE_STR_TYPEATAPI
|
||||
CP IDE_TYPEATAPI
|
||||
CALL Z,WRITESTR
|
||||
;
|
||||
; CHECK FOR BAD STATUS
|
||||
LD A,(IY+IDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
JP NZ,IDE_PRTSTAT ; EXIT VIA PRINT STATUS
|
||||
JP Z,IDE_INIT6
|
||||
CALL PC_SPACE
|
||||
JP NZ,IDE_PRTSTATSTR ; EXIT VIA PRINT STATUS STRING
|
||||
;
|
||||
CALL IDE_PRTPREFIX ; PRINT DEVICE PREFIX
|
||||
IDE_INIT6:
|
||||
LD A,(IY+IDE_TYPE) ; GET DEVICE TYPE
|
||||
CP IDE_TYPEATA ; ATA?
|
||||
RET NZ ; IF NOT, THEN DONE
|
||||
;
|
||||
LD DE,IDE_STR_8BIT
|
||||
BIT 1,(IY+IDE_ACC) ; 8 BIT ACCESS?
|
||||
@@ -555,26 +580,12 @@ IDE_DEVICE1:
|
||||
IDE_MEDIA:
|
||||
LD A,E ; GET FLAGS
|
||||
OR A ; SET FLAGS
|
||||
JR Z,IDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA
|
||||
JR Z,IDE_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA
|
||||
;
|
||||
; GET CURRENT STATUS
|
||||
LD A,(IY+IDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
JR NZ,IDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET
|
||||
;
|
||||
; USE IDENTIFY COMMAND TO CHECK DEVICE
|
||||
LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),IDE_TOFAST ; USE FAST TIMEOUT DURING IDENTIFY COMMAND
|
||||
CALL IDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT
|
||||
CALL IDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND
|
||||
LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),IDE_TONORM ; BACK TO NORMAL TIMEOUT
|
||||
JR Z,IDE_MEDIA2 ; IF SUCCESS, BYPASS RESET
|
||||
;CALL IDE_RESET ; RESET IDE INTERFACE
|
||||
CALL IDE_INITUNIT ; RE-INITIALIZE UNIT
|
||||
;
|
||||
IDE_MEDIA1:
|
||||
CALL IDE_RESET ; RESET IDE INTERFACE
|
||||
;
|
||||
IDE_MEDIA2:
|
||||
LD A,(IY+IDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
LD D,0 ; NO MEDIA CHANGE DETECTED
|
||||
@@ -655,6 +666,32 @@ IDE_SETFEAT:
|
||||
;
|
||||
;
|
||||
;
|
||||
IDE_NOP:
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_PRTPREFIX
|
||||
PRTS(" NOP$")
|
||||
#ENDIF
|
||||
LD A,(IDE_DRVHD)
|
||||
;OUT (IDE_IO_DRVHD),A
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_DRVHD
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; EXECUTE THE NOP COMMAND, BUT DON'T WAIT FOR DRDY, JUST
|
||||
; MAKE SURE BUSY IS CLEAR. THIS COMMAND IS USED DURING
|
||||
; DEVICE DETECTION/INITIALIZATION AND ATAPI DEVICES WILL
|
||||
; NOT ASSERT DRDY AFTER RESET.
|
||||
LD A,IDE_CIDE_NOP ; CMD = NOP
|
||||
LD (IDE_CMD),A ; SAVE IT
|
||||
CALL IDE_WAITBSY
|
||||
RET NZ
|
||||
JP IDE_RUNCMD1 ; RUN COMMAND AND EXIT
|
||||
;
|
||||
;
|
||||
;
|
||||
IDE_IDENTIFY:
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_PRTPREFIX
|
||||
@@ -672,6 +709,40 @@ IDE_IDENTIFY:
|
||||
LD (IDE_CMD),A
|
||||
CALL IDE_RUNCMD
|
||||
RET NZ
|
||||
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
BIT 3,A ; IS DRQ SET?
|
||||
JP Z,IDE_NOMEDIA
|
||||
;
|
||||
LD HL,HB_WRKBUF
|
||||
JP IDE_GETBUF ; EXIT THRU BUFRD
|
||||
;
|
||||
;
|
||||
;
|
||||
IDE_IDENTIFYPACKET:
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_PRTPREFIX
|
||||
PRTS(" IDPKTDEV$")
|
||||
#ENDIF
|
||||
LD A,(IDE_DRVHD)
|
||||
;OUT (IDE_IO_DRVHD),A
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_DRVHD
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
LD A,IDE_CIDE_IDPKTDEV
|
||||
LD (IDE_CMD),A
|
||||
CALL IDE_RUNCMD
|
||||
RET NZ
|
||||
;
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
BIT 3,A ; IS DRQ SET?
|
||||
JP Z,IDE_NOMEDIA
|
||||
;
|
||||
LD HL,HB_WRKBUF
|
||||
JP IDE_GETBUF ; EXIT THRU BUFRD
|
||||
;
|
||||
@@ -766,10 +837,6 @@ IDE_SETADDR:
|
||||
#ENDIF
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_COUNT
|
||||
;;;
|
||||
;;#IF (DSKYENABLE)
|
||||
;; CALL IDE_DSKY
|
||||
;;#ENDIF
|
||||
;
|
||||
RET
|
||||
;
|
||||
@@ -781,6 +848,7 @@ IDE_RUNCMD:
|
||||
CALL IDE_WAITRDY ; WAIT FOR DRIVE READY
|
||||
RET NZ ; BAIL OUT ON TIMEOUT
|
||||
;
|
||||
IDE_RUNCMD1:
|
||||
LD A,(IDE_CMD) ; GET THE COMMAND
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
@@ -937,11 +1005,14 @@ IDE_RESET:
|
||||
PRTS(" RESET$")
|
||||
#ENDIF
|
||||
;
|
||||
;#IF (IDEMODE == IDEMODE_MK4)
|
||||
; HARD RESET
|
||||
;
|
||||
; RESET LINE IS NORMALLY PULSED AT POWER ON. HOWEVER, THIS IS NOT
|
||||
; DONE FOR MK4 BUILT-IN IDE PORT, SO WE DO IT NOW.
|
||||
;
|
||||
LD A,(IY+IDE_MODE) ; GET MODE
|
||||
CP IDEMODE_MK4 ; MK4?
|
||||
JR NZ,IDE_RESET1 ; IF NOT, BYPASS
|
||||
JR NZ,IDE_RESET2 ; IF NOT, BYPASS
|
||||
;
|
||||
; USE HARDWARE RESET LINE
|
||||
#IF (IDETRACE >= 3)
|
||||
@@ -960,66 +1031,59 @@ IDE_RESET:
|
||||
LD DE,20
|
||||
CALL VDELAY
|
||||
;
|
||||
IDE_RESET1:
|
||||
; SOME CF CARDS AND CF CARD EMULATORS NEED A LITTLE TIME TO
|
||||
; "BOOT" THEIR INTERNAL ELECTRONICS, SO THEY CANNOT ASSERT BUSY
|
||||
; IMMEDIATELY. A SMALL WAIT IS PERFORMED HERE TO GIVE SUCH DEVICES
|
||||
; A BETTER CHANCE TO SUCCEED LATER.
|
||||
;
|
||||
;#ENDIF
|
||||
;;; CALL LDELAY ; DELAY FOR SLAVE INIT
|
||||
LD DE,150000 / 16 ;
|
||||
CALL VDELAY ; SMALL DELAY
|
||||
;
|
||||
;#IF ((IDEMODE != IDEMODE_MK4) & (IDEMODE != IDEMODE_RC))
|
||||
JR IDE_RESET3 ; SKIP SOFT RESET
|
||||
;
|
||||
; SOFT RESET
|
||||
;
|
||||
; RC CANNOT ACCESS DEVICE CONTROL REG, SO SKIP THIS
|
||||
;
|
||||
IDE_RESET2:
|
||||
LD A,(IY+IDE_MODE) ; GET MODE
|
||||
CP IDEMODE_MK4 ; MK4?
|
||||
JR Z,IDE_RESET3 ; IF SO, BYPASS
|
||||
CP IDEMODE_RC ; RCBUS?
|
||||
JR Z,IDE_RESET3 ; IF SO, BYPASS
|
||||
JR Z,IDE_RESET4 ; IF SO, BYPASS
|
||||
;
|
||||
; INITIATE SOFT RESET
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" SOFT$")
|
||||
#ENDIF
|
||||
LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES
|
||||
LD A,%00001110 ; ASSERT RESET, NO INTERRUPTS
|
||||
;OUT (IDE_IO_CTRL),A
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_CTRL
|
||||
LD DE,20 ; DELAY 320US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
;
|
||||
IDE_RESET3:
|
||||
;
|
||||
;#ENDIF
|
||||
; CONFIGURE OPERATION AND END SOFT RESET
|
||||
;
|
||||
LD DE,2 ; DELAY 32US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
;
|
||||
;#IF (IDEMODE != IDEMODE_RC)
|
||||
;
|
||||
LD A,(IY+IDE_MODE) ; GET MODE
|
||||
CP IDEMODE_RC ; RCBUS?
|
||||
JR Z,IDE_RESET4 ; IF SO, BYPASS
|
||||
;
|
||||
; CONFIGURE OPERATION AND END SOFT RESET
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" CONFIG$")
|
||||
#ENDIF
|
||||
LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET
|
||||
LD DE,20 ; DELAY 320US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
LD A,%00001010 ; DEASSERT RESET, NO INTERRUPTS
|
||||
;OUT (IDE_IO_CTRL),A ; PUSH TO REGISTER
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_CTRL
|
||||
;
|
||||
IDE_RESET4:
|
||||
;
|
||||
;#ENDIF
|
||||
;
|
||||
; SPEC ALLOWS UP TO 450MS FOR DEVICES TO ASSERT THEIR PRESENCE
|
||||
; VIA -DASP. I ENCOUNTER PROBLEMS LATER ON IF I DON'T WAIT HERE
|
||||
; FOR THAT TO OCCUR. THUS FAR, IT APPEARS THAT 150MS IS SUFFICIENT
|
||||
; FOR ANY DEVICE ENCOUNTERED. MAY NEED TO EXTEND BACK TO 500MS
|
||||
; IF A SLOWER DEVICE IS ENCOUNTERED.
|
||||
;
|
||||
;LD DE,500000/16 ; ~500MS
|
||||
LD DE,150000/16 ; ~???MS
|
||||
CALL VDELAY
|
||||
LD HL,IDE_TONORM ; NORMAL TIMEOUT NOW
|
||||
LD (IDE_TIMEOUT),HL ; AND RESTORE IT
|
||||
;
|
||||
; INITIALIZE THE INDIVIDUAL UNITS (MASTER AND SLAVE).
|
||||
; BASED ON TESTING, IT APPEARS THAT THE MASTER UNIT MUST
|
||||
; BE DONE FIRST OR THIS BEHAVES BADLY.
|
||||
;
|
||||
PUSH IY ; SAVE CFG PTR
|
||||
BIT 0,(IY+IDE_ACC) ; MASTER?
|
||||
CALL Z,IDE_GOPARTNER ; IF NOT, SWITCH TO MASTER
|
||||
@@ -1037,14 +1101,10 @@ IDE_INITUNIT:
|
||||
CALL IDE_SELUNIT ; SELECT UNIT
|
||||
RET NZ ; ABORT IF ERROR
|
||||
|
||||
LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),IDE_TONORM ; SET NORMAL TIMEOUT
|
||||
|
||||
CALL IDE_PROBE ; DO PROBE
|
||||
RET NZ ; JUST RETURN IF NOTHING THERE
|
||||
|
||||
CALL IDE_INITDEV ; IF FOUND, ATTEMPT TO INIT DEVICE
|
||||
RET ; DONE
|
||||
JP IDE_INITDEV ; EXIT VIA INITDEV
|
||||
;
|
||||
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT
|
||||
; UNIT IS SPECIFIED IN IDE_UNIT
|
||||
@@ -1059,9 +1119,15 @@ IDE_SELUNIT:
|
||||
BIT 0,(IY+IDE_ACC) ; MASTER?
|
||||
JR Z,IDE_SELUNIT1 ; HANDLE SLAVE
|
||||
LD A,IDE_DRVMASTER ; MASTER
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" MASTER$")
|
||||
#ENDIF
|
||||
JR IDE_SELUNIT2
|
||||
IDE_SELUNIT1:
|
||||
LD A,IDE_DRVSLAVE ; SLAVE
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" SLAVE$")
|
||||
#ENDIF
|
||||
IDE_SELUNIT2:
|
||||
LD (IDE_DRVHD),A ; SAVE IT
|
||||
XOR A ; SUCCESS
|
||||
@@ -1082,6 +1148,13 @@ IDE_PROBE:
|
||||
CALL IDE_PRTPREFIX
|
||||
PRTS(" PROBE$") ; LABEL FOR IO ADDRESS
|
||||
#ENDIF
|
||||
;
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; SELECT DEVICE (MASTER/SLAVE)
|
||||
LD A,(IDE_DRVHD)
|
||||
@@ -1094,14 +1167,20 @@ IDE_PROBE:
|
||||
#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.
|
||||
; THE RC2014 SD PICO TAKES A FEW SECONDS TO INITIALIZE. DURING THIS
|
||||
; TIME IT APPEARS TO RETURN $00. BELOW IS A SPECIAL CASE FOR RC2014
|
||||
; TO WAIT FOR THIS DEVICE TO INITIALIZE. WE ONLY DO THIS IF THE
|
||||
; MASTER DEVICE IS BEING PROBED. WHEN THE SLAVE DEVICE IS
|
||||
; SELECTED, THE SD PICO WILL ALWAYS RETURN ZERO AND CAUSE AN
|
||||
; UNNECESSARY DELAY.
|
||||
;
|
||||
LD A,(IY+IDE_MODE) ; GET MODE BITS
|
||||
CP IDEMODE_RC ; RCBUS?
|
||||
JR NZ,IDE_PROBE0 ; IF NOT, BYPASS
|
||||
;
|
||||
LD A,(IDE_DRVHD) ; GET CURRENT SETTING
|
||||
BIT 4,A ; TEST SLAVE BIT
|
||||
JR NZ,IDE_PROBE0 ; IF SO, BYPASS
|
||||
;
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
@@ -1109,8 +1188,60 @@ IDE_PROBE:
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
OR A ; SET FLAGS
|
||||
JR NZ,IDE_PROBE0 ; SKIP IF NOT $00
|
||||
;
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" WAIT$")
|
||||
#ENDIF
|
||||
LD HL,(IDE_TIMEOUT) ; GET CURRENT TIMEOUT
|
||||
PUSH HL ; SAVE IT
|
||||
LD HL,IDE_TOPICO ; SLOW TIMEOUT FOR THIS
|
||||
LD (IDE_TIMEOUT),HL ; SET IT
|
||||
CALL IDE_WAIT00 ; WAIT FOR $00 TO CLEAR
|
||||
POP HL ; RECOVER TIMEOUT
|
||||
LD (IDE_TIMEOUT),HL ; SET IT
|
||||
;
|
||||
; IF WE GET HERE AND THE DRIVE IS STILL INITIALIZING, WE NEED TO
|
||||
; WAIT UNTIL THE DRIVE IS READY. IN THIS CASE BUSY *WILL* BE HIGH.
|
||||
; BASED ON TESTING, DRDY AND DSC VALUES VARY. EVERYTHING ELSE SEEMS
|
||||
; TO BE ZERO. SO, WE FILTER OUT DRDY & DSC, THEN LOOK FOR BUSY=1
|
||||
; AND ALL ELSE ZERO. THIS GENERALLY AVOIDS VALUES THAT ARE TYPICAL
|
||||
; FOR FLOATING PORTS AND SO CAN BE USED TO DETERMINE IF WE NEED TO
|
||||
; WAIT FOR THE DEVICE TO BE READY. THIS WAIT IS MANDATORY BECAUSE
|
||||
; SOME (IF NOT ALL) DEVICES WILL NOT PERSIST REGISTER VALUES UNTIL
|
||||
; THE DRIVE IS READY.
|
||||
;
|
||||
IDE_PROBE0:
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
AND %10101111 ; FILTER OUT DRDY & DSC
|
||||
CP $80 ; INIT IN PROGRESS?
|
||||
CALL Z,IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
|
||||
JR NZ,IDE_PROBE1 ; IF NOT, SKIP AHEAD
|
||||
;
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" WAIT$")
|
||||
#ENDIF
|
||||
;
|
||||
LD HL,(IDE_TIMEOUT) ; GET CURRENT TIMEOUT
|
||||
PUSH HL ; SAVE IT
|
||||
LD HL,IDE_TOSLOW ; SLOW TIMEOUT FOR THIS
|
||||
LD (IDE_TIMEOUT),HL ; SET IT
|
||||
CALL IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
|
||||
POP HL ; RECOVER TIMEOUT
|
||||
LD (IDE_TIMEOUT),HL ; SET IT
|
||||
;
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; TEST FOR PRESENCE OF IDE REGISTERS. USE LBA0/1 TO SEE
|
||||
; IF VALUE CAN BE PERSISTED. THE USE OF BOTH LBA0 AND LBA1
|
||||
@@ -1118,11 +1249,12 @@ IDE_PROBE:
|
||||
; PPI ITSELF WILL PERSIST THE LAST VALUE WRITTEN, SO WE USE
|
||||
; MULTIPLE REGISTERS TO WORK AROUND THIS.
|
||||
;
|
||||
IDE_PROBE1:
|
||||
; $AA -> LBA0
|
||||
LD A,$AA
|
||||
CALL IDE_OUT
|
||||
.DB IDE_REG_LBA0
|
||||
;
|
||||
;
|
||||
; $55 => LBA1
|
||||
LD A,$55
|
||||
CALL IDE_OUT
|
||||
@@ -1152,43 +1284,34 @@ IDE_PROBE:
|
||||
CALL IDE_REGDUMP
|
||||
#ENDIF
|
||||
;
|
||||
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
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS
|
||||
#ENDIF
|
||||
OR A ; SET FLAGS TO TEST FOR ZERO
|
||||
JP Z,IDE_NOMEDIA
|
||||
;
|
||||
; 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
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; DONE, NOTE THAT A=0 AND Z IS SET
|
||||
XOR A
|
||||
RET
|
||||
;
|
||||
; (RE)INITIALIZE DEVICE
|
||||
;
|
||||
IDE_INITDEV:
|
||||
;
|
||||
LD A,(IY+IDE_TYPE) ; GET THE DEVICE TYPE
|
||||
OR A ; SET FLAGS
|
||||
JP Z,IDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS
|
||||
#IF (IDETRACE >= 3)
|
||||
CALL IDE_PRTPREFIX
|
||||
PRTS(" INITDEV$") ; LABEL FOR IO ADDRESS
|
||||
#ENDIF
|
||||
;
|
||||
; IF THE IDE STATUS BYTE IS $00, WE HAVE EITHER A NON-PRESENT SLAVE
|
||||
; OR AN ATAPI DEVICE. TO DIFFERENTIATE THESE POSSIBILITIES, WE RUN
|
||||
; A NOP COMMAND. IF WE HAVE AN ATAPI DEVICE, THIS WILL CAUSE THE
|
||||
; STATUS BYTE TO BE "NORMAL" (NON-ZERO). IF THE STATUS IS STILL
|
||||
; ZERO, WE ABORT WITH A NO MEDIA STATUS. NOTE THAT THE NOP COMMAND
|
||||
; RETURNS A COMMAND ERROR BY DESIGN. WE JUST IGNORE THE ERROR.
|
||||
;
|
||||
CALL IDE_NOP
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
OR A
|
||||
JP Z,IDE_NOMEDIA
|
||||
;
|
||||
; WE NEED TO SETUP 8-BIT MODE BEFORE DOING ANYTHING ELSE
|
||||
;
|
||||
IDE_INITDEV0A:
|
||||
BIT 1,(IY+IDE_ACC) ; 8 BIT ACCESS?
|
||||
JR Z,IDE_INITDEV0 ; NO, DO 16 BIT INIT
|
||||
LD A,IDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO
|
||||
@@ -1206,10 +1329,14 @@ IDE_INITDEV0:
|
||||
IDE_INITDEV00:
|
||||
;
|
||||
CALL IDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
JR NZ,IDE_INITDEVP ; ON ERROR, TRY PACKET DEVICE
|
||||
;
|
||||
; DECLARE WE ARE ATA
|
||||
LD A,IDE_TYPEATA ; OTHERWISE TYPE=ATA
|
||||
LD (IY+IDE_TYPE),A ; SET IT IN INSTANCE DATA
|
||||
;
|
||||
LD DE,HB_WRKBUF ; POINT TO BUFFER
|
||||
#IF (IDETRACE >= 3)
|
||||
#IF (IDETRACE >= 4)
|
||||
CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
|
||||
#ENDIF
|
||||
;
|
||||
@@ -1229,38 +1356,15 @@ IDE_INITDEV00:
|
||||
CALL PRTHEXWORD
|
||||
#ENDIF
|
||||
;
|
||||
; SEE PAGE 114 OF CF+ & CF SPECIFICATION REV. 3.0 FOR CF CARD
|
||||
; SIGNATURE VALUES. ALL OF THE BELOW ARE DOCUMENTED THERE EXCEPT
|
||||
; $045A WHICH IS A VALUE DISCOVERED ON A CF<->SD CARD ADAPTER.
|
||||
;
|
||||
; SIGNATURE $045A IS NOT LISTED IN THE CF SPEC. IT WAS ADDED BECAUSE
|
||||
; IT WAS SEEN IN THE WILD ON A CF-SD ADAPTER. HOWEVER IT HAS NOW
|
||||
; ALSO BEEN SEEN ON A SPINNING HARD DISK. SINCE IT IS AMBIGUOUS, I
|
||||
; WILL CONSIDER IT TO BE A HARD DISK.
|
||||
;
|
||||
LD BC,$848A ; STANDARD CF CARD SIGNATURE %1000 1111 1000 1010
|
||||
CALL IDE_INITDEV000 ; TEST & SET
|
||||
LD BC,$044A ; ALT SIG FOR CF NON-REMOVABLE %0000 0100 0100 1010
|
||||
CALL IDE_INITDEV000 ; TEST & SET
|
||||
;LD BC,$045A ; ?ALT SIG FOR CF NON-REMOVABLE %0000 0100 0101 1010
|
||||
;CALL IDE_INITDEV000 ; TEST & SET
|
||||
LD BC,$0040 ; ALT SIG FOR CF NON-REMOVABLE %0000 0000 0100 0000
|
||||
CALL IDE_INITDEV000 ; TEST & SET
|
||||
JR IDE_INITDEV1 ; CONTINUE INIT
|
||||
;
|
||||
IDE_INITDEV000:
|
||||
; CHECK IF FIRST WORD OF IDENTIFY DATA MATCHES VALUE IN BC
|
||||
; AND SET CF FLAG IF SO
|
||||
LD HL,(HB_WRKBUF) ; FIRST WORD OF IDENTIFY DATA
|
||||
OR A ; CLEAR CARRY
|
||||
SBC HL,BC ; COMPARE
|
||||
RET NZ ; ABORT IF NOT EQUAL
|
||||
; DETERMINE IF COMPACTFLASH MEDIA
|
||||
LD A,(HB_WRKBUF+(83*2)) ; LOW BYTE OF WORD 83
|
||||
BIT 2,A ; TEST CFA FEATURE SET BIT
|
||||
JR Z,IDE_INITDEV1 ; IF NOT, SKIP
|
||||
SET 0,(IY+IDE_MED) ; ELSE SET FLAGS BIT FOR CF MEDIA
|
||||
RET ; AND RETURN
|
||||
;
|
||||
IDE_INITDEV1:
|
||||
; DETERMINE IF LBA CAPABLE
|
||||
LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER
|
||||
LD A,(HB_WRKBUF+98+1) ; HIGH BYTE OF WORD 49
|
||||
BIT 1,A ; CHECK THE LBA BIT
|
||||
JR Z,IDE_INITDEV2 ; NOT SET, BYPASS
|
||||
SET 1,(IY+IDE_MED) ; SET FLAGS BIT FOR LBA
|
||||
@@ -1277,12 +1381,39 @@ IDE_INITDEV2:
|
||||
POP BC ; RECOVER POINTER TO CAPACITY ENTRY
|
||||
CALL ST32 ; SAVE CAPACITY
|
||||
;
|
||||
; RESET CARD STATUS TO 0 (OK)
|
||||
; RECORD STATUS OK
|
||||
XOR A ; A := 0 (STATUS = OK)
|
||||
LD (IY+IDE_STAT),A ; SAVE IT
|
||||
;
|
||||
RET ; RETURN, A=0, Z SET
|
||||
;
|
||||
;
|
||||
;
|
||||
IDE_INITDEVP:
|
||||
CALL IDE_IDENTIFYPACKET ; EXECUTE IDENTIFY COMMAND
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
;
|
||||
; DECLARE WE ARE ATAPI
|
||||
LD A,IDE_TYPEATAPI ; OTHERWISE TYPE=ATAPI
|
||||
LD (IY+IDE_TYPE),A ; SET IT IN INSTANCE DATA
|
||||
;
|
||||
LD DE,HB_WRKBUF ; POINT TO BUFFER
|
||||
#IF (IDETRACE >= 4)
|
||||
CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
|
||||
#ENDIF
|
||||
;
|
||||
LD (IY+IDE_MED),0 ; CLEAR FLAGS
|
||||
;
|
||||
; DONE FOR NOW, ATAPI NOT INPLEMENTED
|
||||
;
|
||||
; RETURN NOT SUPPORTED STATUS
|
||||
JP IDE_NOTSUP ; NOT SUPPORTED
|
||||
;
|
||||
; ; RECORD STATUS OK
|
||||
; XOR A ; A := 0 (STATUS = OK)
|
||||
; LD (IY+IDE_STAT),A ; SAVE IT
|
||||
; RET
|
||||
;
|
||||
; SWITCH IY POINTER FROM CURRENT UNIT CFG TO PARTNER UNIT CFG
|
||||
;
|
||||
IDE_GOPARTNER:
|
||||
@@ -1328,7 +1459,7 @@ IDE_WAITRDY2:
|
||||
;
|
||||
;
|
||||
IDE_WAITDRQ:
|
||||
LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
|
||||
LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
IDE_WAITDRQ1:
|
||||
LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
|
||||
@@ -1350,14 +1481,14 @@ IDE_WAITDRQ2:
|
||||
;
|
||||
;
|
||||
IDE_WAITBSY:
|
||||
LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
|
||||
LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
IDE_WAITBSY1:
|
||||
LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
|
||||
IDE_WAITBSY2:
|
||||
;IN A,(IDE_IO_STAT) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER ; 11TS
|
||||
CALL IDE_IN ; 17TS + ???TS
|
||||
.DB IDE_REG_STAT ; 0TS
|
||||
;IN A,(IDE_IO_STAT) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER
|
||||
CALL IDE_IN ; 17TS + 121TS
|
||||
.DB IDE_REG_STAT
|
||||
LD C,A ; SAVE IT ; 4TS
|
||||
AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS
|
||||
RET Z ; 5TS
|
||||
@@ -1366,25 +1497,45 @@ IDE_WAITBSY2:
|
||||
OR E ; 4TS
|
||||
JR NZ,IDE_WAITBSY2 ; 12TS
|
||||
DJNZ IDE_WAITBSY1 ; -----
|
||||
JP IDE_BSYTO ; EXIT WITH BSYTO ERR ; ??TS
|
||||
JP IDE_BSYTO ; EXIT WITH BSYTO ERR ; 180
|
||||
;
|
||||
;
|
||||
;
|
||||
IDE_WAIT00:
|
||||
LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
IDE_WAIT001:
|
||||
LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
|
||||
IDE_WAIT002:
|
||||
;IN A,(IDE_IO_STAT) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER
|
||||
CALL IDE_IN
|
||||
.DB IDE_REG_STAT
|
||||
OR A ; SET FLAGS
|
||||
RET NZ ; DONE IF NOT ZERO
|
||||
DEC DE
|
||||
LD A,D
|
||||
OR E
|
||||
JR NZ,IDE_WAIT002
|
||||
DJNZ IDE_WAIT001
|
||||
RET ; DONE
|
||||
;
|
||||
; READ A VALUE FROM THE DEVICE POINTED TO BY IY AND RETURN IT IN A
|
||||
;
|
||||
IDE_IN:
|
||||
EX (SP),HL ; GET PARM POINTER
|
||||
PUSH BC
|
||||
LD A,(HL)
|
||||
INC HL
|
||||
LD C,(IY+IDE_IOBASE)
|
||||
ADD A,C
|
||||
LD C,A
|
||||
IN A,(C)
|
||||
POP BC
|
||||
EX (SP),HL ; RESTORE STACK
|
||||
RET
|
||||
;
|
||||
; OUTPUT VALUE IN A TO THE DEVICE POINTED TO BY IY
|
||||
;
|
||||
IDE_IN:
|
||||
EX (SP),HL ; GET PARM POINTER ; 19TS
|
||||
PUSH BC ; 11TS
|
||||
LD A,(HL) ; 7TS
|
||||
INC HL ; 6TS
|
||||
LD C,(IY+IDE_IOBASE) ; 19TS
|
||||
ADD A,C ; 4TS
|
||||
LD C,A ; 4TS
|
||||
IN A,(C) ; 12TS
|
||||
POP BC ; 10TS
|
||||
EX (SP),HL ; RESTORE STACK ; 19TS
|
||||
RET ; 10TS
|
||||
; ; ----
|
||||
; OUTPUT VALUE IN A TO THE DEVICE POINTED TO BY IY ; 121TS
|
||||
;
|
||||
IDE_OUT:
|
||||
EX (SP),HL ; GET PARM POINTER
|
||||
PUSH BC
|
||||
@@ -1434,6 +1585,10 @@ IDE_BSYTO:
|
||||
LD A,IDE_STBSYTO
|
||||
JR IDE_ERR
|
||||
;
|
||||
IDE_NOTSUP:
|
||||
LD A,IDE_STNOTSUP
|
||||
JR IDE_ERR
|
||||
;
|
||||
IDE_ERR:
|
||||
LD (IY+IDE_STAT),A ; SAVE NEW STATUS
|
||||
;
|
||||
@@ -1451,39 +1606,15 @@ IDE_PRTERR:
|
||||
RET Z ; DONE IF NO ERRORS
|
||||
; FALL THRU TO IDE_PRTSTAT
|
||||
;
|
||||
; PRINT STATUS STRING (STATUS NUM IN A)
|
||||
; PRINT FULL DEVICE STATUS LINE
|
||||
;
|
||||
IDE_PRTSTAT:
|
||||
PUSH AF
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
LD A,(IY+IDE_STAT)
|
||||
OR A
|
||||
LD DE,IDE_STR_STOK
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STINVUNIT
|
||||
CP IDE_STINVUNIT
|
||||
JR Z,IDE_PRTSTAT2 ; INVALID UNIT IS SPECIAL CASE
|
||||
INC A
|
||||
LD DE,IDE_STR_STNOMEDIA
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STCMDERR
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STIOERR
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STRDYTO
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STDRQTO
|
||||
JR Z,IDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,IDE_STR_STBSYTO
|
||||
JR Z,IDE_PRTSTAT1
|
||||
LD DE,IDE_STR_STUNK
|
||||
IDE_PRTSTAT1:
|
||||
CALL IDE_PRTPREFIX ; PRINT UNIT PREFIX
|
||||
JR IDE_PRTSTAT3
|
||||
IDE_PRTSTAT2:
|
||||
@@ -1491,12 +1622,52 @@ IDE_PRTSTAT2:
|
||||
PRTS("IDE:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT
|
||||
IDE_PRTSTAT3:
|
||||
CALL PC_SPACE ; FORMATTING
|
||||
CALL WRITESTR
|
||||
CALL IDE_PRTSTATSTR
|
||||
POP HL
|
||||
POP DE
|
||||
POP AF
|
||||
RET
|
||||
;
|
||||
; PRINT STATUS STRING
|
||||
;
|
||||
IDE_PRTSTATSTR:
|
||||
PUSH AF
|
||||
PUSH DE
|
||||
LD A,(IY+IDE_STAT)
|
||||
OR A
|
||||
LD DE,IDE_STR_STOK
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STINVUNIT
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STNOMEDIA
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STCMDERR
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STIOERR
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STRDYTO
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STDRQTO
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STBSYTO
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,IDE_STR_STNOTSUP
|
||||
JR Z,IDE_PRTSTATSTR1
|
||||
LD DE,IDE_STR_STUNK
|
||||
IDE_PRTSTATSTR1:
|
||||
CALL WRITESTR
|
||||
POP DE
|
||||
POP AF
|
||||
RET
|
||||
;
|
||||
; PRINT ALL REGISTERS DIRECTLY FROM DEVICE
|
||||
; DEVICE MUST BE SELECTED PRIOR TO CALL
|
||||
;
|
||||
@@ -1536,30 +1707,6 @@ IDE_PRTPREFIX1:
|
||||
CALL PC_COLON
|
||||
POP AF
|
||||
RET
|
||||
;;;
|
||||
;;;
|
||||
;;;
|
||||
;;#IF (DSKYENABLE)
|
||||
;;IDE_DSKY:
|
||||
;; LD HL,DSKY_HEXBUF ; POINT TO DSKY BUFFER
|
||||
;; CALL IDE_IN
|
||||
;; .DB IDE_REG_DRVHD
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL IDE_IN
|
||||
;; .DB IDE_REG_CYLHI
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL IDE_IN
|
||||
;; .DB IDE_REG_CYLLO
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL IDE_IN
|
||||
;; .DB IDE_REG_SECT
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; CALL DSKY_HEXOUT ; SEND IT TO DSKY
|
||||
;; RET
|
||||
;;#ENDIF
|
||||
;
|
||||
;=============================================================================
|
||||
; STRING DATA
|
||||
@@ -1573,6 +1720,7 @@ IDE_STR_STIOERR .TEXT "IO ERROR$"
|
||||
IDE_STR_STRDYTO .TEXT "READY TIMEOUT$"
|
||||
IDE_STR_STDRQTO .TEXT "DRQ TIMEOUT$"
|
||||
IDE_STR_STBSYTO .TEXT "BUSY TIMEOUT$"
|
||||
IDE_STR_STNOTSUP .TEXT "NOT SUPPORTED$"
|
||||
IDE_STR_STUNK .TEXT "UNKNOWN ERROR$"
|
||||
;
|
||||
IDE_STR_NO .TEXT "NO$"
|
||||
@@ -1584,12 +1732,15 @@ IDE_STR_MODE_DIDE .TEXT "DIDE$"
|
||||
IDE_STR_MODE_MK4 .TEXT "MK4$"
|
||||
IDE_STR_MODE_RC .TEXT "RC$"
|
||||
;
|
||||
IDE_STR_TYPEATA .TEXT " ATA$"
|
||||
IDE_STR_TYPEATAPI .TEXT " ATAPI$"
|
||||
;
|
||||
;=============================================================================
|
||||
; DATA STORAGE
|
||||
;=============================================================================
|
||||
;
|
||||
IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
|
||||
IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED
|
||||
IDE_TOSCALER .DW CPUMHZ * 556 ; WAIT FUNCS SCALER FOR CPU SPEED
|
||||
;
|
||||
IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
|
||||
IDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
;=============================================================================
|
||||
;
|
||||
; TODO:
|
||||
; - FIX SCALER CONSTANT
|
||||
; - GOPARTNER NEEDS TO HANDLE "NO PARTNER" CONDITION
|
||||
;
|
||||
; NOTES:
|
||||
@@ -144,9 +143,13 @@ PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3 | $07 ; DRIVE ADDRESS REGISTER (R)
|
||||
;
|
||||
; COMMAND BYTES
|
||||
;
|
||||
PPIDE_CIDE_NOP .EQU $00
|
||||
PPIDE_CIDE_DEVRES .EQU $08
|
||||
PPIDE_CMD_RECAL .EQU $10
|
||||
PPIDE_CMD_READ .EQU $20
|
||||
PPIDE_CMD_WRITE .EQU $30
|
||||
PPIDE_CIDE_DEVDIAG .EQU $90
|
||||
PPIDE_CIDE_IDPKTDEV .EQU $A1
|
||||
PPIDE_CMD_IDDEV .EQU $EC
|
||||
PPIDE_CMD_SETFEAT .EQU $EF
|
||||
;
|
||||
@@ -171,6 +174,7 @@ PPIDE_STIOERR .EQU -4
|
||||
PPIDE_STRDYTO .EQU -5
|
||||
PPIDE_STDRQTO .EQU -6
|
||||
PPIDE_STBSYTO .EQU -7
|
||||
PPIDE_STNOTSUP .EQU -8
|
||||
;
|
||||
; DRIVE SELECTION BYTES (FOR USE IN DRIVE/HEAD REGISTER)
|
||||
;
|
||||
@@ -217,7 +221,7 @@ PPIDE_DEV0M: ; DEVICE 0, MASTER
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE0BASE ; DATALO
|
||||
.DB PPIDE0BASE+2 ; CTL
|
||||
.DB PPIDE0BASE+2 ; CTL
|
||||
.DB PPIDE0BASE+3 ; PPI
|
||||
.DW PPIDE_DEV0S ; PARTNER
|
||||
;
|
||||
@@ -230,7 +234,7 @@ PPIDE_DEV0S: ; DEVICE 0, SLAVE
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE0BASE ; DATALO
|
||||
.DB PPIDE0BASE+2 ; CTL
|
||||
.DB PPIDE0BASE+2 ; CTL
|
||||
.DB PPIDE0BASE+3 ; PPI
|
||||
.DW PPIDE_DEV0M ; PARTNER
|
||||
;
|
||||
@@ -247,7 +251,7 @@ PPIDE_DEV1M: ; DEVICE 1, MASTER
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE1BASE ; DATALO
|
||||
.DB PPIDE1BASE+2 ; CTL
|
||||
.DB PPIDE1BASE+2 ; CTL
|
||||
.DB PPIDE1BASE+3 ; PPI
|
||||
.DW PPIDE_DEV1S ; PARTNER
|
||||
;
|
||||
@@ -260,7 +264,7 @@ PPIDE_DEV1S: ; DEVICE 1, SLAVE
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE1BASE ; DATALO
|
||||
.DB PPIDE1BASE+2 ; CTL
|
||||
.DB PPIDE1BASE+2 ; CTL
|
||||
.DB PPIDE1BASE+3 ; PPI
|
||||
.DW PPIDE_DEV1M ; PARTNER
|
||||
;
|
||||
@@ -277,10 +281,10 @@ PPIDE_DEV2M: ; DEVICE 2, MASTER
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE2BASE ; DATALO
|
||||
.DB PPIDE2BASE+2 ; CTL
|
||||
.DB PPIDE2BASE+2 ; CTL
|
||||
.DB PPIDE2BASE+3 ; PPI
|
||||
.DW PPIDE_DEV2S ; PARTNER
|
||||
;
|
||||
;
|
||||
PPIDE_DEV2S: ; DEVICE 2, SLAVE
|
||||
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY)
|
||||
.DB 0 ; DEVICE STATUS
|
||||
@@ -290,7 +294,7 @@ PPIDE_DEV2S: ; DEVICE 2, SLAVE
|
||||
.DW 0,0 ; DEVICE CAPACITY
|
||||
.DW 0,0 ; CURRENT LBA
|
||||
.DB PPIDE2BASE ; DATALO
|
||||
.DB PPIDE2BASE+2 ; CTL
|
||||
.DB PPIDE2BASE+2 ; CTL
|
||||
.DB PPIDE2BASE+3 ; PPI
|
||||
.DW PPIDE_DEV2M ; PARTNER
|
||||
;
|
||||
@@ -302,17 +306,17 @@ PPIDE_DEV2S: ; DEVICE 2, SLAVE
|
||||
;
|
||||
.DB $FF ; END OF TABLE MARKER
|
||||
;
|
||||
; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL
|
||||
; THE PPIDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL
|
||||
; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING
|
||||
; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES
|
||||
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
|
||||
; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY
|
||||
; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO
|
||||
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
|
||||
; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS.
|
||||
; ON THE SITUATION. THE SLOW TIMEOUT IS USED TO WAIT FOR A DEVICE TO
|
||||
; BECOME READY AFTER A HARD RESET (SPIN UP, ETC.). THE NORMAL TIMEOUT
|
||||
; IS USED DURING NORMAL OPERATION FOR ALL I/O OPERATIONS WHICH SHOULD
|
||||
; OCCUR PRETTY FAST. NOTE THAT THE ATA SPEC ALLOWS UP TO 30 SECONDS
|
||||
; FOR DEVICES TO RESPOND. WE ARE USING MUCH MORE AGGRESSIVE VALUES
|
||||
; BASED ON REAL WORLD EXPERIENCE.
|
||||
;
|
||||
PPIDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS
|
||||
PPIDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
|
||||
PPIDE_TOSLOW .EQU 200 ; SLOW TIMEOUT IS 20 SECS
|
||||
PPIDE_TONORM .EQU 5 ; NORMAL TIMEOUT IS 0.5 SECS
|
||||
;
|
||||
;=============================================================================
|
||||
; INITIALIZATION ENTRY POINT
|
||||
@@ -320,9 +324,12 @@ PPIDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
|
||||
;
|
||||
PPIDE_INIT:
|
||||
; COMPUTE CPU SPEED COMPENSATED TIMEOUT SCALER
|
||||
; AT 1MHZ, THE SCALER IS 218 (50000US / 229TS = 218)
|
||||
; SCALER IS THEREFORE 218 * CPU SPEED IN MHZ
|
||||
LD DE,218 ; LOAD SCALER FOR 1MHZ
|
||||
; ONE INTERNAL LOOP IN WAITBSY IS 263TS. ON A 1 MHZ CPU, 1 TS
|
||||
; TAKES 1NS. SO 1/10 SECOND IS 100000 TS ON A 1 MHZ CPU.
|
||||
; SINCE 1 INTERNAL LOOP IS 263 TS, IT TAKES 100000 / 263 = 356
|
||||
; INTERNAL LOOPS FOR 1/10 SECOND. SO, WE WANT TO USE
|
||||
; 356 * CPU MHZ FOR INTERNAL LOOP COUNT.
|
||||
LD DE,380 ; LOAD SCALER FOR 1MHZ
|
||||
LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
|
||||
CALL MULT8X16 ; HL := DE * A
|
||||
LD (PPIDE_TOSCALER),HL ; SAVE IT
|
||||
@@ -355,7 +362,7 @@ PPIDE_INIT2:
|
||||
LD DE,PPIDE_STR_NOPPI ; NO PPI MESSAGE
|
||||
CALL WRITESTR ; DISPLAY IT
|
||||
JR PPIDE_INIT4 ; SKIP CFG ENTRY
|
||||
;
|
||||
;
|
||||
PPIDE_INIT3:
|
||||
CALL PPIDE_RESET ; RESET THE BUS
|
||||
CALL PPIDE_INIT5 ; DETECT/INIT MASTER
|
||||
@@ -363,7 +370,7 @@ PPIDE_INIT3:
|
||||
CALL PPIDE_GOPARTNER ; SWITCH IY TO PARTNER CFG
|
||||
CALL PPIDE_INIT5 ; DETECT/INIT SLAVE
|
||||
POP IY ; RESTORE CFG PTR
|
||||
;
|
||||
;
|
||||
PPIDE_INIT4:
|
||||
LD DE,PPIDE_CFGSIZ ; SIZE OF CFG TABLE ENTRY
|
||||
ADD IY,DE ; BUMP POINTER
|
||||
@@ -381,13 +388,28 @@ PPIDE_INIT5:
|
||||
PUSH IY ; CFG ENTRY POINTER
|
||||
POP DE ; COPY TO DE
|
||||
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
|
||||
;
|
||||
; START PRINTING DEVICE INFO
|
||||
CALL PPIDE_PRTPREFIX ; PRINT DEVICE PREFIX
|
||||
LD A,(IY+PPIDE_TYPE)
|
||||
LD DE,PPIDE_STR_TYPEATA
|
||||
CP PPIDE_TYPEATA
|
||||
CALL Z,WRITESTR
|
||||
LD DE,PPIDE_STR_TYPEATAPI
|
||||
CP PPIDE_TYPEATAPI
|
||||
CALL Z,WRITESTR
|
||||
;
|
||||
; CHECK FOR BAD STATUS
|
||||
LD A,(IY+PPIDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
JP NZ,PPIDE_PRTSTAT ; EXIT VIA PRINT STATUS
|
||||
JP Z,PPIDE_INIT6
|
||||
CALL PC_SPACE
|
||||
JP NZ,PPIDE_PRTSTATSTR ; EXIT VIA PRINT STATUS STRING
|
||||
;
|
||||
CALL PPIDE_PRTPREFIX ; PRINT DEVICE PREFIX
|
||||
PPIDE_INIT6:
|
||||
LD A,(IY+PPIDE_TYPE) ; GET DEVICE TYPE
|
||||
CP PPIDE_TYPEATA ; ATA?
|
||||
RET NZ ; IF NOT, THEN DONE
|
||||
;
|
||||
LD DE,PPIDE_STR_8BIT
|
||||
BIT 1,(IY+PPIDE_ACC) ; 8 BIT ACCESS?
|
||||
@@ -426,9 +448,9 @@ PPIDE_INIT5:
|
||||
PPIDE_DETECT:
|
||||
;
|
||||
; TEST FOR PPI EXISTENCE
|
||||
; WE SETUP THE PPI TO WRITE, THEN WRITE A VALUE OF ZERO
|
||||
; WE SETUP THE PPI TO WRITE, THEN WRITE A VALUE OF $A5
|
||||
; TO PORT A (DATALO), THEN READ IT BACK. IF THE PPI IS THERE
|
||||
; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE
|
||||
; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE $A5. SINCE
|
||||
; WE ARE IN WRITE MODE, AN IDE CONTROLLER WILL NOT BE ABLE TO
|
||||
; INTERFERE WITH THE VALUE BEING READ.
|
||||
;
|
||||
@@ -437,14 +459,14 @@ PPIDE_DETECT:
|
||||
OUT (C),A ; WRITE IT
|
||||
;
|
||||
LD C,(IY+PPIDE_DATALO) ; PPI PORT A, DATALO
|
||||
XOR A ; VALUE ZERO
|
||||
LD A,$A5 ; TEST VALUE
|
||||
OUT (C),A ; PUSH VALUE TO PORT
|
||||
IN A,(C) ; GET PORT VALUE
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
OR A ; SET FLAGS
|
||||
CP $A5 ; CHECK FOR TEST VALUE
|
||||
RET ; AND RETURN
|
||||
;
|
||||
;=============================================================================
|
||||
@@ -564,26 +586,12 @@ PPIDE_DEVICE1:
|
||||
PPIDE_MEDIA:
|
||||
LD A,E ; GET FLAGS
|
||||
OR A ; SET FLAGS
|
||||
JR Z,PPIDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA
|
||||
JR Z,PPIDE_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA
|
||||
;
|
||||
; GET CURRENT STATUS
|
||||
LD A,(IY+PPIDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
JR NZ,PPIDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET
|
||||
;
|
||||
; USE IDENTIFY COMMAND TO CHECK DEVICE
|
||||
LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),PPIDE_TOFAST ; USE FAST TIMEOUT DURING IDENTIFY COMMAND
|
||||
CALL PPIDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT
|
||||
CALL PPIDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND
|
||||
LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),PPIDE_TONORM ; BACK TO NORMAL TIMEOUT
|
||||
JR Z,PPIDE_MEDIA2 ; IF SUCCESS, BYPASS RESET
|
||||
;CALL PPIDE_RESET ; RESET IDE INTERFACE
|
||||
CALL PPIDE_INITUNIT ; RE-INITIALIZE UNIT
|
||||
;
|
||||
PPIDE_MEDIA1:
|
||||
CALL PPIDE_RESET ; RESET IDE INTERFACE
|
||||
;
|
||||
PPIDE_MEDIA2:
|
||||
LD A,(IY+PPIDE_STAT) ; GET STATUS
|
||||
OR A ; SET FLAGS
|
||||
LD D,0 ; NO MEDIA CHANGE DETECTED
|
||||
@@ -666,6 +674,32 @@ PPIDE_SETFEAT:
|
||||
;
|
||||
;
|
||||
;
|
||||
PPIDE_NOP:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_PRTPREFIX
|
||||
PRTS(" NOP$")
|
||||
#ENDIF
|
||||
LD A,(PPIDE_DRVHD)
|
||||
;OUT (PPIDE_IO_DRVHD),A
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_DRVHD
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; EXECUTE THE NOP COMMAND, BUT DON'T WAIT FOR DRDY, JUST
|
||||
; MAKE SURE BUSY IS CLEAR. THIS COMMAND IS USED DURING
|
||||
; DEVICE DETECTION/INITIALIZATION AND ATAPI DEVICES WILL
|
||||
; NOT ASSERT DRDY AFTER RESET.
|
||||
LD A,PPIDE_CIDE_NOP ; CMD = NOP
|
||||
LD (PPIDE_CMD),A ; SAVE IT
|
||||
CALL PPIDE_WAITBSY
|
||||
RET NZ
|
||||
JP PPIDE_RUNCMD1 ; RUN COMMAND AND EXIT
|
||||
;
|
||||
;
|
||||
;
|
||||
PPIDE_IDENTIFY:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_PRTPREFIX
|
||||
@@ -683,6 +717,35 @@ PPIDE_IDENTIFY:
|
||||
LD (PPIDE_CMD),A
|
||||
CALL PPIDE_RUNCMD
|
||||
RET NZ
|
||||
;
|
||||
LD HL,HB_WRKBUF
|
||||
JP PPIDE_GETBUF ; EXIT THRU BUFRD
|
||||
;
|
||||
;
|
||||
;
|
||||
PPIDE_IDENTIFYPACKET:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_PRTPREFIX
|
||||
PRTS(" IDPKTDEV$")
|
||||
#ENDIF
|
||||
LD A,(PPIDE_DRVHD)
|
||||
;OUT (PPIDE_IO_DRVHD),A
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_DRVHD
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
LD A,PPIDE_CIDE_IDPKTDEV
|
||||
LD (PPIDE_CMD),A
|
||||
CALL PPIDE_RUNCMD
|
||||
RET NZ
|
||||
;
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
BIT 6,A ; IS DRQ SET?
|
||||
JP Z,PPIDE_NOMEDIA
|
||||
;
|
||||
LD HL,HB_WRKBUF
|
||||
JP PPIDE_GETBUF ; EXIT THRU BUFRD
|
||||
;
|
||||
@@ -777,10 +840,6 @@ PPIDE_SETADDR:
|
||||
#ENDIF
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_COUNT
|
||||
;
|
||||
;;#IF (DSKYENABLE)
|
||||
;; CALL PPIDE_DSKY
|
||||
;;#ENDIF
|
||||
;
|
||||
RET
|
||||
;
|
||||
@@ -792,6 +851,7 @@ PPIDE_RUNCMD:
|
||||
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
|
||||
RET NZ ; BAIL OUT ON TIMEOUT
|
||||
;
|
||||
PPIDE_RUNCMD1:
|
||||
LD A,(PPIDE_CMD) ; GET THE COMMAND
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
@@ -982,13 +1042,18 @@ PPIDE_GETRES:
|
||||
; HARDWARE INTERFACE ROUTINES
|
||||
;=============================================================================
|
||||
;
|
||||
; SOFT RESET OF ALL DEVICES ON BUS
|
||||
; RESET ALL DEVICES ON BUS
|
||||
;
|
||||
PPIDE_RESET:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_PRTPREFIX
|
||||
PRTS(" RESET$")
|
||||
#ENDIF
|
||||
;
|
||||
; HARD RESET
|
||||
;
|
||||
; RESET LINE IS NORMALLY PULSED AT POWER ON. HOWEVER, THIS IS NOT
|
||||
; DONE FOR PPIDE DEVICES, SO WE DO IT NOW.
|
||||
;
|
||||
; SETUP PPI TO READ
|
||||
LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ
|
||||
@@ -1013,21 +1078,21 @@ PPIDE_RESET:
|
||||
#ENDIF
|
||||
;
|
||||
; PULSE IDE RESET LINE
|
||||
#IF (IDETRACE >= 3)
|
||||
#IF (PPIDETRACE >= 3)
|
||||
PRTS(" HARD$")
|
||||
#ENDIF
|
||||
LD A,PPIDE_CTL_RESET
|
||||
;OUT (PPIDE_IO_CTL),A
|
||||
LD C,(IY+PPIDE_CTL) ; SET IDE ADDRESS
|
||||
OUT (C),A
|
||||
LD DE,20
|
||||
LD DE,20 ; DELAY 320US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
XOR A
|
||||
;OUT (PPIDE_IO_CTL),A
|
||||
OUT (C),A
|
||||
LD DE,20
|
||||
CALL VDELAY
|
||||
;
|
||||
;
|
||||
#IF (DSKYENABLE)
|
||||
#IF (DSKYMODE == DSKYMODE_NG)
|
||||
; REININT DSKY AND RESTORE CONTENTS
|
||||
@@ -1039,28 +1104,55 @@ PPIDE_RESET:
|
||||
#ENDIF
|
||||
#ENDIF
|
||||
;
|
||||
; CONFIGURE OPERATION
|
||||
; SOME CF CARDS AND CF CARD EMULATORS NEED A LITTLE TIME TO
|
||||
; "BOOT" THEIR INTERNAL ELECTRONICS, SO THEY CANNOT ASSERT BUSY
|
||||
; IMMEDIATELY. A SMALL WAIT IS PERFORMED HERE TO GIVE SUCH DEVICES
|
||||
; A BETTER CHANCE TO SUCCEED LATER.
|
||||
;
|
||||
;;; CALL LDELAY ; DELAY FOR SLAVE INIT
|
||||
LD DE,150000 / 16 ;
|
||||
CALL VDELAY ; SMALL DELAY
|
||||
;
|
||||
JR PPIDE_RESET3 ; SKIP SOFT RESET
|
||||
;
|
||||
; SOFT RESET
|
||||
;
|
||||
; RC CANNOT ACCESS DEVICE CONTROL REG, SO SKIP THIS
|
||||
;
|
||||
PPIDE_RESET2:
|
||||
; INITIATE SOFT RESET
|
||||
#IF (IDETRACE >= 3)
|
||||
PRTS(" SOFT$")
|
||||
#ENDIF
|
||||
LD A,%00001110 ; ASSERT RESET, NO INTERRUPTS
|
||||
;OUT (PPIDE_IO_CTRL),A
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_CTRL
|
||||
LD DE,20 ; DELAY 320US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
;
|
||||
PPIDE_RESET3:
|
||||
;
|
||||
; CONFIGURE OPERATION AND END SOFT RESET
|
||||
;
|
||||
#IF (PPIDETRACE >= 3)
|
||||
PRTS(" CONFIG$")
|
||||
#ENDIF
|
||||
LD A,%00001010 ; SET ~IEN, NO INTERRUPTS
|
||||
LD A,%00001010 ; DEASSERT RESET, NO INTERRUPTS
|
||||
;OUT (PPIDE_REG_CTRL),A
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_CTRL
|
||||
;
|
||||
; SPEC ALLOWS UP TO 450MS FOR DEVICES TO ASSERT THEIR PRESENCE
|
||||
; VIA -DASP. I ENCOUNTER PROBLEMS LATER ON IF I DON'T WAIT HERE
|
||||
; FOR THAT TO OCCUR. THUS FAR, IT APPEARS THAT 150MS IS SUFFICIENT
|
||||
; FOR ANY DEVICE ENCOUNTERED. MAY NEED TO EXTEND BACK TO 500MS
|
||||
; IF A SLOWER DEVICE IS ENCOUNTERED.
|
||||
;
|
||||
;LD DE,500000/16 ; ~500MS
|
||||
LD DE,150000/16 ; ~???MS
|
||||
LD DE,20 ; DELAY 320US (SPEC IS >= 25US)
|
||||
CALL VDELAY
|
||||
;
|
||||
PPIDE_RESET5:
|
||||
LD HL,PPIDE_TONORM ; NORMAL TIMEOUT NOW
|
||||
LD (PPIDE_TIMEOUT),HL ; AND RESTORE IT
|
||||
;
|
||||
; INITIALIZE THE INDIVIDUAL UNITS (MASTER AND SLAVE).
|
||||
; BASED ON TESTING, IT APPEARS THAT THE MASTER UNIT MUST
|
||||
; BE DONE FIRST OR THIS BEHAVES BADLY.
|
||||
;
|
||||
PUSH IY ; SAVE CFG PTR
|
||||
BIT 0,(IY+PPIDE_ACC) ; MASTER?
|
||||
CALL Z,PPIDE_GOPARTNER ; IF NOT, SWITCH TO MASTER
|
||||
@@ -1068,7 +1160,7 @@ PPIDE_RESET:
|
||||
CALL PPIDE_GOPARTNER ; POINT TO SLAVE
|
||||
CALL PPIDE_INITUNIT ; INIT PARTNER UNIT
|
||||
POP IY ; RECOVER ORIG CFG PTR
|
||||
;
|
||||
;
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; AND DONE
|
||||
;
|
||||
@@ -1078,14 +1170,10 @@ PPIDE_INITUNIT:
|
||||
CALL PPIDE_SELUNIT ; SELECT UNIT
|
||||
RET NZ ; ABORT IF ERROR
|
||||
|
||||
LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
|
||||
LD (HL),PPIDE_TONORM ; SET NORMAL TIMEOUT
|
||||
|
||||
CALL PPIDE_PROBE ; DO PROBE
|
||||
RET NZ ; JUST RETURN IF NOTHING THERE
|
||||
|
||||
CALL PPIDE_INITDEV ; IF FOUND, ATTEMPT TO INIT DEVICE
|
||||
RET ; DONE
|
||||
JP PPIDE_INITDEV ; EXIT VIA INITDEV
|
||||
;
|
||||
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT
|
||||
;
|
||||
@@ -1097,10 +1185,16 @@ PPIDE_SELUNIT:
|
||||
BIT 0,(IY+PPIDE_ACC) ; MASTER?
|
||||
JR Z,PPIDE_SELUNIT1 ; HANDLE SLAVE
|
||||
LD A,PPIDE_DRVMASTER ; MASTER
|
||||
JR PPIDE_SELUNIT2
|
||||
PPIDE_SELUNIT1:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
PRTS(" MASTER$")
|
||||
#ENDIF
|
||||
JR PPIDE_SELUNIT2
|
||||
PPIDE_SELUNIT1:
|
||||
LD A,PPIDE_DRVSLAVE ; SLAVE
|
||||
PPIDE_SELUNIT2:
|
||||
#IF (PPIDETRACE >= 3)
|
||||
PRTS(" SLAVE$")
|
||||
#ENDIF
|
||||
PPIDE_SELUNIT2:
|
||||
LD (PPIDE_DRVHD),A ; SAVE IT
|
||||
XOR A ; SUCCESS
|
||||
RET
|
||||
@@ -1112,7 +1206,7 @@ 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
|
||||
; WHICH ARE CAPABLE OF NEITHER A HARD NOR SOFT RESET. SO THIS
|
||||
; CODE SHOULD TRY TO HANDLE THE SCENARIO WHERE NO INTERFACE RESET
|
||||
; HAS OCCURRED.
|
||||
;
|
||||
@@ -1120,6 +1214,13 @@ PPIDE_PROBE:
|
||||
CALL PPIDE_PRTPREFIX
|
||||
PRTS(" PROBE$") ; LABEL FOR IO ADDRESS
|
||||
#ENDIF
|
||||
;
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; SELECT DEVICE (MASTER/SLAVE)
|
||||
LD A,(PPIDE_DRVHD)
|
||||
@@ -1132,14 +1233,15 @@ PPIDE_PROBE:
|
||||
#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.
|
||||
; IF WE GET HERE AND THE DRIVE IS STILL INITIALIZING, WE NEED TO
|
||||
; WAIT UNTIL THE DRIVE IS READY. IN THIS CASE BUSY *WILL* BE HIGH.
|
||||
; BASED ON TESTING, DRDY AND DSC VALUES VARY. EVERYTHING ELSE SEEMS
|
||||
; TO BE ZERO. SO, WE FILTER OUT DRDY & DSC, THEN LOOK FOR BUSY=1
|
||||
; AND ALL ELSE ZERO. THIS GENERALLY AVOIDS VALUES THAT ARE TYPICAL
|
||||
; FOR FLOATING PORTS AND SO CAN BE USED TO DETERMINE IF WE NEED TO
|
||||
; WAIT FOR THE DEVICE TO BE READY. THIS WAIT IS MANDATORY BECAUSE
|
||||
; SOME (IF NOT ALL) DEVICES WILL NOT PERSIST REGISTER VALUES UNTIL
|
||||
; THE DRIVE IS READY.
|
||||
;
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
@@ -1147,8 +1249,29 @@ PPIDE_PROBE:
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
AND %10101111 ; FILTER OUT DRDY & DSC
|
||||
CP $80 ; INIT IN PROGRESS?
|
||||
CALL Z,PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
|
||||
JR NZ,PPIDE_PROBE1 ; IF NOT, SKIP AHEAD
|
||||
;
|
||||
#IF (PPIDETRACE >= 3)
|
||||
PRTS(" WAIT$")
|
||||
#ENDIF
|
||||
;
|
||||
LD HL,(PPIDE_TIMEOUT) ; GET CURRENT TIMEOUT
|
||||
PUSH HL ; SAVE IT
|
||||
LD HL,PPIDE_TOSLOW ; SLOW TIMEOUT FOR THIS
|
||||
LD (PPIDE_TIMEOUT),HL ; SET IT
|
||||
CALL PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR
|
||||
POP HL ; RECOVER TIMEOUT
|
||||
LD (PPIDE_TIMEOUT),HL ; SET IT
|
||||
;
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE
|
||||
#ENDIF
|
||||
;
|
||||
; TEST FOR PRESENCE OF IDE REGISTERS. USE LBA0/1 TO SEE
|
||||
; IF VALUE CAN BE PERSISTED. THE USE OF BOTH LBA0 AND LBA1
|
||||
@@ -1156,11 +1279,12 @@ PPIDE_PROBE:
|
||||
; PPI ITSELF WILL PERSIST THE LAST VALUE WRITTEN, SO WE USE
|
||||
; MULTIPLE REGISTERS TO WORK AROUND THIS FALSE POSITIVE.
|
||||
;
|
||||
PPIDE_PROBE1:
|
||||
; $AA -> LBA0
|
||||
LD A,$AA
|
||||
CALL PPIDE_OUT
|
||||
.DB PPIDE_REG_LBA0
|
||||
;
|
||||
;
|
||||
; $55 => LBA1
|
||||
LD A,$55
|
||||
CALL PPIDE_OUT
|
||||
@@ -1190,43 +1314,34 @@ PPIDE_PROBE:
|
||||
CALL PPIDE_REGDUMP
|
||||
#ENDIF
|
||||
;
|
||||
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
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PC_SPACE
|
||||
CALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS
|
||||
#ENDIF
|
||||
OR A ; SET FLAGS TO TEST FOR ZERO
|
||||
JP Z,PPIDE_NOMEDIA ; CONTINUE IF NON-ZERO
|
||||
;
|
||||
; 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
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; DONE, NOTE THAT A=0 AND Z IS SET
|
||||
XOR A
|
||||
RET
|
||||
;
|
||||
; (RE)INITIALIZE DEVICE
|
||||
;
|
||||
PPIDE_INITDEV:
|
||||
;
|
||||
LD A,(IY+PPIDE_TYPE) ; GET THE DEVICE TYPE
|
||||
OR A ; SET FLAGS
|
||||
JP Z,PPIDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS
|
||||
#IF (PPIDETRACE >= 3)
|
||||
CALL PPIDE_PRTPREFIX
|
||||
PRTS(" INITDEV$") ; LABEL FOR IO ADDRESS
|
||||
#ENDIF
|
||||
;
|
||||
; IF THE IDE STATUS BYTE IS $00, WE HAVE EITHER A NON-PRESENT SLAVE
|
||||
; OR AN ATAPI DEVICE. TO DIFFERENTIATE THESE POSSIBILITIES, WE RUN
|
||||
; A NOP COMMAND. IF WE HAVE AN ATAPI DEVICE, THIS WILL CAUSE THE
|
||||
; STATUS BYTE TO BE "NORMAL" (NON-ZERO). IF THE STATUS IS STILL
|
||||
; ZERO, WE ABORT WITH A NO MEDIA STATUS. NOTE THAT THE NOP COMMAND
|
||||
; RETURNS A COMMAND ERROR BY DESIGN. WE JUST IGNORE THE ERROR.
|
||||
;
|
||||
CALL PPIDE_NOP
|
||||
CALL PPIDE_IN
|
||||
.DB PPIDE_REG_STAT
|
||||
OR A
|
||||
JP Z,PPIDE_NOMEDIA
|
||||
;
|
||||
; WE NEED TO SETUP 8-BIT MODE BEFORE DOING ANYTHING ELSE
|
||||
;
|
||||
PPIDE_INITDEV0A:
|
||||
BIT 1,(IY+PPIDE_ACC) ; 8 BIT ACCESS?
|
||||
JR Z,PPIDE_INITDEV0 ; NO, DO 16 BIT INIT
|
||||
LD A,PPIDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO
|
||||
@@ -1244,10 +1359,14 @@ PPIDE_INITDEV0:
|
||||
PPIDE_INITDEV00:
|
||||
;
|
||||
CALL PPIDE_IDENTIFY ; EXECUTE PPIDENTIFY COMMAND
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
JR NZ,PPIDE_INITDEVP ; ON ERROR, TRY PACKET DEVICE
|
||||
;
|
||||
; DECLARE WE ARE ATA
|
||||
LD A,PPIDE_TYPEATA ; OTHERWISE TYPE=ATA
|
||||
LD (IY+PPIDE_TYPE),A ; SET IT IN INSTANCE DATA
|
||||
;
|
||||
LD DE,HB_WRKBUF ; POINT TO BUFFER
|
||||
#IF (PPIDETRACE >= 3)
|
||||
#IF (PPIDETRACE >= 4)
|
||||
CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
|
||||
#ENDIF
|
||||
;
|
||||
@@ -1267,38 +1386,15 @@ PPIDE_INITDEV00:
|
||||
CALL PRTHEXWORD
|
||||
#ENDIF
|
||||
;
|
||||
; SEE PAGE 114 OF CF+ & CF SPECIFICATION REV. 3.0 FOR CF CARD
|
||||
; SIGNATURE VALUES. ALL OF THE BELOW ARE DOCUMENTED THERE EXCEPT
|
||||
; $045A WHICH IS A VALUE DISCOVERED ON A CF<->SD CARD ADAPTER.
|
||||
;
|
||||
; SIGNATURE $045A IS NOT LISTED IN THE CF SPEC. IT WAS ADDED BECAUSE
|
||||
; IT WAS SEEN IN THE WILD ON A CF-SD ADAPTER. HOWEVER IT HAS NOW
|
||||
; ALSO BEEN SEEN ON A SPINNING HARD DISK. SINCE IT IS AMBIGUOUS, I
|
||||
; WILL CONSIDER IT TO BE A HARD DISK.
|
||||
;
|
||||
LD BC,$848A ; STANDARD CF CARD SIGNATURE %1000 1111 1000 1010
|
||||
CALL PPIDE_INITDEV000 ; TEST & SET
|
||||
LD BC,$044A ; ALT SIG FOR CF NON-REMOVABLE %0000 0100 0100 1010
|
||||
CALL PPIDE_INITDEV000 ; TEST & SET
|
||||
;LD BC,$045A ; ?ALT SIG FOR CF NON-REMOVABLE %0000 0100 0101 1010
|
||||
;CALL PPIDE_INITDEV000 ; TEST & SET
|
||||
LD BC,$0040 ; ALT SIG FOR CF NON-REMOVABLE %0000 0000 0100 0000
|
||||
CALL PPIDE_INITDEV000 ; TEST & SET
|
||||
JR PPIDE_INITDEV1 ; CONTINUE INIT
|
||||
;
|
||||
PPIDE_INITDEV000:
|
||||
; CHECK IF FIRST WORD OF IDENTIFY DATA MATCHES VALUE IN BC
|
||||
; AND SET CF FLAG IF SO
|
||||
LD HL,(HB_WRKBUF) ; FIRST WORD OF IDENTIFY DATA
|
||||
OR A ; CLEAR CARRY
|
||||
SBC HL,BC ; COMPARE
|
||||
RET NZ ; ABORT IF NOT EQUAL
|
||||
; DETERMINE IF COMPACTFLASH MEDIA
|
||||
LD A,(HB_WRKBUF+(83*2)) ; LOW BYTE OF WORD 83
|
||||
BIT 2,A ; TEST CFA FEATURE SET BIT
|
||||
JR Z,PPIDE_INITDEV1 ; IF NOT, SKIP
|
||||
SET 0,(IY+PPIDE_MED) ; ELSE SET FLAGS BIT FOR CF MEDIA
|
||||
RET ; AND RETURN
|
||||
;
|
||||
PPIDE_INITDEV1:
|
||||
; DETERMINE IF LBA CAPABLE
|
||||
LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER
|
||||
LD A,(HB_WRKBUF+98+1) ; HIGH BYTE OF WORD 49
|
||||
BIT 1,A ; CHECK THE LBA BIT
|
||||
JR Z,PPIDE_INITDEV2 ; NOT SET, BYPASS
|
||||
SET 1,(IY+PPIDE_MED) ; SET FLAGS BIT FOR LBA
|
||||
@@ -1315,12 +1411,39 @@ PPIDE_INITDEV2:
|
||||
POP BC ; RECOVER POINTER TO CAPACITY ENTRY
|
||||
CALL ST32 ; SAVE CAPACITY
|
||||
;
|
||||
; RESET CARD STATUS TO 0 (OK)
|
||||
; RECORD STATUS OK
|
||||
XOR A ; A := 0 (STATUS = OK)
|
||||
LD (IY+PPIDE_STAT),A ; SAVE IT
|
||||
;
|
||||
RET ; RETURN, A=0, Z SET
|
||||
;
|
||||
;
|
||||
;
|
||||
PPIDE_INITDEVP:
|
||||
CALL PPIDE_IDENTIFYPACKET ; EXECUTE IDENTIFY COMMAND
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
;
|
||||
; DECLARE WE ARE ATAPI
|
||||
LD A,PPIDE_TYPEATAPI ; OTHERWISE TYPE=ATAPI
|
||||
LD (IY+PPIDE_TYPE),A ; SET IT IN INSTANCE DATA
|
||||
;
|
||||
LD DE,HB_WRKBUF ; POINT TO BUFFER
|
||||
#IF (PPIDETRACE >= 4)
|
||||
CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
|
||||
#ENDIF
|
||||
;
|
||||
LD (IY+PPIDE_MED),0 ; CLEAR FLAGS
|
||||
;
|
||||
; DONE FOR NOW, ATAPI NOT INPLEMENTED
|
||||
;
|
||||
; RETURN NOT SUPPORTED STATUS
|
||||
JP PPIDE_NOTSUP ; NOT SUPPORTED
|
||||
;
|
||||
; ; RECORD STATUS OK
|
||||
; XOR A ; A := 0 (STATUS = OK)
|
||||
; LD (IY+PPIDE_STAT),A ; SAVE IT
|
||||
; RET
|
||||
;
|
||||
; SWITCH IY POINTER FROM CURRENT UNIT CFG TO PARTNER UNIT CFG
|
||||
;
|
||||
PPIDE_GOPARTNER:
|
||||
@@ -1344,7 +1467,7 @@ PPIDE_CHKERR:
|
||||
;
|
||||
;
|
||||
PPIDE_WAITRDY:
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
PPIDE_WAITRDY1:
|
||||
LD DE,(PPIDE_TOSCALER) ; CPU SPEED SCALER TO INNER LOOP VAR
|
||||
@@ -1366,7 +1489,7 @@ PPIDE_WAITRDY2:
|
||||
;
|
||||
;
|
||||
PPIDE_WAITDRQ:
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
PPIDE_WAITDRQ1:
|
||||
LD DE,(PPIDE_TOSCALER) ; CPU SPEED SCALER TO INNER LOOP VAR
|
||||
@@ -1388,14 +1511,14 @@ PPIDE_WAITDRQ2:
|
||||
;
|
||||
;
|
||||
PPIDE_WAITBSY:
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
|
||||
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS
|
||||
LD B,A ; PUT IN OUTER LOOP VAR
|
||||
PPIDE_WAITBSY1:
|
||||
LD DE,(PPIDE_TOSCALER) ; CPU SPEED SCALER TO INNER LOOP VAR
|
||||
PPIDE_WAITBSY2:
|
||||
;IN A,(PPIDE_REG_STAT) ; READ STATUS
|
||||
CALL PPIDE_IN ; 17TS + 170TS
|
||||
.DB PPIDE_REG_STAT ; 0TS
|
||||
CALL PPIDE_IN ; 17TS + 204TS
|
||||
.DB PPIDE_REG_STAT
|
||||
LD C,A ; SAVE IT ; 4TS
|
||||
AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS
|
||||
RET Z ; 5TS
|
||||
@@ -1404,32 +1527,32 @@ PPIDE_WAITBSY2:
|
||||
OR E ; 4TS
|
||||
JR NZ,PPIDE_WAITBSY2 ; 12TS
|
||||
DJNZ PPIDE_WAITBSY1 ; -----
|
||||
JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 229TS
|
||||
JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 263TS
|
||||
;
|
||||
; READ A VALUE FROM THE DEVICE POINTED TO BY IY AND RETURN IT IN A
|
||||
;
|
||||
;
|
||||
PPIDE_IN:
|
||||
EX (SP),HL ; GET PARM POINTER ; 19TS
|
||||
PUSH BC ; SAVE INCOMING BC ; 11TS
|
||||
LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ ; 7TS
|
||||
;OUT (PPIDE_IO_PPI),A ; DO IT ; 11TS
|
||||
LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD
|
||||
OUT (C),A ; WRITE IT
|
||||
;OUT (PPIDE_IO_PPI),A ; DO IT
|
||||
LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD ; 19TS
|
||||
OUT (C),A ; WRITE IT ; 12TS
|
||||
;
|
||||
LD B,(HL) ; GET CTL PORT VALUE ; 7TS
|
||||
;LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE ; 7TS
|
||||
;LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE
|
||||
;LD C,(IY+PPIDE_CTL) ; SET IDE ADDRESS
|
||||
DEC C ; SET IDE ADDRESS
|
||||
DEC C ; SET IDE ADDRESS ; 4TS
|
||||
OUT (C),B ; SET ADDRESS LINES ; 12TS
|
||||
SET 6,B ; TURN ON READ BIT ; 8TS
|
||||
OUT (C),B ; ASSERT READ LINE ; 12TS
|
||||
;
|
||||
;IN A,(PPIDE_IO_DATALO) ; GET DATA VALUE FROM DEVICE ; 11TS
|
||||
DEC C
|
||||
DEC C
|
||||
IN A,(C) ; GET DATA VALUE FROM DEVICE
|
||||
INC C
|
||||
INC C
|
||||
;IN A,(PPIDE_IO_DATALO) ; GET DATA VALUE FROM DEVICE
|
||||
DEC C ; 4TS
|
||||
DEC C ; 4TS
|
||||
IN A,(C) ; GET DATA VALUE FROM DEVICE ; 12
|
||||
INC C ; 4TS
|
||||
INC C ; 4TS
|
||||
;
|
||||
RES 6,B ; CLEAR READ BIT ; 8TS
|
||||
OUT (C),B ; DEASSERT READ LINE ; 12TS
|
||||
@@ -1437,9 +1560,9 @@ PPIDE_IN:
|
||||
INC HL ; POINT PAST PARM ; 6TS
|
||||
EX (SP),HL ; RESTORE STACK ; 19TS
|
||||
RET ; 10TS
|
||||
; ; -----
|
||||
; OUTPUT VALUE IN A TO THE DEVICE POINTED TO BY IY ; 204TS
|
||||
;
|
||||
; OUTPUT VALUE IN A TO THE DEVICE POINTED TO BY IY
|
||||
;
|
||||
PPIDE_OUT:
|
||||
; *** TODO *** FIX ORDER OF SET/CLEAR WRITE LINE
|
||||
EX (SP),HL ; GET PARM POINTER
|
||||
@@ -1507,6 +1630,10 @@ PPIDE_BSYTO:
|
||||
LD A,PPIDE_STBSYTO
|
||||
JR PPIDE_ERR
|
||||
;
|
||||
PPIDE_NOTSUP:
|
||||
LD A,PPIDE_STNOTSUP
|
||||
JR PPIDE_ERR
|
||||
;
|
||||
PPIDE_ERR:
|
||||
LD (IY+PPIDE_STAT),A ; SAVE NEW STATUS
|
||||
;
|
||||
@@ -1524,39 +1651,15 @@ PPIDE_PRTERR:
|
||||
RET Z ; DONE IF NO ERRORS
|
||||
; FALL THRU TO PPIDE_PRTSTAT
|
||||
;
|
||||
; PRINT STATUS STRING (STATUS NUM IN A)
|
||||
; PRINT FULL DEVICE STATUS LINE
|
||||
;
|
||||
PPIDE_PRTSTAT:
|
||||
PUSH AF
|
||||
PUSH DE
|
||||
PUSH HL
|
||||
LD A,(IY+PPIDE_STAT)
|
||||
OR A
|
||||
LD DE,PPIDE_STR_STOK
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STINVUNIT
|
||||
CP PPIDE_STINVUNIT
|
||||
JR Z,PPIDE_PRTSTAT2 ; INVALID UNIT IS SPECIAL CASE
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STNOMEDIA
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STCMDERR
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STIOERR
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STRDYTO
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STDRQTO
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STBSYTO
|
||||
JR Z,PPIDE_PRTSTAT1
|
||||
LD DE,PPIDE_STR_STUNK
|
||||
PPIDE_PRTSTAT1:
|
||||
CALL PPIDE_PRTPREFIX ; PRINT UNIT PREFIX
|
||||
JR PPIDE_PRTSTAT3
|
||||
PPIDE_PRTSTAT2:
|
||||
@@ -1564,12 +1667,52 @@ PPIDE_PRTSTAT2:
|
||||
PRTS("PPIDE:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT
|
||||
PPIDE_PRTSTAT3:
|
||||
CALL PC_SPACE ; FORMATTING
|
||||
CALL WRITESTR
|
||||
CALL PPIDE_PRTSTATSTR
|
||||
POP HL
|
||||
POP DE
|
||||
POP AF
|
||||
RET
|
||||
;
|
||||
; PRINT STATUS STRING
|
||||
;
|
||||
PPIDE_PRTSTATSTR:
|
||||
PUSH AF
|
||||
PUSH DE
|
||||
LD A,(IY+PPIDE_STAT)
|
||||
OR A
|
||||
LD DE,PPIDE_STR_STOK
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STINVUNIT
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STNOMEDIA
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STCMDERR
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STIOERR
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STRDYTO
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STDRQTO
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STBSYTO
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
INC A
|
||||
LD DE,PPIDE_STR_STNOTSUP
|
||||
JR Z,PPIDE_PRTSTATSTR1
|
||||
LD DE,PPIDE_STR_STUNK
|
||||
PPIDE_PRTSTATSTR1:
|
||||
CALL WRITESTR
|
||||
POP DE
|
||||
POP AF
|
||||
RET
|
||||
;
|
||||
; PRINT ALL REGISTERS DIRECTLY FROM DEVICE
|
||||
; DEVICE MUST BE SELECTED PRIOR TO CALL
|
||||
;
|
||||
@@ -1628,30 +1771,6 @@ PPIDE_PRTPREFIX1:
|
||||
CALL PC_COLON
|
||||
POP AF
|
||||
RET
|
||||
;;;
|
||||
;;;
|
||||
;;;
|
||||
;;#IF (DSKYENABLE)
|
||||
;;PPIDE_DSKY:
|
||||
;; LD HL,DSKY_HEXBUF ; POINT TO DSKY BUFFER
|
||||
;; CALL PPIDE_IN
|
||||
;; .DB PPIDE_REG_DRVHD
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL PPIDE_IN
|
||||
;; .DB PPIDE_REG_CYLHI
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL PPIDE_IN
|
||||
;; .DB PPIDE_REG_CYLLO
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; INC HL ; INCREMENT BUFFER POINTER
|
||||
;; CALL PPIDE_IN
|
||||
;; .DB PPIDE_REG_SECT
|
||||
;; LD (HL),A ; SAVE IN BUFFER
|
||||
;; CALL DSKY_HEXOUT ; SEND IT TO DSKY
|
||||
;; RET
|
||||
;;#ENDIF
|
||||
;
|
||||
;=============================================================================
|
||||
; STRING DATA
|
||||
@@ -1665,18 +1784,22 @@ PPIDE_STR_STIOERR .TEXT "IO ERROR$"
|
||||
PPIDE_STR_STRDYTO .TEXT "READY TIMEOUT$"
|
||||
PPIDE_STR_STDRQTO .TEXT "DRQ TIMEOUT$"
|
||||
PPIDE_STR_STBSYTO .TEXT "BUSY TIMEOUT$"
|
||||
PPIDE_STR_STNOTSUP .TEXT "NOT SUPPORTED$"
|
||||
PPIDE_STR_STUNK .TEXT "UNKNOWN ERROR$"
|
||||
;
|
||||
PPIDE_STR_NO .TEXT "NO$"
|
||||
PPIDE_STR_NOPPI .TEXT "PPI NOT PRESENT$"
|
||||
PPIDE_STR_8BIT .TEXT " 8-BIT$"
|
||||
;
|
||||
PPIDE_STR_TYPEATA .TEXT " ATA$"
|
||||
PPIDE_STR_TYPEATAPI .TEXT " ATAPI$"
|
||||
;
|
||||
;=============================================================================
|
||||
; DATA STORAGE
|
||||
;=============================================================================
|
||||
;
|
||||
PPIDE_TIMEOUT .DB PPIDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
|
||||
PPIDE_TOSCALER .DW CPUMHZ * 218 ; WAIT FUNCS SCALER FOR CPU SPEED
|
||||
PPIDE_TOSCALER .DW CPUMHZ * 380 ; WAIT FUNCS SCALER FOR CPU SPEED
|
||||
;
|
||||
PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
|
||||
PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#DEFINE RMN 3
|
||||
#DEFINE RUP 0
|
||||
#DEFINE RTP 0
|
||||
#DEFINE BIOSVER "3.3.0-dev.6"
|
||||
#DEFINE BIOSVER "3.3.0-dev.7"
|
||||
#define rmj RMJ
|
||||
#define rmn RMN
|
||||
#define rup RUP
|
||||
|
||||
@@ -3,5 +3,5 @@ rmn equ 3
|
||||
rup equ 0
|
||||
rtp equ 0
|
||||
biosver macro
|
||||
db "3.3.0-dev.6"
|
||||
db "3.3.0-dev.7"
|
||||
endm
|
||||
|
||||
Reference in New Issue
Block a user