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