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