X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/blobdiff_plain/1d26b86661bff5609cb3ae4404a0208c1b651360..afbcea2d821d1166ae347338ae52a64f3ee51e57:/cbios/sdio.180 diff --git a/cbios/sdio.180 b/cbios/sdio.180 index e6c12ea..28ed4dd 100644 --- a/cbios/sdio.180 +++ b/cbios/sdio.180 @@ -3,14 +3,14 @@ ; CP/M-80 Version 3 -- Modular BIOS - dseg - ; Disk drive dispatching tables for linked BIOS public sd0,sd1,sd2,sd3 + public sd4,sd5,sd6,sd7 ; Variables containing parameters passed by BDOS + extrn @xdph,@op extrn @adrv,@rdrv extrn @trk,@sect,@cnt extrn @dma,@dbnk @@ -19,19 +19,17 @@ extrn @ermde ; BDOS error mode - ; Utility routines in standard BIOS + ; Utility routines extrn ?wboot ; warm boot vector - extrn ?pmsg ; print message @ up to 00, saves & - extrn ?pdec ; print binary number in from 0 to 99. - extrn ?pderr ; print BIOS disk error header - extrn ?conin,?cono ; con in and out - extrn ?const ; get console status - - extrn bnk2phy ; - extrn msg.sm ; - extrn msg.recv ; - extrn add_hla + extrn ?pmsg ; print message @ + extrn pr.idx ; print indexed message + extrn pr.inln,pr.crlf ; print inline message, print + extrn pr.errors ; print BIOS disk error header + extrn bnk2phy ; translate banked to physical linear address + extrn msg.sm ; send message to AVR + extrn msg.recv ; receive message from AVR + extrn add_hla ; add to ; Port Address Equates @@ -41,7 +39,7 @@ ; CP/M 3 Disk definition macros - include cpm3slr.lib + maclib cpm3slr.lib ; Z180 macro library instruction definitions (ignored by slr180) @@ -54,8 +52,15 @@ lf equ 10 bell equ 7 + dseg + ; Extended Disk Parameter Headers (XPDHs) + ; dph translate$table, - disk parameter header + ; disk$parameter$block, + ; checksum$size, (optional) + ; alloc$size (optional) + dw sd$write dw sd$read dw sd$login @@ -73,22 +78,59 @@ sd1: dph 0,dpbsimhd512 dw sd$write dw sd$read dw sd$login - dw sd$init0 + dw sd$init2 db 2,0 ; relative drive zero sd2: dph 0,dpbsimhd512 dw sd$write dw sd$read dw sd$login - dw sd$init1 + dw sd$init3 db 3,0 ; relative drive one sd3: dph 0,dpbsimhd512 + dw sd$write + dw sd$read + dw sd$login + dw sd$init4 + db 4,0 ; relative drive zero +sd4: dph 0,dpbsimhd512 + + dw sd$write + dw sd$read + dw sd$login + dw sd$init5 + db 5,0 ; relative drive one +sd5: dph 0,dpbsimhd512 + + dw sd$write + dw sd$read + dw sd$login + dw sd$init6 + db 6,0 ; relative drive zero +sd6: dph 0,dpbsimhd512 + + dw sd$write + dw sd$read + dw sd$login + dw sd$init7 + db 7,0 ; relative drive one +sd7: dph 0,dpbsimhd512 + + cseg ; DPB must be resident + ; dpb physical$sector$size, - disk parameter block + ; physical$sectors$per$track, + ; number$tracks, + ; block$size, + ; number$dir$entries, + ; track$offset, + ; checksum$vec$size (optional) + dpbsimhd512: - dpb 512,8,2048,4096,1024,6 + dpb 512,8,2048,4096,1024,6,8100h dseg ; rest is banked @@ -99,20 +141,27 @@ dpbsimhd512: ; called for first time initialization. sd$init0: + call pr.inln ; + db 'sdio: SD Card driver'cr,lf,0 ret sd$init1: sd$init2: sd$init3: +sd$init4: +sd$init5: +sd$init6: +sd$init7: ret ; all initialization done by drive 0 - - ; This entry is called when a logical drive is about to ; be logged into for the purpose of density determination. ; It may adjust the parameters contained in the disk ; parameter header pointed at by +; +; absolute drive number in @adrv (8 bits) +0 +; relative drive number in @rdrv (8 bits) +1 sd$login: xor a @@ -144,8 +193,11 @@ sd$login: ld b,recv_msg_len ; max receive message len call msg.recv -; ld a,(recv_msg_rc) -; or a + ld a,(recv_msg_rc) + or a + ret z + ld hl,0 + ld (@xdph),hl ret ; @@ -153,26 +205,21 @@ sd$login: ; disk READ and WRITE entry points. ; these entries are called with the following arguments: ; -; absolute drive number in @adrv (8 bits) +0 -; relative drive number in @rdrv (8 bits) +1 -; disk track address in @trk (16 bits) +2 -; disk sector address in @sect(16 bits) +4 -; multi sector count in @cnt (8 bits) +6 -; disk transfer address in @dma (16 bits) +7 -; disk transfer bank in @dbnk (8 bits) +9 +; operation type (r/w) in @op (8 bits) +0 +; absolute drive number in @adrv (8 bits) +1 +; relative drive number in @rdrv (8 bits) +2 +; disk track address in @trk (16 bits) +3 +; disk sector address in @sect(16 bits) +5 +; multi sector count in @cnt (8 bits) +7 +; disk transfer address in @dma (16 bits) +8 +; disk transfer bank in @dbnk (8 bits) +10 ; pointer to XDPH in ; ; they transfer the appropriate data, perform retries ; if necessary, then return an error code in sd$read: - ld de,read$msg ; point at " Read " - ld c,1 - jr rw$common sd$write: - ld de,write$msg ; point at " Write " - ld c,2 -rw$common: ld hl,residual ; remainng sectors from last multi io? ld a,(hl) sub a,1 @@ -199,16 +246,12 @@ rwc_new_sectors: ; and send it to AVR. rwc_doit: - ld hl,send_msg+1 - ld (hl),c - inc hl ld a,b - ex de,hl - ld (operation$name),hl ; save message for errors - ld hl,@adrv ;address of arguments - ld bc,6 + ld hl,@op ;address of arguments + ld de,send_msg+1 + ld bc,7 ldir - ld (de),a + ld (de),a ;number of sectors inc de push de ld e,(hl) ;dma address @@ -226,7 +269,7 @@ rwc_doit: inc hl ld (hl),a -more$retries: +retry: ld hl,send_msg ld b,send_msg_rw_len @@ -239,87 +282,49 @@ more$retries: or a ret z ; check status and return to BDOS if no error + ld hl,print_details + call pr.errors + jr z,retry ; Yes, then retry once more + ; otherwise, xor a ld (residual),a + ld a,(recv_msg_rc) ; return hard error to BDOS + ld c,0ffh + cp 6 ; media changed? + jr z,e_exit + ld c,2 + cp 5 ; disk read only? + jr z,e_exit + dec c +e_exit: + ld a,c + ret -; suppress error message if BDOS is returning errors to application... - - ld a,(@ermde) - cp 0ffh - jr z,hard$error - - ; Had permanent error, print message like: - ; BIOS Err on d: T-nn, S-mm, , Retry ? - - call ?pderr ; print message header - - ld hl,(operation$name) - call ?pmsg ; last function (read or write) +;------------------------------------------------------------------------------- +print_details: ld a,(recv_msg_rc) + push af + and a,07fh + jr z,fatfs_err -;TODO: rc errorcode - - ld a,(recv_msg_rc) - tst 080h - jr z,fs_end + ld hl,drvmsg0 ; point at first driver error message + call pr.idx fatfs_err: + pop af + and 080h + ret z ; no fatfs error - ld a,(recv_msg_rc+1) - cp 20 - jr c,fs_err1 - xor a -fs_err1 - ld hl,fr$msg0 ; point at first message - ld bc,fr$msg$size - ld e,a ; save message number - xor a - inc e -nxt_str: - dec e - jr z,fs_err_found - cpir - jr z,nxt_str - ld hl,fr$msg0 ; not found, point at first message - -fs_err_found: - call ?pmsg - -fs_end: - ld hl,error$msg - call ?pmsg ; print ", Retry (Y/N) ? " - call u$conin$echo ; get operator response - cp 'y' - jr z,more$retries ; Yes, then retry 10 more times -hard$error: - ; otherwise, - ld a,1 - ret ; return hard error to BDOS - -cancel: ; here to abort job - jp ?wboot ; leap directly to warmstart vector - + call pr.inln + db 'FatFs: ',0 + ld hl,fr$msg0 ; point at first FatFs message + ld a,(recv_msg_rc+1) + jp pr.idx ; return via print routine -u$conin$echo: - ; get console input, echo it, and shift to upper case - call ?const - or a - jp z,u$c1 ; see if any char already struck - call ?conin - jp u$conin$echo ; yes, eat it and try again -u$c1: - call ?conin - push af - ld c,a - call ?cono - pop af - cp 'a' - ret c - sub 'a'-'a' ; make upper case - ret +;------------------------------------------------------------------------------- residual: db 0 @@ -348,66 +353,42 @@ recv_msg_rc: recv_msg_len equ $ - recv_msg - ; error message components - -operation$name: - dw read$msg -read$msg: - db ', Read',0 -write$msg: - db ', Write',0 - - - ; table of pointers to error message strings - -fr$msg0: db ' Unknown FatFs Error,',0 -fr$msg1: db ' DISK_ERR,',0 -fr$msg2: db ' INT_ERR,',0 -fr$msg3: db ' NOT_READY,',0 -fr$msg4: db ' NO_FILE,',0 -fr$msg5: db ' NO_PATH,',0 -fr$msg6: db ' INVALID_NAME,',0 -fr$msg7: db ' DENIED,',0 -fr$msg8: db ' EXIST,',0 -fr$msg9: db ' INVALID_OBJECT,',0 -fr$msg10: db ' WRITE_PROTECTED,',0 -fr$msg11: db ' INVALID_DRIVE,',0 -fr$msg12: db ' NOT_ENABLED,',0 -fr$msg13: db ' NO_FILE_SYSTEM,',0 -fr$msg14: db ' MKFS_ABORTED,',0 -fr$msg15: db ' TIMEOUT,',0 -fr$msg16: db ' LOCKED,',0 -fr$msg17: db ' NOT_ENOUGH_CORE,',0 -fr$msg18: db ' TOO_MANY_OPEN_FILES,',0 -fr$msg19: db ' FR_INVALID_PARAMETER,',0 -fr$msg$size equ $ - fr$msg0 - - -error$msg: - db ' Retry (Y/N) ? ',0 - +;------------------------------------------------------------------------------- +; error message components + ; general driver errors + +drvmsg0: db 'Unknown Error, ',0 +drvmsg1: db 'Invalid Parameter(s), ',0 +drvmsg2: db 'Invalid Drive, ',0 +drvmsg3: db 'Bus Timeout, ',0 +drvmsg4: db 'Access beyond disk size, ',0 +drvmsg5: db 'Write protected, ',0 +drvmsg6: db 'No media, ',0 + db 0 + + ; fat file system errors + +fr$msg0: db 'Unknown Error,',0 +fr$msg1: db 'DISK_ERR,',0 +fr$msg2: db 'INT_ERR,',0 +fr$msg3: db 'NOT_READY,',0 +fr$msg4: db 'NO_FILE,',0 +fr$msg5: db 'NO_PATH,',0 +fr$msg6: db 'INVALID_NAME,',0 +fr$msg7: db 'DENIED,',0 +fr$msg8: db 'EXIST,',0 +fr$msg9: db 'INVALID_OBJECT,',0 +fr$msg10: db 'WRITE_PROTECTED,',0 +fr$msg11: db 'INVALID_DRIVE,',0 +fr$msg12: db 'NOT_ENABLED,',0 +fr$msg13: db 'NO_FILE_SYSTEM,',0 +fr$msg14: db 'MKFS_ABORTED,',0 +fr$msg15: db 'TIMEOUT,',0 +fr$msg16: db 'LOCKED,',0 +fr$msg17: db 'NOT_ENOUGH_CORE,',0 +fr$msg18: db 'TOO_MANY_OPEN_FILES,',0 +fr$msg19: db 'FR_INVALID_PARAMETER,',0 +fr$msg20: db 'short read/write,',0 + db 0 end - -/* File function return code (FRESULT) */ - -FR_OK = 0, /* (0) Succeeded */ -FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ -FR_INT_ERR, /* (2) Assertion failed */ -FR_NOT_READY, /* (3) The physical drive cannot work */ -FR_NO_FILE, /* (4) Could not find the file */ -FR_NO_PATH, /* (5) Could not find the path */ -FR_INVALID_NAME, /* (6) The path name format is invalid */ -FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ -FR_EXIST, /* (8) Access denied due to prohibited access */ -FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ -FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ -FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ -FR_NOT_ENABLED, /* (12) The volume has no work area */ -FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ -FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ -FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ -FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ -FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ -FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ -FR_INVALID_PARAMETER /* (19) Given parameter is invalid */