; 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 @trk,@sect,@cnt\r
extrn @dma,@dbnk\r
; 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
bell equ 7\r
\r
\r
+ dseg\r
+\r
; Extended Disk Parameter Headers (XPDHs)\r
\r
dw sd$write\r
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
dpbsimhd512:\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 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
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
ld hl,@adrv ;address of arguments\r
ld bc,6\r
ldir\r
- ld (de),a\r
+ ld (de),a ;number of sectors\r
inc de\r
push de\r
ld e,(hl) ;dma address\r
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
or a\r
ret z ; check status and return to BDOS if no error\r
\r
- xor a\r
- ld (residual),a\r
-\r
; suppress error message if BDOS is returning errors to application...\r
\r
ld a,(@ermde)\r
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
+ 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
- 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
+ call pdecoded\r
\r
-fs_err_found:\r
- call ?pmsg\r
+prompt:\r
+ call pr.inln\r
+ db ' Retry (Y/N) ? ',0\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
+ cp 'Y'\r
+ jr z,retry ; Yes, then retry 10 more times\r
+\r
hard$error:\r
; otherwise,\r
- ld a,1\r
- ret ; return hard error to BDOS\r
+ xor a\r
+ ld (residual),a\r
+\r
+ ld a,1 ; return hard error to BDOS\r
+ ret\r
\r
cancel: ; here to abort job\r
jp ?wboot ; leap directly to warmstart vector\r
\r
\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
+pdc_nxt_str:\r
+ dec e\r
+ ex (sp),hl\r
+ jr z,pdc_found\r
+ ex (sp),hl\r
+ cpir\r
+ jr z,pdc_nxt_str\r
+ ; not found (should not happen)\r
+pdc_found:\r
+ pop hl\r
+ call ?pmsg\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
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
+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
+drvmsg_size equ $ - drvmsg0\r
+drvmsg_count equ 3\r
+\r
+\r
+; table of pointers to error message strings\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 20\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