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