]> cloudbase.mooo.com Git - avrcpm.git/blob - avr/dsk_fat16.asm
* New config option: SRAM_FILL
[avrcpm.git] / avr / dsk_fat16.asm
1 ; Various functions for the Interaction with the FAT16 Filesystem
2 ;
3 ; Copyright (C) 2010 Frank Zoll
4 ; Copyright (C) 2010 Sprite_tm
5 ; Copyright (C) 2010,2013 Leo C.
6 ;
7 ; This file is part of avrcpm.
8 ;
9 ; avrcpm is free software: you can redistribute it and/or modify it
10 ; under the terms of the GNU General Public License as published by
11 ; the Free Software Foundation, either version 3 of the License, or
12 ; (at your option) any later version.
13 ;
14 ; avrcpm is distributed in the hope that it will be useful,
15 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ; GNU General Public License for more details.
18 ;
19 ; You should have received a copy of the GNU General Public License
20 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
21 ;
22 ; $Id$
23 ;
24
25 ; ============================================================================
26 ; Prelimitary !
27 ; °°°°°°°°°°°°°
28 ; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation
29 ; The Functions below therefore assume a fixed Size of 512 Bytes per Sector.
30 ; ============================================================================
31
32 #if FAT16_SUPPORT
33
34
35 ; ############################################################################
36 ; Defines for FAT16 Structures
37 ; ############################################################################
38
39 /*These are the Offsets to the Variables within the Bootsector of a FAT16
40 Partition.
41 */
42 ;#define FAT16_BSO_SECSIZE 0x0b ; Offset to Sectorsize Word
43 #define FAT16_BSO_CLUSTSZ 0x0d ; Offset to Clustersize Byte
44 #define FAT16_BSO_RESSECT 0x0e ; Offset to Number of Reserved Sectors
45 #define FAT16_BSO_VOLPTR 0x1c ; Offset to First VolumeSector
46 #define FAT16_BSO_SECPERFAT 0x16 ; Offset to Number of Sectors per Fat
47 #define FAT16_BSO_NUMFATCP 0x10 ; Offset to Ammount of FAT Copys
48 #define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. entries
49
50 #define FAT16_FIRST_IMAGENAME 'A' /* First letter of filename to search */
51 #define FAT16_LAST_IMAGENAME 'Z' /* Last letter of filename to */
52 #define FAT16_IMAGENAME_PREFIX "CPMDSK_"
53 #define FAT16_IMAGENAME_SUFFIX "IMG"
54
55 ; ############################################################################
56 ; Start of Data Segment
57 ; ############################################################################
58
59 .dseg
60
61 fat_vars:
62 fat_partfound: .byte 1 ; (partition: 0= no found 0xff=found )
63 fat_parttbl: .byte 4 ; first fat16 partition entry
64 ; only startsector is needed
65 fat_clustersize: .byte 1 ; sectors per cluster
66 fat_ptr2fat: .byte 4 ; pointer to the first fat sector
67 fat_ptr2dat: .byte 4 ; pointer to the first data sector
68
69 /*These variables define a cache that holds the last Cluster and Sector
70 thats been searched vor.
71 */
72 fat_last_dsk: .byte 1 ; number of disk with entry in cache
73 fat_log_clust: .byte 2 ; last searched logical cluster
74 fat_clust_offset: .byte 1 ; offset within the cluster
75 fat_clust_ptr: .byte 4 ; sector of last real cluster
76
77 .equ o_fat_partfound = 0
78 .equ o_fat_parttbl = 1
79 .equ o_fat_clustersize = 5
80 .equ o_fat_ptr2fat = 6
81 .equ o_fat_ptr2dat = 10
82 .equ o_fat_last_dsk = 14
83 .equ o_fat_log_clust = 15
84 .equ o_fat_clust_offset= 17
85 .equ o_fat_clust_ptr = 18
86
87 .if SRAM_SIZE > 1024
88
89 fat_last_fatsect: .byte 1
90 .equ o_fat_last_fatsect = 22
91
92 fat_buf: .byte 512
93
94 .endif
95
96 ; ############################################################################
97 ; Start of Code Segment
98 ; ############################################################################
99
100 .cseg
101
102 fat_cfname: .db FAT16_IMAGENAME_PREFIX, 0
103 fat_cfext: .db FAT16_IMAGENAME_SUFFIX, 0
104
105
106 ; ============================================================================
107 ; Function: Initialize internal FAT-Partition Variables
108 ; ============================================================================
109 ; Parameters
110 ; ----------------------------------------------------------------------------
111 ; Registers : none
112 ; Variables : [out] fat_parttabl
113 ; ----------------------------------------------------------------------------
114 ; Description:
115 ; This Routine initializes the internal Variables, that point to the
116 ; first Found FAT16 Partition.
117 ; ============================================================================
118 fat_init_partitiontable:
119
120 ldiw y,fat_vars
121 std y+o_fat_partfound, _0
122 std y+o_fat_parttbl+0, _0
123 std y+o_fat_parttbl+1, _0
124 std y+o_fat_parttbl+2, _0
125 std y+o_fat_parttbl+3, _0
126 ret
127
128
129 ; ============================================================================
130 ; Function: Resets the Cache
131 ; ============================================================================
132 ; Parameters
133 ; ----------------------------------------------------------------------------
134 ; Registers : none
135 ; Variables : [out] fat_log_clust
136 ; [out] fat_last_dsk
137 ; ----------------------------------------------------------------------------
138 ; Description:
139 ; This Routine resets the internal Cache- Variables. After reset, the
140 ; next read or write Command will initialize a scan of the FAT of
141 ; the FAT16-Partition for the given sector.
142 ; ============================================================================
143 fat_reset_cache:
144 ldiw y,fat_vars
145 std y+o_fat_log_clust ,_255
146 std y+o_fat_log_clust+1,_255
147 std y+o_fat_last_dsk ,_255
148 .if SRAM_SIZE > 1024
149 std y+o_fat_last_fatsect,_255
150 .endif
151
152 ret
153
154 ; ============================================================================
155 ; Function: Saves FAT16 Partitiondata for later Scanning
156 ; ============================================================================
157 ; Parameters
158 ; ----------------------------------------------------------------------------
159 ; Registers : [in] z Pointer to the Partitondata
160 ; Variables : [out] fat_partfound Boolean for "Partition found"
161 ; [out] fat_parttbl Pointer to Partitiontable
162 ; ----------------------------------------------------------------------------
163 ; Description:
164 ; This funktion sets the internal Variables to the Start and Size
165 ; of a given FAT16 Paritition. This Information will be used for a
166 ; later scanning of the Partition. See Function "fat_scan_partition"
167 ; for more information.
168 ; ============================================================================
169
170 fat_add_partition:
171
172 .if FAT16_DEBUG > 0
173 printstring "fat16 part found"
174 printnewline
175 .endif
176
177 ldiw y,fat_vars
178
179 ; set fat16 partition found flag
180
181 std y+o_fat_partfound,_255
182
183 ; save data from first fat16 partition
184
185 ldd temp,z+PART_START
186 std y+o_fat_parttbl,temp
187 ldd temp,z+PART_START+1
188 std y+o_fat_parttbl+1,temp
189 ldd temp,z+PART_START+2
190 std y+o_fat_parttbl+2,temp
191 ldd temp,z+PART_START+3
192 std y+o_fat_parttbl+3,temp
193
194 ret
195
196 ; ============================================================================
197 ; Read and Scann a FAT16 Partition for Imagedatefiles
198 ; ============================================================================
199 ; Registers : none
200 ; Variables : none
201 ; ----------------------------------------------------------------------------
202 ; This Routine reads the Bootblock and scanns it for a Diskimage
203 ; ============================================================================
204
205
206 fat_scan_partition:
207
208 .if FAT16_DEBUG > 0
209 printstring "fat16 scanning"
210 printnewline
211 .endif
212
213 ; Check if a FAT16 Partition was realy found
214 lds yl,fat_partfound
215 cpi yl,0
216 breq fat_scan_error
217
218
219 .if FAT16_DEBUG > 0
220 printstring "free entries in ptable ?"
221 printnewline
222 .endif
223
224 ; Check for free entries in partition table
225 lds yl,ndisks
226 cpi yl,MAXDISKS
227 brge fat_scan_error
228
229 .if FAT16_DEBUG > 0
230 printstring "read fat bootblock."
231 printnewline
232 .endif
233
234 ; Scan partition start
235 ldiw z,fat_parttbl
236 ldd xl,z+0
237 ldd xh,z+1
238 ldd yl,z+2
239 ldd yh,z+3
240 ldiw z,hostbuf
241
242 ; Load first sector from Partition
243 rcall mmcReadSect
244 tst temp
245 breq fat_bootblock_check
246
247 ; Read error: Block not found
248 fat_scan_error:
249 clr temp
250 ret
251
252 fat_bootblock_check:
253
254 .if FAT16_DEBUG > 0
255 printstring "fat16 bootblock check"
256 printnewline
257 .endif
258
259 ldiw y,fat_vars
260 ldiw z,hostbuf
261
262 ; get sectors per cluster from bootblock
263 ldd temp,z+FAT16_BSO_CLUSTSZ
264 std y+o_fat_clustersize,temp
265
266 .if FAT16_DEBUG > 0
267 printstring "Sectors per Cluster "
268 lcall printhex
269 printnewline
270 .endif
271
272 ; get max num of entries in root direktory from bootblock
273 ldd temp ,z+FAT16_BSO_NUMDIRENT
274 ldd temp2,z+FAT16_BSO_NUMDIRENT+1
275
276 .if FAT16_DEBUG > 0
277 printstring "Max. entries in rootdir.: "
278 lcall printhexw
279 .endif
280
281 ; Calculate begin of DATA Clusters within the Volume
282 ; Num. Dir.Sektors = (Num. of Dir. entries * 32) / Bytes per Sektor
283
284 ; Sectorsize is fixed at 512 bytes, makes 16 entries per sector
285
286
287 ; Num. Direntries / 16
288 lsr temp2
289 ror temp
290 lsr temp2
291 ror temp
292 lsr temp2
293 ror temp
294 lsr temp2
295 ror temp
296
297 push temp ;save # of rootdir sectors
298
299 .if FAT16_DEBUG > 0
300 printstring " ("
301 movw temp,_tmp0
302 lcall printhex
303 printstring " sectors)"
304 printnewline
305 .endif
306
307 .if FAT16_DEBUG > 1
308 ; Print begin of Volume
309 printstring "Begin of Volume at: "
310 ldd temp, y+o_fat_parttbl+2
311 ldd temp2,y+o_fat_parttbl+3
312 lcall printhexw
313 ldd temp, y+o_fat_parttbl+0
314 ldd temp2,y+o_fat_parttbl+1
315 lcall printhexw
316 printnewline
317 .endif
318
319 ; get num of reseved sectors from bootblock
320 ldd _tmp0,z+FAT16_BSO_RESSECT
321 ldd _tmp1,z+FAT16_BSO_RESSECT+1
322
323 ; Calculate begin of FAT within the Volume
324 ldd xl,y+o_fat_parttbl+0
325 ldd xh,y+o_fat_parttbl+1
326 ldd temp,y+o_fat_parttbl+2
327 ldd temp2,y+o_fat_parttbl+3
328
329 add xl,_tmp0
330 adc xh,_tmp1
331 adc temp,_0
332 adc temp2,_0
333
334 std y+o_fat_ptr2fat ,xl
335 std y+o_fat_ptr2fat+1,xh
336 std y+o_fat_ptr2fat+2,temp
337 std y+o_fat_ptr2fat+3,temp2
338
339 .if FAT16_DEBUG > 1
340 printstring "Begin of FAT at___: "
341 lcall printhexw
342 movw temp ,x
343 lcall printhexw
344 printnewline
345 .endif
346
347 ; get num of sectors per FAT-Table from bootblock
348 ldd temp, z+FAT16_BSO_SECPERFAT
349 ldd temp2,z+FAT16_BSO_SECPERFAT+1
350
351 .if FAT16_DEBUG > 0
352 printstring "Sectors per FAT___: "
353 lcall printhexw
354 printnewline
355 .endif
356
357 ; get num of FAT Tables from bootblock
358 ldd temp3,z+FAT16_BSO_NUMFATCP
359
360 .if FAT16_DEBUG > 0
361 printstring "Ammount of FAT copies: "
362 push temp
363 mov temp,temp3
364 lcall printhex
365 pop temp
366 printnewline
367 .endif
368
369 movw _tmp0,temp
370
371 ; Calculate begin of Root- Directory within the Volume
372
373 ldd xl, y+o_fat_ptr2fat+0
374 ldd xh, y+o_fat_ptr2fat+1
375 ldd temp, y+o_fat_ptr2fat+2
376 ldd temp2,y+o_fat_ptr2fat+3
377
378 fat_calc_dp_loop:
379 cp temp3,_0
380 breq fat_calc_dp_lend
381
382 add xl,_tmp0
383 adc xh,_tmp1
384 adc temp,_0
385 adc temp2,_0
386 dec temp3
387 rjmp fat_calc_dp_loop
388
389 fat_calc_dp_lend:
390
391 .if FAT16_DEBUG > 1
392 printstring "Begin of DIR at___: "
393 lcall printhexw
394 push temp2
395 push temp
396 movw temp,x
397 lcall printhexw
398 pop temp
399 pop temp2
400 printnewline
401 .endif
402
403 pop temp3 ;number of rootdir sectors
404
405 add xl,temp3
406 adc xh,_0
407 adc temp,_0
408 adc temp2,_0
409
410 std y+o_fat_ptr2dat ,xl
411 std y+o_fat_ptr2dat+1,xh
412 std y+o_fat_ptr2dat+2,temp
413 std y+o_fat_ptr2dat+3,temp2
414
415 .if FAT16_DEBUG > 1
416 printstring "Begin of Data at__: "
417 lcall printhexw
418 movw temp ,x
419 lcall printhexw
420 printnewline
421 .endif
422
423 ;-------------------------------------------------------------------------------
424 ; Here starts the scan of the directory for valid image files.
425
426
427 fat_next_sector_loop:
428
429 ; Get a pointer to the last+1 directory sector
430 lds xl,fat_ptr2dat
431 lds xh,fat_ptr2dat+1
432 lds yl,fat_ptr2dat+2
433 lds yh,fat_ptr2dat+3
434
435 ; Add actual offset
436 sub xl,temp3
437 sbc xh,_0
438 sbc yl,_0
439 sbc yh,_0
440
441 ; Load sector from Directory
442 ldiw z,hostbuf
443 lcall mmcReadSect
444 tst temp
445 breq fat_look_for_images
446
447 ; Read error: Block not found
448 clr temp
449 ret
450
451 ; Looks at a read directory block for image entries
452 fat_look_for_images:
453
454 ldiw x,hostbuf
455
456 fat_look_for_loop:
457
458 movw y,x
459 ldiw z,fat_cfname*2
460 ldi temp2,STRLEN(FAT16_IMAGENAME_PREFIX)
461 lcall strncmp_p
462 brne fat_look_continue
463
464 adiw y,1
465 adiw z,1
466 ldi temp2,STRLEN(FAT16_IMAGENAME_SUFFIX)
467 lcall strncmp_p
468 brne fat_look_continue
469
470 movw y,x
471 ldd temp2,y+STRLEN(FAT16_IMAGENAME_PREFIX)
472 ldi temp,FAT16_FIRST_IMAGENAME
473 fat_look_imgname_loop:
474 cp temp,temp2
475 breq fat_look_imgname_match
476 inc temp
477 cpi temp,FAT16_LAST_IMAGENAME+1
478 brlo fat_look_imgname_loop
479 rjmp fat_look_continue
480
481 fat_look_imgname_match:
482 rcall fat_store_new_entry
483 movw x,y
484
485 fat_look_continue:
486
487 adiw x,32
488 ldi temp,high(hostbuf+HOSTSIZE)
489 cpi xl,low(hostbuf+HOSTSIZE)
490 cpc xh,temp
491 brne fat_look_for_loop
492
493 fat_scan_next_sector:
494
495 dec temp3
496 brne fat_next_sector_loop
497
498 ret
499
500
501
502 #if 0
503 dbg_print_parttbl_raw:
504 push zh
505 push zl
506 push temp2
507 push temp
508 ldiw z,hostparttbl
509 dbg_pptblraw_lp:
510 lcall dbg_hexdump_line
511 adiw z,PARTENTRY_SIZE
512 cpi zl,low(hostparttbltop)
513 ldi temp,high(hostparttbltop)
514 cpc zh,temp
515 brne dbg_pptblraw_lp
516 pop temp
517 pop temp2
518 pop zl
519 pop zh
520 ret
521 #endif
522
523 ;-------------------------------------------------------------------------------
524 ; Create new Partition Entry
525 ; ============================================================================
526 ; Function: Create new Partition Entry
527 ; ============================================================================
528 ; Parameters: [in] yh,yl Directory entry
529 ;
530 ; ----------------------------------------------------------------------------
531 ; Registers :
532 ; Variables : [used]
533 ; [changes] temp
534 ; ----------------------------------------------------------------------------
535 ; Description:
536 ;
537 ; ============================================================================
538
539 fat_store_new_entry:
540
541 ; Found a valid image
542 .if FAT16_DEBUG > 1
543 printnewline
544 printstring "Found a valid Image! Y="
545 push temp2
546 push temp
547 movw temp ,y
548 lcall printhexw
549 pop temp
550 pop temp2
551 printnewline
552 .endif
553
554 #if 0
555 ;;;;
556 printstring "Insert entry in Tab: --> "
557 mov temp,temp2
558 lcall uartputc
559 printnewline
560 printstring "Tab before:"
561
562 rcall dbg_print_parttbl_raw
563 printnewline
564 ;;;;
565 #endif
566 ldiw z,hostparttbl
567
568 fat_st_searchpos:
569 ldd temp,z+PTAB_TYPE
570 tst temp
571 breq fat_st_insert_slot
572 sbrs temp,log2(dskType_FAT)
573 rjmp fat_st_search_next
574
575 ldd temp,z+PTAB_START+2
576 cp temp2,temp
577 brlo fat_st_ins_before
578
579 fat_st_search_next:
580 adiw z,PARTENTRY_SIZE
581 cpi zl,low(hostparttbltop)
582 ldi temp,high(hostparttbltop)
583 cpc zh,temp
584 brne fat_st_searchpos
585
586 ; Table is full.
587 #if 0
588 ;;;;
589 push temp2
590 push temp
591 printstring "Table is full. --> ptr: "
592 movw temp,z
593 lcall printhexw
594 printnewline
595 pop temp
596 pop temp2
597 ;;;;
598 #endif
599 ret
600
601 fat_st_ins_before:
602 movw x,z
603 ldiw z,hostparttbltop-PARTENTRY_SIZE
604 fat_st_insert_mkslotloop:
605 cp zl,xl
606 cpc zh,xh
607 breq fat_st_insert_slot
608
609 ld _tmp0,-z
610 std z+PARTENTRY_SIZE,_tmp0
611 rjmp fat_st_insert_mkslotloop
612
613 fat_st_insert_slot:
614
615 ; Set Type of Partition to FAT16- Fileimage
616 ldi temp,dskType_FAT
617 std z+PTAB_TYPE,temp
618
619 ; Offset to Startcluster + 2
620 ldd _tmp0,y+0x1A
621 ldd _tmp1,y+0x1B
622 std z+PTAB_START, _tmp0
623 std z+PTAB_START+1,_tmp1
624
625 std z+PTAB_START+2,temp2
626 std z+PTAB_START+3,_0
627
628 ; Convert Filesize to ammount of sectors
629 ; (calc with 512byte/sector)
630 ldd _tmp0,y+0x1C
631 ldd xl, y+0x1D
632 ldd xh, y+0x1E
633 ldd temp, y+0x1F
634
635 clc
636 cpse _tmp0,_0 ;round up
637 adiw x,1
638 adc temp,_0
639
640 lsr temp
641 ror xh
642 ror xl
643
644 adc xl,_0
645 adc xh,_0
646 adc temp,_0
647
648 ; store ammount of sectors in partitiontable
649
650 tst temp ;file size larger than 65535 sectors?
651 breq fat_add_noprune
652
653 ldi xl,255
654 ldi xh,255
655 fat_add_noprune:
656 std z+PTAB_SIZE, xl
657 std z+PTAB_SIZE+1,xh
658
659 .if FAT16_DEBUG > 1
660 ; Test finding of the first sector
661
662 push yh
663 push yl
664 ldd xl,z+1
665 ldd xh,z+2
666
667 rcall fat_gethostsec
668
669 printstring "Begin of image at: "
670 movw temp ,y
671 lcall printhexw
672 movw temp ,x
673 lcall printhexw
674 printnewline
675 pop yl
676 pop yh
677 .endif
678
679
680 ; Table counts one more entry if it was'nt allready full
681
682 lds temp,ndisks
683 cpi temp,MAXDISKS
684 breq fat_add_nomore
685 inc temp
686 sts ndisks,temp
687
688 fat_add_nomore:
689
690 #if 0
691 ;;;;
692 printnewline
693 printstring "Table now:"
694 rcall dbg_print_parttbl_raw
695 printnewline
696 ;;;;
697 #endif
698 ret
699
700
701 ; ============================================================================
702 ; Function: Cluster to HostSector
703 ; ============================================================================
704 ; Registers: [in] xl,xh Cluster Number
705 ; [out] yh,yl,xh,xl Sector Number on Disk
706 ; Variables: [in] fat_clustersize Ammount of Sectors per Cluster
707 ; [out] temp =0
708 ; ----------------------------------------------------------------------------
709 ; Description:
710 ; Calculates the logical Sectornumber given the physical ClusterNumber
711 ; and the size of a Cluster un sectors.
712 ;
713 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
714 ; ============================================================================
715 fat_gethostsec:
716
717 ldiw y,fat_vars
718
719 ; Get Offset into Data area of Disk
720
721 clr _tmp0
722 clr _tmp1
723 sbiw x,2 ; Substract the 2 reserved clusters
724
725 ldd temp,y+o_fat_clustersize
726 lsr temp
727 fat_c2s_loop:
728 tst temp
729 breq fat_c2s_end
730 lsr temp
731
732 lsl xl
733 rol xh
734 rol _tmp0
735 rol _tmp1
736 rjmp fat_c2s_loop
737 fat_c2s_end:
738
739 ; Add begin of data area to offset
740
741 ldd temp,y+o_fat_ptr2dat+0
742 add xl,temp
743 ldd temp,y+o_fat_ptr2dat+1
744 adc xh,temp
745 ldd temp,y+o_fat_ptr2dat+2
746 adc _tmp0,temp
747 ldd temp,y+o_fat_ptr2dat+3
748 adc _tmp1,temp
749 movw y,_tmp0
750
751 ret
752
753 ; ====================================================================
754 ; Function: Searches a physical Cluster, given the logical Cluster
755 ; ====================================================================
756 ; Registers: [in] xh,xl logical- Cluster
757 ; [out] yh,yl physical- Cluster
758 ; Variables:
759 ; --------------------------------------------------------------------
760 ; Description:
761 ; ====================================================================
762 fat_find_phsy_clust:
763 lds zl,hostdsk
764 rcall dsk_getpartentry ; get partition entry
765
766 ; Get First FAT- Cluster Number of Diskimage
767
768 ldd yl,z+1
769 ldd yh,z+2
770
771 .if FAT16_DBG_FAT > 0
772 printstring "Search log. cluster "
773 movw temp,x
774 lcall printhexw
775 printnewline
776
777 printstring "Search phys. cluster "
778 movw temp ,y
779 lcall printhexw
780 printnewline
781 .endif
782
783 fat_next_phsy_clust:
784 cp xl,_0
785 cpc xh,_0
786 ; breq fat_found_phsy_clust
787 brne PC+2
788 rjmp fat_found_phsy_clust
789
790 ; Get Next Cluster from Fat
791
792 ; Trick: 512 Bytes Per Sector equals to 256 FAT- entries per Sector
793 ; so given: yl is the Offset within the FAT Sector
794 ; yh is the number off the FAT sector to Read
795
796 ; in zh,zl: Pointer to Word within the Sector to read
797 ; in yh..xl: Start sector number (LBA)
798 ; out zh,zl : word thats been read
799
800 push xl
801 push xh
802
803 ; Create FAT Offset Value
804
805 clr zh
806 mov zl,yl
807 lsl zl
808 rol zh
809 mov temp,yh
810
811 .if SRAM_SIZE > 1024
812
813 ; Check, if required fat sector allready in buffer
814
815 lds temp2,fat_last_fatsect
816 sts fat_last_fatsect,temp
817 cp temp,temp2
818 breq fat_phys_1
819
820 ; Not in buffer, get fat sector
821
822 lds xl,fat_ptr2fat ;get FAT start
823 lds xh,fat_ptr2fat+1
824 lds yl,fat_ptr2fat+2
825 lds yh,fat_ptr2fat+3
826 add xl,temp ;add cluster offset within sector
827 adc xh,_0
828 adc yl,_0
829 adc yh,_0
830 .if 0
831 printnewline
832 printstring "Read FAT sec: "
833 lcall printhex
834 printstring ", "
835 movw temp,z
836 lcall printhexw
837 printstring " "
838 .endif
839 push zl
840 push zh
841 ldiw z,fat_buf
842 lcall mmcReadSect
843 pop zh
844 pop zl
845
846 fat_phys_1:
847 ldiw y,fat_buf
848 add zl,yl
849 adc zh,yh
850 ldd yl,z+0
851 ldd yh,z+1
852 .else
853
854 lds xl,fat_ptr2fat ;get FAT start
855 lds xh,fat_ptr2fat+1
856 lds yl,fat_ptr2fat+2
857 lds yh,fat_ptr2fat+3
858 add xl,temp ;add cluster offset within sector
859 adc xh,_0
860 adc yl,_0
861 adc yh,_0
862 lcall mmcReadWord
863 movw y,z
864 .endif
865 pop xh
866 pop xl
867
868
869 ; Check next logical Cluster
870
871 sbiw x,1
872 rjmp fat_next_phsy_clust
873
874 ; Found the physical cluster
875 fat_found_phsy_clust:
876
877 .if FAT16_DBG_FAT > 0
878 printstring "Found phys. Cluster at:"
879 movw temp,y
880 lcall printhexw
881 printnewline
882 .endif
883
884 ret
885
886 ; ============================================================================
887 ; Function: This Routine searches for the Sector within an Imagefile
888 ; ============================================================================
889 ; Registers: [out] xl,xh,yl,yh Pointer to the sector on the SD-Card
890 ; [out] temp Error variable (0= No Error)
891 ; Variables: [in] hostdsk host disk #, (partition #)
892 ; [in] hostlba host block #, relative to part.start
893 ; [in] fat_last_dsk number of disk with entry in cache
894 ; [in] fat_log_clust last searched logical cluster
895 ; [in] fat_clust_offset offset within the cluster
896 ; [in] fat_clust_ptr sector of last real cluster
897 ; ----------------------------------------------------------------------------
898 ; Description:
899 ; This routine uses the variables hostdsk and hostlba to find an sector
900 ; in the imagefile.
901 ; The CP/M sector given within "hostlba" are splited to a logical cluster-
902 ; number and the subsector within this logical cluster.
903 ; logical cluster number = hostlba / fat_clustersize
904 ; The logical cluster number will be compared to the logical cluster number
905 ; within the cache. When this clusters are the same and the diskid's are
906 ; also the same, then the cached physical sector will be used.
907 ; When the clusters or the disks don't match, a seek for the physical
908 ; cluster is performed. This seek is done thru an access over the fat of
909 ; the fat16 partition. the routine starts at the first cluster of the
910 ; imagefile and goes along the linked list of clusternumber till it reaches
911 ; the searched cluster. The found clusternumber will be used to calculate
912 ; the sektor where this cluster lies on the sd card. Both the found physical
913 ; cluster and the logical cluster together with the physical sectornumber
914 ; are stored in the cache.
915 ; The last step done is to add the subsectoroffset to the found physical
916 ; sector. this gives the pointer to the sector to be read and or written.
917 ; ============================================================================
918
919
920 fat_lba_to_phys:
921
922 ; ################# Get logical Number of Cluster within the imagefile
923 ; printstring "calc log sector"
924 ; Logical Sectornumber in x
925 movw temp,x
926 mov yl,_0
927 mov yh,_0
928 ; Divide logical Sectornumber by size of Cluster in sectors
929 lds zl,fat_clustersize
930 lsr zl
931 fat_search_clst_lp:
932 tst zl
933 breq fat_found_clst
934
935 lsr yh
936 ror yl
937 ror xh
938 ror xl
939
940 lsr zl
941
942 rjmp fat_search_clst_lp
943
944 fat_found_clst:
945 ; at this point xh and xl are carying the logical cluster number
946 ; printstring "find subsector"
947 ; ################# Get subsector within the logical cluster for later use
948 mov yl,xl
949 lds zl,fat_clustersize
950 lsr zl
951 fat_search_clst_lp2:
952 tst zl
953 breq fat_found_subsec
954 lsl yl
955
956 lsr zl
957 rjmp fat_search_clst_lp2
958
959 fat_found_subsec:
960 mov zl,temp
961 sub zl,yl
962 sts fat_clust_offset,zl
963
964 ; Check against last HOSTDISK searched
965 lds yl,fat_last_dsk
966 lds yh,hostdsk
967 cp yl,yh
968 brne fat_wrong_cache_clst
969
970 ; Check against last Cluster searched
971 lds yl,fat_log_clust
972 lds yh,fat_log_clust+1
973
974 cp yl,xl
975 cpc yh,xh
976 brne fat_wrong_cache_clst
977
978 ; Last Cluster = searched Cluster -> get Sectornumber from cache
979 lds xl,fat_clust_ptr
980 lds xh,fat_clust_ptr+1
981 lds yl,fat_clust_ptr+2
982 lds yh,fat_clust_ptr+3
983
984 rjmp fat_add_offset
985
986 ; Cluster is not in cache, so we must search for it
987 fat_wrong_cache_clst:
988 lds yl,hostdsk
989 sts fat_last_dsk,yl
990 sts fat_log_clust,xl
991 sts fat_log_clust+1,xh
992
993 ; Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
994 rcall fat_find_phsy_clust
995
996 ; Get StartSector of "physical" Cluster
997 movw x,y
998 rcall fat_gethostsec
999
1000 ; Found the physical sector
1001 .if FAT16_DBG_FAT > 0
1002 printstring "Found phys. Sector at:"
1003 movw temp,y
1004 lcall printhexw
1005 movw temp,x
1006 lcall printhexw
1007 printnewline
1008 .endif
1009
1010 ; Save the found Sector for later use into cache
1011 sts fat_clust_ptr ,xl
1012 sts fat_clust_ptr+1,xh
1013 sts fat_clust_ptr+2,yl
1014 sts fat_clust_ptr+3,yh
1015
1016 ; Add- Subsector to Startsector
1017 fat_add_offset:
1018 lds zl,fat_clust_offset
1019 add xl,zl
1020 adc xh,_0
1021 adc yl,_0
1022 adc yh,_0
1023
1024 ; Found the physical sector
1025 .if FAT16_DBG_FAT > 0
1026 printstring "Sector with Offset at:"
1027 movw temp,y
1028 lcall printhexw
1029 movw temp,x
1030 lcall printhexw
1031 printnewline
1032 .endif
1033
1034 ret
1035
1036 #endif /* FAT16_SUPPORT */
1037
1038 ; vim:set ts=8 noet nowrap
1039