1 TITLE 'sd disk handler'
3 ; CP/M-80 Version 3 -- Modular BIOS
8 ; Disk drive dispatching tables for linked BIOS
10 public sd0,sd1,sd2,sd3
12 ; Variables containing parameters passed by BDOS
18 ; System Control Block variables
20 extrn @ermde ; BDOS error mode
22 ; Utility routines in standard BIOS
24 extrn ?wboot ; warm boot vector
25 extrn ?pmsg ; print message @<HL> up to 00, saves <BC> & <DE>
26 extrn ?pdec ; print binary number in <A> from 0 to 99.
27 extrn ?pderr ; print BIOS disk error header
28 extrn ?conin,?cono ; con in and out
29 extrn ?const ; get console status
37 ; Port Address Equates
42 ; CP/M 3 Disk definition macros
46 ; Z180 macro library instruction definitions (ignored by slr180)
50 ; common control characters
57 ; Extended Disk Parameter Headers (XPDHs)
63 db 0,0 ; relative drive zero
64 sd0: dph 0,dpbsimhd512
70 db 1,0 ; relative drive one
71 sd1: dph 0,dpbsimhd512
77 db 2,0 ; relative drive zero
78 sd2: dph 0,dpbsimhd512
84 db 3,0 ; relative drive one
85 sd3: dph 0,dpbsimhd512
88 cseg ; DPB must be resident
91 dpb 512,8,2048,4096,1024,6
96 ; Disk I/O routines for standardized BIOS interface
98 ; Initialization entry point.
99 ; called for first time initialization.
107 ret ; all initialization done by drive 0
112 ; This entry is called when a logical drive is about to
113 ; be logged into for the purpose of density determination.
114 ; It may adjust the parameters contained in the disk
115 ; parameter header pointed at by <DE>
121 ld (hl),0 ;login function
131 call bnk2phy ;phys. linear address
140 ld b,send_msg_login_len
144 ld b,recv_msg_len ; max receive message len
153 ; disk READ and WRITE entry points.
154 ; these entries are called with the following arguments:
156 ; absolute drive number in @adrv (8 bits) +0
157 ; relative drive number in @rdrv (8 bits) +1
158 ; disk track address in @trk (16 bits) +2
159 ; disk sector address in @sect(16 bits) +4
160 ; multi sector count in @cnt (8 bits) +6
161 ; disk transfer address in @dma (16 bits) +7
162 ; disk transfer bank in @dbnk (8 bits) +9
163 ; pointer to XDPH in <DE>
165 ; they transfer the appropriate data, perform retries
166 ; if necessary, then return an error code in <A>
169 ld de,read$msg ; point at " Read "
173 ld de,write$msg ; point at " Write "
176 ld hl,residual ; remainng sectors from last multi io?
186 ld b,1 ; assume 1 sector to transfer
191 ld b,a ; number of sectors to transfer
192 dec a ; save remaining
194 xor a ; reset multi sector count
197 ; compute pysical transfer address
199 ; and send it to AVR.
207 ld (operation$name),hl ; save message for errors
208 ld hl,@adrv ;address of arguments
214 ld e,(hl) ;dma address
220 call bnk2phy ;phys. linear address
236 ld b,recv_msg_len ; max receive message len
240 ret z ; check status and return to BDOS if no error
245 ; suppress error message if BDOS is returning errors to application...
251 ; Had permanent error, print message like:
252 ; BIOS Err on d: T-nn, S-mm, <operation> <type>, Retry ?
254 call ?pderr ; print message header
256 ld hl,(operation$name)
257 call ?pmsg ; last function (read or write)
274 ld hl,fr$msg0 ; point at first message
276 ld e,a ; save message number
284 ld hl,fr$msg0 ; not found, point at first message
291 call ?pmsg ; print "<BEL>, Retry (Y/N) ? "
292 call u$conin$echo ; get operator response
294 jr z,more$retries ; Yes, then retry 10 more times
298 ret ; return hard error to BDOS
300 cancel: ; here to abort job
301 jp ?wboot ; leap directly to warmstart vector
306 ; get console input, echo it, and shift to upper case
309 jp z,u$c1 ; see if any char already struck
311 jp u$conin$echo ; yes, eat it and try again
320 sub 'a'-'a' ; make upper case
329 ds 1 ; subcommand (login/read/write)
332 ; -read/write- -login-
333 ds 2 ; @trk xdph address
334 ds 2 ; @sect (3 byte)
337 send_msg_rw_len equ $ - send_msg
338 send_msg_login_len equ 7
347 ds 4 ; room for additional parameter
348 recv_msg_len equ $ - recv_msg
351 ; error message components
361 ; table of pointers to error message strings
363 fr$msg0: db ' Unknown FatFs Error,',0
364 fr$msg1: db ' DISK_ERR,',0
365 fr$msg2: db ' INT_ERR,',0
366 fr$msg3: db ' NOT_READY,',0
367 fr$msg4: db ' NO_FILE,',0
368 fr$msg5: db ' NO_PATH,',0
369 fr$msg6: db ' INVALID_NAME,',0
370 fr$msg7: db ' DENIED,',0
371 fr$msg8: db ' EXIST,',0
372 fr$msg9: db ' INVALID_OBJECT,',0
373 fr$msg10: db ' WRITE_PROTECTED,',0
374 fr$msg11: db ' INVALID_DRIVE,',0
375 fr$msg12: db ' NOT_ENABLED,',0
376 fr$msg13: db ' NO_FILE_SYSTEM,',0
377 fr$msg14: db ' MKFS_ABORTED,',0
378 fr$msg15: db ' TIMEOUT,',0
379 fr$msg16: db ' LOCKED,',0
380 fr$msg17: db ' NOT_ENOUGH_CORE,',0
381 fr$msg18: db ' TOO_MANY_OPEN_FILES,',0
382 fr$msg19: db ' FR_INVALID_PARAMETER,',0
383 fr$msg$size equ $ - fr$msg0
387 db ' Retry (Y/N) ? ',0
392 /* File function return code (FRESULT) */
394 FR_OK = 0, /* (0) Succeeded */
395 FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
396 FR_INT_ERR, /* (2) Assertion failed */
397 FR_NOT_READY, /* (3) The physical drive cannot work */
398 FR_NO_FILE, /* (4) Could not find the file */
399 FR_NO_PATH, /* (5) Could not find the path */
400 FR_INVALID_NAME, /* (6) The path name format is invalid */
401 FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
402 FR_EXIST, /* (8) Access denied due to prohibited access */
403 FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
404 FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
405 FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
406 FR_NOT_ENABLED, /* (12) The volume has no work area */
407 FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
408 FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
409 FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
410 FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
411 FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
412 FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
413 FR_INVALID_PARAMETER /* (19) Given parameter is invalid */