diff --git a/Source/HBIOS/Config/mk4_diskio3.asm b/Source/HBIOS/Config/mk4_diskio3.asm index 71984e4d..65523220 100644 --- a/Source/HBIOS/Config/mk4_diskio3.asm +++ b/Source/HBIOS/Config/mk4_diskio3.asm @@ -54,7 +54,7 @@ IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) ; PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) PPIDEIOB .EQU $20 ; PPIDE IOBASE -PPIDECNT .EQU 1 ; NUMBER OF PPIDE UNITS +PPIDECNT .EQU 2 ; NUMBER OF PPIDE UNITS PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) @@ -98,16 +98,16 @@ BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT ; ; 18.432MHz OSC @ FULL SPEED, 38.4Kbps ; -;Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 -;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) -;Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) -;Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -;Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT +Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 +Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) +Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) +Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT +Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT ; ; 18.432MHz OSC @ DOUBLE SPEED, 38.4Kbps ; -Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2 -Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) -Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) -Z180_ASCIB0 .EQU 21H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -Z180_ASCIB1 .EQU 21H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT +;Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2 +;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) +;Z180_IOWAIT .EQU 2 ; IO WAIT STATES TO INSERT (0-3) +;Z180_ASCIB0 .EQU 21H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT +;Z180_ASCIB1 .EQU 21H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT diff --git a/Source/HBIOS/Config/mk4_std.asm b/Source/HBIOS/Config/mk4_std.asm index 49ceab34..970b8838 100644 --- a/Source/HBIOS/Config/mk4_std.asm +++ b/Source/HBIOS/Config/mk4_std.asm @@ -48,7 +48,7 @@ RFCNT .EQU 1 ; NUMBER OF RAM FLOPPY UNITS IDEENABLE .EQU TRUE ; TRUE FOR IDE SUPPORT IDEMODE .EQU IDEMODE_MK4 ; IDEMODE_DIO, IDEMODE_DIDE, IDEMODE_MK4 IDECNT .EQU 2 ; NUMBER OF IDE UNITS -IDETRACE .EQU 2 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) +IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) IDE8BIT .EQU TRUE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) ; PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) @@ -92,16 +92,16 @@ BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT ; ; 18.432MHz OSC @ FULL SPEED, 38.4Kbps ; -;Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 -;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) -;Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) -;Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -;Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT +Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 +Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) +Z180_IOWAIT .EQU 0 ; IO WAIT STATES TO INSERT (0-3) +Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT +Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT ; ; 18.432MHz OSC @ DOUBLE SPEED, 38.4Kbps ; -Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2 -Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) -Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) -Z180_ASCIB0 .EQU 21H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -Z180_ASCIB1 .EQU 21H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT +;Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2 +;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) +;Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) +;Z180_ASCIB0 .EQU 21H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT +;Z180_ASCIB1 .EQU 21H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT diff --git a/Source/HBIOS/ide.asm b/Source/HBIOS/ide.asm index 4c7ec737..e4ca5844 100644 --- a/Source/HBIOS/ide.asm +++ b/Source/HBIOS/ide.asm @@ -5,6 +5,8 @@ ; ; TODO: ; - IMPLEMENT IDE_INITDEVICE +; - HANDLE SECONDARY INTERFACE ON DIDE +; - BREAK OUT IDE_SELECT FROM UNITSEL ; ; +-----------------------------------------------------------------------+ ; | CONTROL BLOCK REGISTERS | @@ -353,19 +355,13 @@ IDE_STATUS: ; IDE_MEDIA ; IDE_MEDIA: - CALL IDE_INITDEVICE ; RE-INIT SELECTED UNIT + CALL IDE_INITDEV ; RE-INIT SELECTED UNIT LD A,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD A,MID_NONE ; SIGNAL NO MEDA OR A ; SET FLAGS RET ; AND RETURN ; -; NEED TO IMPLEMENT BELOW!!!! -; -IDE_INITDEVICE: - XOR A - RET -; ; ; IDE_CAP: @@ -392,50 +388,6 @@ IDE_GEOM: ; FUNCTION SUPPORT ROUTINES ;============================================================================= ; -; SOFT RESET OF ALL DEVICES ON BUS -; -IDE_RESET: - LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES - OUT (IDE_IO_CTRL),A - LD DE,16 ; DELAY ~250US - CALL VDELAY - LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET - OUT (IDE_IO_CTRL),A - CALL DELAY ; SMALL DELAY - XOR A ; SIGNAL SUCCESS - RET ; RETURN -; -; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT -; UNIT IS SPECIFIED IN A -; -IDE_SELUNIT: - LD HL,IDE_UNIT ; POINT TO PREVIOUSLY SELECTED UNIT - CP (HL) ; SAME? - RET Z ; IF SO, NOTHING MORE TO DO - - CP IDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) - JP NC,IDE_INVUNIT ; HANDLE INVALID UNIT -; - ; NEW UNIT SELECTED, IMPLEMENT IT - LD (IDE_UNIT),A ; RECORD NEW UNIT NUMBER -; -#IF (IDEMODE == IDEMODE_DIDE) - ; SELECT PRIMARY/SECONDARY INTERFACE FOR DIDE HARDWARE -#ENDIF -; - AND $01 ; LS BIT DETERMINES MASTER/SLAVE - LD HL,IDE_DRVSEL - CALL ADDHLA - LD A,(HL) ; LOAD DRIVE/HEAD VALUE -; - OUT (IDE_IO_DRVHD),A ; SELECT DRIVE - LD (IDE_DRVHD),A ; UPDATE SHADOW REGISTER -; - ; SPEC REQUIRES 400NS DELAY BEFORE CHECKING STATUS REGISTER -; - XOR A - RET -; ; (RE)INITIALIZE DEVICE ; IDE_INITDEV: @@ -468,7 +420,7 @@ IDE_INITDEV: RET NZ ; BAIL OUT ON ERROR ; LD DE,(DIOBUF) ; POINT TO BUFFER - DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING + CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING ; ; GET DEVICE CAPACITY AND SAVE IT IDE_DPTR(IDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD @@ -489,62 +441,6 @@ IDE_INITDEV: ; ; ; -IDE_PROBE: - CALL IDE_SELUNIT ; SELECT UNIT - RET NZ ; ABORT ON ERROR - CALL DELAY -; - ; CHECK STATUS - IN A,(IDE_IO_STAT) ; GET STATUS - DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS - OR A ; SET FLAGS TO TEST FOR ZERO - JR NZ,IDE_PROBE0 ; CONTINUE IF NON-ZERO - DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR - RET ; AND DONE -; -IDE_PROBE0: - ;CALL IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR - ;RET NZ ; ABORT ON TIMEOUT -; - ;; CHECK STATUS - ;IN A,(IDE_IO_STAT) ; GET STATUS - ;DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS - ;OR A ; SET FLAGS TO TEST FOR ZERO - ;JR NZ,IDE_PROBE1 ; CONTINUE IF NON-ZERO - ;DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR - ;RET ; AND DONE -; -IDE_PROBE1: - ; CHECK SIGNATURE - DCALL PC_SPACE - IN A,(IDE_IO_COUNT) - DCALL PRTHEXBYTE - CP $01 - RET NZ - DCALL PC_SPACE - IN A,(IDE_IO_SECT) - DCALL PRTHEXBYTE - CP $01 - RET NZ - DCALL PC_SPACE - IN A,(IDE_IO_CYLLO) - DCALL PRTHEXBYTE - CP $00 - RET NZ - DCALL PC_SPACE - IN A,(IDE_IO_CYLHI) - DCALL PRTHEXBYTE - CP $00 - RET NZ -; - ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS - IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD (HL),IDE_TYPEATA ; SET THE DEVICE TYPE - XOR A ; SIGNAL SUCCESS - RET ; DONE, NOTE THAT A=0 AND Z IS SET -; -; -; IDE_SETFEAT: PUSH AF #IF (IDETRACE >= 3) @@ -624,18 +520,6 @@ IDE_WRSEC: ; ; ; -IDE_CHKDEVICE: - IDE_DPTR(IDE_STAT) - LD A,(HL) - OR A - RET Z ; RETURN IF ALL IS WELL -; - ; ATTEMPT TO REINITIALIZE HERE??? - JP IDE_ERR - RET -; -; -; IDE_SETADDR: ; SEND 3 LOWEST BYTES OF LBA IN REVERSE ORDER ; IDE_IO_LBA3 HAS ALREADY BEEN SET BY IDE_SELECT @@ -673,7 +557,9 @@ IDE_SETADDR1: ; RET ; -; +;============================================================================= +; COMMAND PROCESSING +;============================================================================= ; IDE_RUNCMD: CALL IDE_WAITRDY ; WAIT FOR DRIVE READY @@ -709,8 +595,20 @@ IDE_GETBUF: #IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) LD C,IDE_IO_DATA - INIR - INIR +; INIR +; INIR +IDE_GETBUF1: + ;IN A,(IDE_IO_DATA) + ;CALL PRTHEXBYTE + CALL DELAY + INI + JR NZ,IDE_GETBUF1 +IDE_GETBUF2: + ;IN A,(IDE_IO_DATA) + ;CALL PRTHEXBYTE + CALL DELAY + INI + JR NZ,IDE_GETBUF2 #ELSE LD C,IDE_IO_DATAHI IDE_GETBUF1: @@ -756,6 +654,156 @@ IDE_PUTBUF1: ; ; ; +IDE_GETRES: + IN A,(IDE_IO_STAT) ; GET STATUS + DCALL PC_SPACE + DCALL PRTHEXBYTE + AND %00000001 ; ERROR BIT SET? + RET Z ; NOPE, RETURN WITH ZF +; + IN A,(IDE_IO_ERR) ; READ ERROR REGISTER + DCALL PC_SPACE + DCALL PRTHEXBYTE + OR $FF ; FORCE NZ TO SIGNAL ERROR + RET ; RETURN +; +;============================================================================= +; HARDWARE INTERFACE ROUTINES +;============================================================================= +; +; SOFT RESET OF ALL DEVICES ON BUS +; +IDE_RESET: +; +#IF (PLATFORM == PLT_MK4) + LD A,$80 ; HIGH BIT OF XAR IS IDE RESET + OUT (MK4_XAR),A + LD DE,16 ; DELAY ~250US + CALL VDELAY + XOR A ; CLEAR RESET BIT + OUT (MK4_XAR),A +#ELSE + LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES + OUT (IDE_IO_CTRL),A +#ENDIF +; + LD DE,16 ; DELAY ~250US + CALL VDELAY + LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET + OUT (IDE_IO_CTRL),A + LD DE,16 ; DELAY ~250US + CALL VDELAY + XOR A ; SIGNAL SUCCESS + RET ; RETURN +; +; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT +; UNIT IS SPECIFIED IN A +; +IDE_SELUNIT: +; LD HL,IDE_UNIT ; POINT TO PREVIOUSLY SELECTED UNIT +; CP (HL) ; SAME? +; RET Z ; IF SO, NOTHING MORE TO DO + + CP IDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) + JP NC,IDE_INVUNIT ; HANDLE INVALID UNIT +; + ; NEW UNIT SELECTED, IMPLEMENT IT + LD (IDE_UNIT),A ; RECORD NEW UNIT NUMBER +; +#IF (IDEMODE == IDEMODE_DIDE) + ; SELECT PRIMARY/SECONDARY INTERFACE FOR DIDE HARDWARE +#ENDIF +; + AND $01 ; LS BIT DETERMINES MASTER/SLAVE + LD HL,IDE_DRVSEL + CALL ADDHLA + LD A,(HL) ; LOAD DRIVE/HEAD VALUE +; + OUT (IDE_IO_DRVHD),A ; SELECT DRIVE + LD (IDE_DRVHD),A ; UPDATE SHADOW REGISTER +; + ; SPEC REQUIRES 400NS DELAY BEFORE CHECKING STATUS REGISTER +; + XOR A + RET +; +; +; +IDE_PROBE: + CALL IDE_SELUNIT ; SELECT UNIT + RET NZ ; ABORT ON ERROR +; + ;CALL LDELAY + LD DE,$2000 ; DELAY N * 16US (~128MS) + CALL VDELAY +; + ;; WAIT FOR READY... + ;CALL PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR + ;RET NZ ; ABORT ON TIMEOUT +; + ; CHECK STATUS + IN A,(IDE_IO_STAT) ; GET STATUS + DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS + OR A ; SET FLAGS TO TEST FOR ZERO + JR NZ,IDE_PROBE0 ; CONTINUE IF NON-ZERO + DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR + RET ; AND DONE +; +IDE_PROBE0: + ;CALL IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR + ;RET NZ ; ABORT ON TIMEOUT +; + ;; CHECK STATUS + ;IN A,(IDE_IO_STAT) ; GET STATUS + ;DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS + ;OR A ; SET FLAGS TO TEST FOR ZERO + ;JR NZ,IDE_PROBE1 ; CONTINUE IF NON-ZERO + ;DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR + ;RET ; AND DONE +; +IDE_PROBE1: + ; CHECK SIGNATURE + DCALL PC_SPACE + IN A,(IDE_IO_COUNT) + DCALL PRTHEXBYTE + CP $01 + RET NZ + DCALL PC_SPACE + IN A,(IDE_IO_SECT) + DCALL PRTHEXBYTE + CP $01 + RET NZ + DCALL PC_SPACE + IN A,(IDE_IO_CYLLO) + DCALL PRTHEXBYTE + CP $00 + RET NZ + DCALL PC_SPACE + IN A,(IDE_IO_CYLHI) + DCALL PRTHEXBYTE + CP $00 + RET NZ +; + ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS + IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED + LD (HL),IDE_TYPEATA ; SET THE DEVICE TYPE + XOR A ; SIGNAL SUCCESS + RET ; DONE, NOTE THAT A=0 AND Z IS SET +; +; +; +IDE_CHKDEVICE: + IDE_DPTR(IDE_STAT) + LD A,(HL) + OR A + RET Z ; RETURN IF ALL IS WELL +; + ; ATTEMPT TO REINITIALIZE HERE??? + JP IDE_ERR + RET +; +; +; IDE_WAITRDY: LD B,15 ; ~15 SECOND TIMEOUT? IDE_WAITRDY1: @@ -813,26 +861,6 @@ IDE_WAITBSY2: DJNZ IDE_WAITBSY1 JP IDE_BSYTO ; EXIT WITH BSYTO ERR ; -; -; -IDE_GETRES: - IN A,(IDE_IO_STAT) ; GET STATUS - DCALL PC_SPACE - DCALL PRTHEXBYTE - AND %00000001 ; ERROR BIT SET? - RET Z ; NOPE, RETURN WITH ZF -; - IN A,(IDE_IO_ERR) ; READ ERROR REGISTER - DCALL PC_SPACE - DCALL PRTHEXBYTE - OR $FF ; FORCE NZ TO SIGNAL ERROR - RET ; RETURN -; -;============================================================================= -; HARDWARE INTERFACE ROUTINES -;============================================================================= -; -; ;============================================================================= ; ERROR HANDLING AND DIAGNOSTICS ;============================================================================= @@ -940,7 +968,9 @@ IDE_REGDUMP1: IN A,(C) CALL PRTHEXBYTE DEC C - DJNZ IDE_REGDUMP1 + DEC B + CALL NZ,PC_SPACE + JR NZ,IDE_REGDUMP1 CALL PC_RBKT POP BC POP AF @@ -1002,9 +1032,10 @@ IDE_STR_NO .TEXT "NO$" IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK ; +IDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO +; ; UNIT SPECIFIC DATA STORAGE ; -IDE_UNIT .DB -1 ; ACTIVE UNIT, INIT TO -1 TO INDICATE NOTHING SELECTED IDE_UDATA .FILL IDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES IDE_DLEN .EQU $ - IDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS IDE_UDLEN .EQU IDE_DLEN / IDE_UNITCNT ; LENGTH OF PER UNIT DATA diff --git a/Source/HBIOS/ppide.asm b/Source/HBIOS/ppide.asm index ac6d16a2..885d46f5 100644 --- a/Source/HBIOS/ppide.asm +++ b/Source/HBIOS/ppide.asm @@ -1,720 +1,1210 @@ ; -;================================================================================================== +;============================================================================= ; PPIDE DISK DRIVER -;================================================================================================== +;============================================================================= +; +; TODO: +; - IMPLEMENT PPIDE_INITDEVICE +; - BREAK OUT PPIDE_SELECT FROM UNITSEL +; +; +PPIDE_IO_DATALO .EQU PPIDEIOB + 0 ; IDE DATA BUS LSB (8255 PORT A) +PPIDE_IO_DATAHI .EQU PPIDEIOB + 1 ; IDE DATA BUS MSB (8255 PORT B) +PPIDE_IO_CTL .EQU PPIDEIOB + 2 ; IDE ADDRESS BUS AND CONTROL SIGNALS (8255 PORT C) +PPIDE_IO_PPI .EQU PPIDEIOB + 3 ; 8255 CONTROL PORT +; +; THE CONTROL PORT OF THE 8255 IS PROGRAMMED AS NEEDED TO READ OR WRITE +; DATA ON THE IDE BUS. PORT C OF THE 8255 IS ALWAYS IN OUTPUT MODE BECAUSE +; IT IS DRIVING THE ADDRESS BUS AND CONTROL SIGNALS. PORTS A & B WILL BE +; PLACED IN READ OR WRITE MODE DEPENDING ON THE DIRECTION OF THE DATA BUS. +; +PPIDE_DIR_READ .EQU %10010010 ; IDE BUS DATA INPUT MODE +PPIDE_DIR_WRITE .EQU %10000000 ; IDE BUS DATA OUTPUT MODE +; +; PORT C OF THE 8255 IS USED TO DRIVE THE IDE INTERFACE ADDRESS BUS +; AND VARIOUS CONTROL SIGNALS. THE CONSTANTS BELOW REFLECT THESE +; ASSIGNMENTS. +; +PPIDE_CTL_DA0 .EQU %00000001 ; DRIVE ADDRESS BUS - BIT 0 (DA0) +PPIDE_CTL_DA1 .EQU %00000010 ; DRIVE ADDRESS BUS - BIT 1 (DA1) +PPIDE_CTL_DA2 .EQU %00000100 ; DRIVE ADDRESS BUS - BIT 2 (DA2) +PPIDE_CTL_CS1FX .EQU %00001000 ; DRIVE CHIP SELECT 0 (ACTIVE LOW, INVERTED) +PPIDE_CTL_CS3FX .EQU %00010000 ; DRIVE CHIP SELECT 1 (ACTIVE LOW, INVERTED) +PPIDE_CTL_DIOW .EQU %00100000 ; DRIVE I/O WRITE (ACTIVE LOW, INVERTED) +PPIDE_CTL_DIOR .EQU %01000000 ; DRIVE I/O READ (ACTIVE LOW, INVERTED) +PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) +; +; +-----------------------------------------------------------------------+ +; | CONTROL BLOCK REGISTERS (CS3FX) | +; +-----------------------+-------+-------+-------------------------------+ +; | REGISTER | PORT | DIR | DESCRIPTION | +; +-----------------------+-------+-------+-------------------------------+ +; | PPIDE_REG_ALTSTAT | 0x06 | R | ALTERNATE STATUS REGISTER | +; | PPIDE_REG_CTRL | 0x06 | W | DEVICE CONTROL REGISTER | +; | PPIDE_REG_DRVADR | 0x07 | R | DRIVE ADDRESS REGISTER | +; +-----------------------+-------+-------+-------------------------------+ +; +; +-----------------------+-------+-------+-------------------------------+ +; | COMMAND BLOCK REGISTERS (CS1FX) | +; +-----------------------+-------+-------+-------------------------------+ +; | REGISTER | PORT | DIR | DESCRIPTION | +; +-----------------------+-------+-------+-------------------------------+ +; | PPIDE_REG_DATA | 0x00 | R/W | DATA INPUT/OUTPUT | +; | PPIDE_REG_ERR | 0x01 | R | ERROR REGISTER | +; | PPIDE_REG_FEAT | 0x01 | W | FEATURES REGISTER | +; | PPIDE_REG_COUNT | 0x02 | R/W | SECTOR COUNT REGISTER | +; | PPIDE_REG_SECT | 0x03 | R/W | SECTOR NUMBER REGISTER | +; | PPIDE_REG_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) | +; | PPIDE_REG_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) | +; | PPIDE_REG_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER | +; | PPIDE_REG_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | +; | PPIDE_REG_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) | +; | PPIDE_REG_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) | +; | PPIDE_REG_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) | +; | PPIDE_REG_STAT | 0x07 | R | STATUS REGISTER | +; | PPIDE_REG_CMD | 0x07 | W | COMMAND REGISTER (EXECUTE) | +; +-----------------------+-------+-------+-------------------------------+ +; * LBA0-4 ARE ALTERNATE DEFINITIONS OF SECT, CYL, AND DRVHD PORTS +; +; === STATUS REGISTER === +; +; 7 6 5 4 3 2 1 0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; BSY: BUSY +; DRDY: DRIVE READY +; DWF: DRIVE WRITE FAULT +; DSC: DRIVE SEEK COMPLETE +; DRQ: DATA REQUEST +; CORR: CORRECTED DATA +; IDX: INDEX +; ERR: ERROR +; +; === ERROR REGISTER === +; +; 7 6 5 4 3 2 1 0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER) +; +; BBK: BAD BLOCK DETECTED +; UNC: UNCORRECTABLE DATA ERROR +; MC: MEDIA CHANGED +; IDNF: ID NOT FOUND +; MCR: MEDIA CHANGE REQUESTED +; ABRT: ABORTED COMMAND +; TK0NF: TRACK 0 NOT FOUND +; AMNF: ADDRESS MARK NOT FOUND +; +; === DRIVE/HEAD / LBA3 REGISTER === +; +; 7 6 5 4 3 2 1 0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING +; DRV: 0 = DRIVE 0 (PRIMARY) SELECTED, 1 = DRIVE 1 (SLAVE) SELECTED +; HS: CHS = HEAD ADDRESS (0-15), LBA = BITS 24-27 OF LBA +; +; === DEVICE CONTROL REGISTER === +; +; 7 6 5 4 3 2 1 0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | X | X | X | X | 1 | SRST | ~IEN | 0 | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; SRST: SOFTWARE RESET +; ~IEN: INTERRUPT ENABLE +; +; CONTROL VALUES TO USE WHEN ACCESSING THE VARIOUS IDE DEVICE REGISTERS +; +PPIDE_REG_DATA .EQU PPIDE_CTL_CS1FX | $00 ; DATA INPUT/OUTPUT (R/W) +PPIDE_REG_ERR .EQU PPIDE_CTL_CS1FX | $01 ; ERROR REGISTER (R) +PPIDE_REG_FEAT .EQU PPIDE_CTL_CS1FX | $01 ; FEATURES REGISTER (W) +PPIDE_REG_COUNT .EQU PPIDE_CTL_CS1FX | $02 ; SECTOR COUNT REGISTER (R/W) +PPIDE_REG_SECT .EQU PPIDE_CTL_CS1FX | $03 ; SECTOR NUMBER REGISTER (R/W) +PPIDE_REG_CYLLO .EQU PPIDE_CTL_CS1FX | $04 ; CYLINDER NUM REGISTER (LSB) (R/W) +PPIDE_REG_CYLHI .EQU PPIDE_CTL_CS1FX | $05 ; CYLINDER NUM REGISTER (MSB) (R/W) +PPIDE_REG_DRVHD .EQU PPIDE_CTL_CS1FX | $06 ; DRIVE/HEAD REGISTER (R/W) +PPIDE_REG_LBA0 .EQU PPIDE_CTL_CS1FX | $03 ; LBA BYTE 0 (BITS 0-7) (R/W) +PPIDE_REG_LBA1 .EQU PPIDE_CTL_CS1FX | $04 ; LBA BYTE 1 (BITS 8-15) (R/W) +PPIDE_REG_LBA2 .EQU PPIDE_CTL_CS1FX | $05 ; LBA BYTE 2 (BITS 16-23) (R/W) +PPIDE_REG_LBA3 .EQU PPIDE_CTL_CS1FX | $06 ; LBA BYTE 3 (BITS 24-27) (R/W) +PPIDE_REG_STAT .EQU PPIDE_CTL_CS1FX | $07 ; STATUS REGISTER (R) +PPIDE_REG_CMD .EQU PPIDE_CTL_CS1FX | $07 ; COMMAND REGISTER (EXECUTE) (W) +PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3FX | $06 ; ALTERNATE STATUS REGISTER (R) +PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3FX | $06 ; DEVICE CONTROL REGISTER (W) +PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R) +; +#IF (PPIDETRACE >= 3) +#DEFINE DCALL CALL +#ELSE +#DEFINE DCALL \; +#ENDIF ; -; 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. +; UNIT MAPPING IS AS FOLLOWS: +; PPIDE0: PRIMARY MASTER +; PPIDE1: PRIMARY SLAVE +; PPIDE2: SECONDARY MASTER +; PPIDE3: SECONDARY SLAVE ; -; 12/02/2011 wbw - renamed DOUGDEBUG to PPIDESLOW and exposed in config -; PPIDESLOW now controls the RECOVERY macro definition. +PPIDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE ; -#IF (PPIDESLOW) -#DEFINE RECOVERY NOP\ NOP\ NOP\ NOP -#ELSE -#DEFINE RECOVERY ; -#ENDIF +; COMMAND BYTES ; -; 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_CMD_RECAL .EQU $10 +PPIDE_CMD_READ .EQU $20 +PPIDE_CMD_WRITE .EQU $30 +PPIDE_CMD_IDDEV .EQU $EC +PPIDE_CMD_SETFEAT .EQU $EF ; +; FEATURE BYTES ; +PPIDE_FEAT_ENABLE8BIT .EQU $01 +PPIDE_FEAT_DISABLE8BIT .EQU $81 ; -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 DEVICE TYPES ; -PPIDE_RD: - LD A,PPIDE_CMDREAD - LD (PPIDEP_CMD),A - JP PPIDE_RW +PPIDE_TYPEUNK .EQU 0 +PPIDE_TYPEATA .EQU 1 +PPIDE_TYPEATAPI .EQU 2 ; -PPIDE_WR: - LD A,PPIDE_CMDWRITE - LD (PPIDEP_CMD),A - JP PPIDE_RW +; PPIDE DEVICE STATUS ; -PPIDE_ST: - LD A,(PPIDE_STAT) ; LOAD STATUS - OR A ; SET FLAGS - RET +PPIDE_STOK .EQU 0 +PPIDE_STINVUNIT .EQU -1 +PPIDE_STNOMEDIA .EQU -2 +PPIDE_STCMDERR .EQU -3 +PPIDE_STIOERR .EQU -4 +PPIDE_STRDYTO .EQU -5 +PPIDE_STDRQTO .EQU -6 +PPIDE_STBSYTO .EQU -7 +; +; DRIVE SELECTION BYTES (FOR USE IN DRIVE/HEAD REGISTER) +; +PPIDE_DRVSEL: +PPIDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE +PPIDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE ; -PPIDE_MED: - LD A,C ; GET THE DEVICE/UNIT - AND $0F ; ISOLATE UNIT - CP PPIDECNT ; NUM UNITS - LD A,MID_HD ; ASSUME WE ARE OK - RET C ; RETURN - XOR A ; NO MEDIA - RET ; AND RETURN +; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN PPIDE_UNITDATA) +; SEE PPIDE_UNITDATA IN DATA STORAGE BELOW ; +PPIDE_STAT .EQU 0 ; LAST STATUS (1 BYTE) +PPIDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE) +PPIDE_CAPACITY .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES) ; +; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA +; +#DEFINE PPIDE_DPTR(FIELD) CALL PPIDE_DPTRIMP \ .DB FIELD +; +;============================================================================= +; INITIALIZATION ENTRY POINT +;============================================================================= ; PPIDE_INIT: - PRTS("PPIDE: IO=0x$") - LD A,IDELSB + PRTS("PPIDE: IO=0x$") ; LABEL FOR IO ADDRESS + LD A,PPIDEIOB CALL PRTHEXBYTE +#IF (PPIDE8BIT) + PRTS(" 8BIT$") +#ENDIF PRTS(" UNITS=$") - LD A,PPIDECNT + LD A,PPIDE_UNITCNT CALL PRTDECB +; + ; CLEAR OUT ALL DATA (FOR ALL UNITS) + LD HL,PPIDE_UDATA + LD BC,PPIDE_UDLEN + XOR A + CALL FILL +; + ; INITIALIZE THE PPIDE INTERFACE NOW + CALL PPIDE_RESET ; DO HARDWARE SETUP/INIT + JR NZ,PPIDE_INIT2 ; SKIP PROBING IF INTERFACE SETUP FAILS +; + ; INITIAL DEVICE PROBING (CHECKING SIGNATURES) + LD B,PPIDE_UNITCNT ; NUMBER OF UNITS TO TRY + LD C,0 ; UNIT INDEX FOR LOOP +PPIDE_INIT1: + LD A,C ; UNIT NUMBER TO A + DCALL PC_SPACE ; IF DEBUGGING, PRINT A SPACE + DCALL PC_LBKT ; IF DEBUGGING, PRINT LEFT BRACKET + PUSH BC + CALL PPIDE_PROBE ; PROBE FOR DEVICE PRESENCE + POP BC + DCALL PC_RBKT ; IF DEBUGGING, PRINT A RIGHT BRACKET + INC C ; NEXT UNIT + DJNZ PPIDE_INIT1 ; LOOP AS NEEDED +; + ; PRINT UNIT COUNT + PRTS(" UNITS=$") ; PRINT LABEL FOR UNIT COUNT + LD A,PPIDE_UNITCNT ; GET UNIT COUNT + CALL PRTDECB ; PRINT IT IN DECIMAL +; +PPIDE_INIT2: + ; CHECK FOR ZERO UNITS AND GET OUT IF SO! +; + ; DEVICE SETUP LOOP + LD B,A ; LOOP ONCE PER UNIT + LD C,0 ; C IS UNIT INDEX +PPIDE_INIT3: + PUSH BC ; SAVE LOOP CONTROL + LD A,C ; UNIT NUM TO ACCUM + CALL PPIDE_INITUNIT ; IF EXISTS (NZ), INIT UNIT +#IF (PPIDETRACE < 2) + CALL NZ,PPIDE_PRTSTAT ; IF ERROR, NOTIFY USER IF NOT DONE PREVIOUSLY +#ENDIF + POP BC ; RESTORE LOOP CONTROL + INC C ; INCREMENT UNIT INDEX + DJNZ PPIDE_INIT3 ; LOOP UNTIL DONE + RET ; INIT FINISHED +; +; INITIALIZE UNIT DESIGNATED IN ACCUM +; +PPIDE_INITUNIT: + CALL PPIDE_SELUNIT ; SELECT UNIT + RET NZ ; ABORT ON ERROR +; + CALL PPIDE_INITDEV ; INIT DEVICE; FILL DIOBUF W/ IDENTIFY RESULTS + RET NZ ; ABORT ON ERROR +; + CALL PPIDE_PRTPREFIX ; PRINT DEVICE PREFIX +; #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 +; + ; PRINT LBA/NOLBA + CALL PC_SPACE ; FORMATTING + LD HL,(DIOBUF) ; POINT TO BUFFER START + LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG + ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS + LD A,(HL) ; GET THE BYTE + BIT 1,A ; CHECK THE LBA BIT + LD DE,PPIDE_STR_NO ; POINT TO "NO" STRING + CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED + PRTS("LBA$") ; PRINT "LBA" REGARDLESS +; + ; PRINT STORAGE CAPACITY (BLOCK COUNT) + PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL + PPIDE_DPTR(PPIDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY + CALL LD32 ; GET THE CAPACITY VALUE + CALL PRTHEX32 ; PRINT HEX VALUE +; + ; PRINT STORAGE SIZE IN MB + PRTS(" SIZE=$") ; PRINT FIELD LABEL + LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB + CALL SRL32 ; RIGHT SHIFT + CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED) + PRTS("MB$") ; PRINT SUFFIX +; + XOR A ; SIGNAL SUCCESS + RET ; RETURN WITH A=0, AND Z SET +; +;============================================================================= +; FUNCTION DISPATCH ENTRY POINT +;============================================================================= +; +PPIDE_DISPATCH: + LD A,C ; DEVICE/UNIT TO A + AND $0F ; REMOVE DEVICE BITS LEAVING JUST UNIT ID + CALL PPIDE_SELUNIT ; SELECT DESIRED UNIT + RET NZ ; ABORT ON ERROR + LD A,B ; GET REQUESTED FUNCTION + AND $0F + JR Z,PPIDE_READ + DEC A + JR Z,PPIDE_WRITE + DEC A + JR Z,PPIDE_STATUS + DEC A + JR Z,PPIDE_MEDIA + DEC A + JR Z,PPIDE_CAP + DEC A + JR Z,PPIDE_GEOM + CALL PANIC +; +; +; +PPIDE_READ: + JP PPIDE_RDSEC +; +; +; +PPIDE_WRITE: + JP PPIDE_WRSEC +; +; +; +PPIDE_STATUS: + ; RETURN UNIT STATUS + PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED + LD A,(HL) ; GET STATUS OF SELECTED UNIT + OR A ; SET FLAGS + RET ; AND RETURN +; +; PPIDE_MEDIA +; +PPIDE_MEDIA: + CALL PPIDE_INITDEV ; RE-INIT SELECTED UNIT + LD A,MID_HD ; ASSUME WE ARE OK + RET Z ; RETURN IF GOOD INIT + LD A,MID_NONE ; SIGNAL NO MEDA + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +PPIDE_CAP: + PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT + CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL + LD BC,512 ; 512 BYTES PER BLOCK + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +; +; +PPIDE_GEOM: + ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS + ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE + CALL PPIDE_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC + LD L,H ; DIVPPIDE BY 256 FOR # TRACKS + LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL + LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT + LD E,16 ; SECTORS / TRACK = 16 + XOR A ; SIGNAL SUCCESS RET ; +;============================================================================= +; FUNCTION SUPPORT ROUTINES +;============================================================================= +; +; (RE)INITIALIZE DEVICE ; +PPIDE_INITDEV: ; -PPIDE_RW: - ; INIT REQUIRED? - LD A,(PPIDE_STAT) + PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED + LD A,(HL) ; GET THE DEVICE TYPE 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: + JP Z,PPIDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS +; + ; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING + ; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE + ; PROBES WHEN THE PPIDE BUS WAS RESET + PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE + PUSH HL ; SAVE UNIT TYPE FIELD POINTER + PPIDE_DPTR(0) ; SET HL TO START OF UNIT DATA + LD BC,PPIDE_UDLEN 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 + CALL FILL + POP HL ; RECOVER UNIT TYPE FIELD POINTER + POP AF ; RECOVER UNIT TYPE VALUE + LD (HL),A ; AND PUT IT BACK +; +#IF (PPIDE8BIT) + LD A,PPIDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO +#ELSE + LD A,PPIDE_FEAT_DISABLE8BIT ; FEATURE VALUE = DISABLE 8-BIT PIO #ENDIF - XOR A - RET + CALL PPIDE_SETFEAT ; SET FEATURE + RET NZ ; BAIL OUT ON ERROR ; + CALL PPIDE_IDENTIFY ; EXECUTE PPIDENTIFY COMMAND + RET NZ ; BAIL OUT ON ERROR ; + LD DE,(DIOBUF) ; POINT TO BUFFER + DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING ; -PPIDE_RESET: -#IF (PPIDETRACE >= 2) - CALL NEWLINE - PRTX(PPIDESTR_PREFIX) - PRTS(" RESET$") + ; GET DEVICE CAPACITY AND SAVE IT + PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD + PUSH HL ; SAVE POINTER + LD HL,(DIOBUF) ; POINT TO BUFFER START + LD A,120 ; OFFSET OF SECTOR COUNT + CALL ADDHLA ; POINT TO ADDRESS OF SECTOR COUNT + CALL LD32 ; LOAD IT TO DE:HL + POP BC ; RECOVER POINTER TO CAPACITY ENTRY + CALL ST32 ; SAVE CAPACITY +; + ; RESET CARD STATUS TO 0 (OK) + PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED + XOR A ; A := 0 (STATUS = OK) + LD (HL),A ; SAVE IT +; + RET ; RETURN, A=0, Z SET +; +; +; +PPIDE_SETFEAT: + PUSH AF +#IF (PPIDETRACE >= 3) + CALL PPIDE_PRTPREFIX + PRTS(" SETFEAT$") #ENDIF -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD + LD A,(PPIDE_DRVHD) + ;OUT (PPIDE_REG_DRVHD),A + CALL PPIDE_OUT + .DB PPIDE_REG_DRVHD + DCALL PC_SPACE + DCALL PRTHEXBYTE + POP AF + ;OUT (PPIDE_REG_FEAT),A ; SET THE FEATURE VALUE + CALL PPIDE_OUT + .DB PPIDE_REG_FEAT + DCALL PC_SPACE + DCALL PRTHEXBYTE + LD A,PPIDE_CMD_SETFEAT ; CMD = SETFEAT + LD (PPIDE_CMD),A ; SAVE IT + JP PPIDE_RUNCMD ; RUN COMMAND AND EXIT +; +; +; +PPIDE_IDENTIFY: +#IF (PPIDETRACE >= 3) + CALL PPIDE_PRTPREFIX + PRTS(" IDDEV$") #ENDIF - LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER - LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES - CALL PPIDE_WRITE ; DO IT - LD DE,16 ; DELAY ~250US - CALL VDELAY -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD + LD A,(PPIDE_DRVHD) + ;OUT (PPIDE_REG_DRVHD),A + CALL PPIDE_OUT + .DB PPIDE_REG_DRVHD + DCALL PC_SPACE + DCALL PRTHEXBYTE + LD A,PPIDE_CMD_IDDEV + LD (PPIDE_CMD),A + CALL PPIDE_RUNCMD + RET NZ + JP PPIDE_GETBUF ; EXIT THRU BUFRD +; +; +; +PPIDE_RDSEC: + CALL PPIDE_CHKDEVICE + RET NZ +; +#IF (PPIDETRACE >= 3) + CALL PPIDE_PRTPREFIX + PRTS(" READ$") #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 + LD A,(PPIDE_DRVHD) + ;OUT (PPIDE_REG_DRVHD),A + CALL PPIDE_OUT + .DB PPIDE_REG_DRVHD + DCALL PC_SPACE + DCALL PRTHEXBYTE -#IF (PPIDE8BIT) + ;LD HL,HSTLBA + ;CALL LD32 + ;CALL PRTHEX32 -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD -#ENDIF - CALL PPIDE_WAITRDY + CALL PPIDE_SETADDR ; SETUP CYL, TRK, HEAD + LD A,PPIDE_CMD_READ + LD (PPIDE_CMD),A + CALL PPIDE_RUNCMD + RET NZ -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD -#ENDIF - LD C,PPIDE_FEATURE ; IDE FEATURE REGISTER - LD A,01H ; VALUE := 1 - CALL PPIDE_WRITE ; DO IT + ;CALL NEWLINE + ;CALL PPIDE_REGDUMP + ;CALL PPIDE_GETBUF + ;LD DE,(DIOBUF) ; POINT TO BUFFER + ;CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING + ;CALL NEWLINE + ;CALL PPIDE_REGDUMP + ;CALL PANIC -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD + JP PPIDE_GETBUF +; +; +; +PPIDE_WRSEC: + CALL PPIDE_CHKDEVICE + RET NZ +; +#IF (PPIDETRACE >= 3) + CALL PPIDE_PRTPREFIX + PRTS(" WRITE$") #ENDIF - LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER - LD A,PPIDE_CMDSETFEAT ; SET FEATURE - CALL PPIDE_WRITE ; DO IT + LD A,(PPIDE_DRVHD) + OUT (PPIDE_REG_DRVHD),A + DCALL PC_SPACE + DCALL PRTHEXBYTE + CALL PPIDE_SETADDR ; SETUP CYL, TRK, HEAD + LD A,PPIDE_CMD_WRITE + LD (PPIDE_CMD),A + CALL PPIDE_RUNCMD + RET NZ + JP PPIDE_PUTBUF +; +; +; +PPIDE_SETADDR: + LD A,(HSTLBA + 2) + DCALL PC_SPACE + DCALL PRTHEXBYTE + CALL PPIDE_OUT + .DB PPIDE_REG_LBA2 -#IF (PPIDETRACE >= 2) - CALL PC_PERIOD -#ENDIF + LD A,(HSTLBA + 1) + DCALL PC_SPACE + DCALL PRTHEXBYTE + CALL PPIDE_OUT + .DB PPIDE_REG_LBA1 -#ENDIF + LD A,(HSTLBA + 0) + DCALL PC_SPACE + DCALL PRTHEXBYTE + CALL PPIDE_OUT + .DB PPIDE_REG_LBA0 - RET -; + LD A,1 + DCALL PC_SPACE + DCALL PRTHEXBYTE + CALL PPIDE_OUT + .DB PPIDE_REG_COUNT ; +#IF (DSKYENABLE) + CALL PPIDE_DSKY +#ENDIF ; -PPIDE_WAITRDY: - LD DE,0 ; TIMEOUT IS 250us * 65536 = 15 SECONDS -PPIDE_WBSY: - PUSH DE - LD DE,16 ; INNER LOOP DELAY IS ~250us (16us * 16) - 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 ; +;============================================================================= +; COMMAND PROCESSING +;============================================================================= ; +PPIDE_RUNCMD: + CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY + RET NZ ; BAIL OUT ON TIMEOUT +; + LD A,(PPIDE_CMD) ; GET THE COMMAND + DCALL PC_SPACE + DCALL PRTHEXBYTE + ;OUT (PPIDE_REG_CMD),A ; SEND IT (STARTS EXECUTION) + CALL PPIDE_OUT + .DB PPIDE_REG_CMD +#IF (PPIDETRACE >= 3) + PRTS(" -->$") +#ENDIF ; -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 + CALL PPIDE_WAITBSY ; WAIT FOR DRIVE READY (COMMAND DONE) + RET NZ ; BAIL OUT ON TIMEOUT ; - OR A ; CLEAR CF TO SIGNAL ERROR + CALL PPIDE_GETRES + JP NZ,PPIDE_CMDERR 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_GETBUF: +#IF (PPIDETRACE >= 3) + PRTS(" GETBUF$") +#ENDIF ; + ; WAIT FOR BUFFER + CALL PPIDE_WAITDRQ ; WAIT FOR BUFFER READY + RET NZ ; BAIL OUT IF TIMEOUT ; -PPIDE_BUFRD: ; SETUP PPI TO READ - LD A,RD_IDE_8255 ; READ CONFIG - OUT (PPICTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY + LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ + OUT (PPIDE_IO_PPI),A ; DO IT ; ; SELECT READ/WRITE IDE REGISTER - LD A,PPIDE_DATA ; DATA REGISTER - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY + LD A,PPIDE_REG_DATA ; DATA REGISTER + OUT (PPIDE_IO_CTL),A ; DO IT LD E,A ; E := READ UNASSERTED - XOR PPIDE_RD_LINE ; SWAP THE READ LINE BIT + XOR PPIDE_CTL_DIOR ; 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) + LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB) ; - CALL PPIDE_BUFRD1 ; FIRST PASS (FIRST 256 BYTES) - CALL PPIDE_BUFRD1 ; SECOND PASS (LAST 256 BYTES) +#IF (!PPIDE8BIT) + INC C ; PRE-INCREMENT C +#ENDIF +; + CALL PPIDE_GETBUF1 ; FIRST PASS (FIRST 256 BYTES) + CALL PPIDE_GETBUF1 ; SECOND PASS (LAST 256 BYTES) ; - ; CLEAN UP - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY + ;; CLEAN UP + ;XOR A ; ZERO A + ;OUT (PPIDE_IO_CTL),A ; RELEASE ALL BUS SIGNALS +; + CALL PPIDE_GETRES + JP NZ,PPIDE_IOERR RET ; -PPIDE_BUFRD1: ; START OF READ LOOP +PPIDE_GETBUF1: ; 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 + OUT (PPIDE_IO_CTL),A ; DO IT #IF (!PPIDE8BIT) - INC C ; LSB -> MSB + DEC C INI ; GET AND SAVE NEXT BYTE - RECOVERY ; OPTIONAL SMALL DELAY - PUSH AF - DEC C ; MSB -> LSB - POP AF + INC C ; LSB -> MSB #ENDIF + INI ; GET AND SAVE NEXT BYTE LD A,E ; DEASSERT READ - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY + OUT (PPIDE_IO_CTL),A ; DO IT ; - JR NZ,PPIDE_BUFRD1 ; LOOP UNTIL DONE + JR NZ,PPIDE_GETBUF1 ; LOOP UNTIL DONE RET ; ; ; -PPIDE_BUFWR: +PPIDE_PUTBUF: +#IF (PPIDETRACE >= 3) + PRTS(" PUTBUF$") +#ENDIF + + ; WAIT FOR BUFFER + CALL PPIDE_WAITDRQ ; WAIT FOR BUFFER READY + RET NZ ; BAIL OUT IF TIMEOUT + +; ; SETUP PPI TO WRITE - LD A,WR_IDE_8255 ; WRITE CONFIG - OUT (PPICTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY + LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE + OUT (PPIDE_IO_PPI),A ; DO IT ; ; SELECT READ/WRITE IDE REGISTER - LD A,PPIDE_DATA ; DATA REGISTER - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY + LD A,PPIDE_REG_DATA ; DATA REGISTER + OUT (PPIDE_IO_CTL),A ; DO IT LD E,A ; E := WRITE UNASSERTED - XOR PPIDE_WR_LINE ; SWAP THE WRITE LINE BIT + XOR PPIDE_CTL_DIOW ; SWAP THE READ 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) + LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB) +; +#IF (!PPIDE8BIT) + INC C ; PRE-INCREMENT C +#ENDIF ; - CALL PPIDE_BUFWR1 ; FIRST PASS (FIRST 256 BYTES) - CALL PPIDE_BUFWR1 ; SECOND PASS (LAST 256 BYTES) + CALL PPIDE_PUTBUF1 ; FIRST PASS (FIRST 256 BYTES) + CALL PPIDE_PUTBUF1 ; SECOND PASS (LAST 256 BYTES) ; - ; CLEAN UP - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY + ;; CLEAN UP + ;XOR A ; ZERO A + ;OUT (PPIDE_IO_CTL),A ; RELEASE ALL BUS SIGNALS +; + CALL PPIDE_GETRES + JP NZ,PPIDE_IOERR RET ; -PPIDE_BUFWR1: ; START OF WRITE LOOP - OUTI ; SEND NEXT BYTE OF BUFFER - RECOVERY ; OPTIONAL SMALL DELAY +PPIDE_PUTBUF1: ; START OF READ LOOP #IF (!PPIDE8BIT) - INC C ; LSB -> MSB - OUTI ; SEND NEXT BYTE OF BUFFER - PUSH AF - DEC C ; MSB -> LSB - POP AF - RECOVERY ; OPTIONAL SMALL DELAY + DEC C + OUTI ; PUT NEXT BYTE ON THE BUS (LSB) + INC C #ENDIF + OUTI + LD A,D ; ASSERT WRITE + OUT (PPIDE_IO_CTL),A ; DO IT + LD A,E ; DEASSERT WRITE + OUT (PPIDE_IO_CTL),A ; DO IT ; - ; 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 + JR NZ,PPIDE_PUTBUF1 ; 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 +PPIDE_GETRES: + ;IN A,(PPIDE_REG_STAT) ; READ STATUS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + DCALL PC_SPACE + DCALL PRTHEXBYTE + AND %00000001 ; ERROR BIT SET? + RET Z ; NOPE, RETURN WITH ZF +; + ;IN A,(PPIDE_REG_ERR) ; READ ERROR REGISTER + CALL PPIDE_IN + .DB PPIDE_REG_ERR + DCALL PC_SPACE + DCALL PRTHEXBYTE + OR $FF ; FORCE NZ TO SIGNAL ERROR + RET ; RETURN +; +;============================================================================= +; HARDWARE INTERFACE ROUTINES +;============================================================================= +; +; SOFT RESET OF ALL DEVICES ON BUS +; +PPIDE_RESET: + ; SETUP PPI TO READ + LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ + OUT (PPIDE_IO_PPI),A ; DO IT - ; SEND 3 BYTES OF LBA T:SS -> CYL:SEC (CC:S) - LD A,(HSTLBAHI) ; LBA HIGH LSB - LD (PPIDEP_CYLHI),A ; SAVE IT - LD C,PPIDE_CYL_MSB ; IDE CYL MSB REGISTER - CALL PPIDE_WRITE ; -> CYLINDER HI - LD A,(HSTLBALO + 1) ; LBA LOW MSB - LD (PPIDEP_CYLLO),A ; SAVE IT - LD C,PPIDE_CYL_LSB ; IDE CYL LSB REGISTER - CALL PPIDE_WRITE ; -> CYLINDER HI - LD A,(HSTLBALO) ; LBA LOW LSB - LD (PPIDEP_SEC),A ; SAVE IT - LD C,PPIDE_SECTOR ; IDE CYL LSB REGISTER - CALL PPIDE_WRITE ; -> CYLINDER HI + LD A,PPIDE_CTL_RESET + OUT (PPIDE_IO_CTL),A + LD DE,16 + ;LD DE,1024 + CALL VDELAY + XOR A + OUT (PPIDE_IO_CTL),A + LD DE,16 + ;LD DE,1024 + CALL VDELAY -#IF (DSKYENABLE) - CALL PPIDE_DSKY -#ENDIF + LD A,%00001010 ; SET ~IEN, NO INTERRUPTS + ;OUT (PPIDE_REG_CTRL),A + CALL PPIDE_OUT + .DB PPIDE_REG_CTRL + XOR A RET ; + ;LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES + ;;OUT (PPIDE_REG_CTRL),A + ;CALL PPIDE_OUT + ;.DB PPIDE_REG_CTRL + ;LD DE,16 ; DELAY ~250US + ;CALL VDELAY + ;;LD DE,1024 + ;;CALL VDELAY + ;LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET + ;;OUT (PPIDE_REG_CTRL),A + ;CALL PPIDE_OUT + ;.DB PPIDE_REG_CTRL + ;CALL DELAY ; SMALL DELAY + ;;LD DE,1024 + ;;CALL VDELAY + ;XOR A ; SIGNAL SUCCESS + ;RET ; RETURN +; +; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT +; UNIT IS SPECIFIED IN A +; +PPIDE_SELUNIT: + ;LD HL,PPIDE_UNIT ; POINT TO PREVIOUSLY SELECTED UNIT + ;CP (HL) ; SAME? + ;RET Z ; IF SO, NOTHING MORE TO DO + + CP PPIDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) + JP NC,PPIDE_INVUNIT ; HANDLE INVALID UNIT ; + ; NEW UNIT SELECTED, IMPLEMENT IT + LD (PPIDE_UNIT),A ; RECORD NEW UNIT NUMBER ; -PPIDE_READ: + AND $01 ; LS BIT DETERMINES MASTER/SLAVE + LD HL,PPIDE_DRVSEL + CALL ADDHLA + LD A,(HL) ; LOAD DRIVE/HEAD VALUE ; - ; 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 + ;OUT (PPIDE_REG_DRVHD),A ; SELECT DRIVE + CALL PPIDE_OUT + .DB PPIDE_REG_DRVHD + LD (PPIDE_DRVHD),A ; UPDATE SHADOW REGISTER ; + ; SPEC REQUIRES 400NS DELAY BEFORE CHECKING STATUS REGISTER ; + XOR A + RET ; -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 +PPIDE_PROBE: + CALL PPIDE_SELUNIT ; SELECT UNIT + RET NZ ; ABORT ON ERROR ; - ; 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 + ;CALL LDELAY + LD DE,$2000 ; DELAY N * 16US (~128MS) + CALL VDELAY ; - RET ; RETURN + ;; WAIT FOR READY... + ;CALL PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR + ;RET NZ ; ABORT ON TIMEOUT +; + ; CHECK STATUS +; IN A,(PPIDE_REG_STAT) ; GET STATUS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS + OR A ; SET FLAGS TO TEST FOR ZERO + JR NZ,PPIDE_PROBE0 ; CONTINUE IF NON-ZERO + DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR + RET ; AND DONE +; +PPIDE_PROBE0: + ;CALL PPIDE_WAITBSY ; WAIT FOR BUSY TO CLEAR + ;RET NZ ; ABORT ON TIMEOUT +; + ;; CHECK STATUS + ;IN A,(PPIDE_REG_STAT) ; GET STATUS + ;DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS + ;OR A ; SET FLAGS TO TEST FOR ZERO + ;JR NZ,PPIDE_PROBE1 ; CONTINUE IF NON-ZERO + ;DEC A ; ZERO MEANS NO MEDIA, SIGNAL ERROR + ;RET ; AND DONE +; +PPIDE_PROBE1: + ; CHECK SIGNATURE + DCALL PC_SPACE + ;IN A,(PPIDE_REG_COUNT) + CALL PPIDE_IN + .DB PPIDE_REG_COUNT + DCALL PRTHEXBYTE + CP $01 + RET NZ + DCALL PC_SPACE + ;IN A,(PPIDE_REG_SECT) + CALL PPIDE_IN + .DB PPIDE_REG_SECT + DCALL PRTHEXBYTE + CP $01 + RET NZ + DCALL PC_SPACE + ;IN A,(PPIDE_REG_CYLLO) + CALL PPIDE_IN + .DB PPIDE_REG_CYLLO + DCALL PRTHEXBYTE + CP $00 + RET NZ + DCALL PC_SPACE + ;IN A,(PPIDE_REG_CYLHI) + CALL PPIDE_IN + .DB PPIDE_REG_CYLHI + DCALL PRTHEXBYTE + CP $00 + RET NZ +; + ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS + PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED + LD (HL),PPIDE_TYPEATA ; SET THE DEVICE TYPE + XOR A ; SIGNAL SUCCESS + RET ; DONE, NOTE THAT A=0 AND Z IS SET +; +; +; +PPIDE_CHKDEVICE: + PPIDE_DPTR(PPIDE_STAT) + LD A,(HL) + OR A + RET Z ; RETURN IF ALL IS WELL +; + ; ATTEMPT TO REINITIALIZE HERE??? + JP PPIDE_ERR + RET ; ; ; -#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 +PPIDE_WAITRDY: + LD B,15 ; ~15 SECOND TIMEOUT? +PPIDE_WAITRDY1: + LD DE,-1 ; ~1 SECOND INNER LOOP +PPIDE_WAITRDY2: + ;IN A,(PPIDE_REG_STAT) ; READ STATUS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + LD C,A ; SAVE IT + AND %11000000 ; ISOLATE BUSY AND RDY BITS + XOR %01000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 + RET Z ; ALL SET, RETURN WITH Z SET + CALL DELAY ; DELAY 16US + DEC DE + LD A,D + OR E + JR NZ,PPIDE_WAITRDY2 ; INNER LOOP RETURN + DJNZ PPIDE_WAITRDY1 ; OUTER LOOP RETURN + JP PPIDE_RDYTO ; EXIT WITH RDYTO ERR +; +; +; +PPIDE_WAITDRQ: + LD B,3 ; ~3 SECOND TIMEOUT??? +PPIDE_WAITDRQ1: + LD DE,-1 ; ~1 SECOND INNER LOOP +PPIDE_WAITDRQ2: + ;IN A,(PPIDE_REG_STAT) ; READ STATUS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + LD C,A ; SAVE IT + AND %10001000 ; TO FILL (OR READY TO FILL) + XOR %00001000 + RET Z + CALL DELAY ; DELAY 16US + DEC DE + LD A,D + OR E + JR NZ,PPIDE_WAITDRQ2 + DJNZ PPIDE_WAITDRQ1 + JP PPIDE_DRQTO ; EXIT WITH BUFTO ERR +; +; +; +PPIDE_WAITBSY: + LD B,3 ; ~3 SECOND TIMEOUT??? +PPIDE_WAITBSY1: + LD DE,-1 ; ~1 SECOND INNER LOOP +PPIDE_WAITBSY2: + ;IN A,(PPIDE_REG_STAT) ; READ STATUS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + LD C,A ; SAVE IT + AND %10000000 ; TO FILL (OR READY TO FILL) + RET Z + CALL DELAY ; DELAY 16US + DEC DE + LD A,D + OR E + JR NZ,PPIDE_WAITBSY2 + DJNZ PPIDE_WAITBSY1 + JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR +; +; +; +PPIDE_IN: + LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ + OUT (PPIDE_IO_PPI),A ; DO IT + EX (SP),HL ; GET PARM POINTER + PUSH BC ; SAVE INCOMING BC + LD B,(HL) ; GET CTL PORT VALUE + LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE + OUT (C),B ; SET ADDRESS LINES + SET 6,B ; TURN ON WRITE BIT + OUT (C),B ; ASSERT WRITE LINE + IN A,(PPIDE_IO_DATALO) ; GET DATA VALUE FROM DEVICE + RES 6,B ; CLEAR WRITE BIT + OUT (C),B ; DEASSERT WRITE LINE + POP BC ; RECOVER INCOMING BC + INC HL ; POINT PAST PARM + EX (SP),HL ; RESTORE STACK + RET +; +; +; +PPIDE_OUT: + PUSH AF ; PRESERVE INCOMING VALUE + LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE + OUT (PPIDE_IO_PPI),A ; DO IT + POP AF ; RECOVER VALUE TO WRITE + EX (SP),HL ; GET PARM POINTER + PUSH BC ; SAVE INCOMING BC + LD B,(HL) ; GET IDE ADDRESS VALUE + LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE + OUT (C),B ; SET ADDRESS LINES + SET 5,B ; TURN ON WRITE BIT + OUT (C),B ; ASSERT WRITE LINE + OUT (PPIDE_IO_DATALO),A ; SEND DATA VALUE TO DEVICE + RES 5,B ; CLEAR WRITE BIT + OUT (C),B ; DEASSERT WRITE LINE + POP BC ; RECOVER INCOMING BC + INC HL ; POINT PAST PARM + EX (SP),HL ; RESTORE STACK RET -#ENDIF ; +;============================================================================= +; ERROR HANDLING AND DIAGNOSTICS +;============================================================================= ; +; ERROR HANDLERS ; -PPIDE_PRT: +PPIDE_INVUNIT: + LD A,PPIDE_STINVUNIT + JR PPIDE_ERR2 ; SPECIAL CASE FOR INVALID UNIT +; +PPIDE_NOMEDIA: + LD A,PPIDE_STNOMEDIA + JR PPIDE_ERR +; +PPIDE_CMDERR: + LD A,PPIDE_STCMDERR + JR PPIDE_ERR +; +PPIDE_IOERR: + LD A,PPIDE_STIOERR + JR PPIDE_ERR +; +PPIDE_RDYTO: + LD A,PPIDE_STRDYTO + JR PPIDE_ERR +; +PPIDE_DRQTO: + LD A,PPIDE_STDRQTO + JR PPIDE_ERR +; +PPIDE_BSYTO: + LD A,PPIDE_STBSYTO + JR PPIDE_ERR +; +PPIDE_ERR: + PUSH HL ; IS THIS NEEDED? + PUSH AF ; SAVE INCOMING STATUS + PPIDE_DPTR(PPIDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED + POP AF ; RESTORE INCOMING STATUS + LD (HL),A ; UPDATE STATUS + POP HL ; IS THIS NEEDED? +PPIDE_ERR2: +#IF (PPIDETRACE >= 2) + CALL PPIDE_PRTSTAT + CALL PPIDE_REGDUMP +#ENDIF + OR A ; SET FLAGS + RET +; +; PRINT STATUS STRING (STATUS NUM IN A) +; +PPIDE_PRTSTAT: + PUSH AF + PUSH DE + PUSH HL + OR A + LD DE,PPIDE_STR_STOK + JR Z,PPIDE_PRTSTAT1 + INC A + LD DE,PPIDE_STR_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: 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 + PRTS("PPIDE:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT +PPIDE_PRTSTAT3: + CALL PC_SPACE ; FORMATTING 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 - + POP HL + POP DE + POP AF + RET +; +; +; +PPIDE_REGDUMP: + PUSH AF + PUSH BC 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 - + LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ + OUT (PPIDE_IO_PPI),A ; DO IT + LD C,PPIDE_REG_CMD + LD B,7 +PPIDE_REGDUMP1: + LD A,C ; REGISTER ADDRESS + OUT (PPIDE_IO_CTL),A ; SET IT + XOR PPIDE_CTL_DIOR ; SET BIT TO ASSERT READ LINE + OUT (PPIDE_IO_CTL),A ; ASSERT READ + IN A,(PPIDE_IO_DATALO) ; GET VALUE + CALL PRTHEXBYTE ; DISPLAY IT + LD A,C ; RELOAD ADDRESS W/ READ UNASSERTED + OUT (PPIDE_IO_CTL),A ; AND SET IT + DEC C ; NEXT LOWER REGISTER + DEC B ; DEC LOOP COUNTER + CALL NZ,PC_SPACE ; FORMATTING + JR NZ,PPIDE_REGDUMP1 ; LOOP AS NEEDED + CALL PC_RBKT ; FORMATTING + POP BC + POP AF + RET +; +; PRINT DIAGNONSTIC PREFIX +; +PPIDE_PRTPREFIX: + PUSH AF + CALL NEWLINE + PRTS("PPIDE$") + LD A,(PPIDE_UNIT) + ADD A,'0' + CALL COUT + CALL PC_COLON + POP AF 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. +#IF (DSKYENABLE) +PPIDE_DSKY: + LD HL,DSKY_HEXBUF ; POINT TO DSKY BUFFER + IN A,(PPIDE_REG_DRVHD) ; GET DRIVE/HEAD + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER + IN A,(PPIDE_REG_CYLHI) ; GET DRIVE/HEAD + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER + IN A,(PPIDE_REG_CYLLO) ; GET DRIVE/HEAD + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER + IN A,(PPIDE_REG_SECT) ; GET DRIVE/HEAD + LD (HL),A ; SAVE IN BUFFER + CALL DSKY_HEXOUT ; SEND IT TO DSKY + RET +#ENDIF +; +;============================================================================= +; STRING DATA +;============================================================================= +; +PPIDE_STR_STOK .TEXT "OK$" +PPIDE_STR_STINVUNIT .TEXT "INVALID UNIT$" +PPIDE_STR_STNOMEDIA .TEXT "NO MEDIA$" +PPIDE_STR_STCMDERR .TEXT "COMMAND ERROR$" +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_STUNK .TEXT "UNKNOWN ERROR$" +; +PPIDE_STR_NO .TEXT "NO$" +; +;============================================================================= +; DATA STORAGE +;============================================================================= +; +PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS +PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK +; +PPIDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO +; +; UNIT SPECIFIC DATA STORAGE +; +PPIDE_UDATA .FILL PPIDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES +PPIDE_DLEN .EQU $ - PPIDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS +PPIDE_UDLEN .EQU PPIDE_DLEN / PPIDE_UNITCNT ; LENGTH OF PER UNIT DATA +; +;============================================================================= +; HELPER ROUTINES +;============================================================================= +; +; IMPLEMENTATION FOR MACRO PPIDE_DPTR +; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA +; HL := ADR OF PPIDE_UNITDATA[(PPIDE_UNIT)][(SP)] +; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET +; AF IS TRASHED +; +PPIDE_DPTRIMP: + LD HL,PPIDE_UDATA ; POINT TO START OF UNIT DATA ARRAY + LD A,(PPIDE_UNIT) ; GET CURRENT UNIT NUM + RLCA ; MULTIPLY BY + RLCA ; ... SIZE OF PER UNIT DATA + RLCA ; ... (8 BYTES) + EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS + ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM + INC HL ; BUMP HL TO NEXT REAL INSTRUCTION + EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA + JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN diff --git a/Source/HBIOS/sd.asm b/Source/HBIOS/sd.asm index 70ed9341..b02eb868 100644 --- a/Source/HBIOS/sd.asm +++ b/Source/HBIOS/sd.asm @@ -1224,29 +1224,6 @@ SD_WAITRX: JR NZ,SD_WAITRX RET ; -; MSB<-->LSB MIRROR BITS IN A, RESULT IN C -; -MIRROR: - #IF (SDCSIOFAST) ; SLOW SPEED, LEAST CODE SPACE - LD BC,MIRTAB ; 256 BYTE MIRROR TABLE - ADD A,C ; ADD OFFSET - LD C,A - JR NC,MIRROR2 - INC B -MIRROR2: - LD A,(BC) ; GET RESULT - LD C,A ; RETURN RESULT IN C - RET - #ELSE ; FASTEST BUT USES MOST CODE SPACE - LD B,8 ; BIT COUNTER -MIRROR1: - RLA ; ROTATE BIT 7 INTO CARRY - RR C ; ROTATE CARRY INTO RESULT - DJNZ MIRROR1 ; DO ALL 8 BITS - RET - #ENDIF -#ENDIF -; ; SEND ONE BYTE ; SD_PUT: @@ -1583,6 +1560,51 @@ SD_UNITDATA .FILL SD_UNITCNT * 8, 0 ; PER UNIT DATA, 8 BYTES SD_DATALEN .EQU $ - SD_UNITDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS SD_UNITDATALEN .EQU SD_DATALEN / SD_UNITCNT ; LENGTH OF PER UNIT DATA ; +;============================================================================= +; HELPER ROUTINES +;============================================================================= +; +; IMPLEMENTATION FOR MACRO SD_DPTR +; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA +; HL := ADR OF SD_UNITDATA[(SD_UNIT)][(SP)] +; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET +; AF IS TRASHED +; +SD_DPTRIMP: + LD HL,SD_UNITDATA ; POINT TO START OF UNIT DATA ARRAY + LD A,(SD_UNIT) ; GET CURRENT UNIT NUM + RLCA ; MULTIPLY BY + RLCA ; ... SIZE OF PER UNIT DATA + RLCA ; ... (8 BYTES) + EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS + ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM + INC HL ; BUMP HL TO NEXT REAL INSTRUCTION + EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA + JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN +; +; MSB<-->LSB MIRROR BITS IN A, RESULT IN C +; +MIRROR: + #IF (SDCSIOFAST) ; SLOW SPEED, LEAST CODE SPACE + LD BC,MIRTAB ; 256 BYTE MIRROR TABLE + ADD A,C ; ADD OFFSET + LD C,A + JR NC,MIRROR2 + INC B +MIRROR2: + LD A,(BC) ; GET RESULT + LD C,A ; RETURN RESULT IN C + RET + #ELSE ; FASTEST BUT USES MOST CODE SPACE + LD B,8 ; BIT COUNTER +MIRROR1: + RLA ; ROTATE BIT 7 INTO CARRY + RR C ; ROTATE CARRY INTO RESULT + DJNZ MIRROR1 ; DO ALL 8 BITS + RET + #ENDIF +#ENDIF +; ; LOOKUP TABLE TO MIRROR BITS IN A BYTE ; #IF (((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4)) & SDCSIOFAST) @@ -1605,25 +1627,3 @@ MIRTAB .DB 00H, 80H, 40H, 0C0H, 20H, 0A0H, 60H, 0E0H, 10H, 90H, 50H, 0D0H, 30H, .DB 0FH, 8FH, 4FH, 0CFH, 2FH, 0AFH, 6FH, 0EFH, 1FH, 9FH, 5FH, 0DFH, 3FH, 0BFH, 7FH, 0FFH ; #ENDIF -; -;============================================================================= -; HELPER ROUTINES -;============================================================================= -; -; IMPLEMENTATION FOR MACRO SD_DPTR -; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA -; HL := ADR OF SD_UNITDATA[(SD_UNIT)][(SP)] -; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET -; AF IS TRASHED -; -SD_DPTRIMP: - LD HL,SD_UNITDATA ; POINT TO START OF UNIT DATA ARRAY - LD A,(SD_UNIT) ; GET CURRENT UNIT NUM - RLCA ; MULTIPLY BY - RLCA ; ... SIZE OF PER UNIT DATA - RLCA ; ... (8 BYTES) - EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS - ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM - INC HL ; BUMP HL TO NEXT REAL INSTRUCTION - EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA - JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN