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