@ -5,6 +5,7 @@
;
; TODO:
; - GOPARTNER NEEDS TO HANDLE "NO PARTNER" CONDITION
; - DATA TRANSFERS LIMITED TO 512 BYTES WHICH IS INSUFFICIENT FOR CD=ROM MEDIA
;
; NOTES:
; - WELL KNOWN PPIDE PORT ADDRESSES:
@ -135,6 +136,8 @@ PPIDE_REG_LBA0 .EQU PPIDE_CTL_CS1 | $03 ; LBA BYTE 0 (BITS 0-7) (R/W)
PPIDE_REG_LBA1 .EQU PPIDE_CTL_CS1 | $ 04 ; LBA BYTE 1 (BITS 8-15) (R/W)
PPIDE_REG_LBA2 .EQU PPIDE_CTL_CS1 | $ 05 ; LBA BYTE 2 (BITS 16-23) (R/W)
PPIDE_REG_LBA3 .EQU PPIDE_CTL_CS1 | $ 06 ; LBA BYTE 3 (BITS 24-27) (R/W)
PPIDE_REG_BCL .EQU PPIDE_CTL_CS1 | $ 04 ; PKT BYTE COUNT LOW (BITS 0-7) (R/W)
PPIDE_REG_BCH .EQU PPIDE_CTL_CS1 | $ 05 ; PKT BYTE COUNT HIGH (BITS 8-15) (R/W)
PPIDE_REG_STAT .EQU PPIDE_CTL_CS1 | $ 07 ; STATUS REGISTER (R)
PPIDE_REG_CMD .EQU PPIDE_CTL_CS1 | $ 07 ; COMMAND REGISTER (EXECUTE) (W)
PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3 | $ 06 ; ALTERNATE STATUS REGISTER (R)
@ -143,13 +146,14 @@ 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 _NOP .EQU $ 00
PPIDE_CMD _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_DEVDIAG .EQU $ 90
PPIDE_CMD_PACKET .EQU $ A0
PPIDE_CMD_IDPKTDEV .EQU $ A1
PPIDE_CMD_IDDEV .EQU $ EC
PPIDE_CMD_SETFEAT .EQU $ EF
;
@ -175,6 +179,7 @@ PPIDE_STRDYTO .EQU -5
PPIDE_STDRQTO .EQU - 6
PPIDE_STBSYTO .EQU - 7
PPIDE_STNOTSUP .EQU - 8
PPIDE_STNOTRDY .EQU - 9
;
; DRIVE SELECTION BYTES (FOR USE IN DRIVE/HEAD REGISTER)
;
@ -407,10 +412,6 @@ PPIDE_INIT5:
JP NZ , PPIDE_PRTSTATSTR ; EXIT VIA PRINT STATUS STRING
;
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?
CALL NZ , WRITESTR
@ -526,12 +527,12 @@ PPIDE_IO:
PUSH HL ; ... TO FILTER ALL EXITS
# ENDIF
PUSH BC ; SAVE COUNTERS
CALL PPIDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT
CALL PPIDE_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO
POP BC ; RESTORE COUNTERS
JR NZ , PPIDE_IO3 ; BAIL OUT ON ERROR
PPIDE_IO1:
PUSH BC ; SAVE COUNTERS
CALL PPIDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT
LD HL ,( PPIDE_IOFNADR ) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ , PPIDE_IO2 ; IF ERROR, SKIP INCREMENT
@ -644,8 +645,6 @@ PPIDE_GEOM:
; FUNCTION SUPPORT ROUTINES
;=============================================================================
;
;
;
PPIDE_SETFEAT:
PUSH AF
# IF ( PPIDETRACE > = 3 )
@ -674,36 +673,38 @@ PPIDE_SETFEAT:
;
;
;
PPIDE_NOP :
PPIDE_IDENTIFY :
# IF ( PPIDETRACE > = 3 )
CALL PPIDE_PRTPREFIX
PRTS ( " NOP $" )
PRTS ( " IDDEV $" )
# ENDIF
LD A ,( PPIDE_DRVHD )
;OUT (PPIDE_IO _DRVHD),A
;OUT (PPIDE_REG _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
LD A , PPIDE_CMD_IDDEV
LD ( PPIDE_CMD ), A
CALL PPIDE_RUNCMD_ND
RET NZ
JP PPIDE_RUNCMD1 ; RUN COMMAND AND EXIT
;
CALL PPIDE_IN
.DB PPIDE_REG_STAT
BIT 3 , A ; IS DRQ SET?
JP Z , PPIDE_NOMEDIA
;
LD HL , HB_WRKBUF
JP PPIDE_GETBUF ; EXIT THRU BUFRD
;
;
PPIDE_IDENTIFY:
;
PPIDE_IDENTIFYPACKET:
# IF ( PPIDETRACE > = 3 )
CALL PPIDE_PRTPREFIX
PRTS ( " IDDEV$" )
PRTS ( " IDPKT DEV$" )
# ENDIF
LD A ,( PPIDE_DRVHD )
;OUT (PPIDE_REG_DRVHD),A
@ -713,41 +714,45 @@ PPIDE_IDENTIFY:
CALL PC_SPACE
CALL PRTHEXBYTE
# ENDIF
LD A , PPIDE_CMD_IDDEV
LD A , PPIDE_CMD_IDPKT DEV
LD ( PPIDE_CMD ), A
CALL PPIDE_RUNCMD
CALL PPIDE_RUNCMD_ND
RET NZ
;
CALL PPIDE_IN
.DB PPIDE_REG_STAT
BIT 3 , A ; IS DRQ SET?
JP Z , PPIDE_NOMEDIA
;
LD HL , HB_WRKBUF
JP PPIDE_GETBUF ; EXIT THRU BUFRD
;
;
;
PPIDE_IDENTIFY PACKET:
PPIDE_PACKET:
# IF ( PPIDETRACE > = 3 )
CALL PPIDE_PRTPREFIX
PRTS ( " IDPKTDEV $" )
PRTS ( " PACKET $" )
# ENDIF
LD A ,( PPIDE_DRVHD )
;OUT (PPIDE_IO _DRVHD),A
;OUT (PPIDE_REG _DRVHD),A
CALL PPIDE_OUT
.DB PPIDE_REG_DRVHD
# IF ( PPIDETRACE > = 3 )
CALL PC_SPACE
CALL PRTHEXBYTE
# ENDIF
LD A , PPIDE_CIDE_IDPKTDEV
XOR A ; ZERO
CALL PPIDE_OUT
.DB PPIDE_REG_FEAT ; FEATURE REG = 0
CALL PPIDE_OUT
.DB PPIDE_REG_BCL
LD A , 8
CALL PPIDE_OUT
.DB PPIDE_REG_BCH ; BYTE COUNT = 512????
LD A , PPIDE_CMD_PACKET
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
JP PPIDE_RUNCMD_ND
;
;
;
@ -764,6 +769,17 @@ PPIDE_RDSEC:
# IF ( PPIDETRACE > = 3 )
CALL PC_SPACE
CALL PRTHEXBYTE
# ENDIF
LD A ,( IY + PPIDE_TYPE )
CP PPIDE_TYPEATA
JR Z , PPIDE_ATA_RDSEC
CP PPIDE_TYPEATAPI
JR Z , PPIDE_PKT_RDSEC
JP PPIDE_CMDERR
;
PPIDE_ATA_RDSEC:
# IF ( PPIDETRACE > = 3 )
PRTS ( " ATA$" )
# ENDIF
CALL PPIDE_SETADDR ; SETUP CYL, TRK, HEAD
LD A , PPIDE_CMD_READ
@ -773,6 +789,31 @@ PPIDE_RDSEC:
LD HL ,( PPIDE_DSKBUF )
JP PPIDE_GETBUF
;
PPIDE_PKT_RDSEC:
# IF ( PPIDETRACE > = 3 )
PRTS ( " PKT$" )
# ENDIF
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
LD HL , PPIDE_PKTCMD_RW10 + 3 ; START OF LBA FIELD IN CDB (MSB)
LD A ,( IY + PPIDE_LBA + 2 ) ; THIRD BYTE OF LBA FIELD IN CFG (MSB)
LD ( HL ), A
INC HL
LD A ,( IY + PPIDE_LBA + 1 )
LD ( HL ), A
INC HL
LD A ,( IY + PPIDE_LBA + 0 )
LD ( HL ), A
INC HL
LD HL , PPIDE_PKTCMD_RW10
LD A , SCSI_CMD_READ10
LD ( HL ), A
XOR A ; READ DIRECTION
LD ( PPIDE_XFRDIR ), A ; SAVE IT
CALL PPIDE_RUNPCMD
JP NZ , PPIDE_CHKPCMD
RET
;
;
;
PPIDE_WRSEC:
@ -788,6 +829,17 @@ PPIDE_WRSEC:
# IF ( PPIDETRACE > = 3 )
CALL PC_SPACE
CALL PRTHEXBYTE
# ENDIF
LD A ,( IY + PPIDE_TYPE )
CP PPIDE_TYPEATA
JR Z , PPIDE_ATA_WRSEC
CP PPIDE_TYPEATAPI
JR Z , PPIDE_PKT_WRSEC
JP PPIDE_CMDERR
;
PPIDE_ATA_WRSEC:
# IF ( PPIDETRACE > = 3 )
PRTS ( " ATA$" )
# ENDIF
CALL PPIDE_SETADDR ; SETUP CYL, TRK, HEAD
LD A , PPIDE_CMD_WRITE
@ -797,6 +849,31 @@ PPIDE_WRSEC:
LD HL ,( PPIDE_DSKBUF )
JP PPIDE_PUTBUF
;
PPIDE_PKT_WRSEC:
# IF ( PPIDETRACE > = 3 )
PRTS ( " PKT$" )
# ENDIF
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
LD HL , PPIDE_PKTCMD_RW10 + 3 ; START OF LBA FIELD IN CDB (MSB)
LD A ,( IY + PPIDE_LBA + 2 ) ; THIRD BYTE OF LBA FIELD IN CFG (MSB)
LD ( HL ), A
INC HL
LD A ,( IY + PPIDE_LBA + 1 )
LD ( HL ), A
INC HL
LD A ,( IY + PPIDE_LBA + 0 )
LD ( HL ), A
INC HL
LD HL , PPIDE_PKTCMD_RW10
LD A , SCSI_CMD_WRITE10
LD ( HL ), A
OR $ FF ; WRITE DIRECTION
LD ( PPIDE_XFRDIR ), A ; SAVE IT
CALL PPIDE_RUNPCMD
JP NZ , PPIDE_CHKPCMD
RET
;
;
;
PPIDE_SETADDR:
@ -807,8 +884,8 @@ PPIDE_SETADDR:
CALL HB_DSKACT ; SHOW ACTIVITY
# ENDIF
; SEND 3 LOWEST BYTES OF LBA IN REVERSE ORDER
; IDE_IO _LBA3 HAS ALREADY BEEN SET
; HSTLBA2-0 --> IDE_IO _LBA2-0
; IDE_REG _LBA3 HAS ALREADY BEEN SET
; HSTLBA2-0 --> IDE_REG _LBA2-0
LD A ,( IY + PPIDE_LBA + 2 )
# IF ( PPIDETRACE > = 3 )
CALL PC_SPACE
@ -847,6 +924,16 @@ PPIDE_SETADDR:
; COMMAND PROCESSING
;=============================================================================
;
; RUN AN ATA COMMAND. THERE ARE TWO ENTRY POINTS. THE NORMAL ENTRY
; POINT WILL WAIT FOR DRIVE READY. THE _ND ENTRY POINT ONLY WAITS
; FOR THE DEVICE TO BE NOT BUSY. THE CORRECT ENTRY POINT DEPENDS ON
; THE COMMAND.
;
PPIDE_RUNCMD_ND:
CALL PPIDE_WAITBSY ; WAIT WHILE DEVICE BUSY
RET NZ ; BAIL OUT ON TIMEOUT
JR PPIDE_RUNCMD1 ; CONTINUE
PPIDE_RUNCMD:
CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY
RET NZ ; BAIL OUT ON TIMEOUT
@ -871,54 +958,160 @@ PPIDE_RUNCMD1:
JP NZ , PPIDE_CMDERR
RET
;
; PACKET COMMAND PROCESSOR
; HL: ADDRESS OF PACKET COMMAND BUFFER
;
PPIDE_RUNPCMD:
PUSH HL
CALL PPIDE_PACKET
POP HL
RET NZ ; BAIL OUT ON ERROR
;
# IF ( PPIDETRACE > = 3 )
PRTS ( "\r\nPKTCMD:$" )
PUSH HL
POP DE
LD A , 12
CALL PRTHEXBUF
# ENDIF
;
; IF ZIP DRIVE HAS FALLEN ASLEEP, THEN IT WILL NEED EXTRA
; TIME HERE TO WAKE UP BEFORE ACCEPTING THE COMMAND. USE
; LONG TIMEOUT TO ACCOMMODATE THIS.
LD DE ,( PPIDE_TIMEOUT ) ; GET CURRENT TIMEOUT
PUSH DE ; SAVE IT
LD DE , PPIDE_TOSLOW ; SLOW TIMEOUT FOR THIS
LD ( PPIDE_TIMEOUT ), DE ; SET IT
LD B , 6 ; 6 WORDS ALWAYS
CALL PPIDE_PUT
POP DE ; RECOVER TIMEOUT
LD ( PPIDE_TIMEOUT ), DE ; SET IT
RET NZ
;
CALL PPIDE_IN
.DB PPIDE_REG_STAT
BIT 3 , A ; IS DRQ SET?
RET Z ; IF NOT, ALL DONE
;
CALL PPIDE_IN
.DB PPIDE_REG_BCL
LD C , A
CALL PPIDE_IN
.DB PPIDE_REG_BCH
LD B , A
;
; BELOW ASSUMES MAX TRANSFER OF 512 BYTES!!!
PUSH BC ; SAVE BYTE COUNT
SRL B ; CONVERT
RR C ; ... TO WORDS
LD B , C
;LD HL,HB_WRKBUF ; SET XFR BUFFER
LD HL ,( PPIDE_DSKBUF ) ; SET XFR BUFFER
LD A ,( PPIDE_XFRDIR )
OR A
JR NZ , PPIDE_RUNPCMD2 ; NZ = WRITE
CALL PPIDE_GET ; GET SOME DATA
JR PPIDE_RUNPCMD3
PPIDE_RUNPCMD2:
CALL PPIDE_PUT ; PUT SOME DATA
PPIDE_RUNPCMD3:
POP BC ; RESTORE BYTE COUNT
RET NZ ; BAIL OUT ON ERRORS
;
XOR A
RET
;
; THE FOLLOWING IS USED TO ASSESS ANY ERROR THAT OCCURS DURING
; RUNCMD AND SET AN APPROPRIATE ERROR CODE.
;
PPIDE_CHKPCMD:
;
LD HL , HB_WRKBUF
LD ( PPIDE_DSKBUF ), HL
LD HL , PPIDE_PKTCMD_SENSE
CALL PPIDE_RUNPCMD
RET NZ
;
CALL PPIDE_IN
.DB PPIDE_REG_BCL
;
# IF ( PPIDETRACE > = 3 )
CALL NEWLINE
LD DE , HB_WRKBUF
CALL PRTHEXBUF
# ENDIF
;
; ASSESS SENSE DATA AND SET APPROPRIATE ERROR
LD A ,( HB_WRKBUF + 12 )
CP $ 3 A
JP Z , PPIDE_NOMEDIA
CP $ 04
JP Z , PPIDE_NOTRDY
;
JP PPIDE_CMDERR
;
; HL=BUFFER
;
PPIDE_GETBUF:
LD B , 0
; FALL THRU!!!
;
; HL=BUFFER
; B=WORD COUNT, 0=256
;
PPIDE_GET:
# IF ( PPIDETRACE > = 3 )
PRTS ( " GETBUF$" )
PRTS ( " GET$" )
# ENDIF
;
; WAIT FOR BUFFER
PUSH BC
PUSH HL
CALL PPIDE_WAITDRQ ; WAIT FOR BUFFER READY
POP HL
POP BC
RET NZ ; BAIL OUT IF TIMEOUT
;
; SETUP PPI TO READ
LD A , PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ
;OUT (PPIDE_IO_PPI),A ; DO IT
;OUT (PPIDE_REG _PPI),A ; DO IT
LD C ,( IY + PPIDE_PPI ) ; PPI CONTROL WORD
OUT ( C ), A ; WRITE IT
;
; SELECT READ/WRITE IDE REGISTER
LD A , PPIDE_REG_DATA ; DATA REGISTER
;OUT (PPIDE_IO_CTL),A ; DO IT
;OUT (PPIDE_REG _CTL),A ; DO IT
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
OUT ( C ), A ; DO IT
LD E , A ; E := READ UNASSERTED
XOR PPIDE_CTL_DIOR ; SWAP THE READ LINE BIT
LD D , A ; D := READ ASSERTED
;
; LOOP SETUP
XOR A ; IMPORTANT, NEEDED FOR LOOP END COMPARISON
LD B , 0 ; 256 ITERATIONS
LD A , B ; LOOP COUNTER IN A
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
;
BIT 1 ,( IY + PPIDE_ACC ) ; 8 BIT?
JR Z , PPIDE_GETBUF1 ; IF NOT, DO 16 BIT
CALL PPIDE_GETBUF8 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_GETBUF8 ; SECOND PASS (LAST 256 BYTES)
JR PPIDE_GETBUF2 ; CONTINUE
PPIDE_GETBUF1:
CALL PPIDE_GETBUF16 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_GETBUF16 ; SECOND PASS (LAST 256 BYTES)
PPIDE_GETBUF2:
JR Z , PPIDE_GET1 ; IF NOT, DO 16 BIT
CALL PPIDE_GET8 ; 8-BIT READ
JR PPIDE_GET2 ; CONTINUE
PPIDE_GET1:
CALL PPIDE_GET16 ; 16-0BIT READ
PPIDE_GET2:
CALL PPIDE_WAITRDY ; PROBLEMS IF THIS IS REMOVED!
RET NZ
CALL PPIDE_GETRES
JP NZ , PPIDE_IOERR
RET
;
PPIDE_GETBUF8: ; 8 BIT WIDE READ LOOP
; ENTER W/ C = PPIDE_IO_CTL
PPIDE_GET8: ; 8 BIT WIDE READ LOOP
; ENTER W/ C = PPIDE_REG_CTL
OUT ( C ), D ; ASSERT READ
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
INI ; READ FROM LSB
INC C ; LSB -> MSB
INC C ; MSB -> CTL
OUT ( C ), E ; DEASSERT READ
OUT ( C ), D ; ASSERT READ
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
@ -926,12 +1119,12 @@ PPIDE_GETBUF8: ; 8 BIT WIDE READ LOOP
INC C ; LSB -> MSB
INC C ; MSB -> CTL
OUT ( C ), E ; DEASSERT READ
CP B ; B == A == 0?
JR NZ , PPIDE_GETBUF 8 ; LOOP UNTIL DONE
DE C A
JR NZ , PPIDE_GET8 ; LOOP UNTIL DONE
RET
;
PPIDE_GETBUF 16: ; 16 BIT WIDE READ LOOP
; ENTER W/ C = PPIDE_IO _CTL
PPIDE_GET16: ; 16 BIT WIDE READ LOOP
; ENTER W/ C = PPIDE_REG _CTL
OUT ( C ), D ; ASSERT READ
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
@ -940,30 +1133,41 @@ PPIDE_GETBUF16: ; 16 BIT WIDE READ LOOP
INI ; READ MSB FOR 16 BIT
INC C ; MSB -> CTL
OUT ( C ), E ; DEASSERT READ
CP B ; B == A == 0?
JR NZ , PPIDE_GETBUF 16 ; LOOP UNTIL DONE
DE C A
JR NZ , PPIDE_GET16 ; LOOP UNTIL DONE
RET
;
;
; HL=BUFFER
;
PPIDE_PUTBUF:
LD B , 0
; FALL THRU!!!
;
; HL=BUFFER
; B=WORD COUNT, 0=256
;
PPIDE_PUT:
# IF ( PPIDETRACE > = 3 )
PRTS ( " PUTBUF$" )
PRTS ( " PUT$" )
# ENDIF
;
; WAIT FOR BUFFER
PUSH BC
PUSH HL
CALL PPIDE_WAITDRQ ; WAIT FOR BUFFER READY
POP HL
POP BC
RET NZ ; BAIL OUT IF TIMEOUT
;
; SETUP PPI TO WRITE
LD A , PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE
;OUT (PPIDE_IO _PPI),A ; DO IT
;OUT (PPIDE_REG _PPI),A ; DO IT
LD C ,( IY + PPIDE_PPI ) ; PPI CONTROL WORD
OUT ( C ), A ; WRITE IT
;
; SELECT READ/WRITE IDE REGISTER
LD A , PPIDE_REG_DATA ; DATA REGISTER
;OUT (PPIDE_IO _CTL),A ; DO IT
;OUT (PPIDE_REG _CTL),A ; DO IT
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
OUT ( C ), A ; DO IT
LD E , A ; E := WRITE UNASSERTED
@ -971,26 +1175,22 @@ PPIDE_PUTBUF:
LD D , A ; D := WRITE ASSERTED
;
; LOOP SETUP
XOR A ; IMPORTANT, NEEDED FOR LOOP END COMPARISON
LD B , 0 ; 256 ITERATIONS
LD A , B ; LOOP COUNTER IN A
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
;
BIT 1 ,( IY + PPIDE_ACC ) ; 8 BIT?
JR Z , PPIDE_PUTBUF1 ; IF NOT, DO 16 BIT
CALL PPIDE_PUTBUF8 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_PUTBUF8 ; SECOND PASS (LAST 256 BYTES)
JR PPIDE_PUTBUF2 ; CONTINUE
PPIDE_PUTBUF1:
CALL PPIDE_PUTBUF16 ; FIRST PASS (FIRST 256 BYTES)
CALL PPIDE_PUTBUF16 ; SECOND PASS (LAST 256 BYTES)
PPIDE_PUTBUF2:
JR Z , PPIDE_PUT1 ; IF NOT, DO 16 BIT
CALL PPIDE_PUT8 ; SECOND PASS (LAST 256 BYTES)
JR PPIDE_PUT2 ; CONTINUE
PPIDE_PUT1:
CALL PPIDE_PUT16 ; FIRST PASS (FIRST 256 BYTES)
PPIDE_PUT2:
CALL PPIDE_WAITRDY ; PROBLEMS IF THIS IS REMOVED!
RET NZ
CALL PPIDE_GETRES
JP NZ , PPIDE_IOERR
RET
;
PPIDE_PUTBUF 8: ; 8 BIT WIDE WRITE LOOP
PPIDE_PUT8: ; 8 BIT WIDE WRITE LOOP
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
OUTI ; WRITE NEXT BYTE (LSB)
@ -998,11 +1198,18 @@ PPIDE_PUTBUF8: ; 8 BIT WIDE WRITE LOOP
INC C ; MSB -> CTL
OUT ( C ), D ; ASSERT WRITE
OUT ( C ), E ; DEASSERT WRITE
CP B ; B == A == 0?
JR NZ , PPIDE_PUTBUF8 ; LOOP UNTIL DONE
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
OUTI ; WRITE NEXT BYTE (LSB)
INC C ; LSB -> MSB
INC C ; MSB -> CTL
OUT ( C ), D ; ASSERT WRITE
OUT ( C ), E ; DEASSERT WRITE
DEC A
JR NZ , PPIDE_PUT8 ; LOOP UNTIL DONE
RET
;
PPIDE_PUTBUF16: ; 16 BIT WIDE WRITE LOOP
PPIDE_PUT16: ; 16 BIT WIDE WRITE LOOP
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
OUTI ; WRITE NEXT BYTE (LSB)
@ -1011,8 +1218,8 @@ PPIDE_PUTBUF16: ; 16 BIT WIDE WRITE LOOP
INC C ; MSB -> CTL
OUT ( C ), D ; ASSERT WRITE
OUT ( C ), E ; DEASSERT WRITE
CP B ; B == A == 0?
JR NZ , PPIDE_PUTBUF 16 ; LOOP UNTIL DONE
DE C A
JR NZ , PPIDE_PUT16 ; LOOP UNTIL DONE
RET
;
;
@ -1057,7 +1264,7 @@ PPIDE_RESET:
;
; SETUP PPI TO READ
LD A , PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ
;OUT (PPIDE_IO _PPI),A ; DO IT
;OUT (PPIDE_REG _PPI),A ; DO IT
LD C ,( IY + PPIDE_PPI ) ; PPI CONTROL WORD
OUT ( C ), A ; WRITE IT
;
@ -1082,13 +1289,13 @@ PPIDE_RESET:
PRTS ( " HARD$" )
# ENDIF
LD A , PPIDE_CTL_RESET
;OUT (PPIDE_IO _CTL),A
;OUT (PPIDE_REG _CTL),A
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
OUT ( C ), A
LD DE , 20 ; DELAY 320US (SPEC IS >= 25US)
CALL VDELAY
XOR A
;OUT (PPIDE_IO _CTL),A
;OUT (PPIDE_REG _CTL),A
OUT ( C ), A
LD DE , 20
CALL VDELAY
@ -1125,7 +1332,7 @@ PPIDE_RESET2:
PRTS ( " SOFT$" )
# ENDIF
LD A , % 00001110 ; ASSERT RESET, NO INTERRUPTS
;OUT (PPIDE_IO _CTRL),A
;OUT (PPIDE_REG _CTRL),A
CALL PPIDE_OUT
.DB PPIDE_REG_CTRL
LD DE , 20 ; DELAY 320US (SPEC IS >= 25US)
@ -1224,7 +1431,7 @@ PPIDE_PROBE:
;
; SELECT DEVICE (MASTER/SLAVE)
LD A ,( PPIDE_DRVHD )
;OUT (IDE_IO _DRVHD),A
;OUT (IDE_REG _DRVHD),A
CALL PPIDE_OUT
.DB PPIDE_REG_DRVHD
# IF ( PPIDETRACE > = 3 )
@ -1275,7 +1482,7 @@ PPIDE_PROBE:
;
; 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 TG HE 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.
;
@ -1326,14 +1533,24 @@ PPIDE_INITDEV:
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.
; WE NOW USE AN IDENTIFY DEVICE COMMAND TO ENSURE WE HAVE A WORKING
; DEVICE. NO DATA IS RETRIEVED BECAUSE WE HAVE NOT YET ESTABLISHED
; 8/16 BIT I/O MODE. IF THE DEVICE IS ATAPI, IT WILL RETURN A
; COMMAND ABORTED ERROR BY DESIGN. IF THAT HAPPENS, WE GO TO THE
; ATAPI INITIALIZATION AND TRY THAT. IDEALLY, WE WOULD CHECK FOR
; THE PACKET DEVICE SIGNATURE.
;
LD A , PPIDE_CMD_IDDEV ; IDENTIFY DEVICE CMD
LD ( PPIDE_CMD ), A ; SAVE IT
CALL PPIDE_RUNCMD_ND ; RUN COMMAND
JR NZ , PPIDE_INITPDEV ; ON ERROR, TRY PACKET DEVICE
;
; IF THE SLAVE DEVICE IS SELECTED, BUT DOES NOT EXIST, THEN THE MASTER
; DEVICE WILL FORCE THE STATUS BYTE TO BE ZERO. AS SUCH, THE IDENTIFY
; DEVICE COMMAND ABOVE WILL APPEAR TO SUCCEED. AT THIS POINT, WE
; EXPLICITLY CHECK FOR A STATUS OF ZERO. IF SO, WE CONVERT THIS TO
; A NO MEDIA ERROR.
;
CALL PPIDE_NOP
CALL PPIDE_IN
.DB PPIDE_REG_STAT
OR A
@ -1341,7 +1558,6 @@ PPIDE_INITDEV:
;
; 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
@ -1359,7 +1575,7 @@ PPIDE_INITDEV0:
PPIDE_INITDEV00:
;
CALL PPIDE_IDENTIFY ; EXECUTE PPIDENTIFY COMMAND
JR NZ , PPIDE_INITDEVP ; ON ERROR, TRY PACKET DEVICE
RET NZ ; BAIL OUT ON ERROR
;
; DECLARE WE ARE ATA
LD A , PPIDE_TYPEATA ; OTHERWISE TYPE=ATA
@ -1371,13 +1587,6 @@ PPIDE_INITDEV00:
# ENDIF
;
LD ( IY + PPIDE_MED ), 0 ; CLEAR MEDIA FLAGS
;
; DETERMINE IF CF DEVICE BY TESTING FOR CF CARD SIGNATURES
; IN THEORY, THERE ARE SOME OTHER POSSIBLE VARIATIONS, BUT
; THEY ARE NOT RECOMMENDED BY THE CF CARD SPEC AND MIGHT
; OVERLAP WITH "REAL" HARD DISK SIGNATURES. I HAVE NEVER
; SEEN A CF CARD THAT DID NOT USE ONE OF THE BELOW.
; CREDIT TO LASZLO SZOLNOKI
;
# IF ( PPIDETRACE > = 3 )
CALL PPIDE_PRTPREFIX
@ -1417,9 +1626,9 @@ PPIDE_INITDEV2:
;
RET ; RETURN, A=0, Z SET
;
; (RE)INITIALIZE PACKET DEVICE
;
;
PPIDE_INITDEVP:
PPIDE_INITPDEV:
CALL PPIDE_IDENTIFYPACKET ; EXECUTE IDENTIFY COMMAND
RET NZ ; BAIL OUT ON ERROR
;
@ -1432,17 +1641,94 @@ PPIDE_INITDEVP:
CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
# ENDIF
;
LD ( IY + PPIDE_MED ), 0 ; CLEAR FLAGS
LD ( IY + PPIDE_MED ), 0 ; CLEAR FLAGS
SET 1 ,( IY + PPIDE_MED ) ; SET FLAGS BIT FOR LBA (ASSUMED)
;
; WAIT FOR UNIT READY
LD B , 0 ; MAX LOOPS
LD C , 4 ; MAX ERRORS
PPIDE_INITPDEV1:
DEC B ; CHECK LOOP COUNTER EXCEEDED
JP Z , PPIDE_NOMEDIA ; TREAT AS NO MEDIA
PUSH BC ; SAVE LOOP CONTROL
LD HL , PPIDE_PKTCMD_TSTRDY ; TEST UNIT READY
XOR A ; READ DIRECTION
LD ( PPIDE_XFRDIR ), A ; SAVE IT
CALL PPIDE_RUNPCMD ; ISSUE PACKET COMMAND
CALL NZ , PPIDE_CHKPCMD ; IF ERROR, DIAGNOSE IT
POP BC ; RESTORE LOOP CONTROL
JR Z , PPIDE_INITPDEV2 ; IF NO ERROR, CONTINUE
CP PPIDE_STNOMEDIA ; EXPLICIT NO MEDIA RESULT?
RET Z ; EXIT REPORTING NO MEDIA
CP PPIDE_STNOTRDY ; BECOMING READY?
JR Z , PPIDE_INITPDEV1 ; IF SO, NOT AN ERROR, LOOP
DEC C ; DEC ERROR LIMIT
RET Z ; BAIL OUT LIMIT EXCEEDED
JR PPIDE_INITPDEV1 ; LOOP
;
PPIDE_INITPDEV2:
# IF ( PPIDETRACE > = 3 )
LD A , B
NEG
PRTS ( "\r\nLOOPS=$" )
CALL PRTHEXBYTE
# ENDIF
;
; DONE FOR NOW, ATAPI NOT INPLEMENTED
; GET AND RECORD CAPACITY
LD HL , HB_WRKBUF
LD ( PPIDE_DSKBUF ), HL
LD HL , PPIDE_PKTCMD_RDCAP
XOR A ; READ DIRECTION
LD ( PPIDE_XFRDIR ), A ; SAVE IT
CALL PPIDE_RUNPCMD
JP NZ , PPIDE_CHKPCMD
;
# IF ( PPIDETRACE > = 3 )
PRTS ( "\r\nRDCAP:$" )
LD A , 8
LD DE , HB_WRKBUF
CALL PRTHEXBUF
# ENDIF
;
; RETURN NOT SUPPORTED STATUS
JP PPIDE_NOTSUP ; NOT SUPPORTED
; CAPACITY IS RETURNED IN A 4 BYTE, BIG ENDIAN FIELD AND
; INDICATES THE LAST LBA VALUE. WE NEED TO CONVERT THIS TO
; LITTLE ENDIAN AND INCREMENT THE VALUE TO MAKE IT A CAPACITY
; COUNT INSTEAD OF A LAST LBA VALUE.
LD A , PPIDE_MEDCAP ; OFFSET IN CFG FOR CAPACITY
CALL LDHLIYA ; POINTER TO HL
PUSH HL ; SAVE IT
LD HL , HB_WRKBUF ; POINT TO VALUE IN CMD RESULT
CALL LD32 ; LOAD IT TO DE:HL
LD A , L ; FLIP BYTES
LD L , D ; ... BIG ENDIAN
LD D , A ; ... TO LITTLE ENDIAN
LD A , H
LD H , E
LD E , A
CALL INC32 ; INCREMENT TO FINAL VALUE
POP BC ; RECOVER SAVE LOCATION
CALL ST3 2 ; STORE VALUE
;
; CHECK BLOCK LENGTH. WE CURRENTLY ONLY SUPPORT 512 BYTE
; BLOCKS. CD-ROM DEVICES (WHICH USE 2k BLOCKS) WILL FAIL
; HERE AS NOT SUPPORTED.
LD HL , HB_WRKBUF + 4 ; POINT TO BLK SIZE IN RESULT
CALL LD32 ; LOAD IT TO DE:HL
; VALUE IS BIG ENDIAN, SO LH:ED MUST BE EXACTLY 0000:0200
LD A , L ; CHECK THAT LH
OR H ; ... IS ZERO
JP NZ , PPIDE_NOTSUP ; IF NOT, FAIL AS NOT SUP
LD A , D ; LOAD D
OR A ; SET FLAGS
JP NZ , PPIDE_NOTSUP ; IF NOT ZERO, FAIL AS NOT SUP
LD A , E ; LOAD E
CP 2 ; CHECK IT IF IS 2
JP NZ , PPIDE_NOTSUP ; IF NOT, FAIL AS NOT SUP
;
; ; RECORD STATUS OK
; XOR A ; A := 0 (STATUS = OK)
; LD (IY+PPIDE_STAT),A ; SAVE IT
; RET
; 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
;
@ -1535,19 +1821,19 @@ 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
;OUT (PPIDE_REG _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
;LD C,PPIDE_REG _CTL ; SETUP PORT TO WRITE
;LD C,(IY+PPIDE_CTL) ; 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
;IN A,(PPIDE_REG _DATALO) ; GET DATA VALUE FROM DEVICE
DEC C ; 4TS
DEC C ; 4TS
IN A ,( C ) ; GET DATA VALUE FROM DEVICE ; 12
@ -1569,13 +1855,13 @@ PPIDE_OUT:
PUSH BC ; SAVE INCOMING BC
PUSH AF ; PRESERVE INCOMING VALUE
LD A , PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE
;OUT (PPIDE_IO _PPI),A ; DO IT
;OUT (PPIDE_REG _PPI),A ; DO IT
LD C ,( IY + PPIDE_PPI ) ; PPI CONTROL WORD
OUT ( C ), A ; WRITE IT
POP AF ; RECOVER VALUE TO WRITE
;
LD B ,( HL ) ; GET IDE ADDRESS VALUE
;LD C,PPIDE_IO _CTL ; SETUP PORT TO WRITE
;LD C,PPIDE_REG _CTL ; SETUP PORT TO WRITE
;LD C,(IY+PPIDE_CTL) ; SET IDE ADDRESS
DEC C ; SET IDE ADDRESS
OUT ( C ), B ; SET ADDRESS LINES
@ -1584,7 +1870,7 @@ PPIDE_OUT:
;
DEC C
DEC C
;OUT (PPIDE_IO _DATALO),A ; SEND DATA VALUE TO DEVICE
;OUT (PPIDE_REG _DATALO),A ; SEND DATA VALUE TO DEVICE
OUT ( C ), A ; SEND DATA VALUE TO DEVICE
INC C
INC C
@ -1634,6 +1920,10 @@ PPIDE_NOTSUP:
LD A , PPIDE_STNOTSUP
JR PPIDE_ERR
;
PPIDE_NOTRDY:
LD A , PPIDE_STNOTRDY
JR PPIDE_ERR
;
PPIDE_ERR:
LD ( IY + PPIDE_STAT ), A ; SAVE NEW STATUS
;
@ -1706,6 +1996,9 @@ PPIDE_PRTSTATSTR:
INC A
LD DE , PPIDE_STR_STNOTSUP
JR Z , PPIDE_PRTSTATSTR1
INC A
LD DE , PPIDE_STR_STNOTRDY
JR Z , PPIDE_PRTSTATSTR1
LD DE , PPIDE_STR_STUNK
PPIDE_PRTSTATSTR1:
CALL WRITESTR
@ -1723,7 +2016,7 @@ PPIDE_REGDUMP:
CALL PC_SPACE
CALL PC_LBKT
LD A , PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ
;OUT (PPIDE_IO _PPI),A ; DO IT
;OUT (PPIDE_REG _PPI),A ; DO IT
LD C ,( IY + PPIDE_PPI ) ; PPI CONTROL WORD
OUT ( C ), A ; WRITE IT
LD C ,( IY + PPIDE_CTL ) ; SET IDE ADDRESS
@ -1731,12 +2024,12 @@ PPIDE_REGDUMP:
LD B , 7
PPIDE_REGDUMP1:
LD A , E ; REGISTER ADDRESS
;OUT (PPIDE_IO _CTL),A ; SET IT
;OUT (PPIDE_REG _CTL),A ; SET IT
OUT ( C ), A ; REGISTER ADDRESS
XOR PPIDE_CTL_DIOR ; SET BIT TO ASSERT READ LINE
;OUT (PPIDE_IO _CTL),A ; ASSERT READ
;OUT (PPIDE_REG _CTL),A ; ASSERT READ
OUT ( C ), A ; ASSERT READ
;IN A,(PPIDE_IO _DATALO) ; GET VALUE
;IN A,(PPIDE_REG _DATALO) ; GET VALUE
DEC C ; CTL -> MSB
DEC C ; MSB -> LSB
IN A ,( C ) ; GET VALUE
@ -1744,7 +2037,7 @@ PPIDE_REGDUMP1:
INC C ; MSB -> CTL
CALL PRTHEXBYTE ; DISPLAY IT
;LD A,C ; RELOAD ADDRESS W/ READ UNASSERTED
;OUT (PPIDE_IO _CTL),A ; AND SET IT
;OUT (PPIDE_REG _CTL),A ; AND SET IT
OUT ( C ), E ; RELOAD ADDRESS W/ READ UNASSERTED
;DEC C ; NEXT LOWER REGISTER
DEC E ; NEXT LOWER REGISTER
@ -1785,6 +2078,7 @@ 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_STNOTRDY .TEXT "NOT READY$"
PPIDE_STR_STUNK .TEXT "UNKNOWN ERROR$"
;
PPIDE_STR_NO .TEXT "NO$"
@ -1806,5 +2100,14 @@ PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK
;
PPIDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER
PPIDE_XFRDIR .DB 0 ; 0=READ, NON-0=WRITE
;
PPIDE_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT
;
; SCSI COMMAND TEMPLATES (ALWAYS 12 BYTES FOR ATAPI)
;
PPIDE_PKTCMD_RW .DB $ 00 , $ 00 , $ 00 , $ 00 , $ 01 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 ; READ/WRITE SECTOR
PPIDE_PKTCMD_SENSE .DB $ 03 , $ 00 , $ 00 , $ 00 , $ FF , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 ; REQUEST SENSE DATA
PPIDE_PKTCMD_RDCAP .DB $ 25 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 ; READ CAPACITY
PPIDE_PKTCMD_RW10 .DB $ 28 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 01 , $ 00 , $ 00 , $ 00 ; READ/WRITE SECTOR
PPIDE_PKTCMD_TSTRDY .DB $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 , $ 00 ; TEST UNIT READY