]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blob - cbios/sdio.180
sdio: print module identificateion on initialization
[z180-stamp-cpm3.git] / cbios / sdio.180
1 TITLE 'sd disk handler'
2
3 ; CP/M-80 Version 3 -- Modular BIOS
4
5
6 ; Disk drive dispatching tables for linked BIOS
7
8 public sd0,sd1,sd2,sd3
9 public sd4,sd5,sd6,sd7
10
11 ; Variables containing parameters passed by BDOS
12
13 extrn @xdph
14 extrn @adrv,@rdrv
15 extrn @trk,@sect,@cnt
16 extrn @dma,@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,pr.inln ; print message @<HL>, print inline message
26 extrn pr.crlf ; print <cr><lf>
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 dseg
58
59 ; Extended Disk Parameter Headers (XPDHs)
60
61 dw sd$write
62 dw sd$read
63 dw sd$login
64 dw sd$init0
65 db 0,0 ; relative drive zero
66 sd0: dph 0,dpbsimhd512
67
68 dw sd$write
69 dw sd$read
70 dw sd$login
71 dw sd$init1
72 db 1,0 ; relative drive one
73 sd1: dph 0,dpbsimhd512
74
75 dw sd$write
76 dw sd$read
77 dw sd$login
78 dw sd$init2
79 db 2,0 ; relative drive zero
80 sd2: dph 0,dpbsimhd512
81
82 dw sd$write
83 dw sd$read
84 dw sd$login
85 dw sd$init3
86 db 3,0 ; relative drive one
87 sd3: dph 0,dpbsimhd512
88
89
90 dw sd$write
91 dw sd$read
92 dw sd$login
93 dw sd$init4
94 db 4,0 ; relative drive zero
95 sd4: dph 0,dpbsimhd512
96
97 dw sd$write
98 dw sd$read
99 dw sd$login
100 dw sd$init5
101 db 5,0 ; relative drive one
102 sd5: dph 0,dpbsimhd512
103
104 dw sd$write
105 dw sd$read
106 dw sd$login
107 dw sd$init6
108 db 6,0 ; relative drive zero
109 sd6: dph 0,dpbsimhd512
110
111 dw sd$write
112 dw sd$read
113 dw sd$login
114 dw sd$init7
115 db 7,0 ; relative drive one
116 sd7: dph 0,dpbsimhd512
117
118
119 cseg ; DPB must be resident
120
121 dpbsimhd512:
122 dpb 512,8,2048,4096,1024,6
123
124
125 dseg ; rest is banked
126
127 ; Disk I/O routines for standardized BIOS interface
128
129 ; Initialization entry point.
130 ; called for first time initialization.
131
132 sd$init0:
133 call pr.inln ;
134 db 'sdio: SD Card driver'cr,lf,0
135 ret
136
137 sd$init1:
138 sd$init2:
139 sd$init3:
140 sd$init4:
141 sd$init5:
142 sd$init6:
143 sd$init7:
144 ret ; all initialization done by drive 0
145
146
147 ; This entry is called when a logical drive is about to
148 ; be logged into for the purpose of density determination.
149 ; It may adjust the parameters contained in the disk
150 ; parameter header pointed at by <DE>
151 ;
152 ; absolute drive number in @adrv (8 bits) +0
153 ; relative drive number in @rdrv (8 bits) +1
154
155 sd$login:
156 xor a
157 ld (residual),a
158 ld hl,send_msg+1
159 ld (hl),0 ;login function
160 inc hl
161 ld bc,(@adrv)
162 ld (hl),c ;@adrv
163 inc hl
164 ld (hl),b ;@rdrv
165 inc hl
166
167 ex de,hl ;xdph to hl
168 xor a ;bank 0
169 call bnk2phy ;phys. linear address
170 ex de,hl
171 ld (hl),e
172 inc hl
173 ld (hl),d
174 inc hl
175 ld (hl),a
176
177 ld hl,send_msg
178 ld b,send_msg_login_len
179 call msg.sm
180
181 ld hl,recv_msg
182 ld b,recv_msg_len ; max receive message len
183 call msg.recv
184
185 ld a,(recv_msg_rc)
186 or a
187 ret z
188 ld hl,0
189 ld (@xdph),hl
190 ret ;
191
192
193
194 ; disk READ and WRITE entry points.
195 ; these entries are called with the following arguments:
196 ;
197 ; absolute drive number in @adrv (8 bits) +0
198 ; relative drive number in @rdrv (8 bits) +1
199 ; disk track address in @trk (16 bits) +2
200 ; disk sector address in @sect(16 bits) +4
201 ; multi sector count in @cnt (8 bits) +6
202 ; disk transfer address in @dma (16 bits) +7
203 ; disk transfer bank in @dbnk (8 bits) +9
204 ; pointer to XDPH in <DE>
205 ;
206 ; they transfer the appropriate data, perform retries
207 ; if necessary, then return an error code in <A>
208
209 sd$read:
210 ld de,read$msg ; point at " Read "
211 ld c,1
212 jr rw$common
213 sd$write:
214 ld de,write$msg ; point at " Write "
215 ld c,2
216 rw$common:
217
218 ld hl,residual ; remainng sectors from last multi io?
219 ld a,(hl)
220 sub a,1
221 jr c,rwc_new_sectors
222
223 ld (hl),a
224 xor a
225 ret
226
227 rwc_new_sectors:
228 ld b,1 ; assume 1 sector to transfer
229 ld a,(@cnt)
230 or a
231 jr z,rwc_doit
232
233 ld b,a ; number of sectors to transfer
234 dec a ; save remaining
235 ld (hl),a
236 xor a ; reset multi sector count
237 ld (@cnt),a
238
239 ; compute pysical transfer address
240 ; prepare message
241 ; and send it to AVR.
242
243 rwc_doit:
244 ld hl,send_msg+1
245 ld (hl),c
246 inc hl
247 ld a,b
248 ex de,hl
249 ld (operation$name),hl ; save message for errors
250 ld hl,@adrv ;address of arguments
251 ld bc,6
252 ldir
253 ld (de),a ;number of sectors
254 inc de
255 push de
256 ld e,(hl) ;dma address
257 inc hl
258 ld d,(hl)
259 inc hl
260 ld a,(hl) ;bank
261 ex de,hl
262 call bnk2phy ;phys. linear address
263 ex de,hl
264 pop hl
265 ld (hl),e
266 inc hl
267 ld (hl),d
268 inc hl
269 ld (hl),a
270
271 retry:
272
273 ld hl,send_msg
274 ld b,send_msg_rw_len
275 call msg.sm
276
277 ld hl,recv_msg
278 ld b,recv_msg_len ; max receive message len
279 call msg.recv
280 ld a,(recv_msg_rc)
281 or a
282 ret z ; check status and return to BDOS if no error
283
284 ; suppress error message if BDOS is returning errors to application...
285
286 ld a,(@ermde)
287 cp 0ffh
288 jr z,hard$error
289
290 ; Had permanent error, print message like:
291 ; BIOS Err on d: T-nn, S-mm, <operation> <type>, Retry ?
292
293 call ?pderr ; print message header
294
295 ld hl,(operation$name)
296 call ?pmsg ; last function (read or write)
297
298 ld a,(recv_msg_rc)
299 and a,07fh
300 jr z,fatfs_err
301
302 ld hl,drvmsg0 ; point at first driver error message
303 ld c,drvmsg_count
304 call pdecoded
305
306 fatfs_err:
307 ld a,(recv_msg_rc)
308 tst 080h
309 jr z,prompt ; no fatfs error
310
311 call pr.inln
312 db 'FatFs: ',0
313
314 ld hl,fr$msg0 ; point at first FatFs message
315 ld c,fr$msg$count
316 ld a,(recv_msg_rc+1)
317 call pdecoded
318
319 prompt:
320 call pr.inln
321 db ' Retry (Y/N) ? ',0
322
323 call u$conin$echo ; get operator response
324 cp 'Y'
325 jr z,retry ; Yes, then retry 10 more times
326
327 hard$error:
328 ; otherwise,
329 xor a
330 ld (residual),a
331
332 ld a,1 ; return hard error to BDOS
333 ret
334
335 cancel: ; here to abort job
336 jp ?wboot ; leap directly to warmstart vector
337
338
339
340 ; Print message to error code in A
341 ;
342
343 pdecoded:
344 push bc
345 push de
346 push hl ; put pointer to first message on stack
347 cp c
348 jr c,pdc_1
349 xor a
350 pdc_1:
351 ld bc,0
352 ld e,a ; save message number
353 xor a
354 inc e
355 pdc_nxt_str:
356 dec e
357 ex (sp),hl
358 jr z,pdc_found
359 ex (sp),hl
360 cpir
361 jr z,pdc_nxt_str
362 ; not found (should not happen)
363 pdc_found:
364 pop hl
365 call ?pmsg
366 pop de
367 pop bc
368 ret
369
370
371 ; get console input, echo it, and shift to upper case
372
373 u$conin$echo:
374
375 call ?const
376 or a
377 jr z,u$c1 ; see if any char already struck
378 call ?conin
379 jr u$conin$echo ; yes, eat it and try again
380 u$c1:
381 call ?conin
382 push af
383 ld c,a
384 cp ' '-1
385 call nc,?cono
386 pop af
387 cp 'a'
388 ret c
389 sub 'a'-'A' ; make upper case
390 ret
391
392
393 residual:
394 db 0
395
396 send_msg:
397 db 2 ; disk command
398 ds 1 ; subcommand (login/read/write)
399 ds 1 ; @adrv
400 ds 1 ; @rdrv
401 ; -read/write- -login-
402 ds 2 ; @trk xdph address
403 ds 2 ; @sect (3 byte)
404 ds 1 ; @cnt
405 ds 3 ; transfer addr
406 send_msg_rw_len equ $ - send_msg
407 send_msg_login_len equ 7
408
409
410 recv_msg:
411 ds 1 ; len
412 ds 1 ; command
413 ds 1 ; subcommand
414 recv_msg_rc:
415 ds 1 ; result code
416 ds 4 ; room for additional parameter
417 recv_msg_len equ $ - recv_msg
418
419
420 ; error message components
421
422 operation$name:
423 dw read$msg
424 read$msg:
425 db ', Read, ',0
426 write$msg:
427 db ', Write, ',0
428
429 drvmsg0: db 'Unknown Error, ',0
430 drvmsg1: db 'Invalid Parameter(s), ',0
431 drvmsg2: db 'Invalid Drive, ',0
432 drvmsg3: db 'Bus Timeout, ',0
433 drvmsg_size equ $ - drvmsg0
434 drvmsg_count equ 3
435
436
437 ; table of pointers to error message strings
438
439 fr$msg0: db 'Unknown Error,',0
440 fr$msg1: db 'DISK_ERR,',0
441 fr$msg2: db 'INT_ERR,',0
442 fr$msg3: db 'NOT_READY,',0
443 fr$msg4: db 'NO_FILE,',0
444 fr$msg5: db 'NO_PATH,',0
445 fr$msg6: db 'INVALID_NAME,',0
446 fr$msg7: db 'DENIED,',0
447 fr$msg8: db 'EXIST,',0
448 fr$msg9: db 'INVALID_OBJECT,',0
449 fr$msg10: db 'WRITE_PROTECTED,',0
450 fr$msg11: db 'INVALID_DRIVE,',0
451 fr$msg12: db 'NOT_ENABLED,',0
452 fr$msg13: db 'NO_FILE_SYSTEM,',0
453 fr$msg14: db 'MKFS_ABORTED,',0
454 fr$msg15: db 'TIMEOUT,',0
455 fr$msg16: db 'LOCKED,',0
456 fr$msg17: db 'NOT_ENOUGH_CORE,',0
457 fr$msg18: db 'TOO_MANY_OPEN_FILES,',0
458 fr$msg19: db 'FR_INVALID_PARAMETER,',0
459 fr$msg20: db 'short read/write,',0
460 fr$msg$size equ $ - fr$msg0
461 fr$msg$count equ 20
462
463 end