]>
Commit | Line | Data |
---|---|---|
64219415 FZ |
1 | ; Filesystem functions for the Interaction with BIOS and Disks |
2 | ; | |
3 | ; Copyright (C) 2010 Frank Zoll | |
4 | ; | |
5 | ; This file is part of avrcpm. | |
6 | ; | |
7 | ; avrcpm is free software: you can redistribute it and/or modify it | |
8 | ; under the terms of the GNU General Public License as published by | |
9 | ; the Free Software Foundation, either version 3 of the License, or | |
10 | ; (at your option) any later version. | |
11 | ; | |
12 | ; avrcpm is distributed in the hope that it will be useful, | |
13 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ; GNU General Public License for more details. | |
16 | ; | |
17 | ; You should have received a copy of the GNU General Public License | |
18 | ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>. | |
19 | ; | |
20 | ; $Id$ | |
b741422e L |
21 | ; |
22 | ||
23 | ||
64219415 FZ |
24 | ; ---------------- Defines for the Filesystem Interface ------- |
25 | ||
64219415 FZ |
26 | ;***************************************************** |
27 | ;* Disk-Manager constants * | |
28 | ;***************************************************** | |
dd7aea8c L |
29 | |
30 | ; Fields in the parttabl | |
31 | ||
96a054ef | 32 | .equ MAXDISKS = 8 ;Max number of Disks (partitions) |
dd7aea8c L |
33 | .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry |
34 | ||
35 | .equ PTAB_TYPE = 0 | |
36 | .equ PTAB_START = 1 | |
37 | .equ PTAB_SIZE = 5 | |
38 | .equ PTAB_SPT = 7 | |
39 | .equ PTAB_BSH = 8 | |
40 | ||
41 | .equ dskType_None = 0 << 4 | |
42 | .equ dskType_CPM = 1 << 4 | |
43 | .equ dskType_FAT = 2 << 4 | |
44 | ; .equ dskType_RAM = 3 << 4 | |
45 | .equ dskType_MASK = 0xf << 4 | |
64219415 FZ |
46 | |
47 | ;***************************************************** | |
48 | ;* CP/M to host disk constants * | |
49 | ;***************************************************** | |
dd7aea8c L |
50 | ; .equ blksize = 1024 ;CP/M allocation size |
51 | ; .equ CPMSPT = 26 ; | |
52 | ||
53 | .equ HOSTSIZE = 512 ;host disk sector size | |
54 | .equ HOSTBLK = HOSTSIZE/128 ;CP/M sects/host buff | |
55 | .equ SECMSK = HOSTBLK-1 ;sector mask | |
56 | .equ SECSHF = log2(HOSTBLK) ;sector shift | |
64219415 FZ |
57 | |
58 | ;***************************************************** | |
59 | ;* BDOS constants on entry to write * | |
60 | ;***************************************************** | |
61 | .equ WRALL = 0 ;write to allocated | |
62 | .equ WRDIR = 1 ;write to directory | |
63 | .equ WRUAL = 2 ;write to unallocated | |
b741422e | 64 | .equ WRTMSK= 3 ;write type mask |
eb85ce65 | 65 | |
64219415 FZ |
66 | ;----------------------------------------------- Start of Data Segment |
67 | ||
b741422e L |
68 | .dseg |
69 | ||
29ce189c L |
70 | ; The following 3 variables are copied from DRAM. |
71 | ; Don't change order. | |
72 | ||
73 | biosdrvtbl: .byte 2 ; | |
74 | biosdirbuf: .byte 2 ; | |
75 | biosenddat: .byte 2 ; | |
76 | ||
77 | ndisks: .byte 1 ;Number of CP/M disks | |
64219415 | 78 | |
29ce189c L |
79 | ; The following 5 variables are accessed from 8080/z80 via the |
80 | ; virtual port interface. Don't change order. | |
64219415 | 81 | |
29ce189c L |
82 | biospar_base: |
83 | bcbadr: .byte 2 ;adr of BiosControlBlock | |
84 | seekdsk: .byte 1 ;seek disk number | |
85 | seektrk: .byte 2 ;seek track number | |
86 | seeksec: .byte 2 ;seek sector number | |
87 | dmaadr: .byte 2 ;last dma address | |
2ccaac16 | 88 | hostpart: .byte 1 ;part of hostbuf to transfer |
64219415 | 89 | |
dd7aea8c L |
90 | hdrsize: .byte 1 ;Image header size (offset) |
91 | cpmspt: .byte 1 ;CP/M sectors per track | |
92 | secpblk: .byte 1 ;sectors per block (alloc size) | |
29ce189c L |
93 | unacnt: .byte 1 ;unalloc rec cnt |
94 | unadsk: .byte 1 ;last unalloc disk | |
2ccaac16 L |
95 | unalba: .byte 2 ;last unalloc disk block |
96 | unapart: .byte 1 ;last unalloc disk buffer part | |
64219415 | 97 | |
29ce189c L |
98 | erflag: .byte 1 ;error reporting |
99 | wrtype: .byte 1 ;write operation type | |
100 | ||
29ce189c | 101 | hostdsk: .byte 1 ;host disk number |
5482d75f | 102 | hostlba: .byte 2 ;host sector number (relative to partition start) |
dd7aea8c L |
103 | hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count) |
104 | hostparttbltop: | |
105 | hostbuf: .byte HOSTSIZE ;host buffer (from/to SD-card) | |
b741422e L |
106 | |
107 | ||
64219415 | 108 | ; ------------------------------- Start of Code Segment |
b741422e L |
109 | .cseg |
110 | ||
29ce189c L |
111 | ;--------------------------------------------------------------------- |
112 | ||
113 | .if DSKSEL_DEBUG | |
114 | ||
115 | dbg_prdrvtbl: | |
116 | push xh | |
117 | push xl | |
118 | push temp3 | |
119 | push temp2 | |
120 | push temp | |
121 | printnewline | |
122 | printstring "drvtbl (" | |
123 | lds xl,biosdrvtbl | |
124 | lds xh,biosdrvtbl+1 | |
125 | movw temp,x | |
2ccaac16 | 126 | lcall printhexw |
29ce189c L |
127 | printstring "): " |
128 | ldi temp3,16 | |
129 | dbg_pcpel: | |
2ccaac16 L |
130 | lcall dram_readw_pp |
131 | lcall printhexw | |
29ce189c L |
132 | printstring " " |
133 | dec temp3 | |
134 | brne dbg_pcpel | |
135 | pop temp | |
136 | pop temp2 | |
137 | pop temp3 | |
138 | pop xl | |
139 | pop xh | |
140 | ret | |
141 | ||
142 | dbg_print_biosd: | |
143 | printnewline | |
144 | lds temp,bcbadr | |
145 | lds temp2,bcbadr+1 | |
2ccaac16 | 146 | lcall printhexw |
29ce189c L |
147 | printstring " " |
148 | lds temp,biosdrvtbl | |
149 | lds temp2,biosdrvtbl+1 | |
2ccaac16 | 150 | lcall printhexw |
29ce189c L |
151 | printstring " " |
152 | lds temp,biosdirbuf | |
153 | lds temp2,biosdirbuf+1 | |
2ccaac16 | 154 | lcall printhexw |
29ce189c L |
155 | printstring " " |
156 | lds temp,biosenddat | |
157 | lds temp2,biosenddat+1 | |
2ccaac16 | 158 | lcall printhexw |
29ce189c L |
159 | printstring " " |
160 | ret | |
161 | .endif | |
162 | ||
5482d75f | 163 | ; ==================================================================== |
b741422e | 164 | ; ==================================================================== |
1eeb9cbe | 165 | ; Function: Get a Pointer to a Partitiontable entry |
b741422e L |
166 | ; ==================================================================== |
167 | ; Parameters | |
168 | ; -------------------------------------------------------------------- | |
825ecc9d L |
169 | ; Registers : [w] z Pointer to the Partitionentry |
170 | ; [r] zl Number of Diskentry to Read | |
171 | ; [w] r0 scratch | |
172 | ; [w] r1 " | |
b741422e L |
173 | ; -------------------------------------------------------------------- |
174 | ; Description: | |
175 | ; ==================================================================== | |
1eeb9cbe L |
176 | dsk_getpartentry: |
177 | ||
dd7aea8c L |
178 | ldi zh,PARTENTRY_SIZE |
179 | mul zh,zl | |
1eeb9cbe | 180 | ldiw z,hostparttbl |
825ecc9d L |
181 | add zl,r0 |
182 | adc zh,r1 | |
64219415 | 183 | ret |
b741422e | 184 | |
5482d75f | 185 | ; ==================================================================== |
1eeb9cbe | 186 | ; ==================================================================== |
29ce189c | 187 | ; Function: Virtual Port Interface |
1eeb9cbe L |
188 | ; ==================================================================== |
189 | ; Parameters | |
190 | ; -------------------------------------------------------------------- | |
29ce189c L |
191 | ; Registers : |
192 | ; Variables : | |
193 | ; | |
194 | ; -------------------------------------------------------------------- | |
195 | ; Description: | |
196 | ; ==================================================================== | |
197 | ||
198 | dsk_param_getadr: | |
199 | ldiw z,biospar_base | |
200 | add zl,temp3 | |
201 | adc zh,_0 | |
202 | ret | |
203 | ||
5482d75f | 204 | dsk_param_set: |
29ce189c L |
205 | rcall dsk_param_getadr |
206 | st z,temp | |
29ce189c L |
207 | cpi temp3,bcbadr+1-biospar_base |
208 | breq SetBCB | |
209 | ret | |
210 | ||
5482d75f | 211 | dsk_param_get: |
29ce189c L |
212 | cpi temp3,seekdsk-biospar_base |
213 | breq dskDiskCheck | |
214 | rcall dsk_param_getadr | |
215 | ld temp,z | |
216 | ret | |
217 | ||
218 | SetBCB: | |
219 | lds xl,bcbadr | |
220 | mov xh,temp | |
221 | ldiw z,biosdrvtbl | |
222 | ldi temp3,6 | |
223 | sbcb_l: | |
224 | rcall dram_read_pp | |
225 | st z+,temp | |
226 | dec temp3 | |
227 | brne sbcb_l | |
228 | ||
229 | ; rcall dbg_print_biosd | |
5482d75f | 230 | rcall dpb_drvtblclear |
29ce189c L |
231 | ; rcall dbg_prdrvtbl |
232 | ||
233 | ret | |
234 | ||
235 | ; ==================================================================== | |
236 | ; Function: Check if disk exists | |
237 | ; ==================================================================== | |
238 | ; Parameters | |
239 | ; -------------------------------------------------------------------- | |
240 | ; Registers : | |
241 | ; Variables : | |
242 | ; return 0, if selected disk not exist. | |
243 | ; return !0, if disk exist | |
1eeb9cbe L |
244 | ; -------------------------------------------------------------------- |
245 | ; Description: | |
246 | ; ==================================================================== | |
64219415 | 247 | dskDiskCheck: |
637689de L |
248 | lds temp2,ndisks |
249 | lds temp,seekdsk | |
29ce189c L |
250 | .if DSKSEL_DEBUG |
251 | printnewline | |
252 | printstring "DiskCheck: " | |
2ccaac16 | 253 | lcall printhexw |
29ce189c | 254 | .endif |
637689de | 255 | cpi temp,RAMDISKNR |
64219415 FZ |
256 | brsh dsk_dchrd ;maybe ramdisk |
257 | ||
637689de | 258 | tst temp2 ;0 disks? |
64219415 FZ |
259 | brne dsk_dchpart1 |
260 | ||
eb85ce65 | 261 | ; No disks yet, need to init |
64219415 | 262 | |
5482d75f L |
263 | rcall dpb_drvtblclear |
264 | .if 0 | |
265 | ldi temp2,0x40 | |
266 | ldi temp,1 | |
267 | lcall clockput | |
268 | .endif | |
29ce189c | 269 | rcall mgr_init_partitions ;disk chanched? |
5482d75f L |
270 | push temp |
271 | .if 0 | |
272 | ldi temp2,0x40 | |
273 | ldi temp,2 | |
274 | lcall clockput | |
29ce189c L |
275 | ; sbrs temp,7 |
276 | ; rjmp dsk_dchpart0 | |
5482d75f L |
277 | |
278 | lcall mgr_prnt_parttbl | |
279 | printnewline | |
280 | .endif | |
281 | ||
29ce189c | 282 | ; rcall dbg_prdrvtbl |
637689de | 283 | pop temp2 |
29ce189c | 284 | dsk_dchpart0: |
637689de L |
285 | cbr temp2,0x80 |
286 | lds temp,seekdsk | |
64219415 | 287 | |
5482d75f L |
288 | ; Check if selected disk # is less then # of disks. |
289 | ||
64219415 | 290 | dsk_dchpart1: |
637689de | 291 | cp temp,temp2 |
29ce189c L |
292 | brsh dsk_dch_err |
293 | ||
294 | .if DSKSEL_DEBUG | |
295 | printnewline | |
296 | printstring "Select: " | |
2ccaac16 | 297 | lcall printhex |
29ce189c | 298 | .endif |
637689de | 299 | rcall dpb_drvtbl_entry_get |
29ce189c L |
300 | or temp,temp2 ;if !0, drive is allready initialized |
301 | brne dsk_dchend | |
5482d75f L |
302 | lds temp3,seekdsk |
303 | mov temp,temp3 | |
304 | rcall dpb_biosdph_get | |
64219415 | 305 | dsk_dchend: |
5482d75f | 306 | |
29ce189c L |
307 | .if DSKSEL_DEBUG |
308 | push temp | |
29ce189c | 309 | lds temp,seekdsk |
637689de L |
310 | rcall dpb_drvtbl_entry_get |
311 | ||
29ce189c | 312 | printstring ", " |
2ccaac16 | 313 | lcall printhexw |
29ce189c L |
314 | pop temp |
315 | .endif | |
316 | ||
64219415 FZ |
317 | ret |
318 | ||
29ce189c L |
319 | dsk_dch_err: |
320 | ldi temp,0 ;error return | |
321 | ret | |
322 | ||
323 | ; Check RAMDISK | |
324 | ||
64219415 FZ |
325 | dsk_dchrd: |
326 | #if RAMDISKCNT | |
29ce189c L |
327 | cpi temp,RAMDISKNR+RAMDISKCNT |
328 | brsh dsk_dchrd_err | |
329 | ||
330 | ldi temp,0xff ;return ok | |
331 | ret | |
64219415 | 332 | #endif |
29ce189c L |
333 | dsk_dchrd_err: |
334 | ldi temp,0 ;error return | |
64219415 | 335 | ret |
29ce189c L |
336 | |
337 | ||
338 | ; ==================================================================== | |
339 | ; Function: Return status of last disk i/o function | |
340 | ; ==================================================================== | |
341 | ; Parameters | |
342 | ; -------------------------------------------------------------------- | |
343 | ; Registers : | |
344 | ; Variables : | |
345 | ; -------------------------------------------------------------------- | |
346 | ; Description: | |
347 | ; ==================================================================== | |
64219415 | 348 | dskErrorRet: |
29ce189c | 349 | lds temp,erflag |
64219415 FZ |
350 | ret |
351 | ||
29ce189c | 352 | |
5482d75f L |
353 | ; ==================================================================== |
354 | ; ==================================================================== | |
64219415 | 355 | |
64219415 | 356 | |
29ce189c | 357 | .dseg |
dd7aea8c | 358 | tmpdpb: .byte 16 |
29ce189c L |
359 | |
360 | .cseg | |
361 | ||
dcd7e502 L |
362 | str_CPM_Disk: |
363 | .db 10,"<CPM_Disk>",0 | |
364 | ||
dd7aea8c L |
365 | ; DPBs for varios fixed formats |
366 | ; dpb data starts at 2. byte | |
367 | ||
368 | dpbdat_avrcpm: ;(dpb243) | |
369 | .db 0x00,0x1A ;sector offset, low(spt) | |
370 | .db 0x00,0x03 ;high (spt), block shift | |
371 | .db 0x07,0x00 ;bock mask, extent mask | |
372 | .db 0xF2,0x00 ;disk size - 1, | |
373 | .db 0x3F,0x00 ;dir max | |
374 | .db 0xC0,0x00 ;alloc0, alloc1 | |
375 | .db 0x10,0x00 ;chk size | |
376 | .db 0x02,0x00 ;offset | |
377 | ||
dd7aea8c L |
378 | dpbdat_myz80: ; |
379 | .db 0x02,0x80 ;sector offset, low(spt) | |
380 | .db 0x00,0x05 ;high (spt), block shift | |
381 | .db 0x1F,0x01 ;bock mask, extent mask | |
382 | .db 0xFF,0x07 ;disk size - 1, | |
383 | .db 0xFF,0x03 ;dir max | |
384 | .db 0xFF,0x00 ;alloc0, alloc1 | |
385 | .db 0x00,0x01 ;chk size | |
386 | .db 0x00,0x00 ;offset | |
29ce189c | 387 | |
b165699b L |
388 | dpbdat_simhd: ; |
389 | .db 0x00,0x20 ;sector offset, low(spt) | |
390 | .db 0x00,0x05 ;high (spt), block shift | |
391 | .db 0x1F,0x01 ;bock mask, extent mask | |
392 | .db 0xF9,0x07 ;disk size - 1, | |
393 | .db 0xFF,0x03 ;dir max | |
394 | .db 0xFF,0x00 ;alloc0, alloc1 | |
395 | .db 0x00,0x01 ;chk size | |
396 | .db 0x06,0x00 ;offset | |
397 | ||
29ce189c L |
398 | #if 0 |
399 | ;rd1016 | |
400 | .db 0x20,0x00 ;spt | |
401 | .db 0x04,0x0F ;block shift, bock mask | |
402 | .db 0x00,0xFB ;extent mask, low(disk size -1), | |
403 | .db 0x01,0xBF ;high(disk size -1), low(dir max) | |
404 | .db 0x00,0xE0 ;high(dir max), alloc0 | |
405 | .db 0x00,0x30 ;alloc1, low(chk size) | |
406 | .db 0x00,0x02 ;high(chk size), low(offset) | |
407 | .db 0x00,0x00 ;high(offset), fill | |
408 | ;rd9192s | |
409 | .db 0x20,0x00 ;spt | |
410 | .db 0x05,0x1F ;block shift, bock mask | |
411 | .db 0x01,0xFD ;extent mask, low(disk size -1), | |
412 | .db 0x07,0xFF ;high(disk size -1), low(dir max) | |
413 | .db 0x01,0xF0 ;high(dir max), alloc0 | |
414 | .db 0x00,0x80 ;alloc1, low(chk size) | |
415 | .db 0x00,0x02 ;high(chk size), low(offset) | |
416 | .db 0x00,0x00 ;high(offset), fill | |
417 | #endif | |
418 | ||
dd7aea8c | 419 | |
5482d75f | 420 | ; Copy the dpb data from flash memory, pointed to by Z, to temp ram. |
dd7aea8c L |
421 | |
422 | dpb_copy_p: | |
29ce189c L |
423 | push yh |
424 | push yl | |
29ce189c | 425 | ldi temp2,16 |
29ce189c | 426 | ldiw y,tmpdpb |
dd7aea8c | 427 | cpydpb_pl: |
29ce189c L |
428 | lpm temp,z+ |
429 | st y+,temp | |
dd7aea8c L |
430 | dec temp2 |
431 | brne cpydpb_pl | |
29ce189c L |
432 | pop yl |
433 | pop yh | |
64219415 | 434 | ret |
dd7aea8c L |
435 | |
436 | ; Copy the dpb data, pointed to by Z to temp ram. | |
437 | ||
438 | dpb_copy: | |
439 | st y+,temp | |
440 | ldi temp2,15 | |
441 | cpydpb_l: | |
442 | ld temp,z+ | |
443 | st y+,temp | |
444 | dec temp2 | |
445 | brne cpydpb_l | |
446 | ret | |
447 | ||
448 | ||
637689de L |
449 | ; ==================================================================== |
450 | ; Function: get drive table entry pointer for drive # in temp | |
451 | ; ==================================================================== | |
452 | ; Parameters | |
453 | ; -------------------------------------------------------------------- | |
454 | ; Registers : | |
455 | ; Variables : | |
456 | ; | |
457 | ; -------------------------------------------------------------------- | |
458 | ; Description: | |
459 | ; ==================================================================== | |
460 | ||
461 | dpb_drvtbl_entry_p: | |
462 | ||
463 | ldsw x,biosdrvtbl | |
464 | lsl temp ;drive # | |
465 | add xl,temp | |
466 | adc xh,_0 | |
467 | ret | |
468 | ||
469 | ||
470 | ; ==================================================================== | |
471 | ; Function: get drive table entry for drive # in temp | |
472 | ; ==================================================================== | |
473 | ; Parameters | |
474 | ; -------------------------------------------------------------------- | |
475 | ; Registers : | |
476 | ; Variables : | |
477 | ; | |
478 | ; -------------------------------------------------------------------- | |
479 | ; Description: | |
480 | ; ==================================================================== | |
481 | ||
482 | dpb_drvtbl_entry_get: | |
483 | ||
484 | rcall dpb_drvtbl_entry_p | |
485 | ljmp dram_readw_pp | |
486 | ||
487 | ||
29ce189c | 488 | ; ==================================================================== |
dd7aea8c | 489 | ; Function: Clear drive table (entries 0 to 7) |
29ce189c L |
490 | ; ==================================================================== |
491 | ; Parameters | |
492 | ; -------------------------------------------------------------------- | |
493 | ; Registers : | |
494 | ; Variables : | |
495 | ; | |
496 | ; -------------------------------------------------------------------- | |
497 | ; Description: | |
498 | ; ==================================================================== | |
64219415 | 499 | |
dd7aea8c | 500 | ; |
29ce189c | 501 | |
5482d75f | 502 | dpb_drvtblclear: |
29ce189c | 503 | ldsw x,biosdrvtbl |
5482d75f L |
504 | sbiw x,0 |
505 | breq dpb_drvi_ex | |
506 | ||
507 | dpb_drvi_1: | |
dd7aea8c | 508 | ldi temp3,8 |
5482d75f | 509 | dpb_drvi_lp: |
29ce189c L |
510 | ldi temp,0 |
511 | ldi temp2,0 | |
512 | rcall dram_writew_pp | |
513 | dec temp3 | |
5482d75f | 514 | brne dpb_drvi_lp |
29ce189c L |
515 | |
516 | lds temp,biosenddat | |
517 | lds temp2,biosenddat+1 | |
5482d75f L |
518 | cp temp,_0 |
519 | cpc temp2,_0 | |
520 | breq dpb_drvi_ex | |
521 | ||
29ce189c | 522 | rcall heap_init |
5482d75f | 523 | dpb_drvi_ex: |
29ce189c | 524 | clr temp |
64219415 FZ |
525 | ret |
526 | ||
dd7aea8c | 527 | ; ==================================================================== |
5482d75f | 528 | ; Function: Test disk format: avrcpmhd |
dd7aea8c L |
529 | ; ==================================================================== |
530 | ; Parameters | |
531 | ; -------------------------------------------------------------------- | |
532 | ; Registers : temp drive # | |
533 | ; | |
534 | ; -------------------------------------------------------------------- | |
5482d75f | 535 | ; Description: Not implemented yet. |
dd7aea8c L |
536 | ; ==================================================================== |
537 | ||
538 | dsk_tst_avrcpmhd: | |
5482d75f | 539 | clr temp ; Test, return 'not found' for now. |
dd7aea8c L |
540 | ret |
541 | ||
542 | ||
543 | ; ==================================================================== | |
544 | ; Function: Test disk format: YAZE | |
545 | ; ==================================================================== | |
546 | ; Parameters | |
547 | ; -------------------------------------------------------------------- | |
548 | ; Registers : temp drive # | |
549 | ; | |
550 | ; -------------------------------------------------------------------- | |
551 | ; Description: From the YAZE Doc: | |
552 | ; | |
553 | ; The new disk header occupies the first 128 BYTES of the file and has the | |
554 | ; new format: | |
555 | ; | |
556 | ; 0 - 9 <CPM_Disk> | |
557 | ; 10 - 15 a null-terminated ascii comment (may be empty) | |
558 | ; new 16 version (0 = yaze-1.06/1.10, 1 = yaze-ag-2.xx) | |
559 | ; 17 - 31 a null-terminated ascii comment (may be empty) | |
560 | ; 32 - 33 sectors per track | |
561 | ; 34 block shift factor | |
562 | ; 35 block mask | |
563 | ; 36 extent mask | |
564 | ; 37 - 38 disk size max | |
565 | ; 39 - 40 directory max | |
566 | ; 41 al0 | |
567 | ; 42 al1 | |
568 | ; 43 - 44 check size (always zero) | |
569 | ; 45 - 46 track offset | |
570 | ; new 47 psh (used if version=1 and CP/M 3.1 is running) | |
571 | ; new 48 phm ( " " " " " " " " " ) | |
572 | ; 49 - 127 unused (zeros) | |
573 | ; ==================================================================== | |
574 | ||
575 | ||
dd7aea8c L |
576 | dsk_tst_yaze: |
577 | ||
578 | ldiw y,hostbuf | |
dcd7e502 | 579 | ldiw z,str_CPM_Disk*2 |
dd7aea8c | 580 | lpm temp2,z+ ; get length |
623dd899 | 581 | lcall strncmp_p |
dd7aea8c L |
582 | brne dsk_tyze_not |
583 | ||
584 | ldiw z,hostbuf+32 | |
585 | ldiw y,tmpdpb | |
586 | ldi temp,1 ;1 sector header size | |
587 | rcall dpb_copy | |
588 | ||
5482d75f | 589 | ori temp,0xff |
dd7aea8c L |
590 | ret |
591 | ||
592 | dsk_tyze_not: | |
5482d75f | 593 | clr temp ;Not a YAZE disk image. |
dd7aea8c | 594 | ret |
29ce189c | 595 | |
dd7aea8c L |
596 | ; ==================================================================== |
597 | ; Function: Test disk format: MyZ80 | |
598 | ; ==================================================================== | |
599 | ; Parameters | |
600 | ; -------------------------------------------------------------------- | |
601 | ; Registers : temp drive # | |
602 | ; | |
603 | ; -------------------------------------------------------------------- | |
604 | ; Description: Test, if first 2 Sectors are filled with 0xE5, | |
b165699b | 605 | ; and Size = 8192KB + 256Bytes. |
dd7aea8c L |
606 | ; ==================================================================== |
607 | dsk_tst_myz80: | |
608 | ||
609 | mov zl,temp3 | |
610 | rcall dsk_getpartentry ;get partition entry | |
611 | ldd temp,z+PTAB_SIZE | |
b165699b L |
612 | ldd temp2,z+PTAB_SIZE+1 ;check, if size is 16385 phys. sectors |
613 | cpi temp,low(16385) | |
614 | ldi temp,high(16385) | |
dd7aea8c L |
615 | cpc temp2,temp |
616 | brne dsk_tmyz80_not ;wrong size | |
617 | ||
618 | ldiw z,hostbuf | |
619 | ldi temp2,0 | |
620 | ||
621 | dsk_tmyz80_loop: | |
622 | ld temp,z+ | |
623 | cpi temp,0xE5 | |
624 | brne dsk_tmyz80_not | |
625 | dec temp2 | |
626 | brne dsk_tmyz80_loop | |
627 | ||
5482d75f | 628 | ori temp,0xff |
dd7aea8c L |
629 | ret |
630 | ||
631 | dsk_tmyz80_not: | |
5482d75f | 632 | clr temp ;Not a MyZ80 hard disk image. |
dd7aea8c L |
633 | ret |
634 | ||
b165699b L |
635 | ; ==================================================================== |
636 | ; Function: Test disk format: simhd, simh altair 8800 hard disk format | |
637 | ; ==================================================================== | |
638 | ; Parameters | |
639 | ; -------------------------------------------------------------------- | |
640 | ; Registers : temp drive # | |
641 | ; | |
642 | ; -------------------------------------------------------------------- | |
dcd7e502 L |
643 | ; Description: Test, if Size = 8192 KB and |
644 | ; first 6 tracks are filled with 0xE5. | |
b165699b L |
645 | ; Actually, only the first phys. sector is tested, since |
646 | ; the other 47 sectors are not in memory at this time. | |
647 | ; ==================================================================== | |
648 | dsk_tst_simhd: | |
649 | ||
650 | mov zl,temp3 | |
651 | rcall dsk_getpartentry ;get partition entry | |
652 | ldd temp,z+PTAB_SIZE | |
653 | ldd temp2,z+PTAB_SIZE+1 ;check, if size is 16384 phys. sectors | |
654 | cpi temp,low(16384) | |
655 | ldi temp,high(16384) | |
656 | cpc temp2,temp | |
657 | brne dsk_tsimhd_not ;wrong size | |
658 | ||
dcd7e502 L |
659 | ldiw y,hostbuf+128-10 |
660 | ldiw z,str_CPM_Disk*2 | |
661 | lpm temp2,z+ ; get length | |
623dd899 | 662 | lcall strncmp_p |
dcd7e502 L |
663 | breq dsk_tsimhd_found |
664 | ||
b165699b L |
665 | ldiw z,hostbuf |
666 | ldi temp2,high(512) | |
667 | clr _tmp0 ;low(512) | |
b165699b L |
668 | dsk_tsimhd_loop: |
669 | ld temp,z+ | |
670 | cpi temp,0xE5 | |
671 | brne dsk_tsimhd_not | |
672 | dec _tmp0 | |
673 | brne dsk_tsimhd_loop | |
674 | dec temp2 | |
675 | brne dsk_tsimhd_loop | |
676 | ||
dcd7e502 | 677 | dsk_tsimhd_found: |
5482d75f | 678 | ori temp,0xff |
b165699b L |
679 | ret |
680 | ||
681 | dsk_tsimhd_not: | |
5482d75f | 682 | clr temp ;Not a simhd hard disk image. |
b165699b L |
683 | ret |
684 | ||
dd7aea8c L |
685 | ; ==================================================================== |
686 | ; Function: | |
687 | ; ==================================================================== | |
688 | ; Parameters | |
689 | ; -------------------------------------------------------------------- | |
5482d75f | 690 | ; Registers : temp3 drive # |
dd7aea8c L |
691 | ; |
692 | ; -------------------------------------------------------------------- | |
693 | ; Description: | |
694 | ; ==================================================================== | |
695 | ||
5482d75f | 696 | dsk_format_get: |
dd7aea8c L |
697 | |
698 | ; Get first sector (512 byte) of current drive into hostbuf. | |
699 | ||
dd7aea8c L |
700 | ldi temp,0 |
701 | ldi temp2,0 ; | |
702 | rcall dsk_readhost_lba | |
703 | ||
dd7aea8c L |
704 | ; Test for variable format avrcpmhd. |
705 | ||
706 | rcall dsk_tst_avrcpmhd | |
5482d75f | 707 | brne dsk_imgt_done |
dd7aea8c L |
708 | |
709 | ; Test for YAZE formats. | |
710 | ||
711 | rcall dsk_tst_yaze | |
5482d75f | 712 | brne dsk_imgt_done |
dd7aea8c | 713 | |
b165699b L |
714 | ; Test for simhd format. |
715 | ||
716 | rcall dsk_tst_simhd | |
717 | ldiw z,dpbdat_simhd*2 | |
5482d75f | 718 | brne dsk_imgt_fixed |
b165699b | 719 | |
dd7aea8c L |
720 | ; Test for MyZ80 format. |
721 | ||
722 | rcall dsk_tst_myz80 | |
723 | ldiw z,dpbdat_myz80*2 | |
5482d75f | 724 | brne dsk_imgt_fixed |
dd7aea8c L |
725 | |
726 | ; No special image found. Use avrcpm. | |
727 | ||
728 | ldiw z,dpbdat_avrcpm*2 | |
729 | ||
5482d75f | 730 | dsk_imgt_fixed: |
dd7aea8c | 731 | rcall dpb_copy_p |
5482d75f L |
732 | ori temp,0xff |
733 | dsk_imgt_done: | |
5482d75f | 734 | ret |
dd7aea8c | 735 | |
5482d75f L |
736 | ; ==================================================================== |
737 | ; Function: Add CP/M image format data to partition table data | |
738 | ; ==================================================================== | |
739 | ; Parameters | |
740 | ; -------------------------------------------------------------------- | |
741 | ; Registers : temp3 drive # | |
742 | ; | |
743 | ; -------------------------------------------------------------------- | |
744 | ; Description: | |
745 | ; ==================================================================== | |
746 | ||
747 | dpb_imgdata_get: | |
748 | ||
749 | ; Test for known CP/M formats | |
750 | ||
751 | rcall dsk_format_get | |
752 | breq dpb_imgd_err ;no known format detected | |
753 | ||
754 | ; | |
dd7aea8c L |
755 | mov zl,temp3 |
756 | rcall dsk_getpartentry ;get partition entry | |
757 | ldiw y,tmpdpb | |
758 | ||
759 | ; std y+12,_0 ;Test: set check size to 0 | |
760 | ; std y+13,_0 | |
761 | ||
762 | ldd temp,y+0 | |
763 | andi temp,~dskType_MASK | |
764 | ldd temp2,z+PTAB_TYPE | |
765 | andi temp2,dskType_MASK | |
766 | or temp,temp2 | |
767 | std z+PTAB_TYPE,temp | |
768 | ldd temp,y+1 | |
769 | std z+PTAB_SPT,temp | |
770 | ldd temp,y+2 | |
771 | tst temp ;more then 256 sectors per track? | |
772 | brne dsk_imgprp_err ;todo: support 16 bit sector numbers | |
773 | ldd temp2,y+3 | |
774 | andi temp2,0x0f | |
775 | swap temp2 | |
776 | std z+PTAB_BSH,temp2 | |
777 | ||
778 | ori temp,255 | |
779 | ret | |
780 | ||
781 | dsk_imgprp_err: | |
782 | printnewline | |
783 | ldi temp,'A' | |
784 | add temp,temp3 | |
08716d4f | 785 | lcall uartputc |
dd7aea8c L |
786 | printstring ": Format not supported: Too much sectors per track! " |
787 | printnewline | |
788 | ||
5482d75f | 789 | dpb_imgd_err: |
dd7aea8c L |
790 | clr temp |
791 | ret | |
792 | ||
5482d75f L |
793 | ; ==================================================================== |
794 | ; Function: | |
795 | ; ==================================================================== | |
796 | ; Parameters | |
797 | ; -------------------------------------------------------------------- | |
798 | ; Registers : temp drive # | |
799 | ; | |
800 | ; return !0 if ok | |
801 | ; 0 on error | |
802 | ; -------------------------------------------------------------------- | |
803 | ; Description: Init CP/M data structures | |
29ce189c | 804 | ; |
34527fc2 L |
805 | ; ----------------------------------------------------------------- |
806 | ; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV | | |
807 | ; ----------------------------------------------------------------- | |
808 | ;offset: 0 2 4 6 8 10 12 14 | |
5482d75f | 809 | ; |
34527fc2 L |
810 | ; ------------------------------------------------------------- |
811 | ; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF | | |
812 | ; ------------------------------------------------------------- | |
813 | ;offset: 0 2 3 4 5 7 9 10 11 13 | |
5482d75f | 814 | ; ==================================================================== |
29ce189c | 815 | |
5482d75f | 816 | dpb_biosdph_get: |
29ce189c L |
817 | mov temp3,temp ;save disk # |
818 | ||
5482d75f | 819 | rcall dsk_format_get |
dd7aea8c L |
820 | brne dpb_di_0 |
821 | rjmp dpb_di_err | |
29ce189c | 822 | |
dd7aea8c | 823 | dpb_di_0: |
29ce189c L |
824 | |
825 | ; get mem for DPH | |
29ce189c L |
826 | |
827 | ldi temp, low (16) | |
828 | ldi temp2,high(16) | |
5482d75f | 829 | rcall heap_get ;returns ptr to dph mem |
637689de L |
830 | brne dpb_di_1 |
831 | rjmp dpb_di_err ; | |
832 | dpb_di_1: | |
29ce189c | 833 | movw x,temp |
637689de | 834 | movw y,temp ;save dph pointer |
29ce189c L |
835 | ldi temp,0 |
836 | ldi temp2,0 | |
837 | rcall dram_writew_pp ;XLT | |
838 | adiw x,6 | |
839 | lds temp,biosdirbuf | |
840 | lds temp2,biosdirbuf+1 | |
841 | rcall dram_writew_pp ;DIRBUF | |
842 | ||
843 | ; get mem for DPB | |
29ce189c L |
844 | |
845 | ldi temp, low (15) | |
846 | ldi temp2,high(15) | |
847 | rcall heap_get | |
637689de | 848 | breq dpb_di_err_p1 |
29ce189c L |
849 | movw x,temp |
850 | ||
dd7aea8c | 851 | ldiw z,tmpdpb+1 ;skip sector offset byte |
637689de | 852 | dpb_dicpl: |
29ce189c L |
853 | ld temp,z+ |
854 | rcall dram_write_pp | |
dd7aea8c | 855 | cpi zl,low(tmpdpb + 16) |
637689de | 856 | brne dpb_dicpl |
29ce189c L |
857 | sbiw x,15 |
858 | movw temp,x | |
859 | movw x,y | |
860 | adiw x,10 | |
861 | rcall dram_writew_pp ;DPB | |
862 | ||
863 | ; get mem for dir check vector | |
864 | ||
dd7aea8c L |
865 | lds temp,tmpdpb+12 ;cks |
866 | lds temp2,tmpdpb+12+1 | |
29ce189c L |
867 | cp temp,_0 |
868 | cpc temp2,_0 | |
637689de | 869 | breq dpb_dicks0 |
29ce189c | 870 | rcall heap_get |
637689de L |
871 | breq dpb_di_err_p1 |
872 | dpb_dicks0: | |
29ce189c L |
873 | rcall dram_writew_pp ;CSV |
874 | ||
875 | ; get mem for alloc vector | |
876 | ||
dd7aea8c L |
877 | lds temp,tmpdpb+6 ;dsm |
878 | lds temp2,tmpdpb+6+1 | |
29ce189c L |
879 | subi temp, low (-8) |
880 | sbci temp2,high(-8) | |
881 | lsr temp2 | |
882 | ror temp | |
883 | lsr temp2 | |
884 | ror temp | |
885 | lsr temp2 | |
886 | ror temp ;(dsm+1+7)/8 | |
887 | rcall heap_get | |
637689de | 888 | breq dpb_di_err_p1 |
29ce189c L |
889 | rcall dram_writew_pp ;ALV |
890 | ||
891 | ; success, insert DPH into drvtbl | |
892 | ||
637689de L |
893 | mov temp,temp3 |
894 | rcall dpb_drvtbl_entry_p | |
29ce189c L |
895 | movw temp,y |
896 | rcall dram_writew_pp | |
dd7aea8c | 897 | |
29ce189c | 898 | ori temp,0xff ;return ok |
64219415 FZ |
899 | ret |
900 | ||
29ce189c L |
901 | ; error, free mem |
902 | ||
637689de | 903 | dpb_di_err_p1: |
29ce189c L |
904 | movw temp,y |
905 | rcall heap_release | |
637689de | 906 | dpb_di_err: |
29ce189c | 907 | eor temp,temp ;return 0 (+ Z-flag) |
b741422e | 908 | ret |
29ce189c | 909 | |
dd7aea8c L |
910 | ; ==================================================================== |
911 | ; Function: | |
912 | ; ==================================================================== | |
913 | ; Parameters | |
914 | ; -------------------------------------------------------------------- | |
915 | ; Registers : | |
916 | ; | |
917 | ; -------------------------------------------------------------------- | |
918 | ; Description: | |
919 | ; ==================================================================== | |
920 | dsk_setdrvparam: | |
921 | ldd temp2,z+PTAB_TYPE | |
922 | andi temp2,~dskType_MASK ;Lower nibble is image header size | |
923 | sts hdrsize,temp2 | |
924 | ldd temp2,z+PTAB_SPT | |
2ccaac16 | 925 | sts cpmspt,temp2 ;CP/M sectors per track |
dd7aea8c L |
926 | ldd temp2,z+PTAB_BSH |
927 | swap temp2 | |
928 | andi temp2,0x0f | |
929 | clr _tmp0 | |
930 | inc _tmp0 | |
931 | dsk_sdrvpl: | |
932 | lsl _tmp0 | |
933 | dec temp2 | |
934 | brne dsk_sdrvpl | |
2ccaac16 | 935 | sts secpblk,_tmp0 ;Sectors per block |
dd7aea8c L |
936 | ret |
937 | ||
64219415 | 938 | |
b741422e | 939 | ; ==================================================================== |
64219415 | 940 | ; Function: Does a Disk interaction |
b741422e L |
941 | ; ==================================================================== |
942 | ; Parameters | |
943 | ; -------------------------------------------------------------------- | |
2ccaac16 L |
944 | ; Registers : |
945 | ; Variables : | |
946 | ; | |
b741422e L |
947 | ; -------------------------------------------------------------------- |
948 | ; Description: | |
64219415 | 949 | ; ==================================================================== |
2ccaac16 | 950 | |
64219415 FZ |
951 | dskDoIt: |
952 | .if DISK_DEBUG | |
953 | push temp | |
2ccaac16 L |
954 | sbrc temp,HOME_FUNC |
955 | rjmp dskdbghome | |
956 | sbrc temp,BOOT_FUNC | |
957 | rjmp dskdbgboot | |
958 | .if DISK_DEBUG > 1 | |
64219415 | 959 | sbrc temp,READ_FUNC |
2ccaac16 | 960 | rjmp dskdbgread |
64219415 | 961 | sbrc temp,WRITE_FUNC |
2ccaac16 L |
962 | rjmp dskdbgwrite |
963 | .endif | |
64219415 FZ |
964 | rjmp dskdbge |
965 | ||
2ccaac16 L |
966 | dskdbgread: |
967 | printnewline | |
968 | printstring "dsk RD: " | |
969 | rjmp dskdbg1 | |
970 | dskdbgwrite: | |
64219415 | 971 | printnewline |
2ccaac16 | 972 | printstring "dsk WR: " |
64219415 | 973 | rjmp dskdbg1 |
2ccaac16 | 974 | dskdbghome: |
64219415 | 975 | printnewline |
2ccaac16 L |
976 | printstring " HOME: " |
977 | rjmp dskdbg1 | |
978 | dskdbgboot: | |
979 | printnewline | |
980 | printstring " BOOT: " | |
64219415 FZ |
981 | dskdbg1: |
982 | lds temp,seekdsk | |
983 | subi temp,-('A') | |
984 | rcall uartputc | |
2ccaac16 | 985 | printstring ": trk " |
64219415 FZ |
986 | lds temp2,seektrk+1 |
987 | lds temp,seektrk | |
dc705dc0 | 988 | lcall printhexw |
2ccaac16 | 989 | printstring ", sec " |
64219415 | 990 | lds temp,seeksec |
dc705dc0 | 991 | lcall printhex |
2ccaac16 | 992 | printstring ", dma " |
64219415 FZ |
993 | lds temp2,dmaadr+1 |
994 | lds temp,dmaadr | |
dc705dc0 | 995 | lcall printhexw |
64219415 | 996 | dskdbge: |
2ccaac16 | 997 | pop temp |
64219415 | 998 | .endif |
2ccaac16 L |
999 | |
1000 | sts erflag,_0 | |
1001 | ||
64219415 FZ |
1002 | ;See what has to be done. |
1003 | sbrc temp,READ_FUNC | |
2ccaac16 | 1004 | rjmp dsk_readwrite |
64219415 | 1005 | sbrc temp,WRITE_FUNC |
2ccaac16 | 1006 | rjmp dsk_readwrite |
64219415 FZ |
1007 | sbrc temp,HOME_FUNC |
1008 | rjmp dsk_home | |
1009 | sbrc temp,BOOT_FUNC | |
1010 | rjmp dsk_boot | |
1011 | ||
1012 | printstring "DISK I/O: Invalid Function code: " | |
08716d4f | 1013 | lcall printhex |
dc705dc0 | 1014 | ljmp haltinv |
64219415 FZ |
1015 | |
1016 | dsk_boot: | |
dd7aea8c L |
1017 | sts ndisks,_0 ;no active partitions |
1018 | dsk_inval_hostbuf: | |
1019 | cbi flags,hostact ;host buffer inactive | |
1020 | sts unacnt,_0 ;clear unalloc count | |
64219415 FZ |
1021 | ret |
1022 | ||
1023 | dsk_home: | |
dd7aea8c L |
1024 | sbis flags,hostwrt ;check for pending write |
1025 | cbi flags,hostact ;clear host active flag | |
64219415 | 1026 | ret |
64219415 | 1027 | |
b741422e L |
1028 | |
1029 | ||
29ce189c | 1030 | |
2ccaac16 L |
1031 | dsk_readwrite: |
1032 | ||
1033 | ; RAM disk? | |
1034 | ||
dd7aea8c | 1035 | lds zl,seekdsk |
eb85ce65 | 1036 | #if RAMDISKCNT |
dd7aea8c | 1037 | cpi zl,RAMDISKNR |
2ccaac16 L |
1038 | brlt dsk_rw_noramdisk |
1039 | sbrc temp,WRITE_FUNC | |
1040 | rjmp rdsk_write | |
1041 | rjmp rdsk_read | |
1042 | dsk_rw_noramdisk: | |
eb85ce65 | 1043 | #endif |
2ccaac16 L |
1044 | rcall dsk_getpartentry ;Get Paritiontableentry |
1045 | ld temp2,z ;Get Partitiontype | |
1046 | andi temp2,dskType_MASK | |
b741422e L |
1047 | |
1048 | ; Isn't it a Disk ? | |
2ccaac16 L |
1049 | |
1050 | cpi temp2,dskType_None | |
b741422e | 1051 | brne PC+2 |
2ccaac16 | 1052 | ret ;return error |
dd7aea8c | 1053 | |
b741422e | 1054 | ; It must be a FAT16-Imagefile or CP/M Partition. |
dd7aea8c | 1055 | |
2ccaac16 L |
1056 | sbrc temp,WRITE_FUNC |
1057 | rjmp dsk_write | |
dd7aea8c | 1058 | |
2ccaac16 | 1059 | sbi flags,readop ;Set read operation flag |
637689de | 1060 | sbi flags,rsflag ;must read data |
2ccaac16 | 1061 | sts unacnt,_0 |
637689de L |
1062 | ldi temp,WRUAL ;write type |
1063 | sts wrtype,temp ;treat as unalloc | |
2ccaac16 | 1064 | rjmp dsk_rw |
dd7aea8c | 1065 | |
64219415 | 1066 | dsk_write: |
2ccaac16 L |
1067 | cbi flags,readop ;Not a read operation |
1068 | andi temp,WRTMSK | |
1069 | sts wrtype,temp ;save write type | |
1070 | dsk_rw: | |
1071 | rcall dsk_setdrvparam ;todo: do this only if needed (disk change) | |
b741422e | 1072 | |
2ccaac16 | 1073 | ; Convert track/sector to an LBA address (in 128byte blocks) |
b741422e | 1074 | |
2ccaac16 L |
1075 | lds xl,seeksec ; |
1076 | ldi xh,0 ; | |
1077 | ldi temp3,0 ; | |
1078 | lds temp,hdrsize ;add image header size | |
1079 | add xl,temp ; | |
1080 | adc xh,_0 ; | |
1081 | lds temp2,cpmspt ; | |
1082 | lds temp,seektrk ; | |
1083 | mul temp,temp2 ; | |
1084 | add xl,r0 ; | |
1085 | adc xh,r1 ; | |
1086 | lds temp,seektrk+1 ; | |
1087 | mul temp,temp2 ; | |
1088 | add xh,r0 ;temp3:xh:xl := sec + trk * SectorsPerTrack | |
1089 | adc temp3,r1 ; | |
1090 | mov temp,xl | |
1091 | andi temp,SECMSK ;mask buffer number | |
1092 | sts hostpart,temp ;save for later | |
1eeb9cbe | 1093 | |
2ccaac16 | 1094 | ; Convert from CP/M LBA blocks to host LBA blocks |
64219415 | 1095 | |
2ccaac16 L |
1096 | ldi temp,SECSHF |
1097 | dsk_sh1: | |
1098 | lsr temp3 | |
1099 | ror xh | |
1100 | ror xl | |
1101 | dec temp | |
1102 | brne dsk_sh1 | |
1103 | ;todo: temp3 should be 0 here. | |
1104 | ;xh:xl = host block to seek | |
1105 | ; | |
1106 | sbic flags,readop | |
1107 | rjmp dsk_rwoper ;to perform the read | |
dd7aea8c | 1108 | |
2ccaac16 | 1109 | ; Write operation |
64219415 | 1110 | |
2ccaac16 L |
1111 | cbi flags,rsflag ;rsflag = 0 |
1112 | lds temp,wrtype ; | |
dd7aea8c L |
1113 | cpi temp,WRUAL ;write unallocated? |
1114 | brne dsk_chkuna ;check for unalloc | |
64219415 | 1115 | |
64ce65a1 | 1116 | ; write to unallocated, set parameters |
2ccaac16 | 1117 | |
dd7aea8c | 1118 | lds temp,secpblk ;next unalloc recs (blocksize/128) |
2ccaac16 L |
1119 | lds temp2,hostpart ; |
1120 | sts unapart,temp2 ; | |
1121 | cpi temp2,0 ;cpm sector on phys. sector boundary? | |
1122 | breq dsk_una1 | |
1123 | sbi flags,rsflag ; no, rsflag = 1 | |
64ce65a1 L |
1124 | subi temp,HOSTBLK ;don't write |
1125 | lds _tmp0,hdrsize ; in next bock | |
1126 | add temp,_tmp0 ; if there is a header | |
2ccaac16 | 1127 | dsk_una1: |
dd7aea8c L |
1128 | sts unacnt,temp |
1129 | lds temp,seekdsk ;disk to seek | |
1130 | sts unadsk,temp ;unadsk = sekdsk | |
2ccaac16 L |
1131 | sts unalba, xl ;unalba = seeklba (== hostlba) |
1132 | sts unalba+1,xh | |
1133 | ||
1134 | ; check for write to unallocated sector | |
64ce65a1 | 1135 | |
64219415 | 1136 | dsk_chkuna: |
2ccaac16 | 1137 | |
dd7aea8c L |
1138 | lds temp,unacnt ;any unalloc remain? |
1139 | tst temp | |
1140 | breq dsk_alloc ;skip if not | |
64219415 | 1141 | |
64ce65a1 | 1142 | ; more unallocated records remain |
2ccaac16 | 1143 | |
dd7aea8c L |
1144 | dec temp ;unacnt = unacnt-1 |
1145 | sts unacnt,temp | |
1146 | lds temp,seekdsk ;same disk? | |
1147 | lds temp2,unadsk | |
1148 | cp temp,temp2 ;seekdsk = unadsk? | |
1149 | brne dsk_alloc ;skip if not | |
64219415 | 1150 | |
64ce65a1 | 1151 | ; disks are the same |
2ccaac16 L |
1152 | |
1153 | lds temp,unalba | |
1154 | lds temp2,unalba+1 | |
1155 | cp temp,xl ;seeklba = unalba? | |
1156 | cpc temp2,xh | |
dd7aea8c | 1157 | brne dsk_alloc ;skip if not |
64219415 | 1158 | |
2ccaac16 L |
1159 | ; block address is the same |
1160 | ||
1161 | lds _tmp0,hostpart ;same part? | |
1162 | lds temp3,unapart | |
1163 | cp _tmp0,temp3 ;seekpart = unapart? | |
dd7aea8c | 1164 | brne dsk_alloc ;skip if not |
64219415 | 1165 | |
64ce65a1 | 1166 | ; match, move to next sector for future ref |
2ccaac16 L |
1167 | |
1168 | inc temp3 ;next part | |
1169 | andi temp3,SECMSK | |
1170 | sts unapart,temp3 | |
1171 | brne dsk_noovf ;skip if no overflow | |
1172 | ||
1173 | ; overflow to next block | |
1174 | ||
1175 | subi temp, low(-1) ;unalba = unalba+1 | |
64219415 | 1176 | sbci temp2,high(-1) |
2ccaac16 L |
1177 | sts unalba,temp |
1178 | sts unalba+1,temp2 | |
64ce65a1 | 1179 | |
64219415 | 1180 | dsk_noovf: |
dd7aea8c | 1181 | rjmp dsk_rwoper ;to perform the write |
64ce65a1 | 1182 | |
2ccaac16 L |
1183 | ; not an unallocated record, requires pre-read |
1184 | ||
64219415 | 1185 | dsk_alloc: |
dd7aea8c L |
1186 | sts unacnt,_0 ;unacnt = 0 |
1187 | sbi flags,rsflag ;rsflag = 1 | |
b741422e | 1188 | |
b741422e | 1189 | |
2ccaac16 L |
1190 | ; Enter here to perform the read/write |
1191 | ||
b741422e | 1192 | dsk_rwoper: |
2ccaac16 L |
1193 | |
1194 | .if DISK_DEBUG > 1 | |
1195 | printstring ", flags|wtyp " | |
dd7aea8c | 1196 | in temp,flags |
2ccaac16 L |
1197 | cbr temp,WRTMSK |
1198 | lds _tmp0,wrtype | |
1199 | or temp,_tmp0 | |
1200 | lcall printhex | |
1201 | printstring ", buf " | |
1202 | lds temp,hostpart | |
dc705dc0 | 1203 | lcall printhex |
64219415 | 1204 | .endif |
64ce65a1 | 1205 | |
5482d75f L |
1206 | movw temp,x |
1207 | lds temp3,seekdsk | |
1208 | rcall dsk_rw_hostbuf | |
64219415 | 1209 | |
64ce65a1 | 1210 | ; copy data to or from buffer |
2ccaac16 | 1211 | |
64219415 | 1212 | ldiw z,hostbuf |
2ccaac16 L |
1213 | lds temp,hostpart ;get buffer number (which part of hostbuf) |
1214 | ldi temp2,128 | |
1215 | mul temp,temp2 | |
dd7aea8c L |
1216 | add zl,r0 ;offset in hostbuf |
1217 | adc zh,r1 | |
64219415 | 1218 | |
dd7aea8c L |
1219 | lds xl,dmaadr |
1220 | lds xh,dmaadr+1 | |
1221 | ldi temp3,128 ;length of move | |
64219415 | 1222 | sbic flags,readop ;which way? |
dd7aea8c | 1223 | rjmp dsk_rmove ;skip if read |
64219415 | 1224 | |
64ce65a1 | 1225 | ; mark write operation |
dd7aea8c | 1226 | sbi flags,hostwrt ;hostwrt = 1 |
64219415 FZ |
1227 | dsk_wmove: |
1228 | mem_read | |
dd7aea8c | 1229 | st z+,temp |
64219415 | 1230 | adiw xl,1 |
dd7aea8c | 1231 | dec temp3 |
64219415 FZ |
1232 | brne dsk_wmove |
1233 | rjmp dsk_rwmfin | |
1234 | ||
1235 | dsk_rmove: | |
dd7aea8c | 1236 | ld temp,z+ |
64219415 FZ |
1237 | mem_write |
1238 | adiw xl,1 | |
dd7aea8c | 1239 | dec temp3 |
64219415 | 1240 | brne dsk_rmove |
64ce65a1 | 1241 | |
64219415 | 1242 | dsk_rwmfin: |
64ce65a1 | 1243 | ; data has been moved to/from host buffer |
dd7aea8c L |
1244 | lds temp,wrtype ;write type |
1245 | cpi temp,WRDIR ;to directory? | |
64219415 | 1246 | breq dsk_wdir |
dd7aea8c | 1247 | ret ;no further processing |
64ce65a1 L |
1248 | |
1249 | ; clear host buffer for directory write | |
64219415 | 1250 | dsk_wdir: |
dd7aea8c L |
1251 | lds temp,erflag |
1252 | tst temp ;errors? | |
64219415 | 1253 | breq dsk_wdir1 |
dd7aea8c | 1254 | ret ;skip if so |
64ce65a1 | 1255 | |
64219415 FZ |
1256 | dsk_wdir1: |
1257 | rcall dsk_writehost ;clear host buff | |
dd7aea8c | 1258 | cbi flags,hostwrt ;buffer written |
b741422e L |
1259 | ret |
1260 | ||
dd7aea8c L |
1261 | ; ==================================================================== |
1262 | ; Function: | |
1263 | ; ==================================================================== | |
1264 | ; Parameters | |
1265 | ; -------------------------------------------------------------------- | |
1266 | ; Registers : temp2:temp block to read (lba) | |
1267 | ; temp3 disk # | |
1268 | ; | |
1269 | ; -------------------------------------------------------------------- | |
1270 | ; Description: | |
1271 | ; ==================================================================== | |
2ccaac16 | 1272 | ; |
dd7aea8c | 1273 | dsk_readhost_lba: |
2ccaac16 | 1274 | .if HOSTRW_DEBUG |
dd7aea8c | 1275 | printnewline |
2ccaac16 L |
1276 | printstring "Readhost LBA" |
1277 | .endif | |
5482d75f L |
1278 | sbi flags,rsflag ;must read data |
1279 | rcall dsk_rw_hostbuf | |
1280 | lds temp,erflag ;returns 0, if ok | |
1281 | tst temp | |
1282 | ret | |
dd7aea8c | 1283 | |
5482d75f L |
1284 | ; ==================================================================== |
1285 | ; Function: Get physical disk sector in hostbuf. | |
1286 | ; ==================================================================== | |
1287 | ; Parameters | |
1288 | ; -------------------------------------------------------------------- | |
1289 | ; Registers : temp2:temp host block to read/write (lba) | |
1290 | ; temp3 disk # | |
1291 | ; | |
1292 | ; -------------------------------------------------------------------- | |
1293 | ; Description: | |
1294 | ; ==================================================================== | |
1295 | dsk_rw_hostbuf: | |
1296 | ;xh:xl = host block to seek | |
1297 | sts erflag,_0 ;no errors (yet) | |
1298 | ||
64ce65a1 L |
1299 | ; active host sector? |
1300 | ||
5482d75f L |
1301 | in _tmp0,flags ;host active flag |
1302 | sbi flags,hostact ;always becomes 1 | |
1303 | sbrs _tmp0,hostact ;was it already? | |
1304 | rjmp dsk_filhst ;fill host if not | |
1305 | ||
64ce65a1 L |
1306 | ; host buffer active, same as seek buffer? |
1307 | ||
5482d75f L |
1308 | lds _tmp0,hostdsk ;same disk? |
1309 | cp temp3,_tmp0 ;seekdsk = hostdsk? | |
1310 | brne dsk_nomatch | |
1311 | ||
64ce65a1 L |
1312 | ; same disk, same block? |
1313 | ||
5482d75f | 1314 | lds _tmp0,hostlba |
5482d75f | 1315 | cp temp,_tmp0 |
825ecc9d L |
1316 | lds _tmp0,hostlba+1 |
1317 | cpc temp2,_tmp0 | |
5482d75f L |
1318 | breq dsk_match |
1319 | ||
1320 | dsk_nomatch: | |
1321 | ;proper disk, but not correct sector | |
1322 | sbis flags,hostwrt ;host written? | |
1323 | rjmp dsk_filhst | |
1324 | push temp3 | |
1325 | push temp2 | |
1326 | push temp | |
1327 | rcall dsk_writehost ;clear host buff | |
1328 | pop temp | |
1329 | pop temp2 | |
1330 | pop temp3 | |
1331 | ||
64ce65a1 | 1332 | ; may have to fill the host buffer |
5482d75f | 1333 | dsk_filhst: |
5482d75f L |
1334 | sts hostlba,temp |
1335 | sts hostlba+1,temp2 | |
1336 | sts hostdsk,temp3 | |
1337 | ||
1338 | sbic flags,rsflag ;need to read? | |
1339 | rcall dsk_readhost ;yes, if 1 | |
1340 | cbi flags,hostwrt ;no pending write | |
1341 | ||
1342 | dsk_match: | |
1343 | ret | |
dd7aea8c | 1344 | |
b741422e | 1345 | ; ==================================================================== |
64219415 | 1346 | ; Function: Does a Disk write operation |
b741422e L |
1347 | ; ==================================================================== |
1348 | ; Parameters | |
1349 | ; -------------------------------------------------------------------- | |
1350 | ; Registers : none | |
1351 | ; Variables : [r] seekdsk Number of Disk to Read | |
1352 | ; [r] seeksec Sector to read | |
1353 | ; [r] seektrk Track to read | |
1354 | ; -------------------------------------------------------------------- | |
1355 | ; Description: | |
1356 | ; ==================================================================== | |
1357 | dsk_writehost: | |
dd7aea8c | 1358 | lds zl,hostdsk |
637689de L |
1359 | rcall dsk_getpartentry |
1360 | ld temp,z | |
1361 | andi temp,dskType_MASK | |
b741422e L |
1362 | |
1363 | #if FAT16_SUPPORT | |
64219415 | 1364 | ; Is it a FAT16 Diskimage ? |
637689de | 1365 | cpi temp,dskType_FAT |
b741422e L |
1366 | brne PC+2 |
1367 | rjmp fat_writehost | |
1368 | #endif | |
1369 | ||
64219415 | 1370 | ; Is it a CP/M Partition ? |
637689de | 1371 | cpi temp,dskType_CPM |
b741422e L |
1372 | brne PC+2 |
1373 | rjmp cpm_writehost | |
1374 | ; Disktype not supported -> Return | |
1375 | ret | |
1376 | ||
1377 | ; ==================================================================== | |
64219415 | 1378 | ; Function: Does a Disk read operation |
b741422e L |
1379 | ; ==================================================================== |
1380 | ; Parameters | |
1381 | ; -------------------------------------------------------------------- | |
1382 | ; Registers : none | |
1383 | ; Variables : [r] seekdsk Number of Disk to Read | |
1384 | ; [r] seeksec Sector to read | |
1385 | ; [r] seektrk Track to read | |
1386 | ; -------------------------------------------------------------------- | |
1387 | ; Description: | |
1388 | ; ==================================================================== | |
1389 | dsk_readhost: | |
dd7aea8c L |
1390 | |
1391 | #if 0 | |
1392 | printnewline | |
1393 | printstring "readhost" | |
1394 | ldiw z,biosdrvtbl | |
1395 | rcall dbg_hexdump_line | |
1396 | adiw z,16 | |
1397 | rcall dbg_hexdump_line | |
1398 | #endif | |
1399 | ||
1400 | lds zl,hostdsk | |
b741422e L |
1401 | rcall dsk_getpartentry |
1402 | ld temp,z | |
637689de | 1403 | andi temp,dskType_MASK |
b741422e L |
1404 | |
1405 | #if FAT16_SUPPORT | |
64219415 | 1406 | ; Is it a FAT16 Diskimage ? |
637689de | 1407 | cpi temp,dskType_FAT |
b741422e L |
1408 | brne PC+2 |
1409 | rjmp fat_readhost | |
1410 | #endif | |
1411 | ||
64219415 | 1412 | ; Is it a CP/M Partition ? |
637689de | 1413 | cpi temp,dskType_CPM |
b741422e L |
1414 | brne PC+2 |
1415 | rjmp cpm_readhost | |
1416 | ; Disktype not supported -> Return | |
1417 | ret | |
1418 | ||
5482d75f L |
1419 | |
1420 | ; vim:set ts=8 noet nowrap | |
1421 |