]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blobdiff - cbios/sdio.180
Make ASCI1 the default console device after cold boot.
[z180-stamp-cpm3.git] / cbios / sdio.180
index 2b84aea211aa673a865c3ea249f0155fe07633ae..774ed122469f25c1965418d9131839febb971ba5 100644 (file)
@@ -3,17 +3,17 @@
 ;    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\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
@@ -22,8 +22,8 @@
     ; Utility routines in standard BIOS\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 ?pmsg,pr.inln     ; print message @<HL>, print inline message\r
+       extrn pr.crlf           ; print <cr><lf>\r
        extrn ?pderr            ; print BIOS disk error header\r
        extrn ?conin,?cono      ; con in and out\r
        extrn ?const            ; get console status\r
@@ -54,8 +54,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 +80,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 +143,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 +195,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
@@ -153,9 +209,9 @@ sd$login:
 ;\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
-;     disk track address    in @trk (16 bits)  +3\r
-;     disk sector address   in @sect(16 bits)  +5\r
+;     disk track address    in @trk (16 bits)  +2\r
+;     disk sector address   in @sect(16 bits)  +4\r
+;     multi sector count    in @cnt  (8 bits)  +6\r
 ;     disk transfer address in @dma (16 bits)  +7\r
 ;     disk transfer bank    in @dbnk (8 bits)  +9\r
 ;     pointer to XDPH      in <DE>\r
@@ -164,27 +220,51 @@ sd$login:
 ;     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
+       ld      de,read$msg     ; point at " Read "\r
+       ld      c,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      de,write$msg    ; point at " Write "\r
+       ld      c,2\r
+rw$common:\r
+\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
-       ld      de,send_msg+1\r
-       ld      (de),a\r
-       inc     de\r
+rwc_doit:\r
+       ld      hl,send_msg+1\r
+       ld      (hl),c\r
+       inc     hl\r
+       ld      a,b\r
+       ex      de,hl\r
+       ld      (operation$name),hl ; save message for errors\r
        ld      hl,@adrv        ;address of arguments\r
-       ld      bc,7\r
+       ld      bc,6\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 +281,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
@@ -229,83 +309,118 @@ more$retries:
        call    ?pmsg           ; last function (read or write)\r
 \r
        ld      a,(recv_msg_rc)\r
+       and     a,07fh\r
+       jr      z,fatfs_err\r
 \r
-;TODO: rc errorcode\r
+       ld      hl,drvmsg0      ; point at first driver error message\r
+       ld      c,drvmsg_count\r
+       call    pdecoded\r
 \r
+fatfs_err:\r
        ld      a,(recv_msg_rc)\r
-       tst     080h    \r
-       jr      z,fs_end\r
+       tst     080h\r
+       jr      z,prompt        ; no fatfs error\r
 \r
-fatfs_err:\r
+       call    pr.inln\r
+       db      'FatFs: ',0\r
 \r
+       ld      hl,fr$msg0      ; point at first FatFs message\r
+       ld      c,fr$msg$count\r
        ld      a,(recv_msg_rc+1)\r
-       cp      20\r
-       jr      c,fs_err1\r
+       call    pdecoded\r
+\r
+prompt:\r
+       call    pr.inln\r
+       db      ' Retry (Y/N) ? ',0\r
+\r
+       call    u$conin$echo    ; get operator response\r
+       cp      'Y'\r
+       jr      z,retry         ; Yes, then retry once more\r
+\r
+hard$error:\r
+                               ; otherwise,\r
        xor     a\r
-fs_err1\r
-       ld      hl,fr$msg0      ; point at first message\r
-       ld      bc,fr$msg$size\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
+; Print message to error code in A\r
+;\r
+\r
+pdecoded:\r
+       push    bc\r
+       push    de\r
+       push    hl              ; put pointer to first message on stack\r
+       cp      c\r
+       jr      c,pdc_1\r
+       xor     a\r
+pdc_1:\r
+       ld      bc,0\r
        ld      e,a             ; save message number\r
        xor     a\r
        inc     e\r
-nxt_str:\r
+pdc_nxt_str:\r
        dec     e\r
-       jr      z,fs_err_found\r
+       ex      (sp),hl\r
+       jr      z,pdc_found\r
+       ex      (sp),hl\r
        cpir\r
-       jr      z,nxt_str\r
-       ld      hl,fr$msg0      ; not found, point at first message\r
-\r
-fs_err_found:\r
+       jr      z,pdc_nxt_str\r
+                               ; not found (should not happen)\r
+pdc_found:\r
+       pop     hl\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
+       pop     de\r
+       pop     bc\r
+       ret\r
 \r
 \r
+; get console input, echo it, and shift to upper case\r
 \r
 u$conin$echo:\r
-                               ; get console input, echo it, and shift to upper case\r
+\r
        call    ?const\r
        or      a\r
-       jp      z,u$c1          ; see if any char already struck\r
+       jr      z,u$c1          ; see if any char already struck\r
        call    ?conin\r
-       jp      u$conin$echo    ; yes, eat it and try again\r
+       jr      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
+       cp      ' '-1\r
+       call    nc,?cono\r
        pop     af\r
        cp      'a'\r
        ret     c\r
-       sub     'a'-'a'         ; make upper case\r
+       sub     'a'-'A'         ; make upper case\r
        ret\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
@@ -323,62 +438,46 @@ recv_msg_len equ $ - recv_msg
 operation$name:\r
        dw      read$msg\r
 read$msg:\r
-       db      ', Read',0\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
+       db      ', Write, ',0\r
+\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
+drvmsg_size    equ     $ - drvmsg0\r
+drvmsg_count   equ     7\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
 fr$msg$size    equ     $ - fr$msg0\r
-\r
-\r
-error$msg:\r
-       db      ' Retry (Y/N) ? ',0\r
-\r
+fr$msg$count   equ     21\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