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