; ;============================================================================= ; PPA DISK DRIVER ;============================================================================= ; ; PARALLEL PORT INTERFACE FOR SCSI DISK DEVICES USING A PARALLEL PORT ; ADAPTER. PRIMARILY TARGETS PARALLEL PORT IOMEGA ZIP DRIVES. ; ; CURRENTLY CODED SPECIFICALLY FOR RCBUS MG014 PARALLEL PORT HARDWARE. ; INTENDED TO CO-EXIST WITH LPT DRIVER. ; ; CREATED BY WAYNE WARTHEN FOR ROMWBW HBIOS. ; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX). ; ; 5/19/2023 WBW - INITIAL RELEASE ; ;============================================================================= ; ; MG014 STYLE INTERFACE (USED BY RCBUS MG014 MODULE): ; ; PORT 0 (INPUT/OUTPUT): ; ; D7 D6 D5 D4 D3 D2 D1 D0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | PD7 | PD6 | PD5 | PD4 | PD3 | PD2 | PD1 | PD0 | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; PORT 1 (INPUT): ; ; D7 D6 D5 D4 D3 D2 D1 D0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | | | | /ERR | SEL | POUT | BUSY | /ACK | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; PORT 2 (INPUT/OUTPUT): ; ; D7 D6 D5 D4 D3 D2 D1 D0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | LED | | | | /SEL | /RES | /LF | /STB | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ;============================================================================= ; ; TODO: ; ; NOTES: ; ;;;; ;;;; COMMAND BYTES ;;;; ;;;PPA_CPPA_NOP .EQU $00 ;;;PPA_CPPA_DEVRES .EQU $08 ;;;PPA_CPPA_RECAL .EQU $10 ;;;PPA_CPPA_READ .EQU $20 ;;;PPA_CPPA_WRITE .EQU $30 ;;;PPA_CPPA_DEVDIAG .EQU $90 ;;;PPA_CPPA_IDPKTDEV .EQU $A1 ;;;PPA_CPPA_IDDEV .EQU $EC ;;;PPA_CPPA_SETFEAT .EQU $EF ; ; PPA PORT OFFSETS ; PPA_IODATA .EQU 0 ; PORT A, DATA, OUT PPA_IOSTAT .EQU 1 ; PORT B, STATUS, IN PPA_IOCTRL .EQU 2 ; PORT C, CTRL, OUT PPA_IOSETUP .EQU 3 ; PPI SETUP ; ; PPA DEVICE STATUS ; PPA_STOK .EQU 0 PPA_STINVUNIT .EQU -1 PPA_STNOMEDIA .EQU -2 PPA_STCMDERR .EQU -3 PPA_STIOERR .EQU -4 PPA_STTO .EQU -5 PPA_STNOTSUP .EQU -6 ; ; PPA DEVICE CONFIGURATION ; PPA_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES ; ; PER DEVICE DATA OFFSETS IN CONFIG TABLE ENTRIES ; PPA_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) PPA_MODE .EQU 1 ; OPERATION MODE: PPA MODE (BYTE) PPA_STAT .EQU 2 ; LAST STATUS (BYTE) PPA_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE) PPA_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) PPA_LBA .EQU 8 ; OFFSET OF LBA (DWORD) ; ;============================================================================= ; INITIALIZATION ENTRY POINT ;============================================================================= ; PPA_INIT: LD IY,PPA_CFG ; POINT TO START OF CONFIG TABLE ; PPA_INIT1: LD A,(IY) ; LOAD FIRST BYTE TO CHECK FOR END CP $FF ; CHECK FOR END OF TABLE VALUE JR NZ,PPA_INIT2 ; IF NOT END OF TABLE, CONTINUE XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; PPA_INIT2: ; CHECK FOR HARDWARE PRESENCE CALL PPA_DETECT ; PROBE FOR INTERFACE JP NZ,PPA_INIT6 ; SKIP CFG ENTRY ; ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE LD A,(PPA_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN LD (IY+PPA_DEV),A ; UPDATE IT INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN LD (PPA_DEVNUM),A ; SAVE IT ; CALL PPA_PRTPREFIX ; PRINT DEVICE PREFIX ; PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS LD A,(IY+PPA_IOBASE) ; GET IO BASE ADDRES CALL PRTHEXBYTE ; DISPLAY IT ; PRTS(" MODE=$") ; LABEL FOR MODE LD A,(IY+PPA_MODE) ; GET MODE BITS LD DE,PPA_STR_MODE_NONE ; MODE LABEL CP PPAMODE_NONE ; TEST FOR MODE JR Z,PPA_INIT3 ; IF SO, DISPLAY IT LD DE,PPA_STR_MODE_MG014 ; MODE LABEL CP PPAMODE_MG014 ; TEST FOR MODE JR Z,PPA_INIT3 ; IF SO, DISPLAY IT LD DE,PPA_STR_MODE_UNK ; MODE LABEL PPA_INIT3: CALL WRITESTR ; DISPLAY MODE ; PPA_INIT4: CALL PPA_RESET ; RESET THE INTERFACE ; ; ADD UNIT TO GLOBAL DISK UNIT TABLE LD BC,PPA_FNTBL ; BC := FUNC TABLE ADR PUSH IY ; CFG ENTRY POINTER POP DE ; COPY TO DE CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE ; ; CHECK FOR BAD STATUS LD A,(IY+PPA_STAT) ; GET STATUS OR A ; SET FLAGS JP Z,PPA_INIT5 ; CONTINUE CALL PC_SPACE ; FORMATTING CALL PPA_PRTSTATSTR ; PRINT STATUS STRING JR PPA_INIT6 ; LOOP TILL DONE ; PPA_INIT5: ; PRINT STORAGE CAPACITY (BLOCK COUNT) PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL LD A,PPA_MEDCAP ; OFFSET TO CAPACITY FIELD CALL LDHLIYA ; HL := IY + A, REG A TRASHED 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 PRTDEC32 ; PRINT DWORD IN DECIMAL PRTS("MB$") ; PRINT SUFFIX ; PPA_INIT6: LD DE,PPA_CFGSIZ ; SIZE OF CFG TABLE ENTRY ADD IY,DE ; BUMP POINTER JP PPA_INIT1 ; AND LOOP ; ;---------------------------------------------------------------------- ; PROBE FOR PPA HARDWARE ;---------------------------------------------------------------------- ; ; ON RETURN, ZF SET INDICATES HARDWARE FOUND ; PPA_DETECT: XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ;============================================================================= ; DRIVER FUNCTION TABLE ;============================================================================= ; PPA_FNTBL: .DW PPA_STATUS .DW PPA_RESET .DW PPA_SEEK .DW PPA_READ .DW PPA_WRITE .DW PPA_VERIFY .DW PPA_FORMAT .DW PPA_DEVICE .DW PPA_MEDIA .DW PPA_DEFMED .DW PPA_CAP .DW PPA_GEOM #IF (($ - PPA_FNTBL) != (DIO_FNCNT * 2)) .ECHO "*** INVALID PPA FUNCTION TABLE ***\n" #ENDIF ; PPA_VERIFY: PPA_FORMAT: PPA_DEFMED: SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED RET ; ; ; PPA_READ: JP PPA_STNOTSUP ; NOT SUPPORTED ; ; ; PPA_WRITE: JP PPA_STNOTSUP ; NOT SUPPORTED ; ; ; PPA_STATUS: ; RETURN UNIT STATUS LD A,(IY+PPA_STAT) ; GET STATUS OF SELECTED DEVICE OR A ; SET FLAGS RET ; AND RETURN ; ; ; PPA_DEVICE: LD D,DIODEV_PPA ; D := DEVICE TYPE LD E,(IY+PPA_DEV) ; E := PHYSICAL DEVICE NUMBER LD C,%01000000 ; C := REMOVABLE HARD DISK LD H,(IY+PPA_MODE) ; H := MODE LD L,(IY+PPA_IOBASE) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; ; PPA_GETMED ; PPA_MEDIA: LD A,E ; GET FLAGS OR A ; SET FLAGS JR Z,PPA_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA ; ;CALL PPA_RESET ; RESET PPA INTERFACE CALL PPA_INITUNIT ; RE-INITIALIZE UNIT ; PPA_MEDIA1: LD A,(IY+PPA_STAT) ; GET STATUS OR A ; SET FLAGS LD D,0 ; NO MEDIA CHANGE DETECTED LD E,MID_HD ; ASSUME WE ARE OK RET Z ; RETURN IF GOOD INIT LD E,MID_NONE ; SIGNAL NO MEDIA LD A,ERR_NOMEDIA ; NO MEDIA ERROR OR A ; SET FLAGS RET ; AND RETURN ; ; ; PPA_SEEK: BIT 7,D ; CHECK FOR LBA FLAG CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) LD (IY+PPA_LBA+0),L ; SAVE NEW LBA LD (IY+PPA_LBA+1),H ; ... LD (IY+PPA_LBA+2),E ; ... LD (IY+PPA_LBA+3),D ; ... XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; ; PPA_CAP: LD A,(IY+PPA_STAT) ; GET STATUS PUSH AF ; SAVE IT LD A,PPA_MEDCAP ; OFFSET TO CAPACITY FIELD CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK POP AF ; RECOVER STATUS OR A ; SET FLAGS RET ; ; ; PPA_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 PPA_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC LD L,H ; DIVIDE 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 RET ; DONE, A STILL HAS PPA_CAP STATUS ; ;============================================================================= ; FUNCTION SUPPORT ROUTINES ;============================================================================= ; PPA_SELF .EQU 7 PPA_TGT .EQU 6 ; IMM_TGT .EQU 6 ; ; ; PPA_DELAY: PUSH AF CALL DELAY CALL DELAY CALL DELAY CALL DELAY POP AF RET ; ; ; PPA_WRITEDATA: ;PRTS(" D-$") ;CALL PRTHEXBYTE LD C,(IY+PPA_IOBASE) OUT (C),A CALL PPA_DELAY RET ; ; ; PPA_WRITECTRL: ;PRTS(" C-$") ;CALL PRTHEXBYTE XOR $0B ;PRTS(">$") ;CALL PRTHEXBYTE LD C,(IY+PPA_IOBASE) INC C INC C OUT (C),A CALL PPA_DELAY RET ; ; ; PPA_READSTATUS: LD C,(IY+PPA_IOBASE) INC C IN A,(C) ;PRTS(" I-$") ;CALL PRTHEXBYTE LD C,0 ; INIT RESULT ; BIT 0,A ; ACK = $01 JR Z,PPA_READSTATUS1 SET 6,C ; $40 ; PPA_READSTATUS1: ; BIT 1,A ; BUSY = $02 JR NZ,PPA_READSTATUS2 SET 7,C ; $80 ; PPA_READSTATUS2: ; BIT 2,A ; PAPER = $04 JR Z,PPA_READSTATUS3 SET 5,C ; $20 ; PPA_READSTATUS3: ; BIT 3,A ; SELECT = $08 JR Z,PPA_READSTATUS4 SET 4,C ; $10 ; PPA_READSTATUS4: ; BIT 4,A ; FAULT = $10 JR Z,PPA_READSTATUS5 SET 3,C ; $08 ; PPA_READSTATUS5: LD A,C ;PRTS(">$") ;CALL PRTHEXBYTE RET ; ; ; PPA_DPULSE: CALL PPA_WRITEDATA LD A,$0C CALL PPA_WRITECTRL LD A,$0E CALL PPA_WRITECTRL LD A,$0C ;? CALL PPA_WRITECTRL ;? LD A,$04 CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL RET ; ; ; PPA_CPULSE: CALL PPA_WRITEDATA LD A,$04 CALL PPA_WRITECTRL LD A,$06 CALL PPA_WRITECTRL LD A,$04 CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL RET ; ; ; PPA_CONNECT: CALL NEWLINE LD A,$00 CALL PPA_CPULSE LD A,$3C CALL PPA_CPULSE LD A,$20 CALL PPA_CPULSE LD A,$8F CALL PPA_CPULSE RET ; ; ; IMM_CPP: ;CALL NEWLINE PUSH AF LD A,$0C CALL PPA_WRITECTRL LD A,$AA CALL PPA_WRITEDATA LD A,$55 CALL PPA_WRITEDATA LD A,$00 CALL PPA_WRITEDATA LD A,$FF CALL PPA_WRITEDATA CALL PPA_READSTATUS AND $B8 LD (IMM_S1),A LD A,$87 CALL PPA_WRITEDATA CALL PPA_READSTATUS AND $B8 LD (IMM_S2),A LD A,$78 CALL PPA_WRITEDATA CALL PPA_READSTATUS AND $38 LD (IMM_S3),A POP AF CALL PPA_WRITEDATA LD A,$0C CALL PPA_WRITECTRL LD A,$0D CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL LD A,$FF CALL PPA_WRITEDATA ; CONNECT: S1=$B8 S2=$18 S3=$30 ; DISCONNECT: S1=$B8 S2=$18 S3=$38 PRTS("\r\nCPP: S1=$") LD A,(IMM_S1) CALL PRTHEXBYTE PRTS(" S2=$") LD A,(IMM_S2) CALL PRTHEXBYTE PRTS(" S3=$") LD A,(IMM_S3) CALL PRTHEXBYTE XOR A ; ASSUME SUCCESS FOR NOW RET ; IMM_S1 .DB 0 IMM_S2 .DB 0 IMM_S3 .DB 0 ; ; ; IMM_CONNECT: LD A,$E0 CALL IMM_CPP LD A,$30 CALL IMM_CPP LD A,$E0 CALL IMM_CPP RET ; ; ; IMM_DISCONNECT: LD A,$30 CALL IMM_CPP RET ; ; ; IMM_RESETPULSE: ;CALL NEWLINE LD A,$04 CALL PPA_WRITECTRL LD A,$40 CALL PPA_WRITEDATA CALL DELAY LD A,$0C CALL PPA_WRITECTRL LD A,$0D CALL PPA_WRITECTRL CALL DELAY CALL DELAY CALL DELAY CALL DELAY LD A,$0C CALL PPA_WRITECTRL LD A,$04 CALL PPA_WRITECTRL RET ; ; ; PPA_DISCONNECT: ;CALL NEWLINE LD A,$00 CALL PPA_DPULSE LD A,$3C CALL PPA_DPULSE LD A,$20 CALL PPA_DPULSE LD A,$0F CALL PPA_DPULSE RET ; ; ; PPA_SELECT: LD A,1 << PPA_TGT CALL PPA_WRITEDATA LD A,$0E CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL LD A,1 << PPA_SELF CALL PPA_WRITEDATA LD A,$08 CALL PPA_WRITECTRL ; LD HL,0 ; TIMEOUT COUNTER ; PPA_SELECT1: CALL PPA_READSTATUS OR $F0 RET NZ DEC HL LD A,H OR L RET Z ; TIMEOUT JR PPA_SELECT1 ; ; ; IMM_SELECT: PRTS("\r\nSELECT: $") LD A,$0C CALL PPA_WRITECTRL ; LD HL,500 ; TIMEOUT COUNTER ; IMM_SELECT1: CALL PPA_READSTATUS AND $08 JR Z,IMM_SELECT2 ; IF CLEAR, MOVE ON DEC HL LD A,H OR L JP Z,IMM_CMD_TIMEOUT ; TIMEOUT JR IMM_SELECT1 ; IMM_SELECT2: LD A,$04 CALL PPA_WRITECTRL LD A,$80 | (1 << IMM_TGT) CALL PPA_WRITEDATA CALL DELAY LD A,$0C CALL PPA_WRITECTRL CALL PPA_READSTATUS CALL PC_SPACE CALL PRTHEXBYTE LD A,$0D CALL PPA_WRITECTRL CALL PPA_READSTATUS CALL PC_SPACE CALL PRTHEXBYTE ; LD HL,500 ; TIMEOUT COUNTER ; IMM_SELECT3: CALL PPA_READSTATUS CALL PC_SPACE CALL PRTHEXBYTE AND $08 JR NZ,IMM_SELECT4 ; IF CLEAR, MOVE ON DEC HL LD A,H OR L JP Z,IMM_CMD_TIMEOUT ; TIMEOUT JR IMM_SELECT3 ; IMM_SELECT4: LD A,$0C CALL PPA_WRITECTRL ; XOR A RET ; ; ; IMM_SENDCMD: ; TODO: USE PUTDATA ROUTINE??? ; TODO: CHECK BUSY??? PRTS("\r\nSENDCMD:$") LD A,$04 CALL PPA_WRITECTRL ; LD HL,IMM_CMD LD B,6 ; IMM_SENDCMD1: LD A,(HL) CALL PC_SPACE CALL PRTHEXBYTE CALL PPA_WRITEDATA INC HL DEC B LD A,$05 CALL PPA_WRITECTRL LD A,(HL) CALL PC_SPACE CALL PRTHEXBYTE CALL PPA_WRITEDATA INC HL LD A,$00 CALL PPA_WRITECTRL DJNZ IMM_SENDCMD1 LD A,$04 CALL PPA_WRITECTRL ; CALL PPA_READSTATUS CALL PC_SPACE CALL PC_GT CALL PRTHEXBYTE RET ; ; ; IMM_WAITBUSY: LD HL,500 ; NORMAL TIMEOUT COUNTER ; IMM_WAITBUSY_HL: ; VARIABLE TIMEOUT ENTRY ;PRTS("\r\nWAITB: $") LD A,$0C CALL PPA_WRITECTRL ; IMM_WAITBUSY2: CALL PPA_READSTATUS BIT 7,A RET NZ ; IF SET, MOVE ON DEC HL LD A,H OR L JP Z,IMM_CMD_TIMEOUT ; TIMEOUT JR IMM_WAITBUSY2 ; ; ; IMM_WAITDONE: LD HL,500 ; NORMAL TIMEOUT COUNTER ; IMM_WAITDONE_HL: ; VARIABLE TIMEOUT ENTRY CALL IMM_WAITBUSY_HL AND $B8 PUSH AF LD A,$04 CALL PPA_WRITECTRL POP AF RET ; ; ; IMM_NEGOTIATE: ; TODO: REVIEW TIMING DELAYS!!! PRTS("\r\nNEGO: $") LD A,$04 CALL PPA_WRITECTRL CALL DELAY LD A,$00 CALL PPA_WRITEDATA CALL DELAY CALL DELAY CALL DELAY CALL DELAY LD A,$06 CALL PPA_WRITECTRL CALL DELAY CALL PPA_READSTATUS PUSH AF ; SAVE RESULT CALL DELAY LD A,$07 CALL PPA_WRITECTRL CALL DELAY LD A,$06 CALL PPA_WRITECTRL ; POP AF CALL PC_SPACE CALL PRTHEXBYTE AND $20 CALL PC_SPACE CALL PC_GT CALL PRTHEXBYTE CP $20 JP NZ,IMM_CMD_IOERR RET ; ; ; PPA_WAITDONE: LD HL,0 ; TIMEOUT COUNTER PPA_WAITDONE1: CALL PPA_READSTATUS AND $F0 BIT 7,A RET NZ DEC HL LD A,H OR L JP Z,IMM_CMD_TIMEOUT ; TIMEOUT JR PPA_WAITDONE1 ; ; ; IMM_GETBYTE: CALL IMM_WAITBUSY LD A,$04 CALL PPA_WRITECTRL LD A,$06 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 RRCA RRCA RRCA RRCA PUSH AF LD A,$05 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 POP HL OR H PUSH AF LD A,$04 CALL PPA_WRITECTRL POP AF RET ; ; DE=BUFFER ; HL=LENGTH (0 FOR VARIABLE) ; IMM_GETDATA: LD A,H OR L JR NZ,IMM_GETDATALEN PRTS("\r\nGETDATA:$") IMM_GETDATA1: PUSH HL CALL IMM_WAITDONE POP HL CP $98 JR NZ,IMM_GETDATA2 LD A,$04 CALL PPA_WRITECTRL LD A,$06 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 RRCA RRCA RRCA RRCA PUSH AF LD A,$05 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 POP BC OR B LD (DE),A INC DE INC HL LD A,$04 CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL JR IMM_GETDATA1 ; IMM_GETDATA2: CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") RET ; IMM_GETDATALEN: PRTS("\r\nGETDLEN:$") CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") LD A,$04 CALL PPA_WRITECTRL IMM_GETDATALEN1: LD A,$06 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 RRCA RRCA RRCA RRCA PUSH AF LD A,$05 CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 POP BC OR B LD (DE),A INC DE DEC HL LD A,$04 CALL PPA_WRITECTRL LD A,H OR L JR NZ,IMM_GETDATALEN1 LD A,$0C CALL PPA_WRITECTRL RET ; ; DE=BUFFER ; HL=LENGTH (0 FOR VARIABLE) ; IMM_PUTDATA: LD A,H OR L JR NZ,IMM_PUTDATALEN PRTS("\r\nPUTDATA:$") IMM_PUTDATA1: PUSH HL CALL IMM_WAITDONE POP HL CP $88 JR NZ,IMM_PUTDATA2 LD A,$04 CALL PPA_WRITECTRL LD A,(DE) CALL PPA_WRITEDATA INC DE INC HL LD A,$05 CALL PPA_WRITECTRL LD A,(DE) CALL PPA_WRITEDATA INC DE INC HL LD A,$00 CALL PPA_WRITECTRL JR IMM_PUTDATA1 ; IMM_PUTDATA2: LD A,$04 CALL PPA_WRITECTRL CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") RET ; IMM_PUTDATALEN: PRTS("\r\nPUTDLEN:$") CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") LD A,$04 CALL PPA_WRITECTRL IMM_PUTDATALEN1: LD A,(DE) CALL PPA_WRITEDATA INC DE DEC HL LD A,$05 CALL PPA_WRITECTRL LD A,(DE) CALL PPA_WRITEDATA INC DE DEC HL LD A,$00 CALL PPA_WRITECTRL LD A,H OR L JR NZ,IMM_PUTDATALEN1 LD A,$04 CALL PPA_WRITECTRL RET ; ; ; IMM_GETSTATUS: PRTS("\r\nSTATUS:$") CALL IMM_GETBYTE LD (IMM_STATUS),A CALL PC_SPACE CALL PRTHEXBYTE CALL IMM_WAITDONE CP $B8 RET NZ CALL IMM_GETBYTE LD (IMM_STATUS+1),A CALL PC_SPACE CALL PRTHEXBYTE RET ; ; ; IMM_ENDREAD: LD A,$04 CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL LD A,$0E CALL PPA_WRITECTRL LD A,$04 CALL PPA_WRITECTRL RET ; ; ; IMM_RUNCMDX: ; COPY CMD BYTES FROM (HL) PUSH BC PUSH DE LD BC,6 LD DE,IMM_CMD LDIR POP DE POP BC ; IMM_RUNCMD: LD (IMM_CMDSTK),SP ; FOR ERROR ABORTS LD (IMM_DSKBUF),DE ; SAVE BUF PTR LD (IMM_XFRLEN),BC ; SAVE XFER LEN CALL IMM_CONNECT CALL IMM_SELECT CALL IMM_WAITBUSY CALL IMM_SENDCMD ; IMM_RUNCMD_LOOP: LD HL,50000 ; LONG TIMEOUT HERE CALL IMM_WAITDONE_HL ; PRTS("\r\nCMD$") PRTS("LOOP: $") CALL PRTHEXBYTE ; CP $88 JR Z,IMM_RUNCMD_WRITE CP $98 JR Z,IMM_RUNCMD_READ CP $B8 JR Z,IMM_RUNCMD_END JR IMM_CMD_IOERR ; IMM_RUNCMD_WRITE: LD DE,(IMM_DSKBUF) LD HL,(IMM_XFRLEN) ; XFER LENGTH CALL IMM_PUTDATA ; SEND DATA NOW JR IMM_RUNCMD_LOOP ; IMM_RUNCMD_READ: CALL IMM_NEGOTIATE CALL IMM_WAITDONE ; CHECK FOR STATUS $98??? LD DE,(IMM_DSKBUF) LD HL,(IMM_XFRLEN) ; XFER LENGTH CALL IMM_GETDATA ; GET THE DATA NOW CALL IMM_ENDREAD JR IMM_RUNCMD_LOOP ; IMM_RUNCMD_END: CALL IMM_NEGOTIATE CALL IMM_WAITDONE ; CHECK FOR STATUS $B8??? CALL IMM_GETSTATUS CALL IMM_ENDREAD CALL IMM_DISCONNECT XOR A ; SIGNAL SUCCESS RET ; IMM_CMD_IOERR: LD A,PPA_STIOERR JR IMM_CMD_ERR ; IMM_CMD_TIMEOUT: LD A,PPA_STTO JR IMM_CMD_ERR ; IMM_CMD_ERR: LD SP,(IMM_CMDSTK) ; UNWIND STACK PUSH AF ; SAVE STATUS CALL IMM_RESETPULSE ; CLEAN UP THE MESS CALL IMM_DISCONNECT ; MAKE SURE WE ARE OFF THE BUS POP AF ; RECOVER STATUS JP PPA_ERR ; ERROR EXIT ; ;============================================================================= ; HARDWARE INTERFACE ROUTINES ;============================================================================= ; ; RESET ALL DEVICES ON BUS ; PPA_RESET: JP PPA_INITUNIT ; ; ; PPA_INITUNIT: ;JP PPA_INITDEV JP IMM_INITDEV ; ; (RE)INITIALIZE DEVICE ; PPA_INITDEV: ; INITIALIZE 8255 LD A,(IY+PPA_IOBASE) ; BASE PORT ADD A,PPA_IOSETUP ; BUMP TO SETUP PORT LD C,A ; MOVE TO C FOR I/O LD A,$82 ; CONFIG A OUT, B IN, C OUT OUT (C),A ; DO IT CALL DELAY CALL NEWLINE LD A,$0C CALL PPA_WRITECTRL CALL DELAY ; ; INITIALIZE PPA INTERFACE CALL PPA_READSTATUS CALL NEWLINE LD A,$AA CALL PPA_WRITEDATA CALL PPA_DISCONNECT CALL PPA_CONNECT CALL NEWLINE ;LD A,$06 LD A,$0E CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 ;... CHECK VALUE=$F0 CALL PC_SPACE CALL PRTHEXBYTE CALL NEWLINE ;LD A,$04 LD A,$0C CALL PPA_WRITECTRL CALL PPA_READSTATUS AND $F0 ;... CHECK VALUE=$80 CALL PC_SPACE CALL PRTHEXBYTE CALL PPA_DISCONNECT CALL NEWLINE LD A,$AA CALL PPA_WRITEDATA LD A,$0C ; ??? CALL NEWLINE CALL PPA_WRITECTRL CALL PPA_CONNECT CALL NEWLINE LD A,$40 CALL PPA_WRITEDATA LD A,$08 CALL PPA_WRITECTRL LD A,$0C CALL PPA_WRITECTRL CALL PPA_DISCONNECT ; JP PPA_NOMEDIA ; ; RECORD STATUS OK XOR A ; A := 0 (STATUS = OK) LD (IY+PPA_STAT),A ; SAVE IT ; RET ; RETURN, A=0, Z SET ; ; ; IMM_INITDEV: ; INITIALIZE 8255 LD A,(IY+PPA_IOBASE) ; BASE PORT ADD A,PPA_IOSETUP ; BUMP TO SETUP PORT LD C,A ; MOVE TO C FOR I/O LD A,$82 ; CONFIG A OUT, B IN, C OUT OUT (C),A ; DO IT CALL DELAY ; CALL IMM_CONNECT CALL IMM_RESETPULSE LD DE,62 CALL VDELAY CALL IMM_DISCONNECT LD DE,62 CALL VDELAY ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF LD BC,512 LD HL,IMM_CMD_READ CALL IMM_RUNCMDX LD DE,HB_WRKBUF CALL Z,DUMP_BUFFER ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF LD BC,512 LD HL,IMM_CMD_READ CALL IMM_RUNCMDX LD DE,HB_WRKBUF CALL Z,DUMP_BUFFER ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_INQ CALL IMM_RUNCMDX LD DE,HB_WRKBUF CALL Z,DUMP_BUFFER ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF ;LD BC,512 LD BC,0 LD HL,IMM_CMD_WRITE CALL IMM_RUNCMDX LD DE,HB_WRKBUF ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF ; LD DE,HB_WRKBUF LD BC,512 LD HL,IMM_CMD_READ2 CALL IMM_RUNCMDX LD DE,HB_WRKBUF CALL DUMP_BUFFER ; LD DE,HB_WRKBUF LD BC,0 LD HL,IMM_CMD_SENSE CALL IMM_RUNCMDX LD A,16 LD DE,HB_WRKBUF CALL PRTHEXBUF ; JP PPA_NOMEDIA ; IMM_CMD .DB $00, $00, $00, $00, $00, $00 ; TEMPLATE IMM_CMD_READ .DB $08, $00, $00, $00, $01, $00 ; READ SECTOR $0000 IMM_CMD_INQ .DB $12, $00, $00, $00, $FF, $00 ; INQUIRY IMM_CMD_TEST .DB $00, $00, $00, $00, $00, $00 ; TEST UNIT READY IMM_CMD_START .DB $1B, $00, $00, $00, $01, $00 ; START UNIT IMM_CMD_SENSE .DB $03, $00, $00, $00, $FF, $00 ; REQUEST SENSE DATA IMM_CMD_WRITE .DB $0A, $00, $F0, $00, $01, $00 ; READ SECTOR $F000 IMM_CMD_READ2 .DB $08, $00, $F0, $00, $01, $00 ; READ SECTOR $F000 ; ; CHECK CURRENT DEVICE FOR ERROR STATUS AND ATTEMPT TO RECOVER ; VIA RESET IF DEVICE IS IN ERROR. ; PPA_CHKERR: LD A,(IY+PPA_STAT) ; GET STATUS OR A ; SET FLAGS CALL NZ,PPA_RESET ; IF ERROR STATUS, RESET BUS RET ; ;============================================================================= ; ERROR HANDLING AND DIAGNOSTICS ;============================================================================= ; ; ERROR HANDLERS ; PPA_INVUNIT: LD A,PPA_STINVUNIT JR PPA_ERR2 ; SPECIAL CASE FOR INVALID UNIT ; PPA_NOMEDIA: LD A,PPA_STNOMEDIA JR PPA_ERR ; PPA_CMDERR: LD A,PPA_STCMDERR JR PPA_ERR ; PPA_IOERR: LD A,PPA_STIOERR JR PPA_ERR ; PPA_TO: LD A,PPA_STTO JR PPA_ERR ; PPA_NOTSUP: LD A,PPA_STNOTSUP JR PPA_ERR ; PPA_ERR: LD (IY+PPA_STAT),A ; SAVE NEW STATUS ; PPA_ERR2: #IF (PPATRACE >= 2) CALL PPA_PRTSTAT #ENDIF OR A ; SET FLAGS RET ; ; ; PPA_PRTERR: RET Z ; DONE IF NO ERRORS ; FALL THRU TO PPA_PRTSTAT ; ; PRINT FULL DEVICE STATUS LINE ; PPA_PRTSTAT: PUSH AF PUSH DE PUSH HL LD A,(IY+PPA_STAT) CP PPA_STINVUNIT JR Z,PPA_PRTSTAT2 ; INVALID UNIT IS SPECIAL CASE CALL PPA_PRTPREFIX ; PRINT UNIT PREFIX JR PPA_PRTSTAT3 PPA_PRTSTAT2: CALL NEWLINE PRTS("PPA:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT PPA_PRTSTAT3: CALL PC_SPACE ; FORMATTING CALL PPA_PRTSTATSTR POP HL POP DE POP AF RET ; ; PRINT STATUS STRING ; PPA_PRTSTATSTR: PUSH AF PUSH DE LD A,(IY+PPA_STAT) OR A LD DE,PPA_STR_STOK JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STINVUNIT JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STNOMEDIA JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STCMDERR JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STIOERR JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STTO JR Z,PPA_PRTSTATSTR1 INC A LD DE,PPA_STR_STNOTSUP JR Z,PPA_PRTSTATSTR1 LD DE,PPA_STR_STUNK PPA_PRTSTATSTR1: CALL WRITESTR POP DE POP AF RET ; ; PRINT DIAGNONSTIC PREFIX ; PPA_PRTPREFIX: PUSH AF CALL NEWLINE PRTS("PPA$") LD A,(IY+PPA_DEV) ; GET CURRENT DEVICE NUM CP $FE ; NOT YET ASSIGNED? JR Z,PPA_PRTPREFIX1 ; SKIP DEV NUM IF SO CALL PRTDECB PPA_PRTPREFIX1: CALL PC_COLON POP AF RET ; ;============================================================================= ; STRING DATA ;============================================================================= ; PPA_STR_STOK .TEXT "OK$" PPA_STR_STINVUNIT .TEXT "INVALID UNIT$" PPA_STR_STNOMEDIA .TEXT "NO MEDIA$" PPA_STR_STCMDERR .TEXT "COMMAND ERROR$" PPA_STR_STIOERR .TEXT "IO ERROR$" PPA_STR_STTO .TEXT "TIMEOUT$" PPA_STR_STNOTSUP .TEXT "NOT SUPPORTED$" PPA_STR_STUNK .TEXT "UNKNOWN ERROR$" ; ;;;PPA_STR_NO .TEXT "NO$" PPA_STR_NOHW .TEXT "NOT PRESENT$" ; PPA_STR_MODE_NONE .TEXT "NONE$" PPA_STR_MODE_MG014 .TEXT "MG014$" PPA_STR_MODE_UNK .TEXT "???$" ; ;============================================================================= ; DATA STORAGE ;============================================================================= ; ;;;PPA_DSKBUF .DW 0 ; ACTIVE DISK BUFFER ; PPA_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT IMM_CMDSTK .DW 0 ; STACK PTR FOR CMD ABORTING IMM_DSKBUF .DW 0 ; WORKING DISK BUFFER POINTER IMM_XFRLEN .DW 0 ; WORKING TRANSFER LENGTH IMM_STATUS .DB 0, 0 ; CMD RESULT STATUS ; PPA_TYPE_MAP: .DW PPA_STR_NONE .DW PPA_STR_MG014 ; PPA_STR_NONE .DB "$" PPA_STR_MG014 .DB "MG014$" ; ; PPA DEVICE CONFIGURATION TABLE ; PPA_CFG: ; #IF (PPACNT >= 1) ; PPA0_CFG: ; DEVICE 0 .DB 0 ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) .DB PPA0MODE ; DRIVER DEVICE MODE .DB 0 ; DEVICE STATUS .DB PPA0BASE ; IO BASE ADDRESS .DW 0,0 ; DEVICE CAPACITY .DW 0,0 ; CURRENT LBA #ENDIF ; #IF (PPACNT >= 2) ; PPA1_CFG: ; DEVICE 1 .DB 0 ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) .DB PPA1MODE ; DRIVER DEVICE MODE .DB 0 ; DEVICE STATUS .DB PPA1BASE ; IO BASE ADDRESS .DW 0,0 ; DEVICE CAPACITY .DW 0,0 ; CURRENT LBA #ENDIF ; #IF ($ - PPA_CFG) != (PPACNT * PPA_CFGSIZ) .ECHO "*** INVALID PPA CONFIG TABLE ***\n" #ENDIF ; .DB $FF ; END MARKER