mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
687 lines
15 KiB
687 lines
15 KiB
;
|
|
;==================================================================================================
|
|
; 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 FALSE ; 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)
|
|
DEVECHO "CHSD: IO="
|
|
DEVECHO CH0BASE
|
|
DEVECHO "\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)
|
|
DEVECHO "CHSD: IO="
|
|
DEVECHO CH1BASE
|
|
DEVECHO "\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
|
|
EZ80_IO ;!! NOT SUPPORT INIR YET
|
|
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
|
|
EZ80_IO ;!! NOT SUPPORT OTIR YET
|
|
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$"
|
|
|