]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blob - cbios/sdio.180
2b84aea211aa673a865c3ea249f0155fe07633ae
[z180-stamp-cpm3.git] / cbios / sdio.180
1 TITLE 'sd disk handler'
2
3 ; CP/M-80 Version 3 -- Modular BIOS
4
5
6 dseg
7
8 ; Disk drive dispatching tables for linked BIOS
9
10 public sd0,sd1,sd2,sd3
11
12 ; Variables containing parameters passed by BDOS
13
14 extrn @adrv,@rdrv
15 extrn @dma,@trk,@sect
16 extrn @dbnk
17
18 ; System Control Block variables
19
20 extrn @ermde ; BDOS error mode
21
22 ; Utility routines in standard BIOS
23
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
30
31 extrn bnk2phy ;
32 extrn msg.sm ;
33 extrn msg.recv ;
34 extrn add_hla
35
36
37 ; Port Address Equates
38
39 include config.inc
40 include z180reg.inc
41
42 ; CP/M 3 Disk definition macros
43
44 include cpm3slr.lib
45
46 ; Z180 macro library instruction definitions (ignored by slr180)
47
48 include z180.lib
49
50 ; common control characters
51
52 cr equ 13
53 lf equ 10
54 bell equ 7
55
56
57 ; Extended Disk Parameter Headers (XPDHs)
58
59 dw sd$write
60 dw sd$read
61 dw sd$login
62 dw sd$init0
63 db 0,0 ; relative drive zero
64 sd0: dph 0,dpbsimhd512
65
66 dw sd$write
67 dw sd$read
68 dw sd$login
69 dw sd$init1
70 db 1,0 ; relative drive one
71 sd1: dph 0,dpbsimhd512
72
73 dw sd$write
74 dw sd$read
75 dw sd$login
76 dw sd$init0
77 db 2,0 ; relative drive zero
78 sd2: dph 0,dpbsimhd512
79
80 dw sd$write
81 dw sd$read
82 dw sd$login
83 dw sd$init1
84 db 3,0 ; relative drive one
85 sd3: dph 0,dpbsimhd512
86
87
88 cseg ; DPB must be resident
89
90 dpbsimhd512:
91 dpb 512,8,2048,4096,1024,6
92
93
94 dseg ; rest is banked
95
96 ; Disk I/O routines for standardized BIOS interface
97
98 ; Initialization entry point.
99 ; called for first time initialization.
100
101 sd$init0:
102 ret
103
104 sd$init1:
105 sd$init2:
106 sd$init3:
107 ret ; all initialization done by drive 0
108
109
110
111
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>
116
117 sd$login:
118 ld hl,send_msg+1
119 ld (hl),0 ;login function
120 inc hl
121 ld bc,(@adrv)
122 ld (hl),c ;@adrv
123 inc hl
124 ld (hl),b ;@rdrv
125 inc hl
126
127 ex de,hl ;xdph to hl
128 xor a ;bank 0
129 call bnk2phy ;phys. linear address
130 ex de,hl
131 ld (hl),e
132 inc hl
133 ld (hl),d
134 inc hl
135 ld (hl),a
136
137 ld hl,send_msg
138 ld b,send_msg_login_len
139 call msg.sm
140
141 ld hl,recv_msg
142 ld b,recv_msg_len ; max receive message len
143 call msg.recv
144
145 ; ld a,(recv_msg_rc)
146 ; or a
147 ret ;
148
149
150
151 ; disk READ and WRITE entry points.
152 ; these entries are called with the following arguments:
153 ;
154 ; absolute drive number in @adrv (8 bits) +0
155 ; relative drive number in @rdrv (8 bits) +1
156 ; multi sector count in @cnt (8 bits) +2 (currently unused)
157 ; disk track address in @trk (16 bits) +3
158 ; disk sector address in @sect(16 bits) +5
159 ; disk transfer address in @dma (16 bits) +7
160 ; disk transfer bank in @dbnk (8 bits) +9
161 ; pointer to XDPH in <DE>
162 ;
163 ; they transfer the appropriate data, perform retries
164 ; if necessary, then return an error code in <A>
165
166 sd$read:
167 ld hl,read$msg ; point at " Read "
168 ld a,1
169 jr rw$common
170
171 sd$write:
172 ld hl,write$msg ; point at " Write "
173 ld a,2
174 ;fall thru
175
176 ; compute pysical transfer address
177 ; prepare message
178 ; and send it to AVR.
179
180 rw$common:
181 ld (operation$name),HL ; save message for errors
182 ld de,send_msg+1
183 ld (de),a
184 inc de
185 ld hl,@adrv ;address of arguments
186 ld bc,7
187 ldir
188 push de
189 ld e,(hl) ;dma address
190 inc hl
191 ld d,(hl)
192 inc hl
193 ld a,(hl) ;bank
194 ex de,hl
195 call bnk2phy ;phys. linear address
196 ex de,hl
197 pop hl
198 ld (hl),e
199 inc hl
200 ld (hl),d
201 inc hl
202 ld (hl),a
203
204 more$retries:
205
206 ld hl,send_msg
207 ld b,send_msg_rw_len
208 call msg.sm
209
210 ld hl,recv_msg
211 ld b,recv_msg_len ; max receive message len
212 call msg.recv
213 ld a,(recv_msg_rc)
214 or a
215 ret z ; check status and return to BDOS if no error
216
217 ; suppress error message if BDOS is returning errors to application...
218
219 ld a,(@ermde)
220 cp 0ffh
221 jr z,hard$error
222
223 ; Had permanent error, print message like:
224 ; BIOS Err on d: T-nn, S-mm, <operation> <type>, Retry ?
225
226 call ?pderr ; print message header
227
228 ld hl,(operation$name)
229 call ?pmsg ; last function (read or write)
230
231 ld a,(recv_msg_rc)
232
233 ;TODO: rc errorcode
234
235 ld a,(recv_msg_rc)
236 tst 080h
237 jr z,fs_end
238
239 fatfs_err:
240
241 ld a,(recv_msg_rc+1)
242 cp 20
243 jr c,fs_err1
244 xor a
245 fs_err1
246 ld hl,fr$msg0 ; point at first message
247 ld bc,fr$msg$size
248 ld e,a ; save message number
249 xor a
250 inc e
251 nxt_str:
252 dec e
253 jr z,fs_err_found
254 cpir
255 jr z,nxt_str
256 ld hl,fr$msg0 ; not found, point at first message
257
258 fs_err_found:
259 call ?pmsg
260
261 fs_end:
262 ld hl,error$msg
263 call ?pmsg ; print "<BEL>, Retry (Y/N) ? "
264 call u$conin$echo ; get operator response
265 cp 'y'
266 jr z,more$retries ; Yes, then retry 10 more times
267 hard$error:
268 ; otherwise,
269 ld a,1
270 ret ; return hard error to BDOS
271
272 cancel: ; here to abort job
273 jp ?wboot ; leap directly to warmstart vector
274
275
276
277 u$conin$echo:
278 ; get console input, echo it, and shift to upper case
279 call ?const
280 or a
281 jp z,u$c1 ; see if any char already struck
282 call ?conin
283 jp u$conin$echo ; yes, eat it and try again
284 u$c1:
285 call ?conin
286 push af
287 ld c,a
288 call ?cono
289 pop af
290 cp 'a'
291 ret c
292 sub 'a'-'a' ; make upper case
293 ret
294
295
296
297 send_msg:
298 db 2 ; disk command
299 ds 1 ; subcommand (login/read/write)
300 ds 1 ; @adrv
301 ds 1 ; @rdrv
302 ; -read/write- -login-
303 ds 1 ; @cnt 3 byte
304 ds 2 ; @trk xdph address
305 send_msg_login_len equ $ - send_msg
306 ds 2 ; @sect
307 ds 3 ; transfer addr
308 send_msg_rw_len equ $ - send_msg
309
310
311 recv_msg:
312 ds 1 ; len
313 ds 1 ; command
314 ds 1 ; subcommand
315 recv_msg_rc:
316 ds 1 ; result code
317 ds 4 ; room for additional parameter
318 recv_msg_len equ $ - recv_msg
319
320
321 ; error message components
322
323 operation$name:
324 dw read$msg
325 read$msg:
326 db ', Read',0
327 write$msg:
328 db ', Write',0
329
330
331 ; table of pointers to error message strings
332
333 fr$msg0: db ' Unknown FatFs Error,',0
334 fr$msg1: db ' DISK_ERR,',0
335 fr$msg2: db ' INT_ERR,',0
336 fr$msg3: db ' NOT_READY,',0
337 fr$msg4: db ' NO_FILE,',0
338 fr$msg5: db ' NO_PATH,',0
339 fr$msg6: db ' INVALID_NAME,',0
340 fr$msg7: db ' DENIED,',0
341 fr$msg8: db ' EXIST,',0
342 fr$msg9: db ' INVALID_OBJECT,',0
343 fr$msg10: db ' WRITE_PROTECTED,',0
344 fr$msg11: db ' INVALID_DRIVE,',0
345 fr$msg12: db ' NOT_ENABLED,',0
346 fr$msg13: db ' NO_FILE_SYSTEM,',0
347 fr$msg14: db ' MKFS_ABORTED,',0
348 fr$msg15: db ' TIMEOUT,',0
349 fr$msg16: db ' LOCKED,',0
350 fr$msg17: db ' NOT_ENOUGH_CORE,',0
351 fr$msg18: db ' TOO_MANY_OPEN_FILES,',0
352 fr$msg19: db ' FR_INVALID_PARAMETER,',0
353 fr$msg$size equ $ - fr$msg0
354
355
356 error$msg:
357 db ' Retry (Y/N) ? ',0
358
359
360 end
361
362 /* File function return code (FRESULT) */
363
364 FR_OK = 0, /* (0) Succeeded */
365 FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
366 FR_INT_ERR, /* (2) Assertion failed */
367 FR_NOT_READY, /* (3) The physical drive cannot work */
368 FR_NO_FILE, /* (4) Could not find the file */
369 FR_NO_PATH, /* (5) Could not find the path */
370 FR_INVALID_NAME, /* (6) The path name format is invalid */
371 FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
372 FR_EXIST, /* (8) Access denied due to prohibited access */
373 FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
374 FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
375 FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
376 FR_NOT_ENABLED, /* (12) The volume has no work area */
377 FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
378 FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
379 FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
380 FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
381 FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
382 FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
383 FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
384