mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
715 lines
17 KiB
715 lines
17 KiB
;
|
|
;==================================================================================================
|
|
; PPIDE DISK DRIVER
|
|
;==================================================================================================
|
|
;
|
|
; 11/29/2011 dwg - DOUGDEBUG controls the embedded NOPs which adjust for
|
|
; recovery time while using the parallel port to talk to the PPIDE and IDE
|
|
; device. Using this stabilized by Zeta (8MHz) with a CF chip.
|
|
;
|
|
; 12/02/2011 wbw - renamed DOUGDEBUG to PPIDESLOW and exposed in config
|
|
; PPIDESLOW now controls the RECOVERY macro definition.
|
|
;
|
|
#IF (PPIDESLOW)
|
|
#DEFINE RECOVERY NOP\ NOP\ NOP\ NOP
|
|
#ELSE
|
|
#DEFINE RECOVERY ;
|
|
#ENDIF
|
|
;
|
|
; MAP PPI PORTS TO PPIDE PORTS
|
|
;
|
|
IDELSB .EQU PPIDEIOB + 0 ; LSB
|
|
IDEMSB .EQU PPIDEIOB + 1 ; MSB
|
|
IDECTL .EQU PPIDEIOB + 2 ; CONTROL SIGNALS
|
|
PPICTL .EQU PPIDEIOB + 3 ; PPI (8255) CONTROL PORT
|
|
;
|
|
; PPI control bytes for read and write to IDE drive
|
|
;
|
|
RD_IDE_8255 .EQU %10010010 ; IDE_8255_CTL OUT, IDE_8255_LSB/MSB INPUT
|
|
WR_IDE_8255 .EQU %10000000 ; ALL THREE PORTS OUTPUT
|
|
;
|
|
; IDE CONTROL LINES FOR USE WITH IDE_8255_CTL. CHANGE THESE 8
|
|
; CONSTANTS TO REFLECT WHERE EACH SIGNAL OF THE 8255 EACH OF THE
|
|
; IDE CONTROL SIGNALS IS CONNECTED. ALL THE CONTROL SIGNALS MUST
|
|
; BE ON THE SAME PORT, BUT THESE 8 LINES LET YOU CONNECT THEM TO
|
|
; WHICHEVER PINS ON THAT PORT.
|
|
;
|
|
PPIDE_A0_LINE .EQU $01 ; DIRECT FROM 8255 TO IDE INTERFACE
|
|
PPIDE_A1_LINE .EQU $02 ; DIRECT FROM 8255 TO IDE INTERFACE
|
|
PPIDE_A2_LINE .EQU $04 ; DIRECT FROM 8255 TO IDE INTERFACE
|
|
PPIDE_CS0_LINE .EQU $08 ; INVERTER BETWEEN 8255 AND IDE INTERFACE
|
|
PPIDE_CS1_LINE .EQU $10 ; INVERTER BETWEEN 8255 AND IDE INTERFACE
|
|
PPIDE_WR_LINE .EQU $20 ; INVERTER BETWEEN 8255 AND IDE INTERFACE
|
|
PPIDE_RD_LINE .EQU $40 ; INVERTER BETWEEN 8255 AND IDE INTERFACE
|
|
PPIDE_RST_LINE .EQU $80 ; INVERTER BETWEEN 8255 AND IDE INTERFACE
|
|
;
|
|
;------------------------------------------------------------------
|
|
; MORE SYMBOLIC CONSTANTS... THESE SHOULD NOT BE CHANGED, UNLESS OF
|
|
; COURSE THE IDE DRIVE INTERFACE CHANGES, PERHAPS WHEN DRIVES GET
|
|
; TO 128G AND THE PC INDUSTRY WILL DO YET ANOTHER KLUDGE.
|
|
;
|
|
; SOME SYMBOLIC CONSTANTS FOR THE IDE REGISTERS, WHICH MAKES THE
|
|
; CODE MORE READABLE THAN ALWAYS SPECIFYING THE ADDRESS PINS
|
|
;
|
|
PPIDE_DATA .EQU PPIDE_CS0_LINE
|
|
PPIDE_ERROR .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE
|
|
PPIDE_FEATURE .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE
|
|
PPIDE_SEC_CNT .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE
|
|
PPIDE_SECTOR .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE
|
|
PPIDE_CYL_LSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE
|
|
PPIDE_CYL_MSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A0_LINE
|
|
PPIDE_HEAD .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE
|
|
PPIDE_COMMAND .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE
|
|
PPIDE_STTS .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE
|
|
PPIDE_CONTROL .EQU PPIDE_CS1_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE
|
|
PPIDE_ASTTS .EQU PPIDE_CS1_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE
|
|
;
|
|
; IDE COMMAND CONSTANTS. THESE SHOULD NEVER CHANGE.
|
|
;
|
|
PPIDE_CMDRECAL .EQU $10
|
|
PPIDE_CMDREAD .EQU $20
|
|
PPIDE_CMDWRITE .EQU $30
|
|
PPIDE_CMDINIT .EQU $91
|
|
PPIDE_CMDID .EQU $EC
|
|
PPIDE_CMDSPINDOWN .EQU $E0
|
|
PPIDE_CMDSPINUP .EQU $E1
|
|
PPIDE_CMDSETFEAT .EQU $EF
|
|
;
|
|
PPIDE_RCOK .EQU 0
|
|
PPIDE_RCCMDERR .EQU 1
|
|
PPIDE_RCRDYTO .EQU 2
|
|
PPIDE_RCBUFTO .EQU 3
|
|
;
|
|
; UNIT CONFIGURATION
|
|
;
|
|
PPIDE_UNIT0 .DB %11100000 ; LBA, MASTER DEVICE
|
|
PPIDE_UNIT1 .DB %11110000 ; LBA, SLAVE DEVICE
|
|
;
|
|
;
|
|
;
|
|
PPIDE_DISPATCH:
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
AND $0F
|
|
JR Z,PPIDE_RD
|
|
DEC A
|
|
JR Z,PPIDE_WR
|
|
DEC A
|
|
JR Z,PPIDE_ST
|
|
DEC A
|
|
JR Z,PPIDE_MED
|
|
CALL PANIC
|
|
;
|
|
PPIDE_RD:
|
|
LD A,PPIDE_CMDREAD
|
|
LD (PPIDEP_CMD),A
|
|
JP PPIDE_RW
|
|
;
|
|
PPIDE_WR:
|
|
LD A,PPIDE_CMDWRITE
|
|
LD (PPIDEP_CMD),A
|
|
JP PPIDE_RW
|
|
;
|
|
PPIDE_ST:
|
|
LD A,(PPIDE_STAT) ; LOAD STATUS
|
|
OR A ; SET FLAGS
|
|
RET
|
|
;
|
|
PPIDE_MED:
|
|
LD A,MID_HD
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_INIT:
|
|
PRTS("PPIDE: IO=0x$")
|
|
LD A,IDELSB
|
|
CALL PRTHEXBYTE
|
|
PRTS(" UNITS=2$")
|
|
#IF (PPIDE8BIT)
|
|
PRTS(" 8BIT$")
|
|
#ENDIF
|
|
#IF (PPIDESLOW)
|
|
PRTS(" SLOW$")
|
|
#ENDIF
|
|
CALL PPIDE_RESET
|
|
XOR A
|
|
DEC A ; INITIAL STATUS IS NOT READY $FF
|
|
LD (PPIDE_STAT),A ; SAVE IT
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_RW:
|
|
; INIT REQUIRED?
|
|
LD A,(PPIDE_STAT)
|
|
OR A ; SET FLAGS
|
|
JR Z,PPIDE_RW0 ; IF STATUS OK, BYPASS RESET
|
|
|
|
CALL PPIDE_RESET ; DO THE RESET
|
|
; NEED TO CHECK STATUS HERE!!!
|
|
|
|
PPIDE_RW0:
|
|
; CLEAR RESULTS
|
|
XOR A ; A = 0
|
|
LD (PPIDE_RC),A ; CLEAR RETURN CODE
|
|
LD (PPIDEP_STTS),A ; CLEAR SAVED STTS
|
|
LD (PPIDEP_ERR),A ; CLEAR SAVED ERR
|
|
|
|
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
|
|
JP NC,PPIDE_ERR
|
|
CALL PPIDE_SETUP ; SETUP CYL, TRK, HEAD
|
|
LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER
|
|
LD A,(PPIDEP_CMD) ; COMMAND VALUE
|
|
CALL PPIDE_WRITE ; DO IT
|
|
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
|
|
JP NC,PPIDE_ERR
|
|
CALL PPIDE_CHKERR ; CHECK FOR ERRORS
|
|
JP NC,PPIDE_ERR
|
|
CALL PPIDE_WAITBUF ; WAIT FOR BUFFER READY
|
|
JP NC,PPIDE_ERR
|
|
|
|
LD A,(PPIDEP_CMD) ; DISPATCH TO READ OR WRITE SPECIFIC LOGIC
|
|
CP PPIDE_CMDWRITE
|
|
JP Z,PPIDE_RW1
|
|
|
|
CALL PPIDE_BUFRD ; READ BUFFER
|
|
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
|
|
JP NC,PPIDE_ERR
|
|
CALL PPIDE_CHKERR ; CHECK FOR ERRORS
|
|
JP NC,PPIDE_ERR
|
|
JP PPIDE_OK
|
|
|
|
PPIDE_RW1:
|
|
CALL PPIDE_BUFWR ; WRITE BUFFER
|
|
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
|
|
JP NC,PPIDE_ERR
|
|
CALL PPIDE_CHKERR ; CHECK FOR ERRORS
|
|
JP NC,PPIDE_ERR
|
|
JP PPIDE_OK
|
|
|
|
PPIDE_ERR:
|
|
XOR A
|
|
DEC A ; A = $FF TO SIGNAL ERROR
|
|
LD (PPIDE_STAT),A ; SAVE IT
|
|
#IF (PPIDETRACE >= 1)
|
|
PUSH AF
|
|
CALL PPIDE_PRT
|
|
POP AF
|
|
#ENDIF
|
|
RET
|
|
|
|
PPIDE_OK:
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PPIDE_PRT
|
|
#ENDIF
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_RESET:
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL NEWLINE
|
|
PRTX(PPIDESTR_PREFIX)
|
|
PRTS(" RESET$")
|
|
#ENDIF
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER
|
|
LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES
|
|
CALL PPIDE_WRITE ; DO IT
|
|
LD DE,8 ; DELAY ABOUT 200ms
|
|
CALL VDELAY
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER
|
|
LD A,000000010B ; NO INTERRUPTS, DEASSERT RESET
|
|
CALL PPIDE_WRITE ; DO IT
|
|
XOR A ; STATUS OK
|
|
LD (PPIDE_STAT),A ; SAVE IT
|
|
|
|
#IF (PPIDE8BIT)
|
|
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
CALL PPIDE_WAITRDY
|
|
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
LD C,PPIDE_FEATURE ; IDE FEATURE REGISTER
|
|
LD A,01H ; VALUE := 1
|
|
CALL PPIDE_WRITE ; DO IT
|
|
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER
|
|
LD A,PPIDE_CMDSETFEAT ; SET FEATURE
|
|
CALL PPIDE_WRITE ; DO IT
|
|
|
|
#IF (PPIDETRACE >= 2)
|
|
CALL PC_PERIOD
|
|
#ENDIF
|
|
|
|
#ENDIF
|
|
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_WAITRDY:
|
|
LD DE,0 ; TIMEOUT IS 250us * 65536 = 15 SECONDS
|
|
PPIDE_WBSY:
|
|
PUSH DE
|
|
LD DE,10 ; INNER LOOP DELAY IS 250us (25us * 10)
|
|
CALL VDELAY
|
|
POP DE
|
|
DEC DE
|
|
LD A,D
|
|
OR E
|
|
JP Z,PPIDE_TO
|
|
LD C,PPIDE_STTS ; IDE STATUS REGISTER
|
|
CALL PPIDE_READ ; READ ID
|
|
LD (PPIDEP_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,PPIDE_WBSY
|
|
SCF ; CARRY 1 = OK
|
|
RET
|
|
PPIDE_TO:
|
|
LD A,PPIDE_RCRDYTO
|
|
LD (PPIDE_RC),A
|
|
XOR A ; CARRY 0 = TIMEOUT
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_CHKERR:
|
|
LD C,PPIDE_STTS ; IDE STATUS REGISTER
|
|
CALL PPIDE_READ ; READ IT
|
|
LD (PPIDEP_STTS),A ; SAVE IT
|
|
AND 000000001B ; ERROR BIT SET?
|
|
SCF ; ASSUME NO ERR
|
|
RET Z ; NO ERR, RETURN WITH CF SET
|
|
;
|
|
LD C,PPIDE_ERROR ; IDE ERROR REGISTER
|
|
CALL PPIDE_READ ; READ IT
|
|
LD (PPIDEP_ERR),A ; SAVE IT
|
|
;
|
|
LD A,PPIDE_RCCMDERR ; COMMAND ERROR
|
|
LD (PPIDE_RC),A ; SAVE IT
|
|
;
|
|
OR A ; CLEAR CF TO SIGNAL ERROR
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_WAITBUF:
|
|
LD DE,0
|
|
PPIDE_WDRQ:
|
|
CALL DELAY
|
|
INC DE
|
|
LD A,D
|
|
OR E
|
|
JP Z,PPIDE_TO2
|
|
LD C,PPIDE_STTS ; IDE STATUS REGISTER
|
|
CALL PPIDE_READ ; READ IT
|
|
LD (PPIDEP_STTS),A ; SAVE IT
|
|
AND 010001000B ; TO FILL (OR READY TO FILL)
|
|
XOR 000001000B
|
|
JP NZ,PPIDE_WDRQ
|
|
SCF ; CARRY 1 = OK
|
|
RET
|
|
PPIDE_TO2:
|
|
LD A,PPIDE_RCBUFTO
|
|
LD (PPIDE_RC),A
|
|
XOR A ; CARRY 0 = TIMED OUT
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_BUFRD:
|
|
; SETUP PPI TO READ
|
|
LD A,RD_IDE_8255 ; READ CONFIG
|
|
OUT (PPICTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; SELECT READ/WRITE IDE REGISTER
|
|
LD A,PPIDE_DATA ; DATA REGISTER
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
LD E,A ; E := READ UNASSERTED
|
|
XOR PPIDE_RD_LINE ; SWAP THE READ LINE BIT
|
|
LD D,A ; D := READ ASSERTED
|
|
;
|
|
; LOOP SETUP
|
|
LD HL,(DIOBUF) ; LOCATION OF BUFFER
|
|
LD B,0 ; 256 ITERATIONS
|
|
LD C,IDELSB ; SETUP C WITH IO PORT (LSB)
|
|
;
|
|
CALL PPIDE_BUFRD1 ; FIRST PASS (FIRST 256 BYTES)
|
|
CALL PPIDE_BUFRD1 ; SECOND PASS (LAST 256 BYTES)
|
|
;
|
|
; CLEAN UP
|
|
XOR A ; ZERO A
|
|
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
RET
|
|
;
|
|
PPIDE_BUFRD1: ; START OF READ LOOP
|
|
LD A,D ; ASSERT READ
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
INI ; GET AND SAVE NEXT BYTE
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
#IF (!PPIDE8BIT)
|
|
INC C ; LSB -> MSB
|
|
INI ; GET AND SAVE NEXT BYTE
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
PUSH AF
|
|
DEC C ; MSB -> LSB
|
|
POP AF
|
|
#ENDIF
|
|
LD A,E ; DEASSERT READ
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
JR NZ,PPIDE_BUFRD1 ; LOOP UNTIL DONE
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_BUFWR:
|
|
; SETUP PPI TO WRITE
|
|
LD A,WR_IDE_8255 ; WRITE CONFIG
|
|
OUT (PPICTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; SELECT READ/WRITE IDE REGISTER
|
|
LD A,PPIDE_DATA ; DATA REGISTER
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
LD E,A ; E := WRITE UNASSERTED
|
|
XOR PPIDE_WR_LINE ; SWAP THE WRITE LINE BIT
|
|
LD D,A ; D := WRITE ASSERTED
|
|
;
|
|
; LOOP SETUP
|
|
LD HL,(DIOBUF) ; LOCATION OF BUFFER
|
|
LD B,0 ; 256 ITERATIONS
|
|
LD C,IDELSB ; SETUP C WITH IO PORT (LSB)
|
|
;
|
|
CALL PPIDE_BUFWR1 ; FIRST PASS (FIRST 256 BYTES)
|
|
CALL PPIDE_BUFWR1 ; SECOND PASS (LAST 256 BYTES)
|
|
;
|
|
; CLEAN UP
|
|
XOR A ; ZERO A
|
|
OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
RET
|
|
;
|
|
PPIDE_BUFWR1: ; START OF WRITE LOOP
|
|
OUTI ; SEND NEXT BYTE OF BUFFER
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
#IF (!PPIDE8BIT)
|
|
INC C ; LSB -> MSB
|
|
OUTI ; SEND NEXT BYTE OF BUFFER
|
|
PUSH AF
|
|
DEC C ; MSB -> LSB
|
|
POP AF
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
#ENDIF
|
|
;
|
|
; TOGGLE THE WRITE LINE
|
|
LD A,D ; WRITE ASSERTED VALUE
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
LD A,E ; WRITE UNASSERTED VALUE
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
JR NZ,PPIDE_BUFWR1 ; LOOP UNTIL DONE
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_SETUP:
|
|
LD C,PPIDE_SEC_CNT ; IDE SECTOR COUNT REGISTER
|
|
LD A,1 ; 1 SECTOR
|
|
CALL PPIDE_WRITE ; DO IT
|
|
|
|
LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT
|
|
AND 0FH
|
|
CP 0
|
|
JP Z,PPIDE_SETUP_UNIT0
|
|
CP 1
|
|
JP Z,PPIDE_SETUP_UNIT1
|
|
CALL PANIC
|
|
PPIDE_SETUP_UNIT0:
|
|
LD A,(PPIDE_UNIT0)
|
|
JP PPIDE_SETUP1
|
|
PPIDE_SETUP_UNIT1:
|
|
LD A,(PPIDE_UNIT1)
|
|
JP PPIDE_SETUP1
|
|
PPIDE_SETUP1:
|
|
LD C,PPIDE_HEAD ; IDE HEAD REGISTER
|
|
LD (PPIDEP_HEAD),A ; SAVE HEAD VALUE
|
|
CALL PPIDE_WRITE ; WRITE IT
|
|
|
|
LD HL,(HSTTRK) ; HSTTRK -> IDECYLHI/LO
|
|
LD C,PPIDE_CYL_MSB ; IDE MSB CYL REGISTER
|
|
LD A,H ; MSB CYL VALUE
|
|
LD (PPIDEP_CYLHI),A ; SAVE IT
|
|
CALL PPIDE_WRITE ; WRITE IT
|
|
LD C,PPIDE_CYL_LSB ; IDE LSB CYL REGISTER
|
|
LD A,L ; LSB CYL VALUE
|
|
LD (PPIDEP_CYLLO),A ; SAVE IT
|
|
CALL PPIDE_WRITE ; WRITE IT
|
|
|
|
LD HL,(HSTSEC) ; HSTSEC -> IDESECTN
|
|
LD C,PPIDE_SECTOR ; IDE SECTOR REGISTER
|
|
LD A,L ; SECTOR VALUE
|
|
LD (PPIDEP_SEC),A ; SAVE IT
|
|
CALL PPIDE_WRITE ; WRITE IT
|
|
|
|
#IF (DSKYENABLE)
|
|
CALL PPIDE_DSKY
|
|
#ENDIF
|
|
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDE_READ:
|
|
;
|
|
; SET PPI MODE TO READ CONFIGURATION
|
|
LD A,RD_IDE_8255 ; PPI MODE TO READ
|
|
OUT (PPICTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; SELECT REQUESTED IDE REGISTER, THEN ASSERT READ
|
|
LD A,C ; REGISTER SELECTION -> A
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
OR PPIDE_RD_LINE ; ASSERT READ
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; READ THE BYTE
|
|
IN A,(IDELSB) ; READ LSB
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
PUSH AF ; SAVE IT FOR NOW
|
|
;
|
|
; ; DUMMY READ OF MSB
|
|
; IN A,(IDEMSB) ; READ LSB
|
|
; RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; CLEAN UP AND RETURN
|
|
LD A,C ; DEASSERT READ
|
|
OUT (IDECTL),A ; DO IT
|
|
XOR A ; RELEASE ALL BUS SIGNALS
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
POP AF ; RECOVER THE DATA BYTE
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
PPIDE_WRITE:
|
|
;
|
|
; SAVE THE INCOMING VALUE TO WRITE
|
|
PUSH AF
|
|
;
|
|
; SET PPI MODE TO WRITE CONFIGURATION
|
|
LD A,WR_IDE_8255 ; PPI MODE TO WRITE
|
|
OUT (PPICTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; SELECT REQUESTED IDE REGISTER
|
|
LD A,C ; REGISTER SELECTION -> A
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
|
|
; SET THE VALUE TO WRITE
|
|
POP AF ; GET VALUE BACK
|
|
OUT (IDELSB),A ; SET IDE LSB
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; ; MSB ALWAYS GETS ZERO
|
|
; XOR A ; ZERO A
|
|
; OUT (IDEMSB),A ; SET IDE MSB
|
|
; RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; PULSE THE WRITE LINE
|
|
LD A,C ; REGISTER SELECTION -> A
|
|
OR PPIDE_WR_LINE ; ASSERT WRITE
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
LD A,C
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
; CLEAN UP AND RETURN
|
|
XOR A ; RELEASE ALL BUS SIGNALS
|
|
OUT (IDECTL),A ; DO IT
|
|
RECOVERY ; OPTIONAL SMALL DELAY
|
|
;
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
#IF (DSKYENABLE)
|
|
PPIDE_DSKY:
|
|
LD HL,DSKY_HEXBUF
|
|
LD A,(PPIDEP_HEAD)
|
|
LD (HL),A
|
|
INC HL
|
|
LD A,(PPIDEP_CYLHI)
|
|
LD (HL),A
|
|
INC HL
|
|
LD A,(PPIDEP_CYLLO)
|
|
LD (HL),A
|
|
INC HL
|
|
LD A,(PPIDEP_SEC)
|
|
LD (HL),A
|
|
CALL DSKY_HEXOUT
|
|
RET
|
|
#ENDIF
|
|
;
|
|
;
|
|
;
|
|
PPIDE_PRT:
|
|
CALL NEWLINE
|
|
|
|
LD DE,PPIDESTR_PREFIX
|
|
CALL WRITESTR
|
|
|
|
CALL PC_SPACE
|
|
LD DE,PPIDESTR_CMD
|
|
CALL WRITESTR
|
|
LD A,(PPIDEP_CMD)
|
|
CALL PRTHEXBYTE
|
|
|
|
CALL PC_SPACE
|
|
CALL PC_LBKT
|
|
LD A,(PPIDEP_CMD)
|
|
LD DE,PPIDESTR_READ
|
|
CP PPIDE_CMDREAD
|
|
JP Z,PPIDE_PRTCMD
|
|
LD DE,PPIDESTR_WRITE
|
|
CP PPIDE_CMDWRITE
|
|
JP Z,PPIDE_PRTCMD
|
|
LD DE,PPIDESTR_UNKCMD
|
|
PPIDE_PRTCMD:
|
|
CALL WRITESTR
|
|
CALL PC_RBKT
|
|
|
|
CALL PC_SPACE
|
|
LD A,(PPIDEP_HEAD)
|
|
CALL PRTHEXBYTE
|
|
LD A,(PPIDEP_CYLHI)
|
|
CALL PRTHEXBYTE
|
|
LD A,(PPIDEP_CYLLO)
|
|
CALL PRTHEXBYTE
|
|
LD A,(PPIDEP_SEC)
|
|
CALL PRTHEXBYTE
|
|
|
|
CALL PC_SPACE
|
|
LD DE,PPIDESTR_ARROW
|
|
CALL WRITESTR
|
|
|
|
CALL PC_SPACE
|
|
LD C,PPIDE_STTS ; IDE STATUS REGISTER
|
|
CALL PPIDE_READ ; READ IT
|
|
CALL PRTHEXBYTE
|
|
|
|
CALL PC_SPACE
|
|
LD C,PPIDE_ERROR ; IDE ERROR REGISTER
|
|
CALL PPIDE_READ ; READ IT
|
|
CALL PRTHEXBYTE
|
|
|
|
CALL PC_SPACE
|
|
LD DE,PPIDESTR_RC
|
|
CALL WRITESTR
|
|
LD A,(PPIDE_RC)
|
|
CALL PRTHEXBYTE
|
|
|
|
CALL PC_SPACE
|
|
CALL PC_LBKT
|
|
LD A,(PPIDE_RC)
|
|
LD DE,PPIDESTR_RCOK
|
|
CP PPIDE_RCOK
|
|
JP Z,PPIDE_PRTRC
|
|
LD DE,PPIDESTR_RCCMDERR
|
|
CP PPIDE_RCCMDERR
|
|
JP Z,PPIDE_PRTRC
|
|
LD DE,PPIDESTR_RCRDYTO
|
|
CP PPIDE_RCRDYTO
|
|
JP Z,PPIDE_PRTRC
|
|
LD DE,PPIDESTR_RCBUFTO
|
|
CP PPIDE_RCBUFTO
|
|
JP Z,PPIDE_PRTRC
|
|
LD DE,PPIDESTR_RCUNK
|
|
PPIDE_PRTRC:
|
|
CALL WRITESTR
|
|
CALL PC_RBKT
|
|
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
PPIDESTR_PREFIX .TEXT "PPIDE:$"
|
|
PPIDESTR_CMD .TEXT "CMD=$"
|
|
PPIDESTR_RC .TEXT "RC=$"
|
|
PPIDESTR_ARROW .TEXT "-->$"
|
|
PPIDESTR_READ .TEXT "READ$"
|
|
PPIDESTR_WRITE .TEXT "WRITE$"
|
|
PPIDESTR_UNKCMD .TEXT "UNKCMD$"
|
|
PPIDESTR_RCOK .TEXT "OK$"
|
|
PPIDESTR_RCCMDERR .TEXT "COMMAND ERROR$"
|
|
PPIDESTR_RCRDYTO .TEXT "READY TIMEOUT$"
|
|
PPIDESTR_RCBUFTO .TEXT "BUFFER TIMEOUT$"
|
|
PPIDESTR_RCUNK .TEXT "UNKNOWN ERROR$"
|
|
;
|
|
;==================================================================================================
|
|
; PPIDE DISK DRIVER - DATA
|
|
;==================================================================================================
|
|
;
|
|
PPIDE_STAT .DB 0
|
|
PPIDE_RC .DB 0
|
|
;
|
|
; PPIDE PARAMETERS
|
|
;
|
|
PPIDEP_CMD .DB 0
|
|
PPIDEP_HEAD .DB 0
|
|
PPIDEP_CYLHI .DB 0
|
|
PPIDEP_CYLLO .DB 0
|
|
PPIDEP_SEC .DB 0
|
|
PPIDEP_STTS .DB 0
|
|
PPIDEP_ERR .DB 0
|
|
;
|
|
; Error Register (ERR bit being set in the Status Register)
|
|
;
|
|
; Bit 7: BBK (Bad Block Detected) Set when a Bad Block is detected.
|
|
; Bit 6: UNC (Uncorrectable Data Error) Set when Uncorrectable Error is encountered.
|
|
; Bit 5: MC (Media Changed) Set to 0.
|
|
; Bit 4: IDNF (ID Not Found) Set when Sector ID not found.
|
|
; Bit 3: MCR (Media Change Request) Set to 0.
|
|
; Bit 2: ABRT (Aborted Command) Set when Command Aborted due to drive error.
|
|
; Bit 1: TKONF (Track 0 Not Found) Set when Executive Drive Diagnostic Command.
|
|
; Bit 0: AMNF (Address mark Not Found) Set in case of a general error.
|
|
;
|
|
; Status Register (When the contents of this register are read by the host, the IREQ# bit is cleared)
|
|
;
|
|
; Bit 7: BSY (Busy) Set when the drive is busy and unable to process any new ATA commands.
|
|
; Bit 6: DRDY (Data Ready) Set when the device is ready to accept ATA commands from the host.
|
|
; Bit 5: DWF (Drive Write Fault) Always set to 0.
|
|
; Bit 4: DSC (Drive Seek Complete) Set when the drive heads have been positioned over a specific track.
|
|
; Bit 3: DRQ (Data Request) Set when device is ready to transfer a word or byte of data to or from the host and the device.
|
|
; Bit 2: CORR (Corrected Data) Always set to 0.
|
|
; Bit 1: IDX (Index) Always set to 0.
|
|
; Bit 0: ERR (Error) Set when an error occurred during the previous ATA command.
|
|
|