]> cloudbase.mooo.com Git - avrcpm.git/blame - dsk_fsys.asm
* avr/dsk_fat16.asm
[avrcpm.git] / dsk_fsys.asm
CommitLineData
8b13b36c
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$
4f466098
L
21;
22
23
8b13b36c
FZ
24; ---------------- Defines for the Filesystem Interface -------
25
8b13b36c
FZ
26;*****************************************************
27;* Disk-Manager constants *
28;*****************************************************
c7f44b49 29 .equ dskType_None = 0
4f466098
L
30 .equ dskType_CPM = 1
31 .equ dskType_FAT = 2
32 .equ dskType_RAM = 3
8b13b36c
FZ
33
34;*****************************************************
35;* CP/M to host disk constants *
36;*****************************************************
581fb1f7 37 .equ MAXDISKS = 6 ;Max number of Disks (partitions)
8b13b36c
FZ
38 .equ PARTENTRY_SIZE = 9 ;Size of a Partitiontableentry
39 .equ blksize = 1024 ;CP/M allocation size
40 .equ hostsize = 512 ;host disk sector size
41; .equ hostspt = 20 ;host disk sectors/trk
c7f44b49
FZ
42 .equ hostblk = hostsize/128 ;CP/M sects/host buff
43; .equ CPMSPT = hostblk*hostspt ;CP/M sectors/track
44 .equ CPMSPT = 26 ;
8b13b36c 45 .equ SECMSK = hostblk-1 ;sector mask
c7f44b49 46 .equ SECSHF = log2(hostblk) ;sector shift
8b13b36c
FZ
47
48;*****************************************************
49;* BDOS constants on entry to write *
50;*****************************************************
51 .equ WRALL = 0 ;write to allocated
52 .equ WRDIR = 1 ;write to directory
53 .equ WRUAL = 2 ;write to unallocated
4f466098 54 .equ WRTMSK= 3 ;write type mask
581fb1f7
L
55
56 .equ READ_FUNC = 7
57 .equ WRITE_FUNC = 6
58 .equ BOOT_FUNC = 5
59 .equ HOME_FUNC = 4
60
8b13b36c
FZ
61;----------------------------------------------- Start of Data Segment
62
4f466098
L
63 .dseg
64
581fb1f7
L
65; The following 3 variables are copied from DRAM.
66; Don't change order.
67
68biosdrvtbl: .byte 2 ;
69biosdirbuf: .byte 2 ;
70biosenddat: .byte 2 ;
8b13b36c 71
581fb1f7 72ndisks: .byte 1 ;Number of CP/M disks
8b13b36c 73
581fb1f7
L
74; The following 5 variables are accessed from 8080/z80 via the
75; virtual port interface. Don't change order.
8b13b36c 76
581fb1f7
L
77biospar_base:
78bcbadr: .byte 2 ;adr of BiosControlBlock
79seekdsk: .byte 1 ;seek disk number
80seektrk: .byte 2 ;seek track number
81seeksec: .byte 2 ;seek sector number
82dmaadr: .byte 2 ;last dma address
8b13b36c 83
581fb1f7
L
84unacnt: .byte 1 ;unalloc rec cnt
85unadsk: .byte 1 ;last unalloc disk
86unatrk: .byte 2 ;last unalloc track
87unasec: .byte 1 ;last unalloc sector
88
89erflag: .byte 1 ;error reporting
90wrtype: .byte 1 ;write operation type
91
92hostbuf: .byte hostsize ;host buffer (from/to SD-card)
c7f44b49 93hostparttbl: .byte PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
8b13b36c 94hostparttbltop:
581fb1f7
L
95hostdsk: .byte 1 ;host disk number
96hosttype: .byte 1 ;host disk type (same entry as 1 parition entry)
97hostlba: .byte 3 ;host sector number (relative to partition start)
4f466098
L
98
99
8b13b36c 100; ------------------------------- Start of Code Segment
4f466098
L
101 .cseg
102
103; ====================================================================
581fb1f7 104; Function: Virtual Port Interface
4f466098
L
105; ====================================================================
106; Parameters
107; --------------------------------------------------------------------
581fb1f7
L
108; Registers :
109; Variables :
110;
4f466098
L
111; --------------------------------------------------------------------
112; Description:
113; ====================================================================
581fb1f7
L
114
115dsk_param_getadr:
116 ldiw z,biospar_base
117 add zl,temp3
118 adc zh,_0
119 ret
120
121dsk_param_wr:
122 rcall dsk_param_getadr
123 st z,temp
124 cpi temp3,bcbadr+1-seektrk
125 brne dsk_param_wr1
126 std z+1,_0
127dsk_param_wr1:
128 cpi temp3,bcbadr+1-biospar_base
129 breq SetBCB
130 ret
131
132dsk_param_rd:
133 cpi temp3,seekdsk-biospar_base
134 breq dskDiskCheck
135 rcall dsk_param_getadr
136 ld temp,z
8b13b36c 137 ret
4f466098 138
8b13b36c
FZ
139dskDiskCheck:
140 lds temp2,seekdsk
141 cpi temp2,RAMDISKNR
142 brsh dsk_dchrd ;maybe ramdisk
143
144; Check if selected disk # is less then # of disks.
145
146 lds temp,ndisks
581fb1f7 147 tst temp ;0 disks?
8b13b36c
FZ
148 brne dsk_dchpart1
149
581fb1f7 150; No disks yet, need to init
8b13b36c 151
581fb1f7
L
152 rcall mgr_init_partitions ;disk chanched?
153 sbrs temp,7
154 rjmp dsk_dchpart0
155 push temp
156 rcall dsk_drvtblinit
157 rcall dbg_prdrvtbl
158 pop temp
159dsk_dchpart0:
8b13b36c
FZ
160 cbr temp,0x80
161 lds temp2,seekdsk
162
163dsk_dchpart1:
164 cp temp2,temp
165 brsh dsk_dcher
581fb1f7
L
166
167 printnewline
168 printstring "Select: "
169 mov temp,temp2
170 rcall printhex
171
172 lds xl,biosdrvtbl
173 lds xh,biosdrvtbl+1
174 lsl temp2 ;drive #
175 add xl,temp2
176 adc xh,_0
177 rcall dram_readw_pp
178
179 printstring ", "
180 rcall printhexw
181
182 or temp,temp2
183 brne dsk_dchend
184 lds temp,seekdsk
185 rcall dsk_diskinit
186 brne dsk_dcher
8b13b36c
FZ
187
188dsk_dchend:
189 ldi temp,0
190 ret
191
192dsk_dchrd:
193#if RAMDISKCNT
194 cpi temp,RAMDISKNR+RAMDISKCNT
195 brlo dsk_dchend
196#endif
197dsk_dcher:
198 ldi temp,0xff ;error return
199 ret
200
201dskErrorRet:
202 lds temp,erflag
203 ret
204
581fb1f7
L
205SetBCB:
206 lds xl,bcbadr
207 mov xh,temp
208 ldiw z,biosdrvtbl
209 ldi temp3,6
210sbcb_l:
211 rcall dram_read_pp
212 st z+,temp
213 dec temp3
214 brne sbcb_l
215
216 rcall dbg_print_biosd
217 rcall dsk_drvtblinit
218
8b13b36c
FZ
219 ret
220
581fb1f7
L
221;---------------------------------------------------------------------
222
223dbg_prdrvtbl:
224 push xh
225 push xl
226 push temp3
227 push temp2
228 push temp
229 printnewline
230 printstring "drvtbl ("
231 lds xl,biosdrvtbl
232 lds xh,biosdrvtbl+1
233 movw temp,x
234 rcall printhexw
235 printstring "): "
236 ldi temp3,16
237dbg_pcpel:
238 rcall dram_readw_pp
239 rcall printhexw
240 printstring " "
241 dec temp3
242 brne dbg_pcpel
243 pop temp
244 pop temp2
245 pop temp3
246 pop xl
247 pop xh
8b13b36c 248 ret
581fb1f7
L
249
250; -------------------------------------------------------------------
251dbg_print_biosd:
252 printnewline
253 lds temp,bcbadr
254 lds temp2,bcbadr+1
255 rcall printhexw
256 printstring " "
257 lds temp,biosdrvtbl
258 lds temp2,biosdrvtbl+1
259 rcall printhexw
260 printstring " "
261 lds temp,biosdirbuf
262 lds temp2,biosdirbuf+1
263 rcall printhexw
264 printstring " "
265 lds temp,biosenddat
266 lds temp2,biosenddat+1
267 rcall printhexw
268 printstring " "
269
270 ret
271
272
273; -------------------------------------------------------------------
274
8b13b36c 275
581fb1f7
L
276 .dseg
277tmpdpb: .byte 15
278
279 .cseg
280
281; init bios disk tables.
282; leave drive 'A' out for now
283
284
285 rcall dbg_prdrvtbl
286
287 rcall dsk_drvtblinit
288 rcall dbg_prdrvtbl
289
290 lds temp,biosenddat
291 lds temp2,biosenddat+1
292 rcall heap_init
293
294 ldi temp,1
295dsk_pdil:
296 cp temp,temp2
297 brsh dsk_pdie
298 push temp2
299 push temp
300 rcall dsk_diskinit
301 pop temp
302 pop temp2
303 inc temp
304 rjmp dsk_pdil
305
306
307
308dsk_pdie:
309 mov temp,temp2
310; Test DPBs (avrcpm format)
311
312dpblist:
313;dpb243
314 .db 0x1A,0x00 ;spt
315 .db 0x03,0x07 ;block shift, bock mask
316 .db 0x00,0xF2 ;extent mask, low(disk size -1),
317 .db 0x00,0x3F ;high(disk size -1), low(dir max)
318 .db 0x00,0xC0 ;high(dir max), alloc0
319 .db 0x00,0x10 ;alloc1, low(chk size)
320 .db 0x00,0x02 ;high(chk size), low(offset)
321 .db 0x00,0x00 ;high(offset), fill
322;dpb243
323 .db 0x1A,0x00 ;spt
324 .db 0x03,0x07 ;block shift, bock mask
325 .db 0x00,0xF2 ;extent mask, low(disk size -1),
326 .db 0x00,0x3F ;high(disk size -1), low(dir max)
327 .db 0x00,0xC0 ;high(dir max), alloc0
328 .db 0x00,0x10 ;alloc1, low(chk size)
329 .db 0x00,0x02 ;high(chk size), low(offset)
330 .db 0x00,0x00 ;high(offset), fill
331;dpb243
332 .db 0x1A,0x00 ;spt
333 .db 0x03,0x07 ;block shift, bock mask
334 .db 0x00,0xF2 ;extent mask, low(disk size -1),
335 .db 0x00,0x3F ;high(disk size -1), low(dir max)
336 .db 0x00,0xC0 ;high(dir max), alloc0
337 .db 0x00,0x10 ;alloc1, low(chk size)
338 .db 0x00,0x02 ;high(chk size), low(offset)
339 .db 0x00,0x00 ;high(offset), fill
340;dpb243
341 .db 0x1A,0x00 ;spt
342 .db 0x03,0x07 ;block shift, bock mask
343 .db 0x00,0xF2 ;extent mask, low(disk size -1),
344 .db 0x00,0x3F ;high(disk size -1), low(dir max)
345 .db 0x00,0xC0 ;high(dir max), alloc0
346 .db 0x00,0x10 ;alloc1, low(chk size)
347 .db 0x00,0x02 ;high(chk size), low(offset)
348 .db 0x00,0x00 ;high(offset), fill
349#if 0
350;rd1016
351 .db 0x20,0x00 ;spt
352 .db 0x04,0x0F ;block shift, bock mask
353 .db 0x00,0xFB ;extent mask, low(disk size -1),
354 .db 0x01,0xBF ;high(disk size -1), low(dir max)
355 .db 0x00,0xE0 ;high(dir max), alloc0
356 .db 0x00,0x30 ;alloc1, low(chk size)
357 .db 0x00,0x02 ;high(chk size), low(offset)
358 .db 0x00,0x00 ;high(offset), fill
359;rd9192s
360 .db 0x20,0x00 ;spt
361 .db 0x05,0x1F ;block shift, bock mask
362 .db 0x01,0xFD ;extent mask, low(disk size -1),
363 .db 0x07,0xFF ;high(disk size -1), low(dir max)
364 .db 0x01,0xF0 ;high(dir max), alloc0
365 .db 0x00,0x80 ;alloc1, low(chk size)
366 .db 0x00,0x02 ;high(chk size), low(offset)
367 .db 0x00,0x00 ;high(offset), fill
368#endif
369
370; Test
371cpy_dpb:
372 push zh
373 push zl
374 push yh
375 push yl
376 ldiw z,dpblist*2
377 ldi temp2,16
378 mul temp,temp2
379 add zl,_tmp0
380 adc zh,_tmp1
381 ldiw y,tmpdpb
382cpydpb_l:
383 lpm temp,z+
384 st y+,temp
385 cpi yl,low(tmpdpb + 15)
386 brne cpydpb_l
387 pop yl
388 pop yh
389 pop zl
390 pop zh
8b13b36c 391 ret
581fb1f7
L
392
393; clear drive table
394; for now, only entries 1 - 3 are cleared.
395
396; ====================================================================
397; Function: Clear drive table
398; ====================================================================
399; Parameters
400; --------------------------------------------------------------------
401; Registers :
402; Variables :
403;
404; --------------------------------------------------------------------
405; Description:
406; ====================================================================
8b13b36c 407
581fb1f7
L
408; For now, only entries 1 - 3 are cleared.
409
410dsk_drvtblinit:
411 ldsw x,biosdrvtbl
412 adiw x,2
413 ldi temp3,3
414dsk_drvi_l:
415 ldi temp,0
416 ldi temp2,0
417 rcall dram_writew_pp
418 dec temp3
419 brne dsk_drvi_l
420
421 lds temp,biosenddat
422 lds temp2,biosenddat+1
423 rcall heap_init
424 clr temp
8b13b36c
FZ
425 ret
426
581fb1f7
L
427
428; ----------------------------------------------------------------------
429; Init CP/M data structures
430; temp = drive #
431;
432
433
434dsk_diskinit:
435 mov temp3,temp ;save disk #
436
437
438; Test
439 rcall cpy_dpb
440
441
442
443
444; get mem for DPH
445; -----------------------------------------------------------------
446; DPH: | XLT | | | |DIRBUF | DPB | CSV | ALV |
447; -----------------------------------------------------------------
448;(offset) 0 2 4 6 8 10 12 14
449
450 ldi temp, low (16)
451 ldi temp2,high(16)
452 rcall heap_get
453 brne dsk_di_1
454 rjmp dsk_di_err ;
455dsk_di_1:
456 movw x,temp
457 movw y,temp
458 ldi temp,0
459 ldi temp2,0
460 rcall dram_writew_pp ;XLT
461 adiw x,6
462 lds temp,biosdirbuf
463 lds temp2,biosdirbuf+1
464 rcall dram_writew_pp ;DIRBUF
465
466; get mem for DPB
467; -------------------------------------------------------------
468; DPB: | SPT |BSH|BLM|EXM| DSM | DRM |AL0|AL1| CKS | OFF |
469; -------------------------------------------------------------
470; 0 5 7 11 13
471
472 ldi temp, low (15)
473 ldi temp2,high(15)
474 rcall heap_get
475 breq dsk_di_err_p1
476 movw x,temp
477
478 ldiw z,tmpdpb
479dsk_dicpl:
480 ld temp,z+
481 rcall dram_write_pp
482 cpi zl,low(tmpdpb + 15)
483 brne dsk_dicpl
484 sbiw x,15
485 movw temp,x
486 movw x,y
487 adiw x,10
488 rcall dram_writew_pp ;DPB
489
490; get mem for dir check vector
491
492 lds temp,tmpdpb+11 ;cks
493 lds temp2,tmpdpb+11+1
494 cp temp,_0
495 cpc temp2,_0
496 breq dsk_dicks0
497 rcall heap_get
498 breq dsk_di_err_p1
499dsk_dicks0:
500 rcall dram_writew_pp ;CSV
501
502; get mem for alloc vector
503
504 lds temp,tmpdpb+5 ;dsm
505 lds temp2,tmpdpb+5+1
506 subi temp, low (-8)
507 sbci temp2,high(-8)
508 lsr temp2
509 ror temp
510 lsr temp2
511 ror temp
512 lsr temp2
513 ror temp ;(dsm+1+7)/8
514 rcall heap_get
515 breq dsk_di_err_p1
516 rcall dram_writew_pp ;ALV
517
518; success, insert DPH into drvtbl
519
520 lds xl,biosdrvtbl
521 lds xh,biosdrvtbl+1
522 lsl temp3 ;drive #
523 add xl,temp3
524 adc xh,_0
525 movw temp,y
526 rcall dram_writew_pp
527 clr temp
8b13b36c
FZ
528 ret
529
581fb1f7
L
530; error, free mem
531
532dsk_di_err_p1:
533 movw temp,y
534 rcall heap_release
535dsk_di_err:
536 ldi temp,1
537 or temp,temp
538 ret
539
540; ====================================================================
541; Function: Get a Pointer to a Partitiontable entry
542; ====================================================================
543; Parameters
544; --------------------------------------------------------------------
545; Registers : [w] z Pointer to the Partitionentry
546; [r] xl Number of Diskentry to Read
547; [w] _tmp0 scratch
548; [w] _tmp1 "
549; --------------------------------------------------------------------
550; Description:
551; ====================================================================
552dsk_getpartentry:
553
554 ldi zl,PARTENTRY_SIZE
555 mul xl,zl
556 ldiw z,hostparttbl
557 add zl,_tmp0
558 add zh,_tmp1
4f466098 559 ret
8b13b36c 560
581fb1f7 561
4f466098 562; ====================================================================
8b13b36c 563; Function: Does a Disk interaction
4f466098
L
564; ====================================================================
565; Parameters
566; --------------------------------------------------------------------
567; Registers : none
568; Variables : [r] seeksec Sector to read
569; [r] seektrk Track to read
570; --------------------------------------------------------------------
571; Description:
8b13b36c
FZ
572; ====================================================================
573dskDoIt:
574.if DISK_DEBUG
575 push temp
576 sbrc temp,READ_FUNC
577 rjmp dskdbgr
578 sbrc temp,WRITE_FUNC
579 rjmp dskdbgw
580 rjmp dskdbge
581
582dskdbgr:
583 printnewline
584 printstring "Disk read: "
585 rjmp dskdbg1
586dskdbgw:
587 printnewline
588 printstring "Disk write: "
589dskdbg1:
590 lds temp,seekdsk
591 subi temp,-('A')
592 rcall uartputc
593 printstring ": track "
594 lds temp2,seektrk+1
595 lds temp,seektrk
596 rcall printhexw
597 printstring ", sector "
598 lds temp,seeksec
599 rcall printhex
600 printstring ", dma-addr "
601 lds temp2,dmaadr+1
602 lds temp,dmaadr
603 rcall printhexw
604 pop temp
605 push temp
606 sbrs temp,WRITE_FUNC
607 rjmp dskdbge
608 printstring " wrtype "
609 andi temp,3
610 rcall printhex
611dskdbge:
612 pop temp
613.endif
614 ;See what has to be done.
615 sbrc temp,READ_FUNC
616 rjmp dsk_read
617 sbrc temp,WRITE_FUNC
618 rjmp dsk_write
619 sbrc temp,HOME_FUNC
620 rjmp dsk_home
621 sbrc temp,BOOT_FUNC
622 rjmp dsk_boot
623
624 printstring "DISK I/O: Invalid Function code: "
625 rcall printhex
626 rjmp haltinv
627
628dsk_boot:
629 sts ndisks,_0 ;no active partitions
630dsk_cboot:
631 cbi flags,hostact ;host buffer inactive
632 sts unacnt,_0 ;clear unalloc count
633 ret
634
635dsk_home:
636 sbis flags,hostwrt ;check for pending write
637 cbi flags,hostact ;clear host active flag
638 ret
8b13b36c 639
4f466098
L
640
641
642; ====================================================================
8b13b36c 643; Function: Does a Disk read operation
4f466098
L
644; ====================================================================
645; Parameters
646; --------------------------------------------------------------------
581fb1f7 647; Registers : in: temp
4f466098 648; Variables : [r] seekdsk Number of Disk to Read
581fb1f7 649; [r] seeksec Sector to read
4f466098
L
650; [r] seektrk Track to read
651; --------------------------------------------------------------------
652; Description:
8b13b36c
FZ
653; ====================================================================
654dsk_read:
655 sts erflag,_0
4f466098 656 sbi flags,readop ; Set read operation flag
581fb1f7
L
657
658 ;RAM disk?
659 lds xl,seekdsk
660#if RAMDISKCNT
661 cpi xl,RAMDISKNR
662 brlt PC+2
663 rjmp rdsk_read
664#endif
4f466098 665 rcall dsk_getpartentry ; Get Paritiontableentry
581fb1f7 666 ld temp,z ; Get Partitiontype
4f466098
L
667
668; Isn't it a Disk ?
581fb1f7 669 cpi temp,dskType_None
4f466098
L
670 brne PC+2
671 rjmp dsk_read_err
581fb1f7 672
4f466098 673; It must be a FAT16-Imagefile or CP/M Partition.
581fb1f7
L
674 sts unacnt,_0
675 sbi flags,rsflag ;must read data
676 ldi temp,WRUAL ;write type
677 sts wrtype,temp ;treat as unalloc
4f466098 678 rjmp dsk_rwoper ;to perform the read
8b13b36c 679
4f466098
L
680dsk_read_err:
681 ret
8b13b36c 682
4f466098 683; ====================================================================
8b13b36c 684; Function: Does a Disk write operation
4f466098
L
685; ====================================================================
686; Parameters
687; --------------------------------------------------------------------
581fb1f7
L
688; Registers : in: temp Write type
689; Variables : [r] seekdsk Number of Disk to Read
690; [r] seeksec Sector to read
691; [r] seektrk Track to read
4f466098
L
692; --------------------------------------------------------------------
693; Description:
8b13b36c
FZ
694; ====================================================================
695dsk_write:
696 ;write the selected sector
581fb1f7
L
697 sts erflag,_0
698 cbi flags,readop ; not a read operation
699
700 ;RAM disk?
701 lds xl,seekdsk
702#if RAMDISKCNT
703 cpi xl,RAMDISKNR
704 brlt PC+2
705 rjmp rdsk_write
706#endif
4f466098 707 rcall dsk_getpartentry ; Get Paritiontableentry
581fb1f7 708 ld temp2,z ; Get Partitiontype
4f466098
L
709
710; Isn't it a Disk ?
581fb1f7 711 cpi temp2,dskType_None
4f466098
L
712 brne PC+2
713 rjmp dsk_write_err
714
4f466098 715; It must be a FAT16-Imagefile or CP/M Partition.
8b13b36c 716
581fb1f7 717 cbi flags,readop ;not a read operation
8b13b36c
FZ
718
719 andi temp,WRTMSK
581fb1f7 720 sts wrtype,temp ;save write type
8b13b36c 721
581fb1f7 722 cpi temp,WRUAL ;write unallocated?
8b13b36c
FZ
723 brne dsk_chkuna ;check for unalloc
724
725; write to unallocated, set parameters
726 ldi temp,blksize/128 ;next unalloc recs
727 sts unacnt,temp
728 lds temp,seekdsk ;disk to seek
729 sts unadsk,temp ;unadsk = sekdsk
730 lds temp,seektrk
731 sts unatrk,temp ;unatrk = sectrk
732 lds temp,seektrk+1
733 sts unatrk+1,temp ;unatrk = sectrk
734 lds temp,seeksec
735 sts unasec,temp ;unasec = seksec
736;
737dsk_chkuna:
738 ;check for write to unallocated sector
739 lds temp,unacnt ;any unalloc remain?
740 tst temp
741 breq dsk_alloc ;skip if not
742
743; more unallocated records remain
744 dec temp ;unacnt = unacnt-1
745 sts unacnt,temp
746 lds temp,seekdsk ;same disk?
747 lds temp2,unadsk
748 cp temp,temp2 ;seekdsk = unadsk?
749 brne dsk_alloc ;skip if not
750
751; disks are the same
752 lds temp,unatrk
753 lds temp2,unatrk+1
754 lds temp3,seektrk
755 lds temp4,seektrk+1
756 cp temp,temp3 ;seektrk = unatrk?
757 cpc temp2,temp4
758 brne dsk_alloc ;skip if not
759
760; tracks are the same
761 lds temp,seeksec ;same sector?
762 lds temp2,unasec
763 cp temp,temp2 ;seeksec = unasec?
764 brne dsk_alloc ;skip if not
765
766; match, move to next sector for future ref
767 inc temp2 ;unasec = unasec+1
768 sts unasec,temp2
769 cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
770 brlo dsk_noovf ;skip if no overflow
771
772; overflow to next track
773 sts unasec,_0 ;unasec = 0
774 lds temp,unatrk
775 lds temp2,unatrk+1
776 subi temp, low(-1) ;unatrk = unatrk+1
777 sbci temp2,high(-1)
778 sts unatrk,temp
779 sts unatrk+1,temp2
780;
781dsk_noovf:
782 cbi flags,rsflag ;rsflag = 0
783 rjmp dsk_rwoper ;to perform the write
784;
785dsk_alloc:
786 ;not an unallocated record, requires pre-read
787 sts unacnt,_0 ;unacnt = 0
788 sbi flags,rsflag ;rsflag = 1
4f466098
L
789 rjmp dsk_rwoper
790
791dsk_write_err:
792 ret
793
794; ====================================================================
8b13b36c 795; Function: Does a Disk read/write operation
4f466098
L
796; ====================================================================
797; Parameters
798; --------------------------------------------------------------------
799; Registers : none
800; Variables : [r] seekdsk Number of Disk to Read
801; [r] seeksec Sector to read
802; [r] seektrk Track to read
803; --------------------------------------------------------------------
804; Description:
805; ====================================================================
806dsk_rwoper:
8b13b36c
FZ
807 ;enter here to perform the read/write
808.if DISK_DEBUG
809 printstring ", flags: "
810 in temp,flags
811 rcall printhex
812.endif
813 sts erflag,_0 ;no errors (yet)
814
815 ;Convert track/sector to an LBA address (in 128byte blocks)
816
817 lds xl,seeksec ;
818 ldi xh,0 ;
819 ldi yl,0 ;
820 lds temp3,seektrk ;
821 lds temp4,seektrk+1 ;
822 ldi temp,CPMSPT ;
823 mul temp3,temp ;
824 add xl,r0 ;
825 adc xh,r1 ;
826 mul temp4,temp ;
827 add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
828 adc yl,r1 ;
829
830 mov temp,xl
831 andi temp,SECMSK ;mask buffer number
832 push temp ;save for later
833
834 ;Convert from CP/M LBA blocks to host LBA blocks
835 ldi temp,SECSHF
836dsk_sh1:
837 lsr yl
838 ror xh
839 ror xl
840 dec temp
841 brne dsk_sh1
842 ;yl:xh:xl = host block to seek
843; active host sector?
844 in _tmp0,flags ;host active flag
845 sbi flags,hostact ;always becomes 1
846 sbrs _tmp0,hostact ;was it already?
847 rjmp dsk_filhst ;fill host if not
848
849; host buffer active, same as seek buffer?
850 lds temp,seekdsk
851 lds temp2,hostdsk ;same disk?
852 cp temp,temp2 ;seekdsk = hostdsk?
853 brne dsk_nomatch
854
855; same disk, same block?
856 lds temp,hostlba
857 lds temp2,hostlba+1
858 lds temp3,hostlba+2
859 cp xl,temp
860 cpc xh,temp2
861 cpc yl,temp3
862 breq dsk_match
863;
864dsk_nomatch:
865 ;proper disk, but not correct sector
866 sbis flags,hostwrt ;host written?
867 rjmp dsk_filhst
868 push xl
869 push xh
870 push yl
871 rcall dsk_writehost ;clear host buff
872 pop yl
873 pop xh
874 pop xl
875
876dsk_filhst:
877 ;may have to fill the host buffer
878 lds temp,seekdsk
879 sts hostdsk,temp
880 sts hostlba,xl
881 sts hostlba+1,xh
882 sts hostlba+2,yl
883
884 sbic flags,rsflag ;need to read?
885 rcall dsk_readhost ;yes, if 1
886 cbi flags,hostwrt ;no pending write
887
888dsk_match:
889
890 ;copy data to or from buffer
891 ldiw z,hostbuf
892 ldi temp,128
893 pop temp2 ;get buffer number (which part of hostbuf)
894 mul temp2,temp
895 add zl,r0 ;offset in hostbuf
4f466098 896 adc zh,r1
8b13b36c
FZ
897
898.if DISK_DEBUG > 2
899 push r0
900 push r1
901 printstring "; host buf adr: "
902 pop temp2
903 pop temp
904 rcall printhexw
905.endif
906
907 lds xl,dmaadr
908 lds xh,dmaadr+1
909 ldi temp3,128 ;length of move
910 sbic flags,readop ;which way?
911 rjmp dsk_rmove ;skip if read
912
913; mark write operation
914 sbi flags,hostwrt ;hostwrt = 1
915dsk_wmove:
916 mem_read
917 st z+,temp
918 adiw xl,1
919 dec temp3
920 brne dsk_wmove
921 rjmp dsk_rwmfin
922
923dsk_rmove:
924 ld temp,z+
925 mem_write
926 adiw xl,1
927 dec temp3
928 brne dsk_rmove
929dsk_rwmfin:
930; data has been moved to/from host buffer
931 lds temp,wrtype ;write type
932 cpi temp,WRDIR ;to directory?
933 breq dsk_wdir
934 ret ;no further processing
935dsk_wdir:
936; clear host buffer for directory write
937 lds temp,erflag
938 tst temp ;errors?
939 breq dsk_wdir1
940 ret ;skip if so
941dsk_wdir1:
942 rcall dsk_writehost ;clear host buff
943 cbi flags,hostwrt ;buffer written
4f466098
L
944 ret
945
946; ====================================================================
8b13b36c 947; Function: Does a Disk write operation
4f466098
L
948; ====================================================================
949; Parameters
950; --------------------------------------------------------------------
951; Registers : none
952; Variables : [r] seekdsk Number of Disk to Read
953; [r] seeksec Sector to read
954; [r] seektrk Track to read
955; --------------------------------------------------------------------
956; Description:
957; ====================================================================
958dsk_writehost:
959 lds xl,hostdsk
960 rcall dsk_getpartentry
961 ld temp,z
962
963#if FAT16_SUPPORT
8b13b36c 964; Is it a FAT16 Diskimage ?
4f466098
L
965 cpi temp,dskType_FAT
966 brne PC+2
967 rjmp fat_writehost
968#endif
969
8b13b36c 970; Is it a CP/M Partition ?
4f466098
L
971 cpi temp,dskType_CPM
972 brne PC+2
973 rjmp cpm_writehost
974; Disktype not supported -> Return
975 ret
976
977; ====================================================================
8b13b36c 978; Function: Does a Disk read operation
4f466098
L
979; ====================================================================
980; Parameters
981; --------------------------------------------------------------------
982; Registers : none
983; Variables : [r] seekdsk Number of Disk to Read
984; [r] seeksec Sector to read
985; [r] seektrk Track to read
986; --------------------------------------------------------------------
987; Description:
988; ====================================================================
989dsk_readhost:
990 lds xl,hostdsk
991 rcall dsk_getpartentry
992 ld temp,z
993
994#if FAT16_SUPPORT
8b13b36c 995; Is it a FAT16 Diskimage ?
4f466098
L
996 cpi temp,dskType_FAT
997 brne PC+2
998 rjmp fat_readhost
999#endif
1000
8b13b36c 1001; Is it a CP/M Partition ?
4f466098
L
1002 cpi temp,dskType_CPM
1003 brne PC+2
1004 rjmp cpm_readhost
1005; Disktype not supported -> Return
1006 ret
1007