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