]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blame_incremental - cbios/sdio.180
Extended drive table for use with DRIVE.COM, a dynamic drive re-assignment utility.
[z180-stamp-cpm3.git] / cbios / sdio.180
... / ...
CommitLineData
1 TITLE 'sd disk handler'\r
2\r
3; CP/M-80 Version 3 -- Modular BIOS\r
4\r
5\r
6 ; Disk drive dispatching tables for linked BIOS\r
7\r
8 public sd0,sd1,sd2,sd3\r
9 public sd4,sd5,sd6,sd7\r
10\r
11 ; Variables containing parameters passed by BDOS\r
12\r
13 extrn @xdph,@op\r
14 extrn @adrv,@rdrv\r
15 extrn @trk,@sect,@cnt\r
16 extrn @dma,@dbnk\r
17\r
18 ; System Control Block variables\r
19\r
20 extrn @ermde ; BDOS error mode\r
21\r
22 ; Utility routines\r
23\r
24 extrn ?wboot ; warm boot vector\r
25 extrn pr.idx ; print indexed message\r
26 extrn pr.inln ; print inline message\r
27 extrn pr.errors ; print BIOS disk error header\r
28 extrn bnk2phy ; translate banked to physical linear address\r
29 extrn msg.sm ; send message to AVR\r
30 extrn msg.recv ; receive message from AVR\r
31 extrn add_hla ; add <A> to <HL>\r
32\r
33\r
34 ; Port Address Equates\r
35\r
36 maclib z180reg.inc\r
37 maclib config.inc\r
38\r
39 ; CP/M 3 Disk definition macros\r
40\r
41 maclib cpm3slr.lib\r
42\r
43 ; Z180 macro library instruction definitions (ignored by slr180)\r
44\r
45 maclib z180.lib\r
46\r
47 ; common control characters\r
48\r
49cr equ 13\r
50lf equ 10\r
51bell equ 7\r
52\r
53\r
54 dseg\r
55\r
56 ; Extended Disk Parameter Headers (XPDHs)\r
57\r
58 ; dph translate$table, - disk parameter header\r
59 ; disk$parameter$block,\r
60 ; checksum$size, (optional)\r
61 ; alloc$size (optional)\r
62\r
63 dw sd$write\r
64 dw sd$read\r
65 dw sd$login\r
66 dw sd$init0\r
67 db 0,0 ; relative drive zero\r
68sd0: dph 0,dpbsimhd512\r
69\r
70 dw sd$write\r
71 dw sd$read\r
72 dw sd$login\r
73 dw sd$init1\r
74 db 1,0 ; relative drive one\r
75sd1: dph 0,dpbsimhd512\r
76\r
77 dw sd$write\r
78 dw sd$read\r
79 dw sd$login\r
80 dw sd$init2\r
81 db 2,0 ; relative drive zero\r
82sd2: dph 0,dpbsimhd512\r
83\r
84 dw sd$write\r
85 dw sd$read\r
86 dw sd$login\r
87 dw sd$init3\r
88 db 3,0 ; relative drive one\r
89sd3: dph 0,dpbsimhd512\r
90\r
91\r
92 dw sd$write\r
93 dw sd$read\r
94 dw sd$login\r
95 dw sd$init4\r
96 db 4,0 ; relative drive zero\r
97sd4: dph 0,dpbsimhd512\r
98\r
99 dw sd$write\r
100 dw sd$read\r
101 dw sd$login\r
102 dw sd$init5\r
103 db 5,0 ; relative drive one\r
104sd5: dph 0,dpbsimhd512\r
105\r
106 dw sd$write\r
107 dw sd$read\r
108 dw sd$login\r
109 dw sd$init6\r
110 db 6,0 ; relative drive zero\r
111sd6: dph 0,dpbsimhd512\r
112\r
113 dw sd$write\r
114 dw sd$read\r
115 dw sd$login\r
116 dw sd$init7\r
117 db 7,0 ; relative drive one\r
118sd7: dph 0,dpbsimhd512\r
119\r
120\r
121 cseg ; DPB must be resident\r
122\r
123 ; dpb physical$sector$size, - disk parameter block\r
124 ; physical$sectors$per$track,\r
125 ; number$tracks,\r
126 ; block$size,\r
127 ; number$dir$entries,\r
128 ; track$offset,\r
129 ; checksum$vec$size (optional)\r
130\r
131dpbsimhd512:\r
132 dpb 512,8,2048,4096,1024,6,8100h\r
133\r
134\r
135 dseg ; rest is banked\r
136\r
137; Disk I/O routines for standardized BIOS interface\r
138\r
139; Initialization entry point.\r
140; called for first time initialization.\r
141\r
142sd$init0:\r
143 call pr.inln ;\r
144 dc 'sdio: SD Card driver',cr,lf\r
145 ret\r
146\r
147sd$init1:\r
148sd$init2:\r
149sd$init3:\r
150sd$init4:\r
151sd$init5:\r
152sd$init6:\r
153sd$init7:\r
154 ret ; all initialization done by drive 0\r
155\r
156\r
157; This entry is called when a logical drive is about to\r
158; be logged into for the purpose of density determination.\r
159; It may adjust the parameters contained in the disk\r
160; parameter header pointed at by <DE>\r
161;\r
162; absolute drive number in @adrv (8 bits) +0\r
163; relative drive number in @rdrv (8 bits) +1\r
164\r
165sd$login:\r
166 xor a\r
167 ld (residual),a\r
168 ld hl,send_msg+1\r
169 ld (hl),0 ;login function\r
170 inc hl\r
171 ld bc,(@adrv)\r
172 ld (hl),c ;@adrv\r
173 inc hl\r
174 ld (hl),b ;@rdrv\r
175 inc hl\r
176\r
177 ex de,hl ;xdph to hl\r
178 xor a ;bank 0\r
179 call bnk2phy ;phys. linear address\r
180 ex de,hl\r
181 ld (hl),e\r
182 inc hl\r
183 ld (hl),d\r
184 inc hl\r
185 ld (hl),a\r
186\r
187 ld hl,send_msg\r
188 ld b,send_msg_login_len\r
189 call msg.sm\r
190\r
191 ld hl,recv_msg\r
192 ld b,recv_msg_len ; max receive message len\r
193 call msg.recv\r
194\r
195 ld a,(recv_msg_rc)\r
196 or a\r
197 ret z\r
198 ld hl,0\r
199 ld (@xdph),hl\r
200 ret ;\r
201\r
202\r
203\r
204; disk READ and WRITE entry points.\r
205; these entries are called with the following arguments:\r
206;\r
207; operation type (r/w) in @op (8 bits) +0\r
208; absolute drive number in @adrv (8 bits) +1\r
209; relative drive number in @rdrv (8 bits) +2\r
210; disk track address in @trk (16 bits) +3\r
211; disk sector address in @sect(16 bits) +5\r
212; multi sector count in @cnt (8 bits) +7\r
213; disk transfer address in @dma (16 bits) +8\r
214; disk transfer bank in @dbnk (8 bits) +10\r
215; pointer to XDPH in <DE>\r
216;\r
217; they transfer the appropriate data, perform retries\r
218; if necessary, then return an error code in <A>\r
219\r
220sd$read:\r
221sd$write:\r
222 ld hl,residual ; remainng sectors from last multi io?\r
223 ld a,(hl)\r
224 sub a,1\r
225 jr c,rwc_new_sectors\r
226\r
227 ld (hl),a\r
228 xor a\r
229 ret\r
230\r
231rwc_new_sectors:\r
232 ld b,1 ; assume 1 sector to transfer\r
233 ld a,(@cnt)\r
234 or a\r
235 jr z,rwc_doit\r
236\r
237 ld b,a ; number of sectors to transfer\r
238 dec a ; save remaining\r
239 ld (hl),a\r
240 xor a ; reset multi sector count\r
241 ld (@cnt),a\r
242\r
243; compute pysical transfer address\r
244; prepare message\r
245; and send it to AVR.\r
246\r
247rwc_doit:\r
248 ld a,b\r
249 ld hl,@op ;address of arguments\r
250 ld de,send_msg+1\r
251 ld bc,7\r
252 ldir\r
253 ld (de),a ;number of sectors\r
254 inc de\r
255 push de\r
256 ld e,(hl) ;dma address\r
257 inc hl\r
258 ld d,(hl)\r
259 inc hl\r
260 ld a,(hl) ;bank\r
261 ex de,hl\r
262 call bnk2phy ;phys. linear address\r
263 ex de,hl\r
264 pop hl\r
265 ld (hl),e\r
266 inc hl\r
267 ld (hl),d\r
268 inc hl\r
269 ld (hl),a\r
270\r
271retry:\r
272\r
273 ld hl,send_msg\r
274 ld b,send_msg_rw_len\r
275 call msg.sm\r
276\r
277 ld hl,recv_msg\r
278 ld b,recv_msg_len ; max receive message len\r
279 call msg.recv\r
280 ld a,(recv_msg_rc)\r
281 or a\r
282 ret z ; check status and return to BDOS if no error\r
283\r
284 ld hl,print_details\r
285 call pr.errors\r
286 jr z,retry ; Yes, then retry once more\r
287 ; otherwise,\r
288 xor a\r
289 ld (residual),a\r
290 ld a,(recv_msg_rc) ; return hard error to BDOS\r
291 ld c,0ffh\r
292 cp 6 ; media changed?\r
293 jr z,e_exit\r
294 ld c,2\r
295 cp 5 ; disk read only?\r
296 jr z,e_exit\r
297 dec c\r
298e_exit:\r
299 ld a,c\r
300 ret\r
301\r
302;-------------------------------------------------------------------------------\r
303\r
304print_details:\r
305 ld a,(recv_msg_rc)\r
306 push af\r
307 and a,07fh\r
308 jr z,fatfs_err\r
309\r
310 ld hl,drvmsg0 ; point at first driver error message\r
311 call pr.idx\r
312\r
313fatfs_err:\r
314 pop af\r
315 and 080h\r
316 ret z ; no fatfs error\r
317\r
318 call pr.inln\r
319 dc 'FatFs: '\r
320\r
321 ld hl,fr$msg0 ; point at first FatFs message\r
322 ld a,(recv_msg_rc+1)\r
323 jp pr.idx ; return via print routine\r
324\r
325\r
326;-------------------------------------------------------------------------------\r
327\r
328residual:\r
329 db 0\r
330\r
331send_msg:\r
332 db 2 ; disk command\r
333 ds 1 ; subcommand (login/read/write)\r
334 ds 1 ; @adrv\r
335 ds 1 ; @rdrv\r
336 ; -read/write- -login-\r
337 ds 2 ; @trk xdph address\r
338 ds 2 ; @sect (3 byte)\r
339 ds 1 ; @cnt\r
340 ds 3 ; transfer addr\r
341send_msg_rw_len equ $ - send_msg\r
342send_msg_login_len equ 7\r
343\r
344\r
345recv_msg:\r
346 ds 1 ; len\r
347 ds 1 ; command\r
348 ds 1 ; subcommand\r
349recv_msg_rc:\r
350 ds 1 ; result code\r
351 ds 4 ; room for additional parameter\r
352recv_msg_len equ $ - recv_msg\r
353\r
354\r
355;-------------------------------------------------------------------------------\r
356; error message components\r
357 ; general driver errors\r
358\r
359drvmsg0: dc 'Unknown Error, '\r
360drvmsg1: dc 'Invalid Parameter(s), '\r
361drvmsg2: dc 'Invalid Drive, '\r
362drvmsg3: dc 'Bus Timeout, '\r
363drvmsg4: dc 'Access beyond disk size, '\r
364drvmsg5: dc 'Write protected, '\r
365drvmsg6: dc 'No media, '\r
366 db 0\r
367\r
368 ; fat file system errors\r
369\r
370fr$msg0: dc 'Unknown Error,'\r
371fr$msg1: dc 'DISK_ERR,'\r
372fr$msg2: dc 'INT_ERR,'\r
373fr$msg3: dc 'NOT_READY,'\r
374fr$msg4: dc 'NO_FILE,'\r
375fr$msg5: dc 'NO_PATH,'\r
376fr$msg6: dc 'INVALID_NAME,'\r
377fr$msg7: dc 'DENIED,'\r
378fr$msg8: dc 'EXIST,'\r
379fr$msg9: dc 'INVALID_OBJECT,'\r
380fr$msg10: dc 'WRITE_PROTECTED,'\r
381fr$msg11: dc 'INVALID_DRIVE,'\r
382fr$msg12: dc 'NOT_ENABLED,'\r
383fr$msg13: dc 'NO_FILE_SYSTEM,'\r
384fr$msg14: dc 'MKFS_ABORTED,'\r
385fr$msg15: dc 'TIMEOUT,'\r
386fr$msg16: dc 'LOCKED,'\r
387fr$msg17: dc 'NOT_ENOUGH_CORE,'\r
388fr$msg18: dc 'TOO_MANY_OPEN_FILES,'\r
389fr$msg19: dc 'FR_INVALID_PARAMETER,'\r
390fr$msg20: dc 'short read/write,'\r
391 db 0\r
392\r
393 end\r