From 364e48a5d3f77a442498fd4063903868744d7c01 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Fri, 26 May 2023 16:48:13 -0700 Subject: [PATCH] IMM Driver Cleanup, PPA Driver Skeleton IMM Driver has rational timeouts now. It also lights the MG014 LED during activity. The PPA skeleton just attempts to determine if the PPA interface is present. It does not attempt any I/O. --- Source/CBIOS/cbios.asm | 7 + Source/CPM3/boot.z80 | 9 +- Source/HBIOS/hbios.asm | 2 - Source/HBIOS/imm.asm | 619 ++++++++++++--------- Source/HBIOS/lpt.asm | 2 +- Source/HBIOS/ppa.asm | 1182 +++++++++++----------------------------- Source/HBIOS/ppp.asm | 2 +- Source/HBIOS/std.asm | 10 + Source/ver.inc | 2 +- Source/ver.lib | 2 +- 10 files changed, 690 insertions(+), 1147 deletions(-) diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 97771883..0b06d19c 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -2929,6 +2929,12 @@ DRV_INIT3: RET ; DRV_INIT3A: + ; CHECK FOR HARD DISK REMOVABLE CARTRIDGE DRIVES + CP DIODEV_PPA ; PPA (ZIP DRIVE) IS REMOVABLE + JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK + CP DIODEV_IMM ; IMM (ZIP DRIVE) IS REMOVABLE + JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK + ; CHECK FOR ACTIVE AND RETURN IF NOT PUSH DE ; SAVE DE (HARD DISK VOLUME COUNTER) PUSH HL ; SAVE DRIVE LIST PTR @@ -2944,6 +2950,7 @@ DRV_INIT3A: RET NZ ; IF NO MEDIA, JUST RETURN +DRV_INIT3B: ; IF ACTIVE... LD (HL),C ; SAVE UNIT NUM IN LIST INC HL ; BUMP PTR diff --git a/Source/CPM3/boot.z80 b/Source/CPM3/boot.z80 index ce3fef1b..05dcb4f6 100644 --- a/Source/CPM3/boot.z80 +++ b/Source/CPM3/boot.z80 @@ -181,6 +181,12 @@ dinit3: ret ; dinit3a: + ; check for hard disk removable cartridge drives + cp 0A0h ; ppa (zip drive) is removable + jr z,dinit3b ; if so, skip media check + cp 0B0h ; imm (zip drive) is removable + jr z,dinit3b ; if so, skip media check + ; check for active and return if not push de ; save de (hard disk volume counter) push hl ; save drive list ptr @@ -195,7 +201,8 @@ dinit3a: pop de ; restore de ret nz ; if no media, just return - + +dinit3b: ; if active... ld (hl),c ; save unit num in list inc hl ; bump ptr diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index be5110c8..4af09d42 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -6786,7 +6786,6 @@ PS_PRTDC: RES 7,D ; CLEAR LBA BIT LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB CALL SRL32 ; RIGHT SHIFT - ;CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED) CALL PRTDEC32 ; PRINT DWORD IN DECIMAL PRTS("MB$") ; PRINT SUFFIX CALL PC_COMMA @@ -6801,7 +6800,6 @@ PS_PRTDC1: RES 7,D ; CLEAR LBA BIT LD B,1 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB CALL SRL32 ; RIGHT SHIFT - ;CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED) CALL PRTDEC32 ; PRINT DWORD IN DECIMAL PRTS("KB$") ; PRINT SUFFIX CALL PC_COMMA diff --git a/Source/HBIOS/imm.asm b/Source/HBIOS/imm.asm index 7c1b63ec..df3e8301 100644 --- a/Source/HBIOS/imm.asm +++ b/Source/HBIOS/imm.asm @@ -13,6 +13,7 @@ ; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX). ; ; 5/23/2023 WBW - INITIAL RELEASE +; 5/26/3023 WBW - CLEAN UP, LED ACTIVITY ; ;============================================================================= ; @@ -43,25 +44,16 @@ ; ; TODO: ; -; - TIMEOUT IS INFINITE!!! -; -; - ASSIGN DRIVE LETTERS EVEN WHEN NO MEDIA AT BOOT +; - CLEAN UP WAIT LOOP STUFF ; ; - OPTIMIZE READ/WRITE LOOPS ; -; - COMMENT MORE OF THE CODE -; -; - THERE ARE CURRENTLY NO BUFFER OVERRUN CHECKS. WE ASSUME SCSI -; DEVICES WILL SEND/REQUEST THE EXPECTED NUMBER OF BYTES. -; -; - MAKE THE MG014 STATUS LED DO SOMETHING USEFUL? -; ; NOTES: ; -; - THIS DRIVER IS FOR THE ZIP DRIVE EMM INTERFACE. IT WILL SIMPLY +; - THIS DRIVER IS FOR THE ZIP DRIVE IMM INTERFACE. IT WILL SIMPLY ; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE. ; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP -; DRIVE IS EMM OR PPA. SIGH. +; DRIVE IS IMM OR PPA. SIGH. ; ; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE ; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON @@ -76,6 +68,9 @@ ; THE STANDARD IBM PARALLEL PORT WHICH NECESSITATES A BUNCH OF EXTRA ; BIT FIDDLING ON EVERY READ. ; +; - SOME OF THE DATA TRANSFERS HAVE NO BUFFER OVERRUN CHECKS. IT IS +; ASSUMED SCSI DEVICES WILL SEND/REQUEST THE EXPECTED NUMBER OF BYTES. +; ; IMM PORT OFFSETS ; IMM_IODATA .EQU 0 ; PORT A, DATA, OUT @@ -87,17 +82,6 @@ IMM_IOSETUP .EQU 3 ; PPI SETUP ; IMM_SELF .EQU 7 IMM_TGT .EQU 6 -; -; SCSI COMMAND CODES -; -SCSI_CMD_READ .EQU $08 -SCSI_CMD_INQ .EQU $12 -SCSI_CMD_TEST .EQU $00 -SCSI_CMD_START .EQU $1B -SCSI_CMD_SENSE .EQU $03 -SCSI_CMD_WRITE .EQU $0A -SCSI_CMD_RDCAP .EQU $25 - ; ; IMM DEVICE STATUS ; @@ -223,12 +207,18 @@ IMM_DETECT: 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 DELAY ; BRIEF DELAY FOR GOOD MEASURE ; + ; WE USE THIS SEQUENCE TO DETECT AN ACTUAL IMM DEVICE ON THE + ; PARALLEL PORT. THE VALUES RECORDED IN THE FINAL CALL TO + ; IMM_DISCONNECT ARE USED TO CONFIRM DEVICE PRESENCE. + ; NO ACTUAL SCSI COMMANDS ARE USED. CALL IMM_DISCONNECT CALL IMM_CONNECT CALL IMM_DISCONNECT ; + ; THE IMM_SN VALUES ARE RECORDED IN THE CPP ROUTINE USED BY + ; IMM_CONNECT/DISCONNECT. ; EXPECTING S1=$B8, S2=$18, S3=$38 LD A,(IMM_S1) CP $B8 @@ -273,18 +263,18 @@ IMM_DEFMED: ; ; IMM_READ: - CALL HB_DSKREAD - LD A,SCSI_CMD_READ - LD (IMM_CMD_RW),A - JP IMM_IO + CALL HB_DSKREAD ; HOOK DISK READ CONTROLLER + LD A,SCSI_CMD_READ ; SETUP SCSI READ + LD (IMM_CMD_RW),A ; AND SAVE IT IN SCSI CMD + JP IMM_IO ; DO THE I/O ; ; ; IMM_WRITE: - CALL HB_DSKREAD - LD A,SCSI_CMD_WRITE - LD (IMM_CMD_RW),A - JP IMM_IO + CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER + LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE + LD (IMM_CMD_RW),A ; AND SAVE IT IN SCSI CMD + JP IMM_IO ; DO THE I/O ; ; ; @@ -292,7 +282,7 @@ IMM_IO: LD (IMM_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS CALL IMM_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO JR NZ,IMM_IO3 ; BAIL OUT ON ERROR -; +; ; SETUP LBA ; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN LD HL,IMM_CMD_RW+1 ; START OF LBA FIELD IN CDB (MSB) @@ -307,11 +297,11 @@ IMM_IO: INC HL ; ; DO SCSI IO - LD DE,(IMM_DSKBUF) - LD BC,512 - LD HL,IMM_CMD_RW - CALL IMM_RUNCMD - CALL Z,IMM_CHKCMD + LD DE,(IMM_DSKBUF) ; DISK BUFFER TO DE + LD BC,512 ; ONE SECTOR, 512 BYTES + LD HL,IMM_CMD_RW ; POINT TO READ/WRITE CMD TEMPLATE + CALL IMM_RUNCMD ; RUN THE SCSI ENGINE + CALL Z,IMM_CHKCMD ; IF EXIT OK, CHECK SCSI RESULTS JR NZ,IMM_IO2 ; IF ERROR, SKIP INCREMENT ; INCREMENT LBA LD A,IMM_LBA ; LBA OFFSET @@ -343,7 +333,7 @@ IMM_STATUS: ; ; IMM_RESET: - JP IMM_INITDEV + JP IMM_INITDEV ; JUST (RE)INIT DEVICE ; ; ; @@ -363,7 +353,7 @@ IMM_MEDIA: OR A ; SET FLAGS JR Z,IMM_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA ; - CALL IMM_RESET ; RESET IMM INTERFACE + CALL IMM_RESET ; RESET INCLUDES MEDIA CHECK ; IMM_MEDIA1: LD A,(IY+IMM_STAT) ; GET STATUS @@ -418,64 +408,81 @@ IMM_GEOM: ; FUNCTION SUPPORT ROUTINES ;============================================================================= ; +; OUTPUT BYTE IN A TO THE DATA PORT +; IMM_WRITEDATA: - LD C,(IY+IMM_IOBASE) - OUT (C),A - CALL DELAY - RET + LD C,(IY+IMM_IOBASE) ; DATA PORT IS AT IOBASE + OUT (C),A ; WRITE THE BYTE + ;CALL DELAY ; IS THIS NEEDED??? + RET ; DONE ; ; ; IMM_WRITECTRL: - XOR $0B - LD C,(IY+IMM_IOBASE) - INC C + ; IBM PC INVERTS ALL BUT C2 ON THE BUS, MG014 DOES NOT. + ; BELOW TRANSLATES FROM IBM -> MG014. IT ALSO INVERTS THE + ; MG014 LED SIMPLY TO MAKE IT EASY TO KEEP LED ON DURING + ; ALL ACTIVITY. + XOR $0B | $80 ; HIGH BIT IS MG014 LED + LD C,(IY+IMM_IOBASE) ; GET BASE IO ADDRESS + INC C ; BUMP TO CONTROL PORT INC C - OUT (C),A - CALL DELAY - RET + OUT (C),A ; WRITE TO CONTROL PORT + ;CALL DELAY ; IS THIS NEEDED? + RET ; DONE ; +; READ THE PARALLEL PORT INPUT LINES (STATUS) AND MAP SIGNALS FROM +; MG014 TO IBM STANDARD. NOTE POLARITY CHANGE REQUIRED FOR BUSY. ; +; MG014 IBM PC +; -------- -------- +; 0: /ACK 6: /ACK +; 1: BUSY 7: /BUSY +; 2: POUT 5: POUT +; 3: SEL 4: SEL +; 4: /ERR 3: /ERR ; IMM_READSTATUS: - LD C,(IY+IMM_IOBASE) - INC C - IN A,(C) + LD C,(IY+IMM_IOBASE) ; IOBASE TO C + INC C ; BUMP TO STATUS PORT + IN A,(C) ; READ IT LD C,0 ; INIT RESULT -; - BIT 0,A ; ACK = $01 +; + ; SHUFFLE BITS + BIT 0,A ; 0: /ACK JR Z,IMM_READSTATUS1 - SET 6,C ; $40 + SET 6,C ; 6: /ACK ; IMM_READSTATUS1: -; - BIT 1,A ; BUSY = $02 - JR NZ,IMM_READSTATUS2 - SET 7,C ; $80 +; + BIT 1,A ; 1: BUSY + JR NZ,IMM_READSTATUS2 ; POLARITY CHANGE! + SET 7,C ; 7: /BUSY ; IMM_READSTATUS2: -; - BIT 2,A ; PAPER = $04 +; + BIT 2,A ; 2: POUT JR Z,IMM_READSTATUS3 - SET 5,C ; $20 + SET 5,C ; 5: POUT ; IMM_READSTATUS3: -; - BIT 3,A ; SELECT = $08 +; + BIT 3,A ; 3: SEL JR Z,IMM_READSTATUS4 - SET 4,C ; $10 + SET 4,C ; 4: SEL ; IMM_READSTATUS4: -; - BIT 4,A ; FAULT = $10 +; + BIT 4,A ; 4: /ERR JR Z,IMM_READSTATUS5 - SET 3,C ; $08 + SET 3,C ; 3: /ERR ; IMM_READSTATUS5: - LD A,C + LD A,C ; RESULT TO A RET ; -; +; SIGNAL SEQUENCE TO CONNECT/DISCONNECT +; VALUE IN A IS WRITTEN TO DATA PORT DURING SEQUENCE ; IMM_CPP: PUSH AF @@ -516,7 +523,7 @@ IMM_CPP: ; CONNECT: S1=$B8 S2=$18 S3=$30 ; DISCONNECT: S1=$B8 S2=$18 S3=$38 ; -#IF (IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nCPP: S1=$") LD A,(IMM_S1) CALL PRTHEXBYTE @@ -535,7 +542,7 @@ IMM_S1 .DB 0 IMM_S2 .DB 0 IMM_S3 .DB 0 ; -; +; SEQUENCE TO CONNECT TO DEVICE ON PARALLEL PORT BUS. ; IMM_CONNECT: LD A,$E0 @@ -546,14 +553,20 @@ IMM_CONNECT: CALL IMM_CPP RET ; -; +; SEQUENCE TO DISCONNECT FROM DEVICE ON PARALLEL PORT BUS. +; THE FINAL IMM_WRITECTRL IS ONLY TO TURN OFF THE MG014 STATUS LED. ; IMM_DISCONNECT: LD A,$30 CALL IMM_CPP - RET ; + ; TURNS OFF MG014 LED + LD A,$8C + CALL IMM_WRITECTRL +; + RET ; +; INITIATE A SCSI BUS RESET. ; IMM_RESETPULSE: LD A,$04 @@ -574,10 +587,10 @@ IMM_RESETPULSE: CALL IMM_WRITECTRL RET ; -; +; SCSI SELECT PROCESS ; IMM_SELECT: -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nSELECT: $") #ENDIF LD A,$0C @@ -598,13 +611,14 @@ IMM_SELECT1: IMM_SELECT2: LD A,$04 CALL IMM_WRITECTRL + ; PLACE HOST AND TARGET BIT ON DATA BUS LD A,$80 | (1 << IMM_TGT) CALL IMM_WRITEDATA - CALL DELAY + CALL DELAY ; CONFIRM DELAY TIME? LD A,$0C CALL IMM_WRITECTRL ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL IMM_READSTATUS CALL PC_SPACE CALL PRTHEXBYTE @@ -613,7 +627,7 @@ IMM_SELECT2: LD A,$0D CALL IMM_WRITECTRL ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL IMM_READSTATUS CALL PC_SPACE CALL PRTHEXBYTE @@ -623,12 +637,12 @@ IMM_SELECT2: ; IMM_SELECT3: CALL IMM_READSTATUS -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF AND $08 - JR NZ,IMM_SELECT4 ; IF CLEAR, MOVE ON + JR NZ,IMM_SELECT4 ; IF SET, MOVE ON DEC HL LD A,H OR L @@ -642,99 +656,123 @@ IMM_SELECT4: XOR A RET ; +; SEND SCSI CMD BYTE STRING. AT ENTRY, HL POINTS TO START OF +; COMMAND BYTES. THE LENGTH OF THE COMMAND STRING MUST PRECEED +; THE COMMAND BYTES (HL - 1). ; +; NOTE THAT DATA IS SENT AS BYTE PAIRS! EACH LOOP SENDS 2 BYTES. +; DATA OUTPOUT IS BURSTED (NO CHECK FOR BUSY). SEEMS TO WORK FINE. ; IMM_SENDCMD: ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nSENDCMD:$") #ENDIF ; - LD HL,0 + DEC HL ; BACKUP TO LENGTH BYTE + LD B,(HL) ; PUT IN B FOR LOOP COUNTER +; +#IF (IMMTRACE >= 3) + LD A,B + CALL PC_SPACE + CALL PRTHEXBYTE + PRTS(" BYTES$") +#ENDIF +; + INC HL ; BACK TO FIRST CMD BYTE IMM_SENDCMD1: - PUSH HL - CALL IMM_WAITDONE - POP HL - CP $A8 - JR NZ,IMM_SENDCMD2 LD A,$04 CALL IMM_WRITECTRL - LD A,(DE) + LD A,(HL) ; LOAD CMD BYTE ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF ; - CALL IMM_WRITEDATA - INC DE - INC HL + CALL IMM_WRITEDATA ; PUT IT ON THE BUS + INC HL ; BUMP TO NEXT BYTE + DEC B ; DEC LOOP COUNTER LD A,$05 CALL IMM_WRITECTRL - LD A,(DE) + LD A,(HL) ; LOAD CMD BYTE ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF ; - CALL IMM_WRITEDATA - INC DE - INC HL + CALL IMM_WRITEDATA ; PUT IT ON THE BUS + INC HL ; BUMP TO NEXT BYTE LD A,$00 CALL IMM_WRITECTRL - JR IMM_SENDCMD1 + DJNZ IMM_SENDCMD1 ; LOOP TILL DONE ; IMM_SENDCMD2: LD A,$04 CALL IMM_WRITECTRL -; -#IF IMMTRACE >= 2) - CALL PC_SPACE - CALL PRTHEXWORDHL - PRTS(" BYTES$") -#ENDIF ; RET ; +; WAIT FOR SCSI BUS TO BECOME READY WITH A TIMEOUT. ; -; -IMM_WAITBUSY: - LD HL,500 ; NORMAL TIMEOUT COUNTER -; -IMM_WAITBUSY_HL: ; VARIABLE TIMEOUT ENTRY - LD A,$0C - CALL IMM_WRITECTRL -; -IMM_WAITBUSY2: +IMM_WAITLOOP: CALL IMM_READSTATUS BIT 7,A - RET NZ ; IF SET, MOVE ON + RET NZ ; DONE, STATUS IN A DEC HL LD A,H OR L - ; TODO: IMPLEMENT TIMEOUT!!! - ;JP Z,IMM_CMD_TIMEOUT ; TIMEOUT - JR IMM_WAITBUSY2 + RET Z ; TIMEOUT + JR IMM_WAITLOOP ; +IMM_WAIT: + LD HL,500 ; GOOD VALUE??? + LD A,$0C + CALL IMM_WRITECTRL + CALL IMM_WAITLOOP + JP Z,IMM_CMD_TIMEOUT ; HANDLE TIMEOUT + PUSH AF + LD A,$04 + CALL IMM_WRITECTRL + POP AF + AND $B8 + RET ; RETURN W/ RESULT IN A ; +; MAX OBSERVED IMM_WAITLOOP ITERATIONS IS $0116B3 ; -IMM_WAITDONE: - LD HL,500 ; NORMAL TIMEOUT COUNTER +IMM_LONGWAIT: + LD B,3 ; VALUE??? + LD A,$0C + CALL IMM_WRITECTRL +IMM_LONGWAIT1: + LD HL,0 + CALL IMM_WAITLOOP + JR NZ,IMM_LONGWAIT2 ; HANDLE SUCCESS + DJNZ IMM_LONGWAIT1 ; LOOP TILL COUNTER EXHAUSTED + JP IMM_CMD_TIMEOUT ; HANDLE TIMEOUT ; -IMM_WAITDONE_HL: ; VARIABLE TIMEOUT ENTRY - CALL IMM_WAITBUSY_HL - AND $B8 +IMM_LONGWAIT2: PUSH AF LD A,$04 CALL IMM_WRITECTRL - POP AF - RET ; +#IF 0 + CALL PC_GT + LD A,B + CALL PRTHEXBYTE + CALL PC_COLON + CALL PRTHEXWORDHL +#ENDIF ; + POP AF + AND $B8 + RET ; RETURN W/ RESULT IN A +; +; PEROFRM SCSI BUS NEGOTIATION. REQURIED PRIOR TO DATA READS. ; IMM_NEGOTIATE: -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nNEGO: $") #ENDIF LD A,$04 @@ -758,29 +796,28 @@ IMM_NEGOTIATE: ; POP AF ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF ; AND $20 ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PC_GT CALL PRTHEXBYTE #ENDIF ; - CP $20 + CP $20 ; $20 MEANS DATA READY JP NZ,IMM_CMD_IOERR RET ; -; +; GET A BYTE OF DATA FROM THE SCSI DEVICE. THIS IS A NIBBLE READ. +; BYTE RETURNED IN A. ; IMM_GETBYTE: - CALL IMM_WAITBUSY - LD A,$04 - CALL IMM_WRITECTRL + CALL IMM_WAIT LD A,$06 CALL IMM_WRITECTRL CALL IMM_READSTATUS @@ -802,53 +839,62 @@ IMM_GETBYTE: POP AF RET ; +; GET A CHUNK OF DATA FROM SCSI BUS. THIS IS SPECIFICALLY FOR +; READ PHASE. IF A LENGTH IS SPECIFIED (NON-ZERO HL), THEN THE +; DATA IS BURST READ. IF NO LENGTH SPECIFIED, DATA IS READ AS +; LONG AS SCSI DEVICE WANTS TO CONTINUE SENDING (NO OVERRUN +; CHECK IN THIS CASE). +; +; THIS IS A NIBBLE READ. +; ; DE=BUFFER ; HL=LENGTH (0 FOR VARIABLE) ; IMM_GETDATA: + ; BRANCH TO CORRECT ROUTINE LD A,H - OR L - JR NZ,IMM_GETDATALEN + OR L ; IF ZERO + JR NZ,IMM_GETDATALEN ; DO BURST READ ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nGETDATA:$") #ENDIF ; IMM_GETDATA1: - PUSH HL - CALL IMM_WAITDONE - POP HL - CP $98 - JR NZ,IMM_GETDATA2 + PUSH HL ; SAVE BYTE COUNTER + CALL IMM_WAIT ; WAIT FOR BUS READY + POP HL ; RESTORE BYTE COUNTER + CP $98 ; CHECK FOR READ PHASE + JR NZ,IMM_GETDATA2 ; IF NOT, ASSUME WE ARE DONE LD A,$04 CALL IMM_WRITECTRL LD A,$06 CALL IMM_WRITECTRL - CALL IMM_READSTATUS - AND $F0 - RRCA + CALL IMM_READSTATUS ; GET FIRST NIBBLE + AND $F0 ; ISOLATE BITS + RRCA ; AND SHIFT TO LOW NIBBLE RRCA RRCA RRCA - PUSH AF + PUSH AF ; SAVE WORKING VALUE LD A,$05 CALL IMM_WRITECTRL - CALL IMM_READSTATUS - AND $F0 - POP BC - OR B - LD (DE),A - INC DE - INC HL + CALL IMM_READSTATUS ; GET SECOND NIBBLE + AND $F0 ; ISOLATE BITS + POP BC ; RECOVER LOW NIBBLE + OR B ; COMBINE + LD (DE),A ; AND SAVE THE FULL BYTE VALUE + INC DE ; NEXT BUFFER POS + INC HL ; INCREMENT BYTES COUNTER LD A,$04 CALL IMM_WRITECTRL LD A,$0C CALL IMM_WRITECTRL - JR IMM_GETDATA1 + JR IMM_GETDATA1 ; LOOP TILL DONE ; IMM_GETDATA2: ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") @@ -858,7 +904,7 @@ IMM_GETDATA2: ; IMM_GETDATALEN: ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nGETDLEN:$") CALL PC_SPACE CALL PRTHEXWORDHL @@ -870,31 +916,39 @@ IMM_GETDATALEN: IMM_GETDATALEN1: LD A,$06 CALL IMM_WRITECTRL - CALL IMM_READSTATUS - AND $F0 - RRCA + CALL IMM_READSTATUS ; GET FIRST NIBBLE + AND $F0 ; ISOLATE BITS + RRCA ; MOVE TO LOW NIBBLE RRCA RRCA RRCA - PUSH AF + PUSH AF ; SAVE WORKING VALUE LD A,$05 CALL IMM_WRITECTRL - CALL IMM_READSTATUS - AND $F0 - POP BC - OR B - LD (DE),A - INC DE - DEC HL + CALL IMM_READSTATUS ; GET SECOND NIBBLE + AND $F0 ; ISOLATE BITS + POP BC ; RECOVER FIRST NIBBLE + OR B ; COMBINE + LD (DE),A ; SAVE FINAL BYTE VALUE + INC DE ; NEXT BUFFER POS + DEC HL ; DEC LOOP COUNTER LD A,$04 CALL IMM_WRITECTRL - LD A,H + LD A,H ; CHECK LOOP COUNTER OR L - JR NZ,IMM_GETDATALEN1 + JR NZ,IMM_GETDATALEN1 ; LOOP IF NOT DONE LD A,$0C CALL IMM_WRITECTRL RET ; +; PUT A CHUNK OF DATA TO THE SCSI BUS. THIS IS SPECIFICALLY FOR +; WRITE PHASE. IF A LENGTH IS SPECIFIED (NON-ZERO HL), THEN THE +; DATA IS BURST WRITTEN. IF NO LENGTH SPECIFIED, DATA IS WRITTEN AS +; LONG AS SCSI DEVICE WANTS TO CONTINUE RECEIVING (NO OVERRUN +; CHECK IN THIS CASE). +; +; READS ARE DONE AS BYTE PAIRS. EACH LOOP READS 2 BYTES. +; ; DE=BUFFER ; HL=LENGTH (0 FOR VARIABLE) ; @@ -903,37 +957,37 @@ IMM_PUTDATA: OR L JR NZ,IMM_PUTDATALEN ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nPUTDATA:$") #ENDIF ; IMM_PUTDATA1: - PUSH HL - CALL IMM_WAITDONE - POP HL - CP $88 - JR NZ,IMM_PUTDATA2 + PUSH HL ; SAVE BYTE COUNTER + CALL IMM_WAIT ; WAIT FOR BUS READY + POP HL ; RESTORE BYTE COUNTER + CP $88 ; CHECK FOR WRITE PHASE + JR NZ,IMM_PUTDATA2 ; IF NOT, ASSUME WE ARE DONE LD A,$04 CALL IMM_WRITECTRL - LD A,(DE) - CALL IMM_WRITEDATA - INC DE - INC HL + LD A,(DE) ; GET NEXT BYTE TO WRITE (FIRST OF PAIR) + CALL IMM_WRITEDATA ; PUT ON BUS + INC DE ; BUMP TO NEXT BUF POS + INC HL ; INCREMENT COUNTER LD A,$05 CALL IMM_WRITECTRL - LD A,(DE) - CALL IMM_WRITEDATA - INC DE - INC HL + LD A,(DE) ; GET NEXT BYTE TO WRITE (SECOND OF PAIR) + CALL IMM_WRITEDATA ; PUT ON BUS + INC DE ; BUMP TO NEXT BUF POS + INC HL ; INCREMENT COUNTER LD A,$00 CALL IMM_WRITECTRL - JR IMM_PUTDATA1 + JR IMM_PUTDATA1 ; LOOP TILL DONE ; IMM_PUTDATA2: LD A,$04 CALL IMM_WRITECTRL ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXWORDHL PRTS(" BYTES$") @@ -943,7 +997,7 @@ IMM_PUTDATA2: ; IMM_PUTDATALEN: ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nPUTDLEN:$") CALL PC_SPACE CALL PRTHEXWORDHL @@ -953,55 +1007,55 @@ IMM_PUTDATALEN: LD A,$04 CALL IMM_WRITECTRL IMM_PUTDATALEN1: - LD A,(DE) - CALL IMM_WRITEDATA - INC DE - DEC HL + LD A,(DE) ; GET NEXT BYTE (FIRST OF PAIR) + CALL IMM_WRITEDATA ; PUT ON BUS + INC DE ; INCREMENT BUF POS + DEC HL ; DEC LOOP COUNTER LD A,$05 CALL IMM_WRITECTRL - LD A,(DE) - CALL IMM_WRITEDATA - INC DE - DEC HL + LD A,(DE) ; GET NEXT BYTE (SECOND OF PAIR) + CALL IMM_WRITEDATA ; PUT ON BUS + INC DE ; INCREMENT BUF POS + DEC HL ; DEC LOOP COUNTER LD A,$00 CALL IMM_WRITECTRL - LD A,H + LD A,H ; CHECK LOOP COUNTER OR L - JR NZ,IMM_PUTDATALEN1 + JR NZ,IMM_PUTDATALEN1 ; LOOP TILL DONE LD A,$04 CALL IMM_WRITECTRL RET ; -; +; READ SCSI COMMAND STATUS ; IMM_GETSTATUS: ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) PRTS("\r\nSTATUS:$") #ENDIF ; - CALL IMM_GETBYTE - LD (IMM_CMDSTAT),A + CALL IMM_GETBYTE ; GET ONE BYTE + LD (IMM_CMDSTAT),A ; SAVE AS FIRST STATUS BYTE ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF ; - CALL IMM_WAITDONE - CP $B8 - RET NZ - CALL IMM_GETBYTE - LD (IMM_CMDSTAT+1),A + CALL IMM_WAIT ; CHECK FOR OPTIONAL SECOND BYTE + CP $B8 ; STILL IN STATUS PHASE? + RET NZ ; IF NOT, DONE + CALL IMM_GETBYTE ; ELSE, GET THE SECOND BYTE + LD (IMM_CMDSTAT+1),A ; AND SAVE IT ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) CALL PC_SPACE CALL PRTHEXBYTE #ENDIF ; RET ; -; +; TERMINATE A BULD READ OPERATION ; IMM_ENDREAD: LD A,$04 @@ -1014,26 +1068,37 @@ IMM_ENDREAD: CALL IMM_WRITECTRL RET ; +; THIS IS THE MAIN SCSI ENGINE. BASICALLY, IT SELECTS THE DEVICE +; ON THE BUS, SENDS THE COMMAND, THEN PROCESSES THE RESULT. +; ; HL: COMMAND BUFFER ; DE: TRANSFER BUFFER ; BC: TRANSFER LENGTH (0=VARIABLE) ; IMM_RUNCMD: + ; THERE ARE MANY PLACES NESTED WITHIN THE ROUTINES THAT + ; ARE CALLED HERE. HERE WE SAVE THE STACK SO THAT WE CAN + ; EASILY AND QUICKLY ABORT OUT OF ANY NESTED ROUTINE. + ; SEE IMM_CMD_ERR BELOW. LD (IMM_CMDSTK),SP ; FOR ERROR ABORTS LD (IMM_DSKBUF),DE ; SAVE BUF PTR LD (IMM_XFRLEN),BC ; SAVE XFER LEN PUSH HL - CALL IMM_CONNECT - CALL IMM_SELECT - CALL IMM_WAITBUSY - POP DE - CALL IMM_SENDCMD + CALL IMM_CONNECT ; PARALLEL PORT BUS CONNECT + CALL IMM_SELECT ; SELECT TARGET DEVICE + CALL IMM_WAIT ; WAIT TILL READY + POP HL + CALL IMM_SENDCMD ; SEND THE COMMAND ; IMM_RUNCMD_PHASE: - LD HL,50000 ; LONG TIMEOUT HERE - CALL IMM_WAITDONE_HL -; -#IF IMMTRACE >= 2) + ; WAIT FOR THE BUS TO BE READY. WE USE AN EXTRA LONG WAIT + ; TIMEOUT HERE BECAUSE THIS IS WHERE WE WILL WAIT FOR LONG + ; OPERATIONS TO COMPLETE. IT CAN TAKE SOME TIME IF THE + ; DEVICE HAS GONE TO SLEEP BECAUSE IT WILL NEED TO WAKE UP + ; AND SPIN UP BEFORE PROCESSING AN I/O COMMAND. + CALL IMM_LONGWAIT ; WAIT TILL READY +; +#IF (IMMTRACE >= 3) PRTS("\r\nPHASE: $") CALL PRTHEXBYTE #ENDIF @@ -1047,52 +1112,58 @@ IMM_RUNCMD_PHASE: JR IMM_CMD_IOERR ; IMM_RUNCMD_WRITE: - LD DE,(IMM_DSKBUF) + LD DE,(IMM_DSKBUF) ; XFER BUFFER LD HL,(IMM_XFRLEN) ; XFER LENGTH CALL IMM_PUTDATA ; SEND DATA NOW - JR IMM_RUNCMD_PHASE + JR IMM_RUNCMD_PHASE ; BACK TO DISPATCH ; IMM_RUNCMD_READ: - CALL IMM_NEGOTIATE - CALL IMM_WAITDONE + CALL IMM_NEGOTIATE ; NEGOTIATE FOR READ + CALL IMM_WAIT ; WAIT TILL READY ; CHECK FOR STATUS $98??? - LD DE,(IMM_DSKBUF) + LD DE,(IMM_DSKBUF) ; XFER BUFFER LD HL,(IMM_XFRLEN) ; XFER LENGTH CALL IMM_GETDATA ; GET THE DATA NOW - CALL IMM_ENDREAD - JR IMM_RUNCMD_PHASE + CALL IMM_ENDREAD ; TERMINATE THE READ + JR IMM_RUNCMD_PHASE ; BACK TO DISPATCH ; IMM_RUNCMD_END: - CALL IMM_NEGOTIATE - CALL IMM_WAITDONE + CALL IMM_NEGOTIATE ; NEGOTIATE FOR READ (STATUS) + CALL IMM_WAIT ; WAIT TILL READY ; CHECK FOR STATUS $B8??? - CALL IMM_GETSTATUS - CALL IMM_ENDREAD - CALL IMM_DISCONNECT + CALL IMM_GETSTATUS ; READ STATUS BYTES + CALL IMM_ENDREAD ; TERMINATE THE READ + CALL IMM_DISCONNECT ; PARALLEL PORT BUS DISCONNECT XOR A ; SIGNAL SUCCESS RET ; IMM_CMD_IOERR: - LD A,IMM_STIOERR - JR IMM_CMD_ERR + LD A,IMM_STIOERR ; ERROR VALUE TO A + JR IMM_CMD_ERR ; CONTINUE ; IMM_CMD_TIMEOUT: - LD A,IMM_STTO - JR IMM_CMD_ERR + LD A,IMM_STTO ; ERROR VALUE TO A + JR IMM_CMD_ERR ; CONTINUE ; IMM_CMD_ERR: LD SP,(IMM_CMDSTK) ; UNWIND STACK PUSH AF ; SAVE STATUS ;CALL IMM_RESETPULSE ; CLEAN UP THE MESS??? - LD DE,62 + LD DE,62 ; DELAY AFTER RESET PULSE CALL VDELAY - CALL IMM_DISCONNECT - LD DE,62 + CALL IMM_DISCONNECT ; PARALLEL PORT BUS DISCONNECT + LD DE,62 ; DELAY AFTER DISCONNECT CALL VDELAY POP AF ; RECOVER STATUS - JP IMM_ERR ; ERROR EXIT -; + JP IMM_ERR ; NOW DO STANDARD ERR PROCESSING ; +; ERRORS SHOULD GENERALLY NOT CAUSE SCSI PROCESSING TO FAIL. IF A +; DEVICE ERROR (I.E., READ ERROR) OCCURS, THEN THE SCSI PROTOCOL WILL +; PROVIDE ERROR INFORMATION. THE STATUS RESULT OF THE SCSI COMMAND +; WILL INDICATE IF AN ERROR OCCURRED. ADDITIONALLY, IF THE ERROR IS +; A CHECK CONDITION ERROR, THEN IT IS MANDATORY TO ISSUE A SENSE +; REQUEST SCSI COMMAND TO CLEAR THE ERROR AND RETRIEVE DETAILED ERROR +; INFO. ; IMM_CHKCMD: ; SCSI COMMAND COMPLETED, CHECK SCSI CMD STATUS @@ -1114,7 +1185,7 @@ IMM_CHKCMD1: JP NZ,IMM_IOERR ; BAIL IF ERROR IN CMD ; ; REQ SENSE CMD COMPLETED -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) LD A,16 LD DE,HB_WRKBUF CALL Z,PRTHEXBUF @@ -1126,6 +1197,7 @@ IMM_CHKCMD1: JP NZ,IMM_IOERR ; IF FAILED, GENERAL I/O ERROR ; ; RETURN RESULT BASED ON REQ SENSE DATA + ; TODO: WE NEED TO CHECK THE SENSE KEY FIRST!!! LD A,(HB_WRKBUF+12) ; GET ADDITIONAL SENSE CODE CP $3A ; NO MEDIA? JP Z,IMM_NOMEDIA ; IF SO, RETURN NO MEDIA ERR @@ -1149,65 +1221,73 @@ IMM_INITDEV: 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 DELAY ; SHORT DELAY FOR BUS SETTLE ; - CALL IMM_DISCONNECT - CALL IMM_CONNECT - CALL IMM_RESETPULSE - LD DE,62 + CALL IMM_DISCONNECT ; DISCONNECT FIRST JUST IN CASE + CALL IMM_CONNECT ; NOW CONNECT TO BUS + CALL IMM_RESETPULSE ; ISSUE A SCSI BUS RESET + LD DE,62 ; WAIT A BIT CALL VDELAY - CALL IMM_DISCONNECT - LD DE,62 + CALL IMM_DISCONNECT ; AND DISCONNECT FROM BUS + LD DE,62 ; WAIT A BIT MORE CALL VDELAY ; - LD B,4 + ; INITIALLY, THE DEVICE MAY REQUIRE MULTIPLE REQUEST SENSE + ; COMMANDS BEFORE IT WILL ACCEPT I/O COMMANDS. THIS IS DUE + ; TO THINGS LIKE BUS RESET NOTIFICATION, MEDIA CHANGE, ETC. + ; HERE, WE RUN A FEW REQUEST SENSE COMMANDS. AS SOON AS ONE + ; INDICATES NO ERRORS, WE CAN CONTINUE. + LD B,4 ; TRY UP TO 4 TIMES IMM_INITDEV1: - PUSH BC + PUSH BC ; SAVE LOOP COUNTER ; ; REQUEST SENSE COMMAND - LD DE,HB_WRKBUF - LD BC,0 - LD HL,IMM_CMD_SENSE - CALL IMM_RUNCMD + LD DE,HB_WRKBUF ; BUFFER FOR SENSE DATA + LD BC,0 ; READ WHATEVER IS SENT + LD HL,IMM_CMD_SENSE ; POINT TO CMD BUFFER + CALL IMM_RUNCMD ; RUN THE SCSI ENGINE JR NZ,IMM_INITDEV2 ; CMD PROC ERROR ; ; CHECK CMD STATUS LD A,(IMM_CMDSTAT) ; GET STATUS BYTE OR A ; SET FLAGS - JR NZ,IMM_INITDEV2 ; BAD CMD STATUS + JR NZ,IMM_INITDEV2 ; IF ERROR, LOOP ; -#IF IMMTRACE >= 2) +#IF (IMMTRACE >= 3) LD A,16 LD DE,HB_WRKBUF CALL PRTHEXBUF #ENDIF ; ; CHECK SENSE KEY - LD A,(HB_WRKBUF + 2) - OR A + LD A,(HB_WRKBUF + 2) ; GET SENSE KEY + OR A ; SET FLAGS ; IMM_INITDEV2: - POP BC + POP BC ; RESTORE LOOP COUNTER JR Z,IMM_INITDEV3 ; IF NO ERROR, MOVE ON DJNZ IMM_INITDEV1 ; TRY UNTIL COUNTER EXHAUSTED - JP IMM_IOERR ; HANDLE ERROR + JP IMM_IOERR ; BAIL OUT WITH ERROR ; IMM_INITDEV3: ; READ & RECORD DEVICE CAPACITY - LD DE,HB_WRKBUF - LD BC,0 - LD HL,IMM_CMD_RDCAP - CALL IMM_RUNCMD - CALL Z,IMM_CHKCMD - RET NZ ; MEDIA PROBLEM -; -#IF IMMTRACE >= 2) + LD DE,HB_WRKBUF ; BUFFER TO CAPACITY RESPONSE + LD BC,0 ; READ WHATEVER IS SENT + LD HL,IMM_CMD_RDCAP ; POINT TO READ CAPACITY CMD + CALL IMM_RUNCMD ; RUN THE SCSI ENGINE + CALL Z,IMM_CHKCMD ; CHECK AND RECORD AND ERRORS + RET NZ ; BAIL ON ON ERROR +; +#IF (IMMTRACE >= 3) LD A,8 LD DE,HB_WRKBUF CALL PRTHEXBUF #ENDIF ; - ; INCREMENT, BIG->LITTLE ENDIAN, SAVE + ; 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,IMM_MEDCAP ; OFFSET IN CFG FOR CAPACITY CALL LDHLIYA ; POINTER TO HL PUSH HL ; SAVE IT @@ -1430,10 +1510,13 @@ IMM_TYPE_MAP: IMM_STR_NONE .DB "$" IMM_STR_MG014 .DB "MG014$" ; -; SCSI COMMAND TEMPLATES +; SCSI COMMAND TEMPLATES (LENGTH PREFIXED) ; + .DB 6 IMM_CMD_RW .DB $00, $00, $00, $00, $01, $00 ; READ/WRITE SECTOR + .DB 6 IMM_CMD_SENSE .DB $03, $00, $00, $00, $FF, $00 ; REQUEST SENSE DATA + .DB 10 IMM_CMD_RDCAP .DB $25, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; READ CAPACITY ; ; IMM DEVICE CONFIGURATION TABLE diff --git a/Source/HBIOS/lpt.asm b/Source/HBIOS/lpt.asm index 7075a7e1..1ee0aab6 100644 --- a/Source/HBIOS/lpt.asm +++ b/Source/HBIOS/lpt.asm @@ -372,7 +372,7 @@ LPT_PRTCFG: CALL PRTHEXBYTE ; PRINT BASE PORT ; PRINT THE LPT TYPE - CALL PC_SPACE ; FORMATTING + PRTS(": MODE=$") ; FORMATTING LD A,(IY+1) ; GET LPT TYPE BYTE RLCA ; MAKE IT A WORD OFFSET LD HL,LPT_TYPE_MAP ; POINT HL TO TYPE MAP TABLE diff --git a/Source/HBIOS/ppa.asm b/Source/HBIOS/ppa.asm index 529b81b3..e74077de 100644 --- a/Source/HBIOS/ppa.asm +++ b/Source/HBIOS/ppa.asm @@ -12,7 +12,8 @@ ; CREATED BY WAYNE WARTHEN FOR ROMWBW HBIOS. ; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX). ; -; 5/19/2023 WBW - INITIAL RELEASE +; 5/23/2023 WBW - INITIAL RELEASE +; 5/26/3023 WBW - CLEAN UP, LED ACTIVITY ; ;============================================================================= ; @@ -43,20 +44,32 @@ ; ; TODO: ; +; - CLEAN UP WAIT LOOP STUFF +; +; - OPTIMIZE READ/WRITE LOOPS +; ; 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 +; - THIS DRIVER IS FOR THE ZIP DRIVE PPA INTERFACE. IT WILL SIMPLY +; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE. +; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP +; DRIVE IS PPA OR PPA. SIGH. +; +; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE +; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON +; FASTER CPUS. +; +; - THIS DRIVER OPERATES PURELY IN NIBBLE MODE. I SUSPECT IT IS +; POSSIBLE TO USE FULL BYTE MODE (PS2 STYLE), BUT I HAVE NOT +; ATTEMPTED IT. +; +; - RELATIVE TO ABOVE, THIS BEAST IS SLOW. IN ADDITION TO THE +; NIBBLE MODE READS, THE MG014 ASSIGNS SIGNALS DIFFERENTLY THAN +; THE STANDARD IBM PARALLEL PORT WHICH NECESSITATES A BUNCH OF EXTRA +; BIT FIDDLING ON EVERY READ. +; +; - SOME OF THE DATA TRANSFERS HAVE NO BUFFER OVERRUN CHECKS. IT IS +; ASSUMED SCSI DEVICES WILL SEND/REQUEST THE EXPECTED NUMBER OF BYTES. ; ; PPA PORT OFFSETS ; @@ -65,6 +78,11 @@ PPA_IOSTAT .EQU 1 ; PORT B, STATUS, IN PPA_IOCTRL .EQU 2 ; PORT C, CTRL, OUT PPA_IOSETUP .EQU 3 ; PPI SETUP ; +; SCSI UNIT IDS +; +PPA_SELF .EQU 7 +PPA_TGT .EQU 6 +; ; PPA DEVICE STATUS ; PPA_STOK .EQU 0 @@ -103,17 +121,8 @@ PPA_INIT1: 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 + CALL NEWLINE ; FORMATTING + PRTS("PPA:$") ; DRIVER LABEL ; PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS LD A,(IY+PPA_IOBASE) ; GET IO BASE ADDRES @@ -130,15 +139,32 @@ PPA_INIT2: LD DE,PPA_STR_MODE_UNK ; MODE LABEL PPA_INIT3: CALL WRITESTR ; DISPLAY MODE +; + ; CHECK FOR HARDWARE PRESENCE + CALL PPA_DETECT ; PROBE FOR INTERFACE + JR Z,PPA_INIT4 ; IF FOUND, CONTINUE + CALL PC_SPACE ; FORMATTING + LD DE,PPA_STR_NOHW ; NO PPA MESSAGE + CALL WRITESTR ; DISPLAY IT + JR PPA_INIT6 ; SKIP CFG ENTRY ; PPA_INIT4: - CALL PPA_RESET ; RESET THE INTERFACE + ; 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 ; ; 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 +; + CALL PPA_RESET ; RESET/INIT THE INTERFACE +; + ; START PRINTING DEVICE INFO + CALL PPA_PRTPREFIX ; PRINT DEVICE PREFIX ; ; CHECK FOR BAD STATUS LD A,(IY+PPA_STAT) ; GET STATUS @@ -175,9 +201,59 @@ PPA_INIT6: ; ON RETURN, ZF SET INDICATES HARDWARE FOUND ; PPA_DETECT: + ; 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 ; BRIEF DELAY FOR GOOD MEASURE +; + LD A,$AA + CALL PPA_WRITEDATA + CALL PPA_DISCONNECT + CALL PPA_CONNECT + LD A,$06 + CALL PPA_WRITECTRL + CALL PPA_READSTATUS +; + CALL PC_SPACE + CALL PRTHEXBYTE +; + AND $F0 + CP $F0 + JR NZ,PPA_DETECT_FAIL + LD A,$04 + CALL PPA_WRITECTRL + CALL PPA_READSTATUS +; + CALL PC_SPACE + CALL PRTHEXBYTE +; + AND $F0 + CP $80 + JR NZ,PPA_DETECT_FAIL + LD A,$AA + CALL PPA_WRITEDATA + LD A,$0C + CALL PPA_WRITECTRL + CALL PPA_CONNECT + LD A,$40 + CALL PPA_WRITEDATA + LD A,$08 + CALL PPA_WRITECTRL + LD A,$0C + CALL PPA_WRITECTRL + CALL PPA_DISCONNECT +; XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; +PPA_DETECT_FAIL: + OR $FF ; SIGNAL FAILURE + RET NZ + +; ;============================================================================= ; DRIVER FUNCTION TABLE ;============================================================================= @@ -208,12 +284,64 @@ PPA_DEFMED: ; ; PPA_READ: - JP PPA_STNOTSUP ; NOT SUPPORTED + CALL HB_DSKREAD ; HOOK DISK READ CONTROLLER + LD A,SCSI_CMD_READ ; SETUP SCSI READ + LD (PPA_CMD_RW),A ; AND SAVE IT IN SCSI CMD + JP PPA_IO ; DO THE I/O ; ; ; PPA_WRITE: - JP PPA_STNOTSUP ; NOT SUPPORTED + CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER + LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE + LD (PPA_CMD_RW),A ; AND SAVE IT IN SCSI CMD + JP PPA_IO ; DO THE I/O +; +; +; +PPA_IO: + LD (PPA_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + CALL PPA_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO + JR NZ,PPA_IO3 ; BAIL OUT ON ERROR +; + ; SETUP LBA + ; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN + LD HL,PPA_CMD_RW+1 ; START OF LBA FIELD IN CDB (MSB) + LD A,(IY+PPA_LBA+2) ; THIRD BYTE OF LBA FIELD IN CFG (MSB) + LD (HL),A + INC HL + LD A,(IY+PPA_LBA+1) + LD (HL),A + INC HL + LD A,(IY+PPA_LBA+0) + LD (HL),A + INC HL +; + ; DO SCSI IO + LD DE,(PPA_DSKBUF) ; DISK BUFFER TO DE + LD BC,512 ; ONE SECTOR, 512 BYTES + LD HL,PPA_CMD_RW ; POINT TO READ/WRITE CMD TEMPLATE + CALL PPA_RUNCMD ; RUN THE SCSI ENGINE + CALL Z,PPA_CHKCMD ; IF EXIT OK, CHECK SCSI RESULTS + JR NZ,PPA_IO2 ; IF ERROR, SKIP INCREMENT + ; INCREMENT LBA + LD A,PPA_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA + LD HL,IDE_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR + INC (HL) ; BUMP DMA BY + INC (HL) ; ... 512 BYTES + XOR A ; SIGNAL SUCCESS +; +PPA_IO2: +PPA_IO3: + LD HL,(PPA_DSKBUF) ; CURRENT DMA TO HL + OR A ; SET FLAGS BASED ON RETURN CODE + RET Z ; RETURN IF SUCCESS + LD A,ERR_IO ; SIGNAL IO ERROR + OR A ; SET FLAGS + RET ; AND DONE ; ; ; @@ -225,6 +353,11 @@ PPA_STATUS: ; ; ; +PPA_RESET: + JP PPA_INITDEV ; JUST (RE)INIT DEVICE +; +; +; PPA_DEVICE: LD D,DIODEV_PPA ; D := DEVICE TYPE LD E,(IY+PPA_DEV) ; E := PHYSICAL DEVICE NUMBER @@ -236,13 +369,12 @@ PPA_DEVICE: ; ; PPA_GETMED ; -PPA_MEDIA: +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 + CALL PPA_RESET ; RESET INCLUDES MEDIA CHECK ; PPA_MEDIA1: LD A,(IY+PPA_STAT) ; GET STATUS @@ -297,11 +429,6 @@ PPA_GEOM: ; FUNCTION SUPPORT ROUTINES ;============================================================================= ; -PPA_SELF .EQU 7 -PPA_TGT .EQU 6 -; -IMM_TGT .EQU 6 -; ; ; PPA_DELAY: @@ -315,79 +442,90 @@ PPA_DELAY: ; ; ; +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 +; +; OUTPUT BYTE IN A TO THE DATA PORT +; PPA_WRITEDATA: - ;PRTS(" D-$") - ;CALL PRTHEXBYTE - - LD C,(IY+PPA_IOBASE) - OUT (C),A - CALL PPA_DELAY - RET + LD C,(IY+PPA_IOBASE) ; DATA PORT IS AT IOBASE + OUT (C),A ; WRITE THE BYTE + ;CALL DELAY ; IS THIS NEEDED??? + RET ; DONE ; ; ; PPA_WRITECTRL: - ;PRTS(" C-$") - ;CALL PRTHEXBYTE - - XOR $0B - - ;PRTS(">$") - ;CALL PRTHEXBYTE - - LD C,(IY+PPA_IOBASE) + ; IBM PC INVERTS ALL BUT C2 ON THE BUS, MG014 DOES NOT. + ; BELOW TRANSLATES FROM IBM -> MG014. IT ALSO INVERTS THE + ; MG014 LED SIMPLY TO MAKE IT EASY TO KEEP LED ON DURING + ; ALL ACTIVITY. + XOR $0B | $80 ; HIGH BIT IS MG014 LED + LD C,(IY+PPA_IOBASE) ; GET BASE IO ADDRESS + INC C ; BUMP TO CONTROL PORT INC C - INC C - OUT (C),A - CALL PPA_DELAY - RET + OUT (C),A ; WRITE TO CONTROL PORT + ;CALL DELAY ; IS THIS NEEDED? + RET ; DONE ; +; READ THE PARALLEL PORT INPUT LINES (STATUS) AND MAP SIGNALS FROM +; MG014 TO IBM STANDARD. NOTE POLARITY CHANGE REQUIRED FOR BUSY. ; +; MG014 IBM PC +; -------- -------- +; 0: /ACK 6: /ACK +; 1: BUSY 7: /BUSY +; 2: POUT 5: POUT +; 3: SEL 4: SEL +; 4: /ERR 3: /ERR ; PPA_READSTATUS: - LD C,(IY+PPA_IOBASE) - INC C - IN A,(C) - - ;PRTS(" I-$") - ;CALL PRTHEXBYTE - + LD C,(IY+PPA_IOBASE) ; IOBASE TO C + INC C ; BUMP TO STATUS PORT + IN A,(C) ; READ IT LD C,0 ; INIT RESULT -; - BIT 0,A ; ACK = $01 +; + ; SHUFFLE BITS + BIT 0,A ; 0: /ACK JR Z,PPA_READSTATUS1 - SET 6,C ; $40 + SET 6,C ; 6: /ACK ; PPA_READSTATUS1: -; - BIT 1,A ; BUSY = $02 - JR NZ,PPA_READSTATUS2 - SET 7,C ; $80 +; + BIT 1,A ; 1: BUSY + JR NZ,PPA_READSTATUS2 ; POLARITY CHANGE! + SET 7,C ; 7: /BUSY ; PPA_READSTATUS2: -; - BIT 2,A ; PAPER = $04 +; + BIT 2,A ; 2: POUT JR Z,PPA_READSTATUS3 - SET 5,C ; $20 + SET 5,C ; 5: POUT ; PPA_READSTATUS3: -; - BIT 3,A ; SELECT = $08 +; + BIT 3,A ; 3: SEL JR Z,PPA_READSTATUS4 - SET 4,C ; $10 + SET 4,C ; 4: SEL ; PPA_READSTATUS4: -; - BIT 4,A ; FAULT = $10 +; + BIT 4,A ; 4: /ERR JR Z,PPA_READSTATUS5 - SET 3,C ; $08 + SET 3,C ; 3: /ERR ; PPA_READSTATUS5: - LD A,C - - ;PRTS(">$") - ;CALL PRTHEXBYTE - + LD A,C ; RESULT TO A RET ; ; @@ -423,7 +561,6 @@ PPA_CPULSE: ; ; PPA_CONNECT: - CALL NEWLINE LD A,$00 CALL PPA_CPULSE LD A,$3C @@ -436,108 +573,7 @@ PPA_CONNECT: ; ; ; -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 @@ -548,6 +584,7 @@ PPA_DISCONNECT: CALL PPA_DPULSE RET ; +; SCSI SELECT PROCESS ; ; PPA_SELECT: @@ -574,700 +611,95 @@ PPA_SELECT1: RET Z ; TIMEOUT JR PPA_SELECT1 ; +; SEND SCSI CMD BYTE STRING. AT ENTRY, HL POINTS TO START OF +; COMMAND BYTES. THE LENGTH OF THE COMMAND STRING MUST PRECEED +; THE COMMAND BYTES (HL - 1). ; +; NOTE THAT DATA IS SENT AS BYTE PAIRS! EACH LOOP SENDS 2 BYTES. +; DATA OUTPOUT IS BURSTED (NO CHECK FOR BUSY). SEEMS TO WORK FINE. ; -IMM_SELECT: - PRTS("\r\nSELECT: $") - LD A,$0C - CALL PPA_WRITECTRL +PPA_SENDCMD: + JP PPA_ERR ; NOW DO STANDARD ERR PROCESSING ; - LD HL,500 ; TIMEOUT COUNTER +; THIS IS THE MAIN SCSI ENGINE. BASICALLY, IT SELECTS THE DEVICE +; ON THE BUS, SENDS THE COMMAND, THEN PROCESSES THE RESULT. ; -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 +; HL: COMMAND BUFFER +; DE: TRANSFER BUFFER +; BC: TRANSFER LENGTH (0=VARIABLE) ; -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 +PPA_RUNCMD: + JP PPA_ERR ; NOW DO STANDARD ERR PROCESSING ; - LD HL,500 ; TIMEOUT COUNTER +; ERRORS SHOULD GENERALLY NOT CAUSE SCSI PROCESSING TO FAIL. IF A +; DEVICE ERROR (I.E., READ ERROR) OCCURS, THEN THE SCSI PROTOCOL WILL +; PROVIDE ERROR INFORMATION. THE STATUS RESULT OF THE SCSI COMMAND +; WILL INDICATE IF AN ERROR OCCURRED. ADDITIONALLY, IF THE ERROR IS +; A CHECK CONDITION ERROR, THEN IT IS MANDATORY TO ISSUE A SENSE +; REQUEST SCSI COMMAND TO CLEAR THE ERROR AND RETRIEVE DETAILED ERROR +; INFO. ; -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 +PPA_CHKCMD: + ; SCSI COMMAND COMPLETED, CHECK SCSI CMD STATUS + LD A,(PPA_CMDSTAT) ; GET STATUS BYTE + OR A ; SET FLAGS + RET Z ; IF ZERO, ALL GOOD, DONE +; + ; DO WE HAVE A CHECK CONDITION? + CP 2 ; CHECK CONDITION RESULT? + JR Z,PPA_CHKCMD1 ; IF SO, REQUEST SENSE + JP PPA_IOERR ; ELSE, GENERAL I/O ERROR +; +PPA_CHKCMD1: + ; USE REQUEST SENSE CMD TO GET ERROR DETAILS + LD DE,HB_WRKBUF ; PUT DATA IN WORK BUF + LD BC,0 ; VARIABLE LENGTH REQUEST + LD HL,PPA_CMD_SENSE ; REQUEST SENSE CMD + CALL PPA_RUNCMD ; DO IT + JP NZ,PPA_IOERR ; BAIL IF ERROR IN CMD +; + ; REQ SENSE CMD COMPLETED +#IF (PPATRACE >= 3) + LD A,16 + LD DE,HB_WRKBUF + CALL Z,PRTHEXBUF +#ENDIF ; -IMM_SELECT4: - LD A,$0C - CALL PPA_WRITECTRL + ; CHECK SCSI CMD STATUS + LD A,(PPA_CMDSTAT) ; GET STATUS BYTE + OR A ; SET FLAGS + JP NZ,PPA_IOERR ; IF FAILED, GENERAL I/O ERROR ; - XOR A - RET + ; RETURN RESULT BASED ON REQ SENSE DATA + ; TODO: WE NEED TO CHECK THE SENSE KEY FIRST!!! + LD A,(HB_WRKBUF+12) ; GET ADDITIONAL SENSE CODE + CP $3A ; NO MEDIA? + JP Z,PPA_NOMEDIA ; IF SO, RETURN NO MEDIA ERR + JP PPA_IOERR ; ELSE GENERAL I/O ERR ; +; 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 ; -IMM_SENDCMD: - ; TODO: USE PUTDATA ROUTINE??? - ; TODO: CHECK BUSY??? - PRTS("\r\nSENDCMD:$") - LD A,$04 - CALL PPA_WRITECTRL +; (RE)INITIALIZE DEVICE ; - LD HL,IMM_CMD - LD B,6 +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 ; SHORT DELAY FOR BUS SETTLE ; -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 HANDLING AND DIAGNOSTICS +;============================================================================= ; ; ERROR HANDLERS ; @@ -1395,7 +827,6 @@ 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$" @@ -1406,13 +837,11 @@ 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_CMDSTK .DW 0 ; STACK PTR FOR CMD ABORTING +PPA_DSKBUF .DW 0 ; WORKING DISK BUFFER POINTER +PPA_XFRLEN .DW 0 ; WORKING TRANSFER LENGTH +PPA_CMDSTAT .DB 0, 0 ; CMD RESULT STATUS ; PPA_TYPE_MAP: .DW PPA_STR_NONE @@ -1421,6 +850,15 @@ PPA_TYPE_MAP: PPA_STR_NONE .DB "$" PPA_STR_MG014 .DB "MG014$" ; +; SCSI COMMAND TEMPLATES (LENGTH PREFIXED) +; + .DB 6 +PPA_CMD_RW .DB $00, $00, $00, $00, $01, $00 ; READ/WRITE SECTOR + .DB 6 +PPA_CMD_SENSE .DB $03, $00, $00, $00, $FF, $00 ; REQUEST SENSE DATA + .DB 10 +PPA_CMD_RDCAP .DB $25, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; READ CAPACITY +; ; PPA DEVICE CONFIGURATION TABLE ; PPA_CFG: diff --git a/Source/HBIOS/ppp.asm b/Source/HBIOS/ppp.asm index c8cc27d6..ac61f866 100644 --- a/Source/HBIOS/ppp.asm +++ b/Source/HBIOS/ppp.asm @@ -904,7 +904,7 @@ PPPSD_GETCSD: CALL PPP_SNDCMD ; SEND COMMAND RET NZ ; ABORT ON ERROR - LD B,16 ; GET 4 BYTES + LD B,16 ; GET 16 BYTES LD HL,PPPSD_CSDBUF PPPSD_GETCSD1: CALL PPP_GETBYTE diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index f057e926..be353573 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -447,6 +447,16 @@ SPD_UNSUP .EQU 0 ; PLATFORM CAN CHANGE SPEEDS BUT IS UNSUPPORTED SPD_HIGH .EQU 1 ; PLATFORM CAN CHANGE SPEED, STARTS HIGH SPD_LOW .EQU 2 ; PLATFORM CAN CHANGE SPEED, STARTS LOW ; +; SCSI COMMAND CODES (SHOULD BE IT IT'S OWN FILE) +; +SCSI_CMD_READ .EQU $08 +SCSI_CMD_INQ .EQU $12 +SCSI_CMD_TEST .EQU $00 +SCSI_CMD_START .EQU $1B +SCSI_CMD_SENSE .EQU $03 +SCSI_CMD_WRITE .EQU $0A +SCSI_CMD_RDCAP .EQU $25 +; #INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE ; ; INCLUDE Z180 REGISTER DEFINITIONS diff --git a/Source/ver.inc b/Source/ver.inc index 1a5a4399..83cbe21f 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 3 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.3.0-dev.15" +#DEFINE BIOSVER "3.3.0-dev.16" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index d9e32aa6..3f43e883 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 3 rup equ 0 rtp equ 0 biosver macro - db "3.3.0-dev.15" + db "3.3.0-dev.16" endm