diff --git a/Source/HBIOS/ch.asm b/Source/HBIOS/ch.asm index 9eae6985..ad884da4 100644 --- a/Source/HBIOS/ch.asm +++ b/Source/HBIOS/ch.asm @@ -8,23 +8,10 @@ ; Thanks and credit to Alan Cox. Much of this driver is based on ; his code in FUZIX (https://github.com/EtchedPixels/FUZIX). ; -; NOTES: -; - There seem to be compatibility issues with older USB thumb drives. -; Such drives will complete DISK_INIT successfully, but then return -; an error attempting to do any I/O. The error is $17 indicating -; the CH37x encountered an overflow during communication with the -; device. I found that adding a DISK_MOUNT command (only possible -; on CH376) resolved the issue for some devices, so that has been -; added to the RESET routine when using CH376. -; -; TODO: -; - Implement auto-recovery on error status? -; - !!! Move CH_MODE to config variable !!! -; -; PORT OFFSETS FROM BASE PORT -; -;CH_DATA .EQU 0 ; DATA PORT AT BASE + 0 -;CH_CMD .EQU 1 ; CMD PORT AT BASE + 1 +; This file is the core driver file for the CH37x devices. Since the +; CH376 supports both a USB Drive interface and an SD Card interface, +; the code for these interfaces is included as needed. See +; chusb.asm and chsd.asm. ; ; CH DEVICE TYPES ; @@ -77,6 +64,21 @@ CH_CMD_DSKWRGO .EQU $57 ; CONTINUE DISK WRITE CH_CMD_DSKINQ .EQU $58 ; DISK INQUIRY CH_CMD_DSKRDY .EQU $59 ; DISK READY ; +; SUB-DRIVER SETUP +; +CHUSBENABLE .EQU ((CH0USBENABLE == TRUE) | (CH1USBENABLE == TRUE)) +CHSDENABLE .EQU ((CH0SDENABLE == TRUE) | (CH1SDENABLE == TRUE)) +; +#IF (!CHUSBENABLE) +CHUSB_CFG0 .EQU 0 ; DUMMY ENTRY +CHUSB_CFG1 .EQU 0 ; DUMMY ENTRY +#ENDIF +; +#IF (!CHSDENABLE) +CHSD_CFG0 .EQU 0 ; DUMMY ENTRY +CHSD_CFG1 .EQU 0 ; DUMMY ENTRY +#ENDIF +; ; CH DEVICE CONFIGURATION ; CH_CFGSIZ .EQU 9 ; SIZE OF CFG TBL ENTRIES @@ -153,14 +155,17 @@ CH_INIT2: CALL PRTHEXBYTE ; DISPLAY IT ; XOR A ; UNKNOWN MODE - LD (CH_MODE),A ; SAVE IT + LD (CH0_MODE),A ; SAVE IT + LD (CH1_MODE),A ; SAVE IT ;CALL CH_FLUSH ; FLUSH DEVICE OUTPUT QUEUE ; - ; I AM ENCOUNTERING SOME CH376 CHIPS THAT GO HAYWIRE AFTER A - ; RESET COMMAND. THEY STOP RESPONDING FOR A VERY LONG TIME. - ; I AM SEEING THIS ONLY ON "LC TECH" ADAPTERS AND ONLY ON Z80 - ; SYSTEMS (NOT Z180). NO IDEA WHAT IS GOING ON, SO I AM + ; VERSION 4 OF THE CH376 CHIPS ARE HAVING TROUBLE WITH THE + ; RESET COMMAND. ON Z80 SYSTEMS THEY TAKE A VERY LONG TIME + ; TO RESET. ON Z180 SYSTEMS, I AM NOT SEEING AN ISSUE. + ; CH375 CHIPS AND VERSION 3 OF THE CH376 SEEM FINE (IN Z80 + ; OR Z180 SYSTEMS). NO IDEA WHAT IS GOING ON, SO I AM ; GIVING UP FOR NOW AND REMOVING THE RESET. +; ;CALL CH_RESET ; FULL CH37X RESET ; CALL CH_DETECT ; DETECT CHIP PRESENCE @@ -199,6 +204,7 @@ CH_INIT3A: AND $3F ; ISOLATE VERSION BITS CALL PRTHEXBYTE ; PRINT IT ; +#IF (CHUSBENABLE) ; USB SUB-DRIVER INIT LD L,(IY+CH_USBCFG+0) ; LSB OF USB CFG ENTRY LD H,(IY+CH_USBCFG+1) ; MSB OF USB CFG ENTRY @@ -207,7 +213,9 @@ CH_INIT3A: OR A ; SET FLAGS CALL NZ,CHUSB_INIT ; IF SO, DO USB INIT POP IY ; RESTORE IY +#ENDIF ; +#IF (CHSDENABLE) ; SD CARD SUB-DRIVER INIT LD L,(IY+CH_SDCFG+0) ; LSB OF SD CFG ENTRY LD H,(IY+CH_SDCFG+1) ; MSB OF SD CFG ENTRY @@ -216,6 +224,7 @@ CH_INIT3A: OR A ; SET FLAGS CALL NZ,CHSD_INIT ; IF SO, DO SD INIT POP IY ; RESTORE IY +#ENDIF ; CH_INIT4: LD DE,CH_CFGSIZ ; SIZE OF CFG TABLE ENTRY @@ -384,22 +393,33 @@ CH_GETVER: ; THE CH376 DOES NOT SEEM TO MAINTAIN SEPARATE OPERATING CONTEXTS FOR ; THE USB AND SD DEVICES. IF BOTH ARE IN OPERATION, THEN A MODE ; SWITCH REQUIRES A COMPLETE REINITIALIZATION OF THE REQUESTED -; DEVICE. +; DEVICE. THIS WHOLE MESS IS ONLY NEEDED IF BOTH CHSD AND CHUSB +; ARE ENDABLED, SO IT IS CONDITIONAL. ; CH_SETMODE: +#IF (CHUSBENABLE & CHSDENABLE) PUSH BC ; SAVE BC PUSH DE ; SAVE DE PUSH HL ; SAVE HL ;PRTS("\r\nSETMODE:$") ; *DEBUG* - LD L,A ; SAVE REQUESTED MODE - LD A,(CH_MODE) ; GET CURRENT MODE ;CALL PC_SPACE ; *DEBUG* ;CALL PRTHEXBYTE ; *DEBUG* - CP L ; COMPARE + LD E,A ; SAVE REQUESTED MODE +; + ; WARNING: CH_SETMODE IS CALLED BY THE SUB-DRIVERS, SO + ; IY WILL BE A POINTER TO THE CONFIG BLOCK OF THE SUB-DRIVER. + ; BY CONVENTION, THE LOCATION OF THE MODE BYTE FOR EACH + ; SUB-DRIVER IS AT OFFSET 12 IN THE CONFIG BLOCK! + LD L,(IY+12) ; GET MODE PTR (LSB) + LD H,(IY+13) ; GET MODE PTR (MSB) + LD A,(HL) ; GET CUR MODE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP E ; COMPARE JR Z,CH_SETMODE_Z ; IF EQUAL, DONE ; ; NEED TO CHANGE MODES - LD A,L ; GET REQUESTED MODE + LD A,E ; RECOVER REQUESTED MODE CP CH_MODE_USB ; USB? JR Z,CH_SETMODE_USB ; IF SO, DO IT CP CH_MODE_SD ; SD? @@ -408,1447 +428,41 @@ CH_SETMODE: JR CH_SETMODE_Z ; BAIL OUT ; CH_SETMODE_USB: +#IF (CHUSBENABLE) CALL CHUSB_RESET ; FULL USB STACK RESET +#ENDIF JR CH_SETMODE_Z ; MOVE ON ; CH_SETMODE_SD: +#IF (CHSDENABLE) CALL CHSD_RESET ; FULL SD STACK RESET +#ENDIF JR CH_SETMODE_Z ; MOVE ON ; CH_SETMODE_Z: POP HL ; RECOVER HL POP DE ; RECOVER DE POP BC ; RECOVER BC +#ENDIF RET ; DONE ; ; ; -CH_MODE .DB CH_MODE_UNK +CH0_MODE .DB CH_MODE_UNK +CH1_MODE .DB CH_MODE_UNK ; CH_STR_NOHW .TEXT " NOT PRESENT$" ; CH_STR_375 .TEXT "CH375$" CH_STR_376 .TEXT "CH376$" ; -;================================================================================================== -; CH375/376 USB SUB-DRIVER -;================================================================================================== -; -CHUSB_FASTIO .EQU TRUE ; USE INIR/OTIR? -; -; CHUSB DEVICE STATUS -; -CHUSB_STOK .EQU 0 -CHUSB_STNOMEDIA .EQU -1 -CHUSB_STCMDERR .EQU -2 -CHUSB_STIOERR .EQU -3 -CHUSB_STTO .EQU -4 -CHUSB_STNOTSUP .EQU -5 -; -; CHUSB DEVICE CONFIGURATION -; -CHUSB_CFGSIZ .EQU 12 ; SIZE OF USB CFG TBL ENTRIES -; -; CONFIG ENTRY DATA OFFSETS -; -; FIRST 3 BYTES SAME AS CH CONFIG -CHUSB_STAT .EQU 3 ; LAST STATUS (BYTE) -CHUSB_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) -CHUSB_LBA .EQU 8 ; CURRENT LBA (DWORD) -; -CHUSB_CFGTBL: -; -#IF (CHCNT >= 1) -CHUSB_CFG0: - .DB 0 ; DEV NUM, FILLED DYNAMICALLY - .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY - .DB CH0BASE ; IO BASE ADDRESS - .DB 0 ; DEVICE STATUS - .DW 0,0 ; DEVICE CAPACITY - .DW 0,0 ; CURRENT LBA -; - #IF (CH0USBENABLE) - .ECHO "CHUSB: IO=" - .ECHO CH0BASE - .ECHO "\n" - #ENDIF -#ENDIF -; -#IF (CHCNT >= 2) -CHUSB_CFG1: - .DB 0 ; DEV NUM - .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY - .DB CH1BASE ; IO BASE ADDRESS - .DB 0 ; DEVICE STATUS - .DW 0,0 ; DEVICE CAPACITY - .DW 0,0 ; CURRENT LBA -; - #IF (CH1USBENABLE) - .ECHO "CHUSB: IO=" - .ECHO CH1BASE - .ECHO "\n" - #ENDIF -#ENDIF -; -#IF ($ - CHUSB_CFGTBL) != (CHCNT * CHUSB_CFGSIZ) - .ECHO "*** INVALID CHUSB CONFIG TABLE ***\n" -#ENDIF -; - .DB $FF ; END OF TABLE MARKER -; -; -; -CHUSB_INIT: - LD A,(IY+CH_TYPE) ; GET DEVICE TYPE - PUSH HL ; COPY INCOMING HL - POP IY ; ... TO IY - LD (IY+CH_TYPE),A ; SAVE DEVICE TYPE -; - ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE - LD A,(CHUSB_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN - LD (IY+CH_DEV),A ; UPDATE IT - INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN - LD (CHUSB_DEVNUM),A ; SAVE IT -; - ; ADD UNIT TO GLOBAL DISK UNIT TABLE - LD BC,CHUSB_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 CHUSB_RESET ; RESET & DISCOVER MEDIA -#IF (CHUSBTRACE <= 1) - CALL NZ,CHUSB_PRTSTAT -#ENDIF - RET NZ ; ABORT ON FAILURE -; - ; START PRINTING DEVICE INFO - CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX -; - ; PRINT STORAGE CAPACITY (BLOCK COUNT) - PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - LD A,CHUSB_MEDCAP ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL LD32 ; GET THE CAPACITY VALUE - CALL PRTHEX32 ; PRINT HEX VALUE -; - ; PRINT STORAGE SIZE IN MB - PRTS(" SIZE=$") ; PRINT FIELD LABEL - LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB - CALL SRL32 ; RIGHT SHIFT - CALL PRTDEC32 ; PRINT DWORD IN DECIMAL - PRTS("MB$") ; PRINT SUFFIX -; - XOR A ; SIGNAL SUCCESS - RET -; -; DRIVER FUNCTION TABLE -; -CHUSB_FNTBL: - .DW CHUSB_STATUS - .DW CHUSB_RESET - .DW CHUSB_SEEK - .DW CHUSB_READ - .DW CHUSB_WRITE - .DW CHUSB_VERIFY - .DW CHUSB_FORMAT - .DW CHUSB_DEVICE - .DW CHUSB_MEDIA - .DW CHUSB_DEFMED - .DW CHUSB_CAP - .DW CHUSB_GEOM -#IF (($ - CHUSB_FNTBL) != (DIO_FNCNT * 2)) - .ECHO "*** INVALID CHUSB FUNCTION TABLE ***\n" -#ENDIF -; -CHUSB_VERIFY: -CHUSB_FORMAT: -CHUSB_DEFMED: - SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED - RET -; -; -; -CHUSB_READ: - LD A,CH_MODE_USB ; REQUEST USB MODE - CALL CH_SETMODE ; DO IT - JP NZ,CHUSB_CMDERR ; HANDLE ERROR -; - CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR - LD (CHUSB_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS - LD A,CH_CMD_DSKRD ; DISK READ COMMAND - CALL CHUSB_RWSTART ; SEND CMD AND LBA -; - ; READ THE SECTOR IN 64 BYTE CHUNKS - LD B,8 ; 8 CHUNKS OF 64 FOR 512 BYTE SECTOR - LD HL,(CHUSB_DSKBUF) ; GET DISK BUF ADR -CHUSB_READ1: - CALL CH_POLL ; WAIT FOR DATA READY - CP $1D ; DATA READY TO READ? - ;CALL PC_LT ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - JP NZ,CHUSB_IOERR ; HANDLE IO ERROR - CALL CH_CMD_RD ; SEND READ USB DATA CMD - CALL CH_RD ; READ DATA BLOCK LENGTH - CP 64 ; AS EXPECTED? - JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR -; -#IF (CHUSB_FASTIO) - ; READ 64 BYTE CHUNK - PUSH BC ; SAVE LOOP CONTROL - LD B,64 ; READ 64 BYTES - LD C,(IY+CH_IOBASE) ; BASE PORT - INIR ; DO IT FAST - POP BC ; RESTORE LOOP CONTROL -#ELSE - ; BYTE READ LOOP - PUSH BC ; SAVE LOOP CONTROL - LD B,64 ; READ 64 BYTES -CHUSB_READ2: - CALL CH_RD ; GET NEXT BYTE - LD (HL),A ; SAVE IT - INC HL ; INC BUF PTR - DJNZ CHUSB_READ2 ; LOOP AS NEEDED - POP BC ; RESTORE LOOP CONTROL -#ENDIF -; - ; PREPARE FOR NEXT CHUNK - LD A,CH_CMD_DSKRDGO ; CONTINUE DISK READ - CALL CH_CMD ; SEND IT - DJNZ CHUSB_READ1 ; LOOP TILL DONE -; - ; FINAL CHECK FOR COMPLETION & SUCCESS - CALL CH_POLL ; WAIT FOR COMPLETION - CP $14 ; SUCCESS? - JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR -; - ; INCREMENT LBA - PUSH HL ; SAVE HL - LD A,CHUSB_LBA ; LBA OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL INC32HL ; INCREMENT THE VALUE - POP HL ; RESTORE HL -; - XOR A ; SIGNAL SUCCESS - RET -; -; -; -CHUSB_WRITE: - LD A,CH_MODE_USB ; REQUEST USB MODE - CALL CH_SETMODE ; DO IT - JP NZ,CHUSB_CMDERR ; HANDLE ERROR -; - CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR - LD (CHUSB_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS - LD A,CH_CMD_DSKWR ; DISK READ COMMAND - CALL CHUSB_RWSTART ; SEND CMD AND LBA -; - ; WRITE THE SECTOR IN 64 BYTE CHUNKS - LD B,8 ; 8 CHUNKS OF 64 FOR 512 BYTE SECTOR - LD HL,(CHUSB_DSKBUF) ; GET DISK BUF ADR -CHUSB_WRITE1: - CALL CH_POLL ; WAIT FOR DATA READY - CP $1E ; DATA READY TO WRITE - ;CALL PC_GT ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - JP NZ,CHUSB_IOERR ; HANDLE IO ERROR - CALL CH_CMD_WR ; SEND WRITE USB DATA CMD - LD A,64 ; 64 BYTE CHUNK - CALL CH_WR ; SEND DATA BLOCK LENGTH -; -#IF (CHUSB_FASTIO) - ; WRITE 64 BYTE CHUNK - PUSH BC ; SAVE LOOP CONTROL - LD B,64 ; WRITE 64 BYTES - LD C,(IY+CH_IOBASE) ; BASE PORT - OTIR ; DO IT FAST - POP BC ; RESTORE LOOP CONTROL -#ELSE - ; BYTE WRITE LOOP - PUSH BC ; SAVE LOOP CONTROL - LD B,64 ; WRITE 64 BYTES -CHUSB_WRITE2: - LD A,(HL) ; GET NEXT BYTE - INC HL ; INC BUF PTR - CALL CH_WR ; WRITE NEXT BYTE - DJNZ CHUSB_WRITE2 ; LOOP AS NEEDED - POP BC ; RESTORE LOOP CONTROL -#ENDIF -; - ; PREPARE FOR NEXT CHUNK - LD A,CH_CMD_DSKWRGO ; CONTINUE DISK READ - CALL CH_CMD ; SEND IT - DJNZ CHUSB_WRITE1 ; LOOP TILL DONE -; - ; FINAL CHECK FOR COMPLETION & SUCCESS - CALL CH_POLL ; WAIT FOR COMPLETION - CP $14 ; SUCCESS? - JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR -; - ; INCREMENT LBA - PUSH HL ; SAVE HL - LD A,CHUSB_LBA ; LBA OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL INC32HL ; INCREMENT THE VALUE - POP HL ; RESTORE HL -; - XOR A ; SIGNAL SUCCESS - RET -; -; INITIATE A DISK SECTOR READ/WRITE OPERATION -; A: READ OR WRITE OPCODE -; -CHUSB_RWSTART: - CALL CH_CMD ; SEND R/W COMMAND -; - ; SEND LBA, 4 BYTES, LITTLE ENDIAN - LD A,CHUSB_LBA ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - LD B,4 ; SEND 4 BYTES -CHUSB_RWSTART1: - LD A,(HL) ; GET BYTE - INC HL ; BUMP PTR - CALL CH_WR ; SEND BYTE - DJNZ CHUSB_RWSTART1 ; LOOP AS NEEDED -; - ; REQUEST 1 SECTOR - LD A,1 ; 1 SECTOR - CALL CH_WR ; SEND IT - RET -; -; -; -CHUSB_STATUS: - ; RETURN UNIT STATUS - LD A,(IY+CHUSB_STAT) ; GET STATUS OF SELECTED DEVICE - OR A ; SET FLAGS - RET ; AND RETURN -; -; RESET THE INTERFACE AND REDISCOVER MEDIA -; -CHUSB_RESET: - ;PRTS("\n\rRES USB:$") ; *DEBUG* - ;CALL CH_FLUSH ; DISCARD ANY GARBAGE - ;CALL CH_RESET ; FULL CH37X RESET -; - ; RESET THE BUS - LD A,CH_CMD_MODE ; SET MODE COMMAND - CALL CH_CMD ; SEND IT - LD A,7 ; RESET BUS - CALL CH_WR ; SEND IT - CALL CH_NAP ; SMALL WAIT - CALL CH_RD ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CALL CH_NAP ; SMALL WAIT -; - ; ACTIVATE USB MODE - LD A,CH_CMD_MODE ; SET MODE COMMAND - CALL CH_CMD ; SEND IT - LD A,6 ; USB ENABLED, SEND SOF - CALL CH_WR ; SEND IT - CALL CH_NAP ; SMALL WAIT - CALL CH_RD ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CALL CH_NAP ; SMALL WAIT -; - LD A,CH_MODE_USB ; WE ARE NOW IN USB MODE - LD (CH_MODE),A ; SAVE IT -; - ; INITIALIZE DISK - LD B,24 ; TRY A FEW TIMES -CHUSB_RESET1: - ;PRTS("\n\rDSKINIT:$") ; *DEBUG* - LD A,CH_CMD_DSKINIT ; DISK INIT COMMAND - CALL CH_CMD ; SEND IT - LD DE,10000 ; 10000 * 16 = 160US ??? - LD DE,20000 ; 10000 * 16 = 160US ??? - LD DE,12500 ; 1250 * 16 = 200US ??? - CALL VDELAY ; DELAY - CALL CH_POLL ; WAIT FOR RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; SUCCESS? - JR Z,CHUSB_RESET1A ; IF SO, CHECK READY - CP $16 ; NO MEDIA - JP Z,CHUSB_NOMEDIA ; HANDLE IT - CALL CH_NAP ; SMALL DELAY - DJNZ CHUSB_RESET1 ; LOOP AS NEEDED - JP CHUSB_TO ; HANDLE TIMEOUT -; -CHUSB_RESET1A: - ;CALL CHUSB_DSKRES ; DISK RESET - ;CP $14 ; GOOD? - ;JR Z,CHUSB_RESET2 - ;CALL CHUSB_DSKRDY ; CHECK IF DISK READY - ;CP $14 ; GOOD? - ;JR Z,CHUSB_RESET2 ; IF SO, MOVE ON - ;DJNZ CHUSB_RESET1 ; KEEP TRYING -; -CHUSB_RESET2: - ; USE OF CH376 DISK_MOUNT COMMAND SEEMS TO IMPROVE - ; COMPATIBILITY WITH SOME OLDER USB THUMBDRIVES. - LD A,(IY+CH_TYPE) ; CH37X TYPE? - CP CHTYP_376 ; IS CH376? - CALL Z,CHUSB_DSKMNT ; IF SO, TRY MOUNT, IGNORE ERRS - ;CALL CHUSB_AUTOSET ; *DEBUG* - ;CALL CHUSB_TSTCON ; *DEBUG* - ;CALL CHUSB_MAXLUN ; *DEBUG* - ;CALL CHUSB_DSKRDY ; *DEBUG* - ;CALL CHUSB_DSKINQ ; *DEBUG* -;; - CALL CHUSB_DSKSIZ ; GET AND RECORD DISK SIZE - RET NZ ; ABORT ON ERROR -; - ; SET STATUS AND RETURN - XOR A ; CLEAR STATUS - LD (IY+CHUSB_STAT),A ; RECORD STATUS - OR A ; SET FLAGS - RET ; AND RETURN -; -; -; -CHUSB_DEVICE: - LD D,DIODEV_CHUSB ; D := DEVICE TYPE - LD E,(IY+CH_DEV) ; E := PHYSICAL DEVICE NUMBER - LD C,%00110011 ; USB HARD DISK ATTRIBUTES - LD H,(IY+CH_TYPE) ; H := MODE - LD L,(IY+CH_IOBASE) ; L := BASE I/O ADDRESS - XOR A ; SIGNAL SUCCESS - RET -; -; CHUSB_GETMED -; -CHUSB_MEDIA: - LD A,E ; GET FLAGS - OR A ; SET FLAGS - JR Z,CHUSB_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA - CALL CHUSB_RESET ; RESET CHUSB INTERFACE -; -CHUSB_MEDIA1: - LD A,(IY+CHUSB_STAT) ; GET STATUS - OR A ; SET FLAGS - LD D,0 ; NO MEDIA CHANGE DETECTED - LD E,MID_HD ; ASSUME WE ARE OK - RET Z ; RETURN IF GOOD INIT - LD E,MID_NONE ; SIGNAL NO MEDIA - LD A,ERR_NOMEDIA ; NO MEDIA ERROR - OR A ; SET FLAGS - RET ; AND RETURN -; -; -; -CHUSB_SEEK: - BIT 7,D ; CHECK FOR LBA FLAG - CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA - RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) - LD (IY+CHUSB_LBA+0),L ; SAVE NEW LBA - LD (IY+CHUSB_LBA+1),H ; ... - LD (IY+CHUSB_LBA+2),E ; ... - LD (IY+CHUSB_LBA+3),D ; ... - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN -; -; -; -CHUSB_CAP: - LD A,(IY+CHUSB_STAT) ; GET STATUS - PUSH AF ; SAVE IT - LD A,CHUSB_MEDCAP ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL - LD BC,512 ; 512 BYTES PER BLOCK - POP AF ; RECOVER STATUS - OR A ; SET FLAGS - RET -; -; -; -CHUSB_GEOM: - ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS - ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE - CALL CHUSB_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC - LD L,H ; DIVIDE BY 256 FOR # TRACKS - LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL - LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT - LD E,16 ; SECTORS / TRACK = 16 - RET ; DONE, A STILL HAS CHUSB_CAP STATUS -; -; CH37X HELPER ROUTINES -; -; -; PERFORM DISK MOUNT -; -CHUSB_DSKMNT: - ;PRTS("\n\rMOUNT:$") ; *DEBUG* - LD A,CH_CMD_DSKMNT ; DISK QUERY - CALL CH_CMD ; DO IT - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; SUCCESS? - RET NZ ; ABORT IF NOT -; -#IF FALSE - CALL CH_CMD_RD ; SEND READ COMMAND - CALL CH_RD ; GET LENGTH - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - LD B,A ; LOOP COUNTER - LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA -CHUSB_DSKMNT1: - CALL CH_RD ; GET A BYTE - LD (HL),A ; SAVE IT - INC HL ; BUMP BUF PTR - DJNZ CHUSB_DSKMNT1 ; LOOP FOR ALL DATA -; - ;LD DE,HB_WRKBUF ; *DEBUG* - ;CALL DUMP_BUFFER ; *DEBUG* -; - CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX - LD HL,HB_WRKBUF + 8 - LD B,28 -CHUSB_DSKMNT2: - LD A,(HL) - INC HL - CALL COUT - DJNZ CHUSB_DSKMNT2 -#ENDIF -; - XOR A - RET -; -; PERFORM DISK SIZE -; -CHUSB_DSKSIZ: - ;PRTS("\n\rDSKSIZ:$") ; *DEBUG* - LD A,CH_CMD_DSKSIZ ; DISK SIZE COMMAND - CALL CH_CMD ; SEND IT - CALL CH_POLL ; WAIT FOR RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; SUCCESS? - JP NZ,CHUSB_CMDERR ; HANDLE CMD ERROR - CALL CH_CMD_RD ; SEND READ USB DATA CMD - CALL CH_RD ; GET RD DATA LEN - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $08 ; MAKE SURE IT IS 8 - JP NZ,CHUSB_CMDERR ; HANDLE CMD ERROR - LD A,CHUSB_MEDCAP ; MEDIA CAPACITY OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - PUSH HL ; SAVE ADDRESS - CALL CH_RD - LD D,A - CALL CH_RD - LD E,A - CALL CH_RD - LD H,A - CALL CH_RD - LD L,A - CALL CH_RD - CALL CH_RD - CALL CH_RD - CALL CH_RD - POP BC ; RECOVER ADDRESS TO BC - CALL ST32 ; STORE IT - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -#IF FALSE -; -; PERFORM DISK INQUIRY -; BASICALLY THE SCSI INQUIRY COMMAND -; -CHUSB_DSKINQ: - ;PRTS("\n\rINQUIRY:$") ; *DEBUG* - LD A,CH_CMD_DSKINQ ; DISK QUERY - CALL CH_CMD ; DO IT - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; SUCCESS? - RET NZ ; ABORT IF NOT - CALL CH_CMD_RD ; SEND READ COMMAND - CALL CH_RD ; GET LENGTH - LD B,A ; LOOP COUNTER - LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA -DSKINQ1: - CALL CH_RD ; GET A BYTE - LD (HL),A ; SAVE IT - INC HL ; BUMP BUF PTR - DJNZ DSKINQ1 ; LOOP FOR ALL DATA -; - ;LD DE,HB_WRKBUF ; *DEBUG* - ;CALL DUMP_BUFFER ; *DEBUG* -; - ;CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX - ;LD HL,HB_WRKBUF + 8 - ;LD B,28 -DSKINQ2: - ;LD A,(HL) - ;INC HL - ;CALL COUT - ;DJNZ DSKINQ2 -; - RET -; -; PERFORM SET RETRIES -; -CHUSB_SETRETRY: - ;PRTS("\n\rSETRETRY:$") ; *DEBUG* - LD A,CH_CMD_SETRETRY ; DISK READY - CALL CH_CMD ; DO IT - CALL CH_NAP - LD A,$25 ; CONSTANT - CALL CH_WR ; SEND IT - CALL CH_NAP - LD A,$BF ; MAX - CALL CH_WR - CALL CH_NAP - CALL CH_RD ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; - RET -; -; PERFORM DISK RESET -; -CHUSB_DSKRES: - ;PRTS("\n\rDSKRES:$") ; *DEBUG* - LD A,CH_CMD_DSKRES ; DISK READY - CALL CH_CMD ; DO IT - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; - RET -; -; PERFORM DISK READY -; -CHUSB_DSKRDY: - ;PRTS("\n\rDSKRDY:$") ; *DEBUG* - LD A,CH_CMD_DSKRDY ; DISK READY - CALL CH_CMD ; DO IT - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; *DEBUG* - JR NZ,CHUSB_DSKRDY ; *DEBUG* -; - RET -; -; PERFORM AUTO SETUP -; -CHUSB_AUTOSET: - ;PRTS("\n\rAUTOSET:$") ; *DEBUG* - LD A,CH_CMD_AUTOSET ; AUTOMATIC SETUP FOR USB - CALL CH_CMD ; DO IT - CALL LDELAY ; *DEBUG* - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; - RET -; -; PERFORM TEST CONNECT -; -CHUSB_TSTCON: - ;PRTS("\n\rTSTCON:$") ; *DEBUG* - LD A,CH_CMD_TSTCON ; TEST USB DEVICE CONNECT - CALL CH_CMD ; DO IT - CALL CH_NAP ; WAIT A BIT - CALL CH_RD ; GET RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; - RET -; -; PERFORM GET MAX LUN -; -CHUSB_MAXLUN: - ;PRTS("\n\rMAXLUN:$") ; *DEBUG* - LD A,CH_CMD_MAXLUN ; TEST USB DEVICE CONNECT - CALL CH_CMD ; DO IT - CALL CH_NAP ; WAIT A BIT - LD A,$38 ; CONSTANT - CALL CH_WR ; SEND IT - CALL CH_NAP - CALL CH_RD ; GET RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; - RET -; -#ENDIF -; -; ERROR HANDLERS -; -; -CHUSB_NOMEDIA: - LD A,CHUSB_STNOMEDIA - JR CHUSB_ERR -; -CHUSB_CMDERR: - LD A,CHUSB_STCMDERR - JR CHUSB_ERR -; -CHUSB_IOERR: - LD A,CHUSB_STIOERR - JR CHUSB_ERR +; INCLUDE SUB-DRIVERS AS NEEDED ; -CHUSB_TO: - LD A,CHUSB_STTO - JR CHUSB_ERR -; -CHUSB_NOTSUP: - LD A,CHUSB_STNOTSUP - JR CHUSB_ERR -; -CHUSB_ERR: - LD (IY+CHUSB_STAT),A ; SAVE NEW STATUS -; -CHUSB_ERR2: -#IF (CHUSBTRACE >= 2) - CALL CHUSB_PRTSTAT +#IF (CHUSBENABLE) + #INCLUDE "chusb.asm" #ENDIF - OR A ; SET FLAGS - RET -; -; -; -CHUSB_PRTERR: - RET Z ; DONE IF NO ERRORS - ; FALL THRU TO CHUSB_PRTSTAT -; -; PRINT FULL DEVICE STATUS LINE -; -CHUSB_PRTSTAT: - PUSH AF - PUSH DE - PUSH HL - LD A,(IY+CHUSB_STAT) - CALL CHUSB_PRTPREFIX ; PRINT UNIT PREFIX - CALL PC_SPACE ; FORMATTING - CALL CHUSB_PRTSTATSTR - POP HL - POP DE - POP AF - RET -; -; PRINT STATUS STRING -; -CHUSB_PRTSTATSTR: - PUSH AF - PUSH DE - PUSH HL - LD A,(IY+CHUSB_STAT) - NEG - LD HL,CHUSB_STR_ST_MAP - ADD A,A - CALL ADDHLA - LD E,(HL) - INC HL - LD D,(HL) - CALL WRITESTR - POP HL - POP DE - POP AF - RET -; -; PRINT DIAGNONSTIC PREFIX -; -CHUSB_PRTPREFIX: - PUSH AF - CALL NEWLINE - PRTS("CHUSB$") - LD A,(IY+CH_DEV) ; GET CURRENT DEVICE NUM - CALL PRTDECB - CALL PC_COLON - POP AF - RET -; -; DATA STORAGE -; -CHUSB_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT -CHUSB_DSKBUF .DW 0 -; -CHUSB_STR_ST_MAP: - .DW CHUSB_STR_STOK - .DW CHUSB_STR_STNOMEDIA - .DW CHUSB_STR_STCMDERR - .DW CHUSB_STR_STIOERR - .DW CHUSB_STR_STTO - .DW CHUSB_STR_STNOTSUP -; -CHUSB_STR_STOK .TEXT "OK$" -CHUSB_STR_STNOMEDIA .TEXT "NO MEDIA$" -CHUSB_STR_STCMDERR .TEXT "COMMAND ERROR$" -CHUSB_STR_STIOERR .TEXT "IO ERROR$" -CHUSB_STR_STTO .TEXT "TIMEOUT$" -CHUSB_STR_STNOTSUP .TEXT "NOT SUPPORTED$" -CHUSB_STR_STUNK .TEXT "UNKNOWN ERROR$" -; -;================================================================================================== -; CH375/376 SD CARD SUB-DRIVER -;================================================================================================== -; -#DEFINE CHSD_IMGFILE "DISK.IMG" -; -CHSD_FASTIO .EQU TRUE ; USE INIR/OTIR? -; -; CHUSB DEVICE STATUS ; -CHSD_STOK .EQU 0 -CHSD_STNOMEDIA .EQU -1 -CHSD_STCMDERR .EQU -2 -CHSD_STIOERR .EQU -3 -CHSD_STTO .EQU -4 -CHSD_STNOTSUP .EQU -5 -CHSD_STNOFILE .EQU -6 -; -; CHSD DEVICE CONFIGURATION -; -CHSD_CFGSIZ .EQU 12 ; SIZE OF USB CFG TBL ENTRIES -; -; CONFIG ENTRY DATA OFFSETS -; -; FIRST 3 BYTES SAME AS CH CONFIG -CHSD_STAT .EQU 3 ; LAST STATUS (BYTE) -CHSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) -CHSD_LBA .EQU 8 ; CURRENT LBA (DWORD) -; -CHSD_CFGTBL: -; -#IF (CHCNT >= 1) -CHSD_CFG0: - .DB 0 ; DEV NUM, FILLED DYNAMICALLY - .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY - .DB CH0BASE ; IO BASE ADDRESS - .DB 0 ; DEVICE STATUS - .DW 0,0 ; DEVICE CAPACITY - .DW 0,0 ; CURRENT LBA -; - #IF (CH0SDENABLE) - .ECHO "CHSD: IO=" - .ECHO CH0BASE - .ECHO "\n" - #ENDIF -#ENDIF -; -#IF (CHCNT >= 2) -CHSD_CFG1: - .DB 0 ; DEV NUM - .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY - .DB CH1BASE ; IO BASE ADDRESS - .DB 0 ; DEVICE STATUS - .DW 0,0 ; DEVICE CAPACITY - .DW 0,0 ; CURRENT LBA -; - #IF (CH1SDENABLE) - .ECHO "CHSD: IO=" - .ECHO CH1BASE - .ECHO "\n" - #ENDIF +#IF (CHSDENABLE) + #INCLUDE "chsd.asm" #ENDIF ; -#IF ($ - CHSD_CFGTBL) != (CHCNT * CHSD_CFGSIZ) - .ECHO "*** INVALID CHSD CONFIG TABLE ***\n" -#ENDIF -; - .DB $FF ; END OF TABLE MARKER -; -; -; -CHSD_INIT: - LD A,(IY+CH_TYPE) ; GET DEVICE TYPE - PUSH HL ; COPY INCOMING HL - POP IY ; ... TO IY - LD (IY+CH_TYPE),A ; SAVE DEVICE TYPE -; - ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE - LD A,(CHSD_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN - LD (IY+CH_DEV),A ; UPDATE IT - INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN - LD (CHSD_DEVNUM),A ; SAVE IT -; - ; ADD UNIT TO GLOBAL DISK UNIT TABLE - LD BC,CHSD_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 CHSD_RESET ; RESET & DISCOVER MEDIA -#IF (CHSDTRACE <= 1) - CALL NZ,CHSD_PRTSTAT -#ENDIF - RET NZ ; ABORT ON FAILURE -; - ; START PRINTING DEVICE INFO - CALL CHSD_PRTPREFIX ; PRINT DEVICE PREFIX -; - ; PRINT STORAGE CAPACITY (BLOCK COUNT) - PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - LD A,CHSD_MEDCAP ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL LD32 ; GET THE CAPACITY VALUE - CALL PRTHEX32 ; PRINT HEX VALUE -; - ; PRINT STORAGE SIZE IN MB - PRTS(" SIZE=$") ; PRINT FIELD LABEL - LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB - CALL SRL32 ; RIGHT SHIFT - CALL PRTDEC32 ; PRINT DWORD IN DECIMAL - PRTS("MB$") ; PRINT SUFFIX -; - XOR A ; SIGNAL SUCCESS - RET -; -; DRIVER FUNCTION TABLE -; -CHSD_FNTBL: - .DW CHSD_STATUS - .DW CHSD_RESET - .DW CHSD_SEEK - .DW CHSD_READ - .DW CHSD_WRITE - .DW CHSD_VERIFY - .DW CHSD_FORMAT - .DW CHSD_DEVICE - .DW CHSD_MEDIA - .DW CHSD_DEFMED - .DW CHSD_CAP - .DW CHSD_GEOM -#IF (($ - CHSD_FNTBL) != (DIO_FNCNT * 2)) - .ECHO "*** INVALID CHSD FUNCTION TABLE ***\n" -#ENDIF -; -CHSD_VERIFY: -CHSD_FORMAT: -CHSD_DEFMED: - SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED - RET -; -; -; -CHSD_READ: - LD A,CH_MODE_SD ; REQUEST SD MODE - CALL CH_SETMODE ; DO IT - JP NZ,CHSD_CMDERR ; HANDLE ERROR -; - CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR - LD (CHSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS - CALL CHSD_RWSTART ; SET LBA OFFSET - RET NZ -; - ;PRTS("\n\rREAD:$") ; *DEBUG* - LD A,CH_CMD_BYTERD ; BYTE READ - CALL CH_CMD ; SEND COMMAND - CALL CH_NAP - LD A,0 ; LSB - CALL CH_WR ; SEND IT - LD A,2 ; MSB - CALL CH_WR ; SEND IT - CALL CH_POLL ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $1D ; DATA READY TO READ? - JP NZ,CHSD_IOERR ; HANDLE I/O ERROR -; - LD HL,(CHSD_DSKBUF) -CHSD_READ1: - CALL CH_CMD_RD ; SEND READ USB DATA CMD - CALL CH_RD ; GET DATA LENGTH - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; -#IF (CHSD_FASTIO) - LD B,A ; BYTE COUNT TO READ - LD C,(IY+CH_IOBASE) ; BASE PORT - INIR ; DO IT FAST -#ELSE - LD B,A ; SAVE IT -CHSD_READ2: - CALL CH_RD ; GET DATA BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUF PTR - DJNZ CHSD_READ2 ; LOOP TILL DONE W/ ALL BYTES -#ENDIF -; - LD A,CH_CMD_BYTERDGO ; BYTE READ GO COMMAND - CALL CH_CMD ; SEND IT - CALL CH_NAP - CALL CH_POLL ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $1D ; MORE? - JR Z,CHSD_READ1 ; IF SO, GET MORE - CP $14 ; GOOD FINISH? - JP NZ,CHSD_IOERR ; HANDLE ERROR -; - ; INCREMENT LBA - PUSH HL ; SAVE HL - LD A,CHSD_LBA ; LBA OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL INC32HL ; INCREMENT THE VALUE - POP HL ; RESTORE HL -; - XOR A ; SIGNAL SUCCESS - RET -; -; -; -CHSD_WRITE: - LD A,CH_MODE_SD ; REQUEST SD MODE - CALL CH_SETMODE ; DO IT - JP NZ,CHSD_CMDERR ; HANDLE ERROR -; - CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR - LD (CHSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS - CALL CHSD_RWSTART ; SET LBA OFFSET' - RET NZ -; - ;PRTS("\n\rWRITE:$") ; *DEBUG* - LD A,CH_CMD_BYTEWR ; BYTE WRITE - CALL CH_CMD ; SEND COMMAND - LD A,0 ; LSB - CALL CH_WR ; SEND IT - LD A,2 ; MSB - CALL CH_WR ; SEND IT - CALL CH_POLL ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $1E ; DATA READY TO GO? - JP NZ,CHSD_IOERR ; HANDLE I/O ERROR -; - LD HL,(CHSD_DSKBUF) -CHSD_WRITE1: - LD A,CH_CMD_WRREQDAT ; WRITE REQUESTED DATA CMD - CALL CH_CMD ; SEND IT - CALL CH_RD ; GET DATA LENGTH - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* -; -#IF (CHSD_FASTIO) - LD B,A ; BYTE COUNT TO WRITE - LD C,(IY+CH_IOBASE) ; BASE PORT - OTIR ; DO IT FAST -#ELSE - LD B,A ; SAVE IT -CHSD_WRITE2: - CALL CH_WR ; WRITE DATA BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUF PTR - DJNZ CHSD_WRITE2 ; LOOP TILL DONE W/ ALL BYTES -#ENDIF -; - LD A,CH_CMD_BYTEWRGO ; BYTE WRITE GO COMMAND - CALL CH_CMD ; SEND IT - CALL CH_NAP - CALL CH_POLL ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $1E ; MORE? - JR Z,CHSD_WRITE1 ; IF SO, SEND MORE - CP $14 ; GOOD FINISH? - JP NZ,CHSD_IOERR ; HANDLE ERROR -; - ; INCREMENT LBA - PUSH HL ; SAVE HL - LD A,CHSD_LBA ; LBA OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL INC32HL ; INCREMENT THE VALUE - POP HL ; RESTORE HL -; - XOR A ; SIGNAL SUCCESS - RET -; -; SEEK TO CURRENT LBA -; -CHSD_RWSTART: - ;PRTS("\n\rRWST:$") ; *DEBUG* - LD A,CH_CMD_BYTE_LOC ; BYTE LOCATE COMMAND (SEEK) - CALL CH_CMD ; SEND IT -; - ; GET CURRENT LBA OFFSET - LD A,CHSD_LBA ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL LD32 ; OFFSET = DE:HL -; - ; CONVERT OFFSET FROM LBA TO BYTE - LD B,9 -CHSD_RWSTART1: - SLA L - RL H - RL E - RL D - DJNZ CHSD_RWSTART1 - ;CALL PRTHEX32 ; *DEBUG* -; - ; SEND THE BYTE OFFSET (LSB FIRST) - LD A,L - CALL CH_WR - LD A,H - CALL CH_WR - LD A,E - CALL CH_WR - LD A,D - CALL CH_WR -; - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $14 ; CHECK RESULT - JP NZ,CHUSB_CMDERR ; HANDLE CMD ERROR -; - XOR A - RET -; -; -; -CHSD_STATUS: - ; RETURN UNIT STATUS - LD A,(IY+CHSD_STAT) ; GET STATUS OF SELECTED DEVICE - OR A ; SET FLAGS - RET ; AND RETURN -; -; RESET THE INTERFACE AND REDISCOVER MEDIA -; -CHSD_RESET: - ;PRTS("\n\rRES SD:$") ; *DEBUG* -; - ; ACTIVATE SD MODE - LD A,CH_CMD_MODE ; SET MODE COMMAND - CALL CH_CMD ; SEND IT - LD A,3 ; SD MODE - CALL CH_WR ; SEND IT - CALL CH_NAP ; SMALL WAIT - CALL CH_RD ; GET RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CALL CH_NAP ; SMALL WAIT -; - LD A,CH_MODE_SD ; WE ARE NOW IN SD MODE - LD (CH_MODE),A ; SAVE IT -; - CALL CHSD_DSKMNT ; MOUNT DISK - RET NZ -; - ; OPEN DISK IMAGE FILE - LD DE,CHSD_FNAME - CALL CHSD_FOPEN - RET NZ -; - ; GET FILESIZE - CALL CHSD_FILESIZE - RET NZ -; - ; SET STATUS AND RETURN - XOR A ; CLEAR STATUS - LD (IY+CHSD_STAT),A ; RECORD STATUS - OR A ; SET FLAGS - RET ; AND RETURN -; -; -; -CHSD_DEVICE: - LD D,DIODEV_CHSD ; D := DEVICE TYPE - LD E,(IY+CH_DEV) ; E := PHYSICAL DEVICE NUMBER - LD C,%00110010 ; SD HARD DISK ATTRIBUTES - LD H,(IY+CH_TYPE) ; H := MODE - LD L,(IY+CH_IOBASE) ; L := BASE I/O ADDRESS - XOR A ; SIGNAL SUCCESS - RET -; -; CHSD_GETMED -; -CHSD_MEDIA: - LD A,E ; GET FLAGS - OR A ; SET FLAGS - JR Z,CHSD_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA - CALL CHSD_RESET ; RESET CHSD INTERFACE -; -CHSD_MEDIA1: - LD A,(IY+CHSD_STAT) ; GET STATUS - OR A ; SET FLAGS - LD D,0 ; NO MEDIA CHANGE DETECTED - LD E,MID_HD ; ASSUME WE ARE OK - RET Z ; RETURN IF GOOD INIT - LD E,MID_NONE ; SIGNAL NO MEDIA - LD A,ERR_NOMEDIA ; NO MEDIA ERROR - OR A ; SET FLAGS - RET ; AND RETURN -; -; -; -CHSD_SEEK: - BIT 7,D ; CHECK FOR LBA FLAG - CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA - RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) - LD (IY+CHSD_LBA+0),L ; SAVE NEW LBA - LD (IY+CHSD_LBA+1),H ; ... - LD (IY+CHSD_LBA+2),E ; ... - LD (IY+CHSD_LBA+3),D ; ... - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN -; -; -; -CHSD_CAP: - LD A,(IY+CHSD_STAT) ; GET STATUS - PUSH AF ; SAVE IT - LD A,CHSD_MEDCAP ; OFFSET TO CAPACITY FIELD - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL - LD BC,512 ; 512 BYTES PER BLOCK - POP AF ; RECOVER STATUS - OR A ; SET FLAGS - RET -; -; -; -CHSD_GEOM: - ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS - ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE - CALL CHSD_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC - LD L,H ; DIVIDE BY 256 FOR # TRACKS - LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL - LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT - LD E,16 ; SECTORS / TRACK = 16 - RET ; DONE, A STILL HAS CHSD_CAP STATUS -; -; CH37X HELPER ROUTINES -; -; -; PERFORM DISK MOUNT -; -CHSD_DSKMNT: - ;PRTS("\n\rMOUNT:$") ; *DEBUG* - LD A,CH_CMD_DSKMNT ; DISK QUERY - CALL CH_CMD ; DO IT - CALL CH_POLL ; WAIT FOR RESPONSE - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $82 ; NO DISK? - JP Z,CHSD_NOMEDIA ; HANDLE NO MEDIA ERROR - CP $14 ; SUCCESS? - JP NZ,CHSD_CMDERR ; HANDLE ERROR -; -#IF FALSE - CALL CH_CMD_RD ; SEND READ COMMAND - CALL CH_RD ; GET LENGTH - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - LD B,A ; LOOP COUNTER - LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA -CHSD_DSKMNT1: - CALL CH_RD ; GET A BYTE - LD (HL),A ; SAVE IT - INC HL ; BUMP BUF PTR - DJNZ CHSD_DSKMNT1 ; LOOP FOR ALL DATA -; - ;LD DE,HB_WRKBUF ; *DEBUG* - ;CALL DUMP_BUFFER ; *DEBUG* -; - CALL CHSD_PRTPREFIX ; PRINT DEVICE PREFIX - LD HL,HB_WRKBUF + 8 - LD B,28 -CHSD_DSKMNT2: - LD A,(HL) - INC HL - CALL COUT - DJNZ CHSD_DSKMNT2 -#ENDIF -; - XOR A - RET -; -; SET FILE NAME -; -CHSD_SETFNAME: - ;PRTS("\n\rSETFNAME:$") ; *DEBUG* - LD A,CH_CMD_SET_FN ; SET FILE NAME COMMAND - CALL CH_CMD ; SEND IT - CALL CH_NAP - ;CALL DELAY ; MAY NOT BE NEEDED - ;CALL PC_SPACE ; *DEBUG* -CHSD_SETFNAME1: - ;CALL DELAY - LD A,(DE) ; GET NEXT BYTE - INC DE ; BUMP POINTER - CALL CH_WR ; SEND IT - ;CALL COUT ; *DEBUG* - OR A ; CHECK FOR NUL (EOS) - RET Z ; IF NUL, DONE - JR CHSD_SETFNAME1 ; SEND MORE CHARACTERS -; -; OPEN FILE -; -CHSD_FOPEN: - CALL CHSD_SETFNAME - ;PRTS("\n\rFOPEN:$") ; *DEBUG* - LD A,CH_CMD_FOPEN ; FILE OPEN COMMAND - CALL CH_CMD ; SEND IT - CALL CH_POLL ; WAIT FOR RESULT - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEXBYTE ; *DEBUG* - CP $42 ; MISSING FILE? - JP Z,CHSD_NOFILE ; HANDLE ERROR - CP $14 ; SUCCESS? - JP NZ,CHSD_IOERR ; HANDLE ERROR - RET ; RETURN WITH ZF SET APPROPRIATELY -; -; GET FILE SIZE -; -CHSD_FILESIZE: - ;PRTS("\n\rFSIZE:$") - LD A,CH_CMD_FILESIZE ; FILE SIZE COMMAND - CALL CH_CMD ; SEND IT - LD A,$68 ; REQUIRED CMD PARAMETER - CALL CH_WR ; SEND IT - CALL CH_NAP - LD A,CHSD_MEDCAP ; MEDIA CAPACITY OFFSET - CALL LDHLIYA ; HL := IY + A, REG A TRASHED - PUSH HL ; SAVE ADDRESS - CALL CH_RD - LD L,A - CALL CH_RD - LD H,A - CALL CH_RD - LD E,A - CALL CH_RD - LD D,A - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEX32 ; *DEBUG* - LD B,9 ; ROTATE 9 BITS FOR DIV 512 -CHSD_FILESIZE1: - SRL D - RR E - RR H - RR L - DJNZ CHSD_FILESIZE1 ; LOOP TILL DONE - POP BC ; RECOVER ADDRESS TO BC - ;CALL PC_SPACE ; *DEBUG* - ;CALL PRTHEX32 ; *DEBUG* - CALL ST32 ; STORE IT - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -; ERROR HANDLERS -; -; -CHSD_NOFILE: - LD A,CHSD_STNOFILE - JR CHSD_ERR -; -CHSD_NOMEDIA: - LD A,CHSD_STNOMEDIA - JR CHSD_ERR -; -CHSD_CMDERR: - LD A,CHSD_STCMDERR - JR CHSD_ERR -; -CHSD_IOERR: - LD A,CHSD_STIOERR - JR CHSD_ERR -; -CHSD_TO: - LD A,CHSD_STTO - JR CHSD_ERR -; -CHSD_NOTSUP: - LD A,CHSD_STNOTSUP - JR CHSD_ERR -; -CHSD_ERR: - LD (IY+CHSD_STAT),A ; SAVE NEW STATUS -; -CHSD_ERR2: -#IF (CHSDTRACE >= 2) - CALL CHSD_PRTSTAT -#ENDIF - OR A ; SET FLAGS - RET -; -; -; -CHSD_PRTERR: - RET Z ; DONE IF NO ERRORS - ; FALL THRU TO CHSD_PRTSTAT -; -; PRINT FULL DEVICE STATUS LINE -; -CHSD_PRTSTAT: - PUSH AF - PUSH DE - PUSH HL - LD A,(IY+CHSD_STAT) - CALL CHSD_PRTPREFIX ; PRINT UNIT PREFIX - CALL PC_SPACE ; FORMATTING - CALL CHSD_PRTSTATSTR - POP HL - POP DE - POP AF - RET -; -; PRINT STATUS STRING -; -CHSD_PRTSTATSTR: - PUSH AF - PUSH DE - PUSH HL - LD A,(IY+CHSD_STAT) - NEG - LD HL,CHSD_STR_ST_MAP - ADD A,A - CALL ADDHLA - LD E,(HL) - INC HL - LD D,(HL) - CALL WRITESTR - POP HL - POP DE - POP AF - RET -; -; PRINT DIAGNONSTIC PREFIX -; -CHSD_PRTPREFIX: - PUSH AF - CALL NEWLINE - PRTS("CHSD$") - LD A,(IY+CH_DEV) ; GET CURRENT DEVICE NUM - CALL PRTDECB - CALL PC_COLON - POP AF - RET -; -; DATA STORAGE -; -CHSD_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT -CHSD_DSKBUF .DW 0 -; -CHSD_FNAME .DB "/", CHSD_IMGFILE, 0 -; -CHSD_STR_ST_MAP: - .DW CHSD_STR_STOK - .DW CHSD_STR_STNOMEDIA - .DW CHSD_STR_STCMDERR - .DW CHSD_STR_STIOERR - .DW CHSD_STR_STTO - .DW CHSD_STR_STNOTSUP - .DW CHSD_STR_STNOFILE -; -CHSD_STR_STOK .TEXT "OK$" -CHSD_STR_STNOMEDIA .TEXT "NO MEDIA$" -CHSD_STR_STCMDERR .TEXT "COMMAND ERROR$" -CHSD_STR_STIOERR .TEXT "IO ERROR$" -CHSD_STR_STTO .TEXT "TIMEOUT$" -CHSD_STR_STNOTSUP .TEXT "NOT SUPPORTED$" -CHSD_STR_STNOFILE .TEXT "MISSING " - .TEXT CHSD_IMGFILE - .TEXT " FILE$" -CHSD_STR_STUNK .TEXT "UNKNOWN ERROR$" diff --git a/Source/HBIOS/chsd.asm b/Source/HBIOS/chsd.asm new file mode 100644 index 00000000..a5789c9a --- /dev/null +++ b/Source/HBIOS/chsd.asm @@ -0,0 +1,685 @@ +; +;================================================================================================== +; CH376 SD CARD SUB-DRIVER +;================================================================================================== +; +; Thanks and credit to Alan Cox. Much of this driver is based on +; his code in FUZIX (https://github.com/EtchedPixels/FUZIX). +; +; This file contains the SD Card specific support for the CH37x +; driver. This file is included by the core driver file (ch.asm) as +; needed. Note that only the CH376 actually supports SD Card access. +; +; The SD Card support is implemented using the CH376 file-level +; support. It is *not* possible to access SD Cards using raw +; sector I/O. +; +; TODO: +; - Implement auto-recovery on error status? +; +#DEFINE CHSD_IMGFILE "DISK.IMG" +; +CHSD_FASTIO .EQU TRUE ; USE INIR/OTIR? +; +; CHUSB DEVICE STATUS +; +CHSD_STOK .EQU 0 +CHSD_STNOMEDIA .EQU -1 +CHSD_STCMDERR .EQU -2 +CHSD_STIOERR .EQU -3 +CHSD_STTO .EQU -4 +CHSD_STNOTSUP .EQU -5 +CHSD_STNOFILE .EQU -6 +; +; CHSD DEVICE CONFIGURATION +; +CHSD_CFGSIZ .EQU 14 ; SIZE OF USB CFG TBL ENTRIES +; +; CONFIG ENTRY DATA OFFSETS +; +; THE LOCATION OF CHSD_MODE IS SHARED BY ALL SUB-DRIVERS AND THE +; CH_SETMODE FUNCTION IN THE MAIN DRIVER (CH.ASM). IF YOU CHANGE +; IT, YOU MUST SYNC UP THE MAIN DRIVER AND ALL SUB-DRIVERS! +; +; FIRST 3 BYTES SAME AS CH CONFIG +CHSD_STAT .EQU 3 ; LAST STATUS (BYTE) +CHSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +CHSD_LBA .EQU 8 ; CURRENT LBA (DWORD) +CHSD_MODE .EQU 12 ; PTR TO MODE BYTE (WORD) +; +CHSD_CFGTBL: +; +#IF (CHCNT >= 1) +CHSD_CFG0: + .DB 0 ; DEV NUM, FILLED DYNAMICALLY + .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY + .DB CH0BASE ; IO BASE ADDRESS + .DB 0 ; DEVICE STATUS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA + .DW CH0_MODE ; POINTER TO MODE BYTE +; + #IF (CH0SDENABLE) + .ECHO "CHSD: IO=" + .ECHO CH0BASE + .ECHO "\n" + #ENDIF +#ENDIF +; +#IF (CHCNT >= 2) +CHSD_CFG1: + .DB 0 ; DEV NUM + .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY + .DB CH1BASE ; IO BASE ADDRESS + .DB 0 ; DEVICE STATUS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA + .DW CH1_MODE ; POINTER TO MODE BYTE +; + #IF (CH1SDENABLE) + .ECHO "CHSD: IO=" + .ECHO CH1BASE + .ECHO "\n" + #ENDIF +#ENDIF +; +#IF ($ - CHSD_CFGTBL) != (CHCNT * CHSD_CFGSIZ) + .ECHO "*** INVALID CHSD CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END OF TABLE MARKER +; +; +; +CHSD_INIT: + LD A,(IY+CH_TYPE) ; GET DEVICE TYPE + PUSH HL ; COPY INCOMING HL + POP IY ; ... TO IY + LD (IY+CH_TYPE),A ; SAVE DEVICE TYPE +; + ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE + LD A,(CHSD_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN + LD (IY+CH_DEV),A ; UPDATE IT + INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN + LD (CHSD_DEVNUM),A ; SAVE IT +; + ; ADD UNIT TO GLOBAL DISK UNIT TABLE + LD BC,CHSD_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 CHSD_RESET ; RESET & DISCOVER MEDIA +#IF (CHSDTRACE <= 1) + CALL NZ,CHSD_PRTSTAT +#ENDIF + RET NZ ; ABORT ON FAILURE +; + ; START PRINTING DEVICE INFO + CALL CHSD_PRTPREFIX ; PRINT DEVICE PREFIX +; + ; PRINT STORAGE CAPACITY (BLOCK COUNT) + PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL + LD A,CHSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CAPACITY VALUE + CALL PRTHEX32 ; PRINT HEX VALUE +; + ; PRINT STORAGE SIZE IN MB + PRTS(" SIZE=$") ; PRINT FIELD LABEL + LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB + CALL SRL32 ; RIGHT SHIFT + CALL PRTDEC32 ; PRINT DWORD IN DECIMAL + PRTS("MB$") ; PRINT SUFFIX +; + XOR A ; SIGNAL SUCCESS + RET +; +; DRIVER FUNCTION TABLE +; +CHSD_FNTBL: + .DW CHSD_STATUS + .DW CHSD_RESET + .DW CHSD_SEEK + .DW CHSD_READ + .DW CHSD_WRITE + .DW CHSD_VERIFY + .DW CHSD_FORMAT + .DW CHSD_DEVICE + .DW CHSD_MEDIA + .DW CHSD_DEFMED + .DW CHSD_CAP + .DW CHSD_GEOM +#IF (($ - CHSD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID CHSD FUNCTION TABLE ***\n" +#ENDIF +; +CHSD_VERIFY: +CHSD_FORMAT: +CHSD_DEFMED: + SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED + RET +; +; +; +CHSD_READ: + LD A,CH_MODE_SD ; REQUEST SD MODE + CALL CH_SETMODE ; DO IT + JP NZ,CHSD_CMDERR ; HANDLE ERROR +; + CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR + LD (CHSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + CALL CHSD_RWSTART ; SET LBA OFFSET + RET NZ +; + ;PRTS("\n\rREAD:$") ; *DEBUG* + LD A,CH_CMD_BYTERD ; BYTE READ + CALL CH_CMD ; SEND COMMAND + CALL CH_NAP + LD A,0 ; LSB + CALL CH_WR ; SEND IT + LD A,2 ; MSB + CALL CH_WR ; SEND IT + CALL CH_POLL ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $1D ; DATA READY TO READ? + JP NZ,CHSD_IOERR ; HANDLE I/O ERROR +; + LD HL,(CHSD_DSKBUF) +CHSD_READ1: + CALL CH_CMD_RD ; SEND READ USB DATA CMD + CALL CH_RD ; GET DATA LENGTH + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; +#IF (CHSD_FASTIO) + LD B,A ; BYTE COUNT TO READ + LD C,(IY+CH_IOBASE) ; BASE PORT + INIR ; DO IT FAST +#ELSE + LD B,A ; SAVE IT +CHSD_READ2: + CALL CH_RD ; GET DATA BYTE + LD (HL),A ; SAVE IN BUFFER + INC HL ; INC BUF PTR + DJNZ CHSD_READ2 ; LOOP TILL DONE W/ ALL BYTES +#ENDIF +; + LD A,CH_CMD_BYTERDGO ; BYTE READ GO COMMAND + CALL CH_CMD ; SEND IT + CALL CH_NAP + CALL CH_POLL ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $1D ; MORE? + JR Z,CHSD_READ1 ; IF SO, GET MORE + CP $14 ; GOOD FINISH? + JP NZ,CHSD_IOERR ; HANDLE ERROR +; + ; INCREMENT LBA + PUSH HL ; SAVE HL + LD A,CHSD_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + POP HL ; RESTORE HL +; + XOR A ; SIGNAL SUCCESS + RET +; +; +; +CHSD_WRITE: + LD A,CH_MODE_SD ; REQUEST SD MODE + CALL CH_SETMODE ; DO IT + JP NZ,CHSD_CMDERR ; HANDLE ERROR +; + CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR + LD (CHSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + CALL CHSD_RWSTART ; SET LBA OFFSET' + RET NZ +; + ;PRTS("\n\rWRITE:$") ; *DEBUG* + LD A,CH_CMD_BYTEWR ; BYTE WRITE + CALL CH_CMD ; SEND COMMAND + LD A,0 ; LSB + CALL CH_WR ; SEND IT + LD A,2 ; MSB + CALL CH_WR ; SEND IT + CALL CH_POLL ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $1E ; DATA READY TO GO? + JP NZ,CHSD_IOERR ; HANDLE I/O ERROR +; + LD HL,(CHSD_DSKBUF) +CHSD_WRITE1: + LD A,CH_CMD_WRREQDAT ; WRITE REQUESTED DATA CMD + CALL CH_CMD ; SEND IT + CALL CH_RD ; GET DATA LENGTH + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; +#IF (CHSD_FASTIO) + LD B,A ; BYTE COUNT TO WRITE + LD C,(IY+CH_IOBASE) ; BASE PORT + OTIR ; DO IT FAST +#ELSE + LD B,A ; SAVE IT +CHSD_WRITE2: + CALL CH_WR ; WRITE DATA BYTE + LD (HL),A ; SAVE IN BUFFER + INC HL ; INC BUF PTR + DJNZ CHSD_WRITE2 ; LOOP TILL DONE W/ ALL BYTES +#ENDIF +; + LD A,CH_CMD_BYTEWRGO ; BYTE WRITE GO COMMAND + CALL CH_CMD ; SEND IT + CALL CH_NAP + CALL CH_POLL ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $1E ; MORE? + JR Z,CHSD_WRITE1 ; IF SO, SEND MORE + CP $14 ; GOOD FINISH? + JP NZ,CHSD_IOERR ; HANDLE ERROR +; + ; INCREMENT LBA + PUSH HL ; SAVE HL + LD A,CHSD_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + POP HL ; RESTORE HL +; + XOR A ; SIGNAL SUCCESS + RET +; +; SEEK TO CURRENT LBA +; +CHSD_RWSTART: + ;PRTS("\n\rRWST:$") ; *DEBUG* + LD A,CH_CMD_BYTE_LOC ; BYTE LOCATE COMMAND (SEEK) + CALL CH_CMD ; SEND IT +; + ; GET CURRENT LBA OFFSET + LD A,CHSD_LBA ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; OFFSET = DE:HL +; + ; CONVERT OFFSET FROM LBA TO BYTE + LD B,9 +CHSD_RWSTART1: + SLA L + RL H + RL E + RL D + DJNZ CHSD_RWSTART1 + ;CALL PRTHEX32 ; *DEBUG* +; + ; SEND THE BYTE OFFSET (LSB FIRST) + LD A,L + CALL CH_WR + LD A,H + CALL CH_WR + LD A,E + CALL CH_WR + LD A,D + CALL CH_WR +; + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; CHECK RESULT + JP NZ,CHSD_CMDERR ; HANDLE CMD ERROR +; + XOR A + RET +; +; +; +CHSD_STATUS: + ; RETURN UNIT STATUS + LD A,(IY+CHSD_STAT) ; GET STATUS OF SELECTED DEVICE + OR A ; SET FLAGS + RET ; AND RETURN +; +; RESET THE INTERFACE AND REDISCOVER MEDIA +; +CHSD_RESET: + ;PRTS("\n\rRES SD:$") ; *DEBUG* +; + ; ACTIVATE SD MODE + LD A,CH_CMD_MODE ; SET MODE COMMAND + CALL CH_CMD ; SEND IT + LD A,3 ; SD MODE + CALL CH_WR ; SEND IT + CALL CH_NAP ; SMALL WAIT + CALL CH_RD ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CALL CH_NAP ; SMALL WAIT +; + LD A,CH_MODE_SD ; WE ARE NOW IN SD MODE + LD L,(IY+CHSD_MODE+0) ; GET MODE PTR (LSB) + LD H,(IY+CHSD_MODE+1) ; GET MODE PTR (MSB) + LD (HL),A ; SAVE IT +; + CALL CHSD_DSKMNT ; MOUNT DISK + RET NZ +; + ; OPEN DISK IMAGE FILE + LD DE,CHSD_FNAME + CALL CHSD_FOPEN + RET NZ +; + ; GET FILESIZE + CALL CHSD_FILESIZE + RET NZ +; + ; SET STATUS AND RETURN + XOR A ; CLEAR STATUS + LD (IY+CHSD_STAT),A ; RECORD STATUS + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +CHSD_DEVICE: + LD D,DIODEV_CHSD ; D := DEVICE TYPE + LD E,(IY+CH_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%00110010 ; SD HARD DISK ATTRIBUTES + LD H,(IY+CH_TYPE) ; H := MODE + LD L,(IY+CH_IOBASE) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; CHSD_GETMED +; +CHSD_MEDIA: + LD A,E ; GET FLAGS + OR A ; SET FLAGS + JR Z,CHSD_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA + CALL CHSD_RESET ; RESET CHSD INTERFACE +; +CHSD_MEDIA1: + LD A,(IY+CHSD_STAT) ; GET STATUS + OR A ; SET FLAGS + LD D,0 ; NO MEDIA CHANGE DETECTED + LD E,MID_HD ; ASSUME WE ARE OK + RET Z ; RETURN IF GOOD INIT + LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +CHSD_SEEK: + BIT 7,D ; CHECK FOR LBA FLAG + CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA + RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) + LD (IY+CHSD_LBA+0),L ; SAVE NEW LBA + LD (IY+CHSD_LBA+1),H ; ... + LD (IY+CHSD_LBA+2),E ; ... + LD (IY+CHSD_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; +; +CHSD_CAP: + LD A,(IY+CHSD_STAT) ; GET STATUS + PUSH AF ; SAVE IT + LD A,CHSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL + LD BC,512 ; 512 BYTES PER BLOCK + POP AF ; RECOVER STATUS + OR A ; SET FLAGS + RET +; +; +; +CHSD_GEOM: + ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS + ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE + CALL CHSD_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC + LD L,H ; DIVIDE BY 256 FOR # TRACKS + LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL + LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT + LD E,16 ; SECTORS / TRACK = 16 + RET ; DONE, A STILL HAS CHSD_CAP STATUS +; +; CH37X HELPER ROUTINES +; +; +; PERFORM DISK MOUNT +; +CHSD_DSKMNT: + ;PRTS("\n\rMOUNT:$") ; *DEBUG* + LD A,CH_CMD_DSKMNT ; DISK QUERY + CALL CH_CMD ; DO IT + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $82 ; NO DISK? + JP Z,CHSD_NOMEDIA ; HANDLE NO MEDIA ERROR + CP $14 ; SUCCESS? + JP NZ,CHSD_CMDERR ; HANDLE ERROR +; +#IF FALSE + CALL CH_CMD_RD ; SEND READ COMMAND + CALL CH_RD ; GET LENGTH + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + LD B,A ; LOOP COUNTER + LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA +CHSD_DSKMNT1: + CALL CH_RD ; GET A BYTE + LD (HL),A ; SAVE IT + INC HL ; BUMP BUF PTR + DJNZ CHSD_DSKMNT1 ; LOOP FOR ALL DATA +; + ;LD DE,HB_WRKBUF ; *DEBUG* + ;CALL DUMP_BUFFER ; *DEBUG* +; + CALL CHSD_PRTPREFIX ; PRINT DEVICE PREFIX + LD HL,HB_WRKBUF + 8 + LD B,28 +CHSD_DSKMNT2: + LD A,(HL) + INC HL + CALL COUT + DJNZ CHSD_DSKMNT2 +#ENDIF +; + XOR A + RET +; +; SET FILE NAME +; +CHSD_SETFNAME: + ;PRTS("\n\rSETFNAME:$") ; *DEBUG* + LD A,CH_CMD_SET_FN ; SET FILE NAME COMMAND + CALL CH_CMD ; SEND IT + CALL CH_NAP + ;CALL DELAY ; MAY NOT BE NEEDED + ;CALL PC_SPACE ; *DEBUG* +CHSD_SETFNAME1: + ;CALL DELAY + LD A,(DE) ; GET NEXT BYTE + INC DE ; BUMP POINTER + CALL CH_WR ; SEND IT + ;CALL COUT ; *DEBUG* + OR A ; CHECK FOR NUL (EOS) + RET Z ; IF NUL, DONE + JR CHSD_SETFNAME1 ; SEND MORE CHARACTERS +; +; OPEN FILE +; +CHSD_FOPEN: + CALL CHSD_SETFNAME + ;PRTS("\n\rFOPEN:$") ; *DEBUG* + LD A,CH_CMD_FOPEN ; FILE OPEN COMMAND + CALL CH_CMD ; SEND IT + CALL CH_POLL ; WAIT FOR RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $42 ; MISSING FILE? + JP Z,CHSD_NOFILE ; HANDLE ERROR + CP $14 ; SUCCESS? + JP NZ,CHSD_IOERR ; HANDLE ERROR + RET ; RETURN WITH ZF SET APPROPRIATELY +; +; GET FILE SIZE +; +CHSD_FILESIZE: + ;PRTS("\n\rFSIZE:$") + LD A,CH_CMD_FILESIZE ; FILE SIZE COMMAND + CALL CH_CMD ; SEND IT + LD A,$68 ; REQUIRED CMD PARAMETER + CALL CH_WR ; SEND IT + CALL CH_NAP + LD A,CHSD_MEDCAP ; MEDIA CAPACITY OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + PUSH HL ; SAVE ADDRESS + CALL CH_RD + LD L,A + CALL CH_RD + LD H,A + CALL CH_RD + LD E,A + CALL CH_RD + LD D,A + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEX32 ; *DEBUG* + LD B,9 ; ROTATE 9 BITS FOR DIV 512 +CHSD_FILESIZE1: + SRL D + RR E + RR H + RR L + DJNZ CHSD_FILESIZE1 ; LOOP TILL DONE + POP BC ; RECOVER ADDRESS TO BC + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEX32 ; *DEBUG* + CALL ST32 ; STORE IT + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +; ERROR HANDLERS +; +; +CHSD_NOFILE: + LD A,CHSD_STNOFILE + JR CHSD_ERR +; +CHSD_NOMEDIA: + LD A,CHSD_STNOMEDIA + JR CHSD_ERR +; +CHSD_CMDERR: + LD A,CHSD_STCMDERR + JR CHSD_ERR +; +CHSD_IOERR: + LD A,CHSD_STIOERR + JR CHSD_ERR +; +CHSD_TO: + LD A,CHSD_STTO + JR CHSD_ERR +; +CHSD_NOTSUP: + LD A,CHSD_STNOTSUP + JR CHSD_ERR +; +CHSD_ERR: + LD (IY+CHSD_STAT),A ; SAVE NEW STATUS +; +CHSD_ERR2: +#IF (CHSDTRACE >= 2) + CALL CHSD_PRTSTAT +#ENDIF + OR A ; SET FLAGS + RET +; +; +; +CHSD_PRTERR: + RET Z ; DONE IF NO ERRORS + ; FALL THRU TO CHSD_PRTSTAT +; +; PRINT FULL DEVICE STATUS LINE +; +CHSD_PRTSTAT: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+CHSD_STAT) + CALL CHSD_PRTPREFIX ; PRINT UNIT PREFIX + CALL PC_SPACE ; FORMATTING + CALL CHSD_PRTSTATSTR + POP HL + POP DE + POP AF + RET +; +; PRINT STATUS STRING +; +CHSD_PRTSTATSTR: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+CHSD_STAT) + NEG + LD HL,CHSD_STR_ST_MAP + ADD A,A + CALL ADDHLA + LD E,(HL) + INC HL + LD D,(HL) + CALL WRITESTR + POP HL + POP DE + POP AF + RET +; +; PRINT DIAGNONSTIC PREFIX +; +CHSD_PRTPREFIX: + PUSH AF + CALL NEWLINE + PRTS("CHSD$") + LD A,(IY+CH_DEV) ; GET CURRENT DEVICE NUM + CALL PRTDECB + CALL PC_COLON + POP AF + RET +; +; DATA STORAGE +; +CHSD_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT +CHSD_DSKBUF .DW 0 +; +CHSD_FNAME .DB "/", CHSD_IMGFILE, 0 +; +CHSD_STR_ST_MAP: + .DW CHSD_STR_STOK + .DW CHSD_STR_STNOMEDIA + .DW CHSD_STR_STCMDERR + .DW CHSD_STR_STIOERR + .DW CHSD_STR_STTO + .DW CHSD_STR_STNOTSUP + .DW CHSD_STR_STNOFILE +; +CHSD_STR_STOK .TEXT "OK$" +CHSD_STR_STNOMEDIA .TEXT "NO MEDIA$" +CHSD_STR_STCMDERR .TEXT "COMMAND ERROR$" +CHSD_STR_STIOERR .TEXT "IO ERROR$" +CHSD_STR_STTO .TEXT "TIMEOUT$" +CHSD_STR_STNOTSUP .TEXT "NOT SUPPORTED$" +CHSD_STR_STNOFILE .TEXT "MISSING " + .TEXT CHSD_IMGFILE + .TEXT " FILE$" +CHSD_STR_STUNK .TEXT "UNKNOWN ERROR$" diff --git a/Source/HBIOS/chusb.asm b/Source/HBIOS/chusb.asm new file mode 100644 index 00000000..fd4c5d44 --- /dev/null +++ b/Source/HBIOS/chusb.asm @@ -0,0 +1,792 @@ +; +;================================================================================================== +; CH375/376 USB SUB-DRIVER +;================================================================================================== +; +; Thanks and credit to Alan Cox. Much of this driver is based on +; his code in FUZIX (https://github.com/EtchedPixels/FUZIX). +; +; This file contains the USB Drive specific support for the CH37x +; driver. This file is included by the core driver file (ch.asm) as +; needed. +; +; The USB support is implemented as pure raw sector I/O. The CH376 +; file-level support is not utilized. +; +; NOTES: +; - There seem to be compatibility issues with older USB thumb drives. +; Such drives will complete DISK_INIT successfully, but then return +; an error attempting to do any I/O. The error is $17 indicating +; the CH37x encountered an overflow during communication with the +; device. I found that adding a DISK_MOUNT command (only possible +; on CH376) resolved the issue for some devices, so that has been +; added to the RESET routine when using CH376. +; +; TODO: +; - Implement auto-recovery on error status? +; +CHUSB_FASTIO .EQU TRUE ; USE INIR/OTIR? +; +; CHUSB DEVICE STATUS +; +CHUSB_STOK .EQU 0 +CHUSB_STNOMEDIA .EQU -1 +CHUSB_STCMDERR .EQU -2 +CHUSB_STIOERR .EQU -3 +CHUSB_STTO .EQU -4 +CHUSB_STNOTSUP .EQU -5 +; +; CHUSB DEVICE CONFIGURATION +; +CHUSB_CFGSIZ .EQU 14 ; SIZE OF USB CFG TBL ENTRIES +; +; CONFIG ENTRY DATA OFFSETS +; +; THE LOCATION OF CHSD_MODE IS SHARED BY ALL SUB-DRIVERS AND THE +; CH_SETMODE FUNCTION IN THE MAIN DRIVER (CH.ASM). IF YOU CHANGE +; IT, YOU MUST SYNC UP THE MAIN DRIVER AND ALL SUB-DRIVERS! +; +; FIRST 3 BYTES SAME AS CH CONFIG +CHUSB_STAT .EQU 3 ; LAST STATUS (BYTE) +CHUSB_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +CHUSB_LBA .EQU 8 ; CURRENT LBA (DWORD) +CHUSB_MODE .EQU 12 ; PTR TO MODE BYTE (WORD) +; +CHUSB_CFGTBL: +; +#IF (CHCNT >= 1) +CHUSB_CFG0: + .DB 0 ; DEV NUM, FILLED DYNAMICALLY + .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY + .DB CH0BASE ; IO BASE ADDRESS + .DB 0 ; DEVICE STATUS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA + .DW CH0_MODE ; POINTER TO MODE BYTE +; + #IF (CH0USBENABLE) + .ECHO "CHUSB: IO=" + .ECHO CH0BASE + .ECHO "\n" + #ENDIF +#ENDIF +; +#IF (CHCNT >= 2) +CHUSB_CFG1: + .DB 0 ; DEV NUM + .DB CHTYP_NONE ; DEV TYPE, FILLED DYNCAMICALLY + .DB CH1BASE ; IO BASE ADDRESS + .DB 0 ; DEVICE STATUS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA + .DW CH1_MODE ; POINTER TO MODE BYTE +; + #IF (CH1USBENABLE) + .ECHO "CHUSB: IO=" + .ECHO CH1BASE + .ECHO "\n" + #ENDIF +#ENDIF +; +#IF ($ - CHUSB_CFGTBL) != (CHCNT * CHUSB_CFGSIZ) + .ECHO "*** INVALID CHUSB CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END OF TABLE MARKER +; +; +; +CHUSB_INIT: + LD A,(IY+CH_TYPE) ; GET DEVICE TYPE + PUSH HL ; COPY INCOMING HL + POP IY ; ... TO IY + LD (IY+CH_TYPE),A ; SAVE DEVICE TYPE +; + ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE + LD A,(CHUSB_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN + LD (IY+CH_DEV),A ; UPDATE IT + INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN + LD (CHUSB_DEVNUM),A ; SAVE IT +; + ; ADD UNIT TO GLOBAL DISK UNIT TABLE + LD BC,CHUSB_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 CHUSB_RESET ; RESET & DISCOVER MEDIA +#IF (CHUSBTRACE <= 1) + CALL NZ,CHUSB_PRTSTAT +#ENDIF + RET NZ ; ABORT ON FAILURE +; + ; START PRINTING DEVICE INFO + CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX +; + ; PRINT STORAGE CAPACITY (BLOCK COUNT) + PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL + LD A,CHUSB_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CAPACITY VALUE + CALL PRTHEX32 ; PRINT HEX VALUE +; + ; PRINT STORAGE SIZE IN MB + PRTS(" SIZE=$") ; PRINT FIELD LABEL + LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB + CALL SRL32 ; RIGHT SHIFT + CALL PRTDEC32 ; PRINT DWORD IN DECIMAL + PRTS("MB$") ; PRINT SUFFIX +; + XOR A ; SIGNAL SUCCESS + RET +; +; DRIVER FUNCTION TABLE +; +CHUSB_FNTBL: + .DW CHUSB_STATUS + .DW CHUSB_RESET + .DW CHUSB_SEEK + .DW CHUSB_READ + .DW CHUSB_WRITE + .DW CHUSB_VERIFY + .DW CHUSB_FORMAT + .DW CHUSB_DEVICE + .DW CHUSB_MEDIA + .DW CHUSB_DEFMED + .DW CHUSB_CAP + .DW CHUSB_GEOM +#IF (($ - CHUSB_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID CHUSB FUNCTION TABLE ***\n" +#ENDIF +; +CHUSB_VERIFY: +CHUSB_FORMAT: +CHUSB_DEFMED: + SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED + RET +; +; +; +CHUSB_READ: + LD A,CH_MODE_USB ; REQUEST USB MODE + CALL CH_SETMODE ; DO IT + JP NZ,CHUSB_CMDERR ; HANDLE ERROR +; + CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR + LD (CHUSB_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + LD A,CH_CMD_DSKRD ; DISK READ COMMAND + CALL CHUSB_RWSTART ; SEND CMD AND LBA +; + ; READ THE SECTOR IN 64 BYTE CHUNKS + LD B,8 ; 8 CHUNKS OF 64 FOR 512 BYTE SECTOR + LD HL,(CHUSB_DSKBUF) ; GET DISK BUF ADR +CHUSB_READ1: + CALL CH_POLL ; WAIT FOR DATA READY + CP $1D ; DATA READY TO READ? + ;CALL PC_LT ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + JP NZ,CHUSB_IOERR ; HANDLE IO ERROR + CALL CH_CMD_RD ; SEND READ USB DATA CMD + CALL CH_RD ; READ DATA BLOCK LENGTH + CP 64 ; AS EXPECTED? + JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR +; +#IF (CHUSB_FASTIO) + ; READ 64 BYTE CHUNK + PUSH BC ; SAVE LOOP CONTROL + LD B,64 ; READ 64 BYTES + LD C,(IY+CH_IOBASE) ; BASE PORT + INIR ; DO IT FAST + POP BC ; RESTORE LOOP CONTROL +#ELSE + ; BYTE READ LOOP + PUSH BC ; SAVE LOOP CONTROL + LD B,64 ; READ 64 BYTES +CHUSB_READ2: + CALL CH_RD ; GET NEXT BYTE + LD (HL),A ; SAVE IT + INC HL ; INC BUF PTR + DJNZ CHUSB_READ2 ; LOOP AS NEEDED + POP BC ; RESTORE LOOP CONTROL +#ENDIF +; + ; PREPARE FOR NEXT CHUNK + LD A,CH_CMD_DSKRDGO ; CONTINUE DISK READ + CALL CH_CMD ; SEND IT + DJNZ CHUSB_READ1 ; LOOP TILL DONE +; + ; FINAL CHECK FOR COMPLETION & SUCCESS + CALL CH_POLL ; WAIT FOR COMPLETION + CP $14 ; SUCCESS? + JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR +; + ; INCREMENT LBA + PUSH HL ; SAVE HL + LD A,CHUSB_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + POP HL ; RESTORE HL +; + XOR A ; SIGNAL SUCCESS + RET +; +; +; +CHUSB_WRITE: + LD A,CH_MODE_USB ; REQUEST USB MODE + CALL CH_SETMODE ; DO IT + JP NZ,CHUSB_CMDERR ; HANDLE ERROR +; + CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR + LD (CHUSB_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + LD A,CH_CMD_DSKWR ; DISK READ COMMAND + CALL CHUSB_RWSTART ; SEND CMD AND LBA +; + ; WRITE THE SECTOR IN 64 BYTE CHUNKS + LD B,8 ; 8 CHUNKS OF 64 FOR 512 BYTE SECTOR + LD HL,(CHUSB_DSKBUF) ; GET DISK BUF ADR +CHUSB_WRITE1: + CALL CH_POLL ; WAIT FOR DATA READY + CP $1E ; DATA READY TO WRITE + ;CALL PC_GT ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + JP NZ,CHUSB_IOERR ; HANDLE IO ERROR + CALL CH_CMD_WR ; SEND WRITE USB DATA CMD + LD A,64 ; 64 BYTE CHUNK + CALL CH_WR ; SEND DATA BLOCK LENGTH +; +#IF (CHUSB_FASTIO) + ; WRITE 64 BYTE CHUNK + PUSH BC ; SAVE LOOP CONTROL + LD B,64 ; WRITE 64 BYTES + LD C,(IY+CH_IOBASE) ; BASE PORT + OTIR ; DO IT FAST + POP BC ; RESTORE LOOP CONTROL +#ELSE + ; BYTE WRITE LOOP + PUSH BC ; SAVE LOOP CONTROL + LD B,64 ; WRITE 64 BYTES +CHUSB_WRITE2: + LD A,(HL) ; GET NEXT BYTE + INC HL ; INC BUF PTR + CALL CH_WR ; WRITE NEXT BYTE + DJNZ CHUSB_WRITE2 ; LOOP AS NEEDED + POP BC ; RESTORE LOOP CONTROL +#ENDIF +; + ; PREPARE FOR NEXT CHUNK + LD A,CH_CMD_DSKWRGO ; CONTINUE DISK READ + CALL CH_CMD ; SEND IT + DJNZ CHUSB_WRITE1 ; LOOP TILL DONE +; + ; FINAL CHECK FOR COMPLETION & SUCCESS + CALL CH_POLL ; WAIT FOR COMPLETION + CP $14 ; SUCCESS? + JP NZ,CHUSB_IOERR ; IF NOT, HANDLE ERROR +; + ; INCREMENT LBA + PUSH HL ; SAVE HL + LD A,CHUSB_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + POP HL ; RESTORE HL +; + XOR A ; SIGNAL SUCCESS + RET +; +; INITIATE A DISK SECTOR READ/WRITE OPERATION +; A: READ OR WRITE OPCODE +; +CHUSB_RWSTART: + CALL CH_CMD ; SEND R/W COMMAND +; + ; SEND LBA, 4 BYTES, LITTLE ENDIAN + LD A,CHUSB_LBA ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + LD B,4 ; SEND 4 BYTES +CHUSB_RWSTART1: + LD A,(HL) ; GET BYTE + INC HL ; BUMP PTR + CALL CH_WR ; SEND BYTE + DJNZ CHUSB_RWSTART1 ; LOOP AS NEEDED +; + ; REQUEST 1 SECTOR + LD A,1 ; 1 SECTOR + CALL CH_WR ; SEND IT + RET +; +; +; +CHUSB_STATUS: + ; RETURN UNIT STATUS + LD A,(IY+CHUSB_STAT) ; GET STATUS OF SELECTED DEVICE + OR A ; SET FLAGS + RET ; AND RETURN +; +; RESET THE INTERFACE AND REDISCOVER MEDIA +; +CHUSB_RESET: + ;PRTS("\n\rRES USB:$") ; *DEBUG* + ;CALL CH_FLUSH ; DISCARD ANY GARBAGE + ;CALL CH_RESET ; FULL CH37X RESET +; + ; RESET THE BUS + LD A,CH_CMD_MODE ; SET MODE COMMAND + CALL CH_CMD ; SEND IT + LD A,7 ; RESET BUS + CALL CH_WR ; SEND IT + CALL CH_NAP ; SMALL WAIT + CALL CH_RD ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CALL CH_NAP ; SMALL WAIT +; + ; ACTIVATE USB MODE + LD A,CH_CMD_MODE ; SET MODE COMMAND + CALL CH_CMD ; SEND IT + LD A,6 ; USB ENABLED, SEND SOF + CALL CH_WR ; SEND IT + CALL CH_NAP ; SMALL WAIT + CALL CH_RD ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CALL CH_NAP ; SMALL WAIT +; + LD A,CH_MODE_USB ; WE ARE NOW IN USB MODE + LD L,(IY+CHUSB_MODE+0) ; GET MODE PTR (LSB) + LD H,(IY+CHUSB_MODE+1) ; GET MODE PTR (MSB) + LD (HL),A ; SAVE IT +; + ; INITIALIZE DISK + LD B,24 ; TRY A FEW TIMES +CHUSB_RESET1: + ;PRTS("\n\rDSKINIT:$") ; *DEBUG* + LD A,CH_CMD_DSKINIT ; DISK INIT COMMAND + CALL CH_CMD ; SEND IT + LD DE,10000 ; 10000 * 16 = 160US ??? + LD DE,20000 ; 10000 * 16 = 160US ??? + LD DE,12500 ; 1250 * 16 = 200US ??? + CALL VDELAY ; DELAY + CALL CH_POLL ; WAIT FOR RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; SUCCESS? + JR Z,CHUSB_RESET1A ; IF SO, CHECK READY + CP $16 ; NO MEDIA + JP Z,CHUSB_NOMEDIA ; HANDLE IT + CALL CH_NAP ; SMALL DELAY + DJNZ CHUSB_RESET1 ; LOOP AS NEEDED + JP CHUSB_TO ; HANDLE TIMEOUT +; +CHUSB_RESET1A: + ;CALL CHUSB_DSKRES ; DISK RESET + ;CP $14 ; GOOD? + ;JR Z,CHUSB_RESET2 + ;CALL CHUSB_DSKRDY ; CHECK IF DISK READY + ;CP $14 ; GOOD? + ;JR Z,CHUSB_RESET2 ; IF SO, MOVE ON + ;DJNZ CHUSB_RESET1 ; KEEP TRYING +; +CHUSB_RESET2: + ; USE OF CH376 DISK_MOUNT COMMAND SEEMS TO IMPROVE + ; COMPATIBILITY WITH SOME OLDER USB THUMBDRIVES. + LD A,(IY+CH_TYPE) ; CH37X TYPE? + CP CHTYP_376 ; IS CH376? + CALL Z,CHUSB_DSKMNT ; IF SO, TRY MOUNT, IGNORE ERRS + ;CALL CHUSB_AUTOSET ; *DEBUG* + ;CALL CHUSB_TSTCON ; *DEBUG* + ;CALL CHUSB_MAXLUN ; *DEBUG* + ;CALL CHUSB_DSKRDY ; *DEBUG* + ;CALL CHUSB_DSKINQ ; *DEBUG* +;; + CALL CHUSB_DSKSIZ ; GET AND RECORD DISK SIZE + RET NZ ; ABORT ON ERROR +; + ; SET STATUS AND RETURN + XOR A ; CLEAR STATUS + LD (IY+CHUSB_STAT),A ; RECORD STATUS + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +CHUSB_DEVICE: + LD D,DIODEV_CHUSB ; D := DEVICE TYPE + LD E,(IY+CH_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%00110011 ; USB HARD DISK ATTRIBUTES + LD H,(IY+CH_TYPE) ; H := MODE + LD L,(IY+CH_IOBASE) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; CHUSB_GETMED +; +CHUSB_MEDIA: + LD A,E ; GET FLAGS + OR A ; SET FLAGS + JR Z,CHUSB_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA + CALL CHUSB_RESET ; RESET CHUSB INTERFACE +; +CHUSB_MEDIA1: + LD A,(IY+CHUSB_STAT) ; GET STATUS + OR A ; SET FLAGS + LD D,0 ; NO MEDIA CHANGE DETECTED + LD E,MID_HD ; ASSUME WE ARE OK + RET Z ; RETURN IF GOOD INIT + LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +CHUSB_SEEK: + BIT 7,D ; CHECK FOR LBA FLAG + CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA + RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) + LD (IY+CHUSB_LBA+0),L ; SAVE NEW LBA + LD (IY+CHUSB_LBA+1),H ; ... + LD (IY+CHUSB_LBA+2),E ; ... + LD (IY+CHUSB_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; +; +CHUSB_CAP: + LD A,(IY+CHUSB_STAT) ; GET STATUS + PUSH AF ; SAVE IT + LD A,CHUSB_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL + LD BC,512 ; 512 BYTES PER BLOCK + POP AF ; RECOVER STATUS + OR A ; SET FLAGS + RET +; +; +; +CHUSB_GEOM: + ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS + ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE + CALL CHUSB_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC + LD L,H ; DIVIDE BY 256 FOR # TRACKS + LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL + LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT + LD E,16 ; SECTORS / TRACK = 16 + RET ; DONE, A STILL HAS CHUSB_CAP STATUS +; +; CH37X HELPER ROUTINES +; +; +; PERFORM DISK MOUNT +; +CHUSB_DSKMNT: + ;PRTS("\n\rMOUNT:$") ; *DEBUG* + LD A,CH_CMD_DSKMNT ; DISK QUERY + CALL CH_CMD ; DO IT + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; SUCCESS? + RET NZ ; ABORT IF NOT +; +#IF FALSE + CALL CH_CMD_RD ; SEND READ COMMAND + CALL CH_RD ; GET LENGTH + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + LD B,A ; LOOP COUNTER + LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA +CHUSB_DSKMNT1: + CALL CH_RD ; GET A BYTE + LD (HL),A ; SAVE IT + INC HL ; BUMP BUF PTR + DJNZ CHUSB_DSKMNT1 ; LOOP FOR ALL DATA +; + ;LD DE,HB_WRKBUF ; *DEBUG* + ;CALL DUMP_BUFFER ; *DEBUG* +; + CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX + LD HL,HB_WRKBUF + 8 + LD B,28 +CHUSB_DSKMNT2: + LD A,(HL) + INC HL + CALL COUT + DJNZ CHUSB_DSKMNT2 +#ENDIF +; + XOR A + RET +; +; PERFORM DISK SIZE +; +CHUSB_DSKSIZ: + ;PRTS("\n\rDSKSIZ:$") ; *DEBUG* + LD A,CH_CMD_DSKSIZ ; DISK SIZE COMMAND + CALL CH_CMD ; SEND IT + CALL CH_POLL ; WAIT FOR RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; SUCCESS? + JP NZ,CHUSB_CMDERR ; HANDLE CMD ERROR + CALL CH_CMD_RD ; SEND READ USB DATA CMD + CALL CH_RD ; GET RD DATA LEN + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $08 ; MAKE SURE IT IS 8 + JP NZ,CHUSB_CMDERR ; HANDLE CMD ERROR + LD A,CHUSB_MEDCAP ; MEDIA CAPACITY OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + PUSH HL ; SAVE ADDRESS + CALL CH_RD + LD D,A + CALL CH_RD + LD E,A + CALL CH_RD + LD H,A + CALL CH_RD + LD L,A + CALL CH_RD + CALL CH_RD + CALL CH_RD + CALL CH_RD + POP BC ; RECOVER ADDRESS TO BC + CALL ST32 ; STORE IT + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +#IF FALSE +; +; PERFORM DISK INQUIRY +; BASICALLY THE SCSI INQUIRY COMMAND +; +CHUSB_DSKINQ: + ;PRTS("\n\rINQUIRY:$") ; *DEBUG* + LD A,CH_CMD_DSKINQ ; DISK QUERY + CALL CH_CMD ; DO IT + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; SUCCESS? + RET NZ ; ABORT IF NOT + CALL CH_CMD_RD ; SEND READ COMMAND + CALL CH_RD ; GET LENGTH + LD B,A ; LOOP COUNTER + LD HL,HB_WRKBUF ; USE WORK BUFFER FOR DATA +DSKINQ1: + CALL CH_RD ; GET A BYTE + LD (HL),A ; SAVE IT + INC HL ; BUMP BUF PTR + DJNZ DSKINQ1 ; LOOP FOR ALL DATA +; + ;LD DE,HB_WRKBUF ; *DEBUG* + ;CALL DUMP_BUFFER ; *DEBUG* +; + ;CALL CHUSB_PRTPREFIX ; PRINT DEVICE PREFIX + ;LD HL,HB_WRKBUF + 8 + ;LD B,28 +DSKINQ2: + ;LD A,(HL) + ;INC HL + ;CALL COUT + ;DJNZ DSKINQ2 +; + RET +; +; PERFORM SET RETRIES +; +CHUSB_SETRETRY: + ;PRTS("\n\rSETRETRY:$") ; *DEBUG* + LD A,CH_CMD_SETRETRY ; DISK READY + CALL CH_CMD ; DO IT + CALL CH_NAP + LD A,$25 ; CONSTANT + CALL CH_WR ; SEND IT + CALL CH_NAP + LD A,$BF ; MAX + CALL CH_WR + CALL CH_NAP + CALL CH_RD ; GET RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; + RET +; +; PERFORM DISK RESET +; +CHUSB_DSKRES: + ;PRTS("\n\rDSKRES:$") ; *DEBUG* + LD A,CH_CMD_DSKRES ; DISK READY + CALL CH_CMD ; DO IT + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; + RET +; +; PERFORM DISK READY +; +CHUSB_DSKRDY: + ;PRTS("\n\rDSKRDY:$") ; *DEBUG* + LD A,CH_CMD_DSKRDY ; DISK READY + CALL CH_CMD ; DO IT + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; *DEBUG* + JR NZ,CHUSB_DSKRDY ; *DEBUG* +; + RET +; +; PERFORM AUTO SETUP +; +CHUSB_AUTOSET: + ;PRTS("\n\rAUTOSET:$") ; *DEBUG* + LD A,CH_CMD_AUTOSET ; AUTOMATIC SETUP FOR USB + CALL CH_CMD ; DO IT + CALL LDELAY ; *DEBUG* + CALL CH_POLL ; WAIT FOR RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; + RET +; +; PERFORM TEST CONNECT +; +CHUSB_TSTCON: + ;PRTS("\n\rTSTCON:$") ; *DEBUG* + LD A,CH_CMD_TSTCON ; TEST USB DEVICE CONNECT + CALL CH_CMD ; DO IT + CALL CH_NAP ; WAIT A BIT + CALL CH_RD ; GET RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; + RET +; +; PERFORM GET MAX LUN +; +CHUSB_MAXLUN: + ;PRTS("\n\rMAXLUN:$") ; *DEBUG* + LD A,CH_CMD_MAXLUN ; TEST USB DEVICE CONNECT + CALL CH_CMD ; DO IT + CALL CH_NAP ; WAIT A BIT + LD A,$38 ; CONSTANT + CALL CH_WR ; SEND IT + CALL CH_NAP + CALL CH_RD ; GET RESPONSE + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* +; + RET +; +#ENDIF +; +; ERROR HANDLERS +; +; +CHUSB_NOMEDIA: + LD A,CHUSB_STNOMEDIA + JR CHUSB_ERR +; +CHUSB_CMDERR: + LD A,CHUSB_STCMDERR + JR CHUSB_ERR +; +CHUSB_IOERR: + LD A,CHUSB_STIOERR + JR CHUSB_ERR +; +CHUSB_TO: + LD A,CHUSB_STTO + JR CHUSB_ERR +; +CHUSB_NOTSUP: + LD A,CHUSB_STNOTSUP + JR CHUSB_ERR +; +CHUSB_ERR: + LD (IY+CHUSB_STAT),A ; SAVE NEW STATUS +; +CHUSB_ERR2: +#IF (CHUSBTRACE >= 2) + CALL CHUSB_PRTSTAT +#ENDIF + OR A ; SET FLAGS + RET +; +; +; +CHUSB_PRTERR: + RET Z ; DONE IF NO ERRORS + ; FALL THRU TO CHUSB_PRTSTAT +; +; PRINT FULL DEVICE STATUS LINE +; +CHUSB_PRTSTAT: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+CHUSB_STAT) + CALL CHUSB_PRTPREFIX ; PRINT UNIT PREFIX + CALL PC_SPACE ; FORMATTING + CALL CHUSB_PRTSTATSTR + POP HL + POP DE + POP AF + RET +; +; PRINT STATUS STRING +; +CHUSB_PRTSTATSTR: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+CHUSB_STAT) + NEG + LD HL,CHUSB_STR_ST_MAP + ADD A,A + CALL ADDHLA + LD E,(HL) + INC HL + LD D,(HL) + CALL WRITESTR + POP HL + POP DE + POP AF + RET +; +; PRINT DIAGNONSTIC PREFIX +; +CHUSB_PRTPREFIX: + PUSH AF + CALL NEWLINE + PRTS("CHUSB$") + LD A,(IY+CH_DEV) ; GET CURRENT DEVICE NUM + CALL PRTDECB + CALL PC_COLON + POP AF + RET +; +; DATA STORAGE +; +CHUSB_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT +CHUSB_DSKBUF .DW 0 +; +CHUSB_STR_ST_MAP: + .DW CHUSB_STR_STOK + .DW CHUSB_STR_STNOMEDIA + .DW CHUSB_STR_STCMDERR + .DW CHUSB_STR_STIOERR + .DW CHUSB_STR_STTO + .DW CHUSB_STR_STNOTSUP +; +CHUSB_STR_STOK .TEXT "OK$" +CHUSB_STR_STNOMEDIA .TEXT "NO MEDIA$" +CHUSB_STR_STCMDERR .TEXT "COMMAND ERROR$" +CHUSB_STR_STIOERR .TEXT "IO ERROR$" +CHUSB_STR_STTO .TEXT "TIMEOUT$" +CHUSB_STR_STNOTSUP .TEXT "NOT SUPPORTED$" +CHUSB_STR_STUNK .TEXT "UNKNOWN ERROR$" diff --git a/Source/HBIOS/ctc.asm b/Source/HBIOS/ctc.asm index 364b849b..777b28f8 100644 --- a/Source/HBIOS/ctc.asm +++ b/Source/HBIOS/ctc.asm @@ -162,7 +162,9 @@ CTCTIVT .EQU INT_CTC0A + CTCTIMCH ;================================================================================================== ; CTC_PREINIT: - ; BLINDLY RESET THE CTC ASSUMING IT IS THERE + ; BLINDLY RESET THE CTC ASSUMING IT IS THERE. PER ALAN COX + ; THE CTC CONFIGURATION IS UNDEFINED AT STARTUP. THIS SHOULD + ; PRECLUDE POSSIBLE EXTRANEOUS INTERRUPTS. LD A,CTC_DEFCFG OUT (CTCBASE),A OUT (CTCBASE+1),A diff --git a/Source/ver.inc b/Source/ver.inc index d8cdd1ce..137203d7 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 4 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.4.0-dev.37" +#DEFINE BIOSVER "3.4.0-dev.38" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index 54c608fb..745f88e1 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 4 rup equ 0 rtp equ 0 biosver macro - db "3.4.0-dev.37" + db "3.4.0-dev.38" endm