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