From 888d9879c9bcab014838436924e2b355c60567dc Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 16 Nov 2023 19:39:09 -0800 Subject: [PATCH] Preliminary Support for CH37x SD Cards - Currently operates as a read only disk device. --- Source/HBIOS/cfg_duo.asm | 2 +- Source/HBIOS/ch.asm | 753 +++++++++++++++++++++++++++++++++++++-- Source/ver.inc | 2 +- Source/ver.lib | 2 +- 4 files changed, 727 insertions(+), 32 deletions(-) diff --git a/Source/HBIOS/cfg_duo.asm b/Source/HBIOS/cfg_duo.asm index 5d360c09..8af03521 100644 --- a/Source/HBIOS/cfg_duo.asm +++ b/Source/HBIOS/cfg_duo.asm @@ -236,7 +236,7 @@ CHSDTRACE .EQU 1 ; CHSD: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) CHCNT .EQU 1 ; CH: NUMBER OF BOARDS TO DETECT (1-2) CH0BASE .EQU $4E ; CH 0: BASE I/O ADDRESS CH0USBENABLE .EQU TRUE ; CH 0: ENABLE USB DISK -CH0SDENABLE .EQU FALSE ; CH 0: ENABLE SD DISK +CH0SDENABLE .EQU TRUE ; CH 0: ENABLE SD DISK CH1BASE .EQU $FF ; CH 1: BASE I/O ADDRESS CH1USBENABLE .EQU FALSE ; CH 1: ENABLE USB DISK CH1SDENABLE .EQU FALSE ; CH 1: ENABLE SD DISK diff --git a/Source/HBIOS/ch.asm b/Source/HBIOS/ch.asm index 8e4eca04..46ee3bbf 100644 --- a/Source/HBIOS/ch.asm +++ b/Source/HBIOS/ch.asm @@ -1,4 +1,5 @@ ; +; ;================================================================================================== ; CH375/376 USB/SD DRIVER ;================================================================================================== @@ -19,8 +20,7 @@ ; ; TODO: ; - Implement auto-recovery on error status. -; -CHUSB_FASTIO .EQU TRUE ; USE INIR/OTIR? +; - !!! Move CH_MODE to config variable !!! ; ; PORT OFFSETS FROM BASE PORT ; @@ -33,6 +33,12 @@ CHTYP_NONE .EQU 0 ; NONE CHTYP_375 .EQU 1 ; CH375 CHTYP_376 .EQU 2 ; CH376 ; +; CH MODE MANAGEMENT +; +CH_MODE_UNK .EQU 0 ; CURRENT MODE UNKNOWN +CH_MODE_USB .EQU 1 ; CURRENT MODE = USB +CH_MODE_SD .EQU 2 ; CURRENT MODE = SD +; ; CH375/376 COMMANDS ; CH_CMD_VER .EQU $01 ; GET IC VER @@ -49,7 +55,15 @@ CH_CMD_RD6 .EQU $27 ; READ USB DATA (375 & 376) CH_CMD_RD5 .EQU $28 ; READ USB DATA (375) CH_CMD_WR5 .EQU $2B ; WRITE USB DATA (375) CH_CMD_WR6 .EQU $2C ; WRITE USB DATA (376) +CH_CMD_SET_FN .EQU $2F ; SET FILENAME (376) CH_CMD_DSKMNT .EQU $31 ; DISK MOUNT +CH_CMD_FOPEN .EQU $32 ; FILE OPEN (376) +CH_CMD_FCREAT .EQU $34 ; FILE CREATE (376) +CH_CMD_BYTE_LOC .EQU $39 ; BYTE LOCATE +CH_CMD_BYTERD .EQU $3A ; BYTE READ +CH_CMD_BYTERDGO .EQU $3B ; BYTE READ GO +CH_CMD_BYTEWR .EQU $3C ; BYTE WRITE +CH_CMD_BYTEWRGO .EQU $3D ; BYTE WRITE GO CH_CMD_DSKCAP .EQU $3E ; DISK CAPACITY CH_CMD_AUTOSET .EQU $4D ; USB AUTO SETUP CH_CMD_DSKINIT .EQU $51 ; DISK INIT @@ -347,18 +361,64 @@ CH_GETVER: CALL CH_RD ; GET VERSION BYTE RET ; DONE ; +; SET MODE TO VALUE IN A +; AVOID CHANGING MODES IF CURRENT MODE = NEW MODE +; +CH_SETMODE: + PUSH BC + PUSH DE + PUSH 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 + JR Z,CH_SETMODE_Z ; IF EQUAL, DONE +; + ; NEED TO CHANGE MODES + LD A,L ; GET REQUESTED MODE + CP CH_MODE_USB + JR Z,CH_SETMODE_USB + CP CH_MODE_SD + JR Z,CH_SETMODE_SD + OR $FF ; SIGNAL ERROR + JR CH_SETMODE_Z ; BAIL OUT +; +CH_SETMODE_USB: + CALL CHUSB_RESET + JR CH_SETMODE_Z +; +CH_SETMODE_SD: + CALL CHSD_RESET + JR CH_SETMODE_Z +; +CH_SETMODE_Z: + POP HL + POP DE + POP BC + RET +; ; ; -CH_STR_NOHW .TEXT " NOT PRESENT$" -CH_STR_UPGRADE .TEXT " !!!UPGRADE REQUIRED!!!$" +CH_MODE .DB CH_MODE_UNK ; -CH_STR_375 .TEXT "CH375$" -CH_STR_376 .TEXT "CH376$" +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 @@ -368,7 +428,7 @@ CHUSB_STIOERR .EQU -3 CHUSB_STTO .EQU -4 CHUSB_STNOTSUP .EQU -5 ; -; CH DEVICE CONFIGURATION +; CHUSB DEVICE CONFIGURATION ; CHUSB_CFGSIZ .EQU 12 ; SIZE OF USB CFG TBL ENTRIES ; @@ -481,6 +541,10 @@ CHUSB_DEFMED: ; ; 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 @@ -542,6 +606,10 @@ CHUSB_READ2: ; ; 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 @@ -631,7 +699,7 @@ CHUSB_STATUS: ; RESET THE INTERFACE AND REDISCOVER MEDIA ; CHUSB_RESET: - ;PRTS("\n\rRESET:$") ; *DEBUG* + ;PRTS("\n\rRES USB:$") ; *DEBUG* ;CALL CH_FLUSH ; DISCARD ANY GARBAGE ;CALL CH_RESET ; FULL CH37X RESET ; @@ -656,6 +724,9 @@ CHUSB_RESET: ;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 @@ -714,7 +785,7 @@ CHUSB_RESET2: CHUSB_DEVICE: LD D,DIODEV_CHUSB ; D := DEVICE TYPE LD E,(IY+CH_DEV) ; E := PHYSICAL DEVICE NUMBER - LD C,%01110011 ; USB HARD DISK ATTRIBUTES + 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 @@ -1081,17 +1152,28 @@ CHUSB_STR_ST_MAP: 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_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 ;================================================================================================== ; -; CH DEVICE CONFIGURATION +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 ; @@ -1144,36 +1226,649 @@ CHSD_INIT: INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN LD (CHSD_DEVNUM),A ; SAVE IT ; - CALL NEWLINE ; FORMATTING - PRTS("CHSD$") ; LABEL FOR IO ADDRESS - LD A,(IY+CH_DEV) ; GET DEVICE NUM - CALL PRTDECB ; PRINT IT - CALL PC_COLON ; FORMATTING + ; 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 + 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 +; + JP CHSD_IOERR -CHSD_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT + CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR + LD (CHSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + LD A,CH_CMD_DSKWR ; DISK READ COMMAND + CALL CHSD_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,(CHSD_DSKBUF) ; GET DISK BUF ADR +CHSD_WRITE1: + CALL CH_POLL ; WAIT FOR DATA READY + CP $1E ; DATA READY TO WRITE + ;CALL PC_GT ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + JP NZ,CHSD_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 (CHSD_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 +CHSD_WRITE2: + LD A,(HL) ; GET NEXT BYTE + INC HL ; INC BUF PTR + CALL CH_WR ; WRITE NEXT BYTE + DJNZ CHSD_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 CHSD_WRITE1 ; LOOP TILL DONE +; + ; FINAL CHECK FOR COMPLETION & SUCCESS + CALL CH_POLL ; WAIT FOR COMPLETION + CP $14 ; SUCCESS? + JP NZ,CHSD_IOERR ; IF NOT, 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* + ;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 +; + ; 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 +;;;; +;;; ; INITIALIZE DISK +;;; LD B,24 ; TRY A FEW TIMES +;;;CHSD_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,CHSD_RESET2 ; IF SO, CONTINUE +;;; ;JR Z,CHSD_RESET1A ; IF SO, CHECK READY +;;; CP $16 ; NO MEDIA +;;; JP Z,CHSD_NOMEDIA ; HANDLE IT +;;; CALL CH_NAP ; SMALL DELAY +;;; DJNZ CHSD_RESET1 ; LOOP AS NEEDED +;;; JP CHSD_TO ; HANDLE TIMEOUT +;;;;;;; +;;;;;;CHSD_RESET1A: +;;;;;; CALL CHSD_DSKRES ; DISK RESET +;;;;;; CP $14 ; GOOD? +;;;;;; JR Z,CHSD_RESET2 +;;;;;; CALL CHSD_DSKRDY ; CHECK IF DISK READY +;;;;;; CP $14 ; GOOD? +;;;;;; JR Z,CHSD_RESET2 ; IF SO, MOVE ON +;;;;;; DJNZ CHSD_RESET1 ; KEEP TRYING +; +CHSD_RESET2: + CALL CHSD_DSKMNT ; MOUNT DISK + RET NZ +; + ;CALL CHSD_AUTOSET ; *DEBUG* + ;CALL CHSD_TSTCON ; *DEBUG* + ;CALL CHSD_MAXLUN ; *DEBUG* + ;CALL CHSD_DSKRDY ; *DEBUG* + ;CALL CHSD_DSKINQ ; *DEBUG* +;; + CALL CHSD_DSKCAP ; GET AND RECORD DISK CAPACITY + RET NZ ; ABORT ON ERROR +; + ; OPEN DISK IMAGE FILE + LD DE,CHSD_FNAME + CALL CHSD_FOPEN + RET NZ +;;;; +;;; ; *DEBUG* +;;; LD HL,HB_WRKBUF +;;; LD E,1 +;;; CALL CHSD_READ +;;;; +;;;; +;;; LD DE,HB_WRKBUF ; *DEBUG* +;;; CALL DUMP_BUFFER ; *DEBUG* + ; -;============================================================================= -; DATA STORAGE -;============================================================================= + ; 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 $14 ; SUCCESS? + JP NZ,CHSD_CMDERR ; HANDLE ERROR +; +; 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 +; CALL PC_SPACE +; CALL PRTHEXBYTE +; 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 +; PRTS(" \"$") +; LD HL,HB_WRKBUF + 8 +; LD B,28 +;CHSD_DSKMNT2: +; LD A,(HL) +; INC HL +; CALL COUT +; DJNZ CHSD_DSKMNT2 +; PRTS("\"$") +; + XOR A + RET +; +; PERFORM DISK CAPACITY +; +CHSD_DSKCAP: + ;PRTS("\n\rDSKCAP:$") ; *DEBUG* + LD A,CH_CMD_DSKCAP ; DISK CAPACITY COMMAND + CALL CH_CMD ; SEND IT + CALL CH_POLL ; WAIT FOR RESULT + ;CALL PC_SPACE ; *DEBUG* + ;CALL PRTHEXBYTE ; *DEBUG* + CP $14 ; SUCCESS? + JP NZ,CHSD_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 $04 ; MAKE SURE IT IS 8 + JP NZ,CHSD_CMDERR ; HANDLE CMD ERROR + 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 + POP BC ; RECOVER ADDRESS TO BC + CALL ST32 ; STORE IT + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +; 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 $14 ; SUCCESS? + JP NZ,CHSD_NOFILE ; HANDLE ERROR + RET ; RETURN WITH ZF SET APPROPRIATELY +; +; 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 ; -CH_FWVER .DW 0,0 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD) +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_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS +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 ; -CHSD_DSKBUF .DW 0 +; PRINT DIAGNONSTIC PREFIX ; -CHSD_DSKSTAT .DB 0 -CHSD_ERRCODE .DW 0,0 -CHSD_CSDBUF .FILL 16,0 +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 ; -CHSD_CMD .DB 0 +; DATA STORAGE ; -CHSD_TIMEOUT .DW $0000 ; FIX: MAKE THIS CPU SPEED RELATIVE +CHSD_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT +CHSD_DSKBUF .DW 0 +; +CHSD_FNAME .DB "/DISK.IMG",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 DISK IMAGE FILE$" +CHSD_STR_STUNK .TEXT "UNKNOWN ERROR$" diff --git a/Source/ver.inc b/Source/ver.inc index 43938e36..f1bb410d 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.18" +#DEFINE BIOSVER "3.4.0-dev.19" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index e9e98711..ac00769e 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.18" + db "3.4.0-dev.19" endm