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