]> cloudbase.mooo.com Git - avrcpm.git/blob - dsk_fat16.asm
4d2683d7b247e057f8cdd9a27c9b83508154d88c
[avrcpm.git] / 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 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 #define PARTID_FAT16 0x0E
40
41 /*These are the Offsets to the Variables within the Bootsector of a FAT16
42 Partition.
43 */
44 ;#define FAT16_BSO_SECSIZE 0x0b ; Offset to Sectorsize Word
45 #define FAT16_BSO_CLUSTSZ 0x0d ; Offset to Clustersize Byte
46 #define FAT16_BSO_RESSECT 0x0e ; Offset to Number of Reserved Sectors
47 #define FAT16_BSO_VOLPTR 0x1c ; Offset to First VolumeSector
48 #define FAT16_BSO_SECPERFAT 0x16 ; Offset to Number of Sectors per Fat
49 #define FAT16_BSO_NUMFATCP 0x10 ; Offset to Ammount of FAT Copys
50 #define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. Entrys
51 #define FAT16_FIRST_IMAGENAME 'A' ; First letter of filename to search
52 #define FAT16_LAST_IMAGENAME 'Z' ; Last letter of filename to search
53
54 ; ############################################################################
55 ; Start of Data Segment
56 ; ############################################################################
57 .dseg
58
59 fat_partfound: .byte 1 ; (partition: 0= no found 1=found )
60 fat_parttbl: .byte 4 ; first fat16 partition entry
61 ; only startsector is needed
62 fat_clustersize: .byte 1 ; sectors per cluster
63 fat_numdirentrys:.byte 2 ; Max. num. of entrys within Rootdirektory
64 fat_ptr2fat: .byte 4 ; pointer to the first fat sector
65 fat_ptr2dat: .byte 4 ; pointer to the first data sector
66
67 /*These variables define a cache that holds the last Cluster and Sector
68 thats been searched vor. To save some of the valuabe SRAM- Space these
69 variables also are used as temporary variables by the function
70 fat_scan_partition.
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
78 ; ############################################################################
79 ; Start of Code Segment
80 ; ############################################################################
81 .cseg
82
83 ; ============================================================================
84 ; Function: Initialize internal FAT-Partition Variables
85 ; ============================================================================
86 ; Parameters
87 ; ----------------------------------------------------------------------------
88 ; Registers : none
89 ; Variables : [out] fat_parttabl
90 ; ----------------------------------------------------------------------------
91 ; Description:
92 ; This Routine initializes the internal Variables, that point to the
93 ; first Found FAT16 Partition.
94 ; ============================================================================
95 fat_init_partitiontable:
96
97 sts fat_partfound,_0
98
99 ldiw y,fat_parttbl
100 st y+,_0
101 st y+,_0
102 st y+,_0
103 st y+,_0
104 st y+,_0
105 st y+,_0
106 st y+,_0
107 st y+,_0
108 ret
109
110 ; ============================================================================
111 ; Function: Resets the Cache
112 ; ============================================================================
113 ; Parameters
114 ; ----------------------------------------------------------------------------
115 ; Registers : none
116 ; Variables : [out] fat_log_clust
117 ; [out] fat_last_dsk
118 ; ----------------------------------------------------------------------------
119 ; Description:
120 ; This Routine resets the internal Cache- Variables. After reset, the
121 ; next read or write Command will initialize a scan of the FAT of
122 ; the FAT16-Partition for the given sector.
123 ; ============================================================================
124 fat_reset_cache:
125 push yl
126 ldi yl,0xFF
127 sts fat_log_clust ,yl
128 sts fat_log_clust+1,yl
129 sts fat_last_dsk ,yl
130 pop yl
131 ret
132
133 ; ============================================================================
134 ; Function: Saves FAT16 Partitiondata for later Scanning
135 ; ============================================================================
136 ; Parameters
137 ; ----------------------------------------------------------------------------
138 ; Registers : [in] z Pointer to the Partitondata
139 ; Variables : [out] fat_partfound Boolean for "Partition found"
140 ; [out] fat_parttbl Pointer to Partitiontable
141 ; ----------------------------------------------------------------------------
142 ; Description:
143 ; This funktion sets the internal Variables to the Start and Size
144 ; of a given FAT16 Paritition. This Information will be used for a
145 ; later scanning of the Partition. See Function "fat_scan_partition"
146 ; for more information.
147 ; ============================================================================
148 fat_add_partition:
149
150 .if FAT16_DEBUG > 0
151 printstring "fat16 part found",0
152 printnewline
153 .endif
154
155
156 ; save variables on stack
157 push yl
158 push yh
159
160 ; set fat16 partition found flag
161 ldi yl,1
162 sts fat_partfound,yl
163
164 ; save data from first fat16 partition
165 ldiw y,fat_parttbl
166
167 ldd temp,z+PART_START
168 st y+,temp
169 ldd temp,z+PART_START+1
170 st y+,temp
171 ldd temp,z+PART_START+2
172 st y+,temp
173 ldd temp,z+PART_START+3
174 st y+,temp
175
176 ; Don't need the Size of the Partition for use with Imagefiles
177 ; ldd temp,z+PART_SIZE
178 ; st y+,temp
179 ; ldd temp,z+PART_SIZE+1
180 ; st y+,temp
181 ; ldd temp,z+PART_SIZE+2
182 ; st y+,temp
183 ; ldd temp,z+PART_SIZE+3
184 ; st y+,temp
185
186
187 ; reload variables from stack
188 pop yh
189 pop yl
190
191 ret
192
193 ; ============================================================================
194 ; Read and Scann a FAT16 Partition for Imagedatefiles
195 ; ============================================================================
196 ; Registers : none
197 ; Variables : none
198 ; ----------------------------------------------------------------------------
199 ; This Routine reads the Bootblock and scanns it for a Diskimage
200 ; ============================================================================
201
202
203 fat_scan_partition:
204
205 .if FAT16_DEBUG > 0
206 printstring "fat16 scanning",0
207 printnewline
208 .endif
209
210 ; Check if a FAT16 Partition was realy found
211 lds yl,fat_partfound
212 cpi yl,1
213 brne fat_scan_error
214
215
216 .if FAT16_DEBUG > 0
217 printstring "free entrys in ptable ?",0
218 printnewline
219 .endif
220
221 ; Check for free Entrys in Partition table
222 lds yl,ndisks
223 cpi yl,MAXDISKS
224 breq fat_scan_error
225
226 .if FAT16_DEBUG > 0
227 printstring "read fat bootblock.",0
228 printnewline
229 .endif
230
231 ; Scan partition start
232 ldiw z,fat_parttbl
233 ldd xl,z+0
234 ldd xh,z+1
235 ldd yl,z+2
236 ldd yh,z+3
237
238 ; Load first sector from Partition
239 rcall mmcReadSect
240 tst temp
241 breq fat_bootblock_check
242
243 ; Read error: Block not found
244 fat_scan_error:
245 clr temp
246 ret
247
248 fat_bootblock_check:
249
250 .if FAT16_DEBUG > 0
251 printstring "fat16 bootblock check",0
252 printnewline
253 .endif
254
255 ; get sectors per cluster from bootblock
256 ldiw z,hostbuf+FAT16_BSO_CLUSTSZ
257 ld temp,z
258 sts fat_clustersize,temp
259
260 .if FAT16_DEBUG > 0
261 printstring "Sectors per Cluster ",0
262 rcall printhex
263 printnewline
264 .endif
265
266 ; get num of FAT Tables from bootblock
267 ldiw z,hostbuf+FAT16_BSO_NUMFATCP
268 ld temp,z
269 sts fat_last_dsk,temp ; low byte
270
271 .if FAT16_DEBUG > 0
272 printstring "Ammount of FAT copies: ",0
273 rcall printhex
274 printnewline
275 .endif
276
277 ; get max num of entrys in root direktory from bootblock
278 ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
279 ld temp,z+
280 sts fat_numdirentrys,temp ; low byte
281 ld temp2,z
282 sts fat_numdirentrys+1,temp2 ; high byte
283
284 .if FAT16_DEBUG > 0
285 printstring "Max. entrys in Rootdir.: ",0
286 rcall printhexw
287 printnewline
288 .endif
289
290 ; Print begin of Volume
291 .if FAT16_DEBUG > 1
292
293 ldiw z,fat_parttbl
294 ldd xl,z+0
295 ldd xh,z+1
296 ldd yl,z+2
297 ldd yh,z+3
298
299 printstring "Begin of Volume at: ",0
300 mov temp ,yl
301 mov temp2,yh
302 rcall printhexw
303 mov temp ,xl
304 mov temp2,xh
305 rcall printhexw
306 printnewline
307 .endif
308
309 ; get num of sectors per FAT-Table from bootblock
310 ldiw z,hostbuf+FAT16_BSO_SECPERFAT
311 ld temp,z+
312 sts fat_log_clust,temp ; low byte
313 ld temp2,z
314 sts fat_log_clust+1,temp2 ; high byte
315
316 .if FAT16_DEBUG > 0
317 printstring "Sectors per FAT__: ",0
318 rcall printhexw
319 printnewline
320 .endif
321
322 ; get num of reseved sectors from bootblock
323 ldiw z,hostbuf+FAT16_BSO_RESSECT
324 ld temp,z+
325 ld temp2,z
326
327 ; Calculate begin of FAT within the Volume
328 ldiw z,fat_parttbl
329 ldd xl,z+0
330 ldd xh,z+1
331 ldd yl,z+2
332 ldd yh,z+3
333
334 add xl,temp
335 adc xh,temp2
336 adc yl,_0
337 adc yh,_0
338
339 sts fat_ptr2fat ,xl
340 sts fat_ptr2fat+1,xh
341 sts fat_ptr2fat+2,yl
342 sts fat_ptr2fat+3,yh
343
344 .if FAT16_DEBUG > 1
345 printstring "Begin of FAT at___: ",0
346 mov temp ,yl
347 mov temp2,yh
348 rcall printhexw
349 mov temp ,xl
350 mov temp2,xh
351 rcall printhexw
352 printnewline
353 .endif
354
355 ; Calculate begin of Root- Directory within the Volume
356 ldiw z,fat_ptr2fat
357 ldd xl,z+0
358 ldd xh,z+1
359 ldd yl,z+2
360 ldd yh,z+3
361
362 lds temp ,fat_log_clust
363 lds temp2,fat_log_clust+1
364 lds temp3,fat_last_dsk
365
366 fat_calc_dp_loop:
367 cp temp3,_0
368 breq fat_calc_dp_lend
369
370 add xl,temp
371 adc xh,temp2
372 adc yl,_0
373 adc yh,_0
374
375 dec temp3
376
377 jmp fat_calc_dp_loop
378 fat_calc_dp_lend:
379
380 sts fat_clust_ptr ,xl
381 sts fat_clust_ptr+1,xh
382 sts fat_clust_ptr+2,yl
383 sts fat_clust_ptr+3,yh
384
385
386 .if FAT16_DEBUG > 1
387 printstring "Begin of DIR at___: ",0
388 mov temp ,yl
389 mov temp2,yh
390 rcall printhexw
391 mov temp ,xl
392 mov temp2,xh
393 rcall printhexw
394 printnewline
395 .endif
396
397 ; Calculate begin of DATA Clusters within the Volume
398 ; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor
399
400 ; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
401
402 lds zl,fat_numdirentrys ; low byte
403 lds zh,fat_numdirentrys+1 ; high byte
404
405 ; Num. Direntrys / 16
406 lsr zh
407 ror zl
408 lsr zh
409 ror zl
410 lsr zh
411 ror zl
412 lsr zh
413 ror zl
414
415 lds xl,fat_clust_ptr
416 lds xh,fat_clust_ptr+1
417 lds yl,fat_clust_ptr+2
418 lds yh,fat_clust_ptr+3
419
420 add xl,zl
421 adc xh,zh
422 adc yl,_0
423 adc yh,_0
424
425 sts fat_ptr2dat ,xl
426 sts fat_ptr2dat+1,xh
427 sts fat_ptr2dat+2,yl
428 sts fat_ptr2dat+3,yh
429
430 .if FAT16_DEBUG > 1
431 printstring "Begin of Data at__: ",0
432 mov temp ,yl
433 mov temp2,yh
434 rcall printhexw
435 mov temp ,xl
436 mov temp2,xh
437 rcall printhexw
438 printnewline
439 .endif
440
441 ; Here Starts the Scann of the Directory for valid image Files.
442
443 ; Init Image-Namecounter
444 ldi temp,FAT16_FIRST_IMAGENAME
445 sts fat_last_dsk,temp
446
447 fat_scan_for_next_image:
448
449 ; Init Offset into Directory-Sectors
450 ldi temp,0
451 sts fat_clust_offset,temp
452
453 ; Init counter for number of entry left to scan
454 lds temp,fat_numdirentrys
455 sts fat_log_clust ,temp
456
457 lds temp,fat_numdirentrys+1
458 sts fat_log_clust+1,temp
459
460 fat_next_sector_loop:
461 ; Get a Pointer to the first Directory sector
462 lds xl,fat_clust_ptr
463 lds xh,fat_clust_ptr+1
464 lds yl,fat_clust_ptr+2
465 lds yh,fat_clust_ptr+3
466
467 ; Add actual offset
468 lds temp,fat_clust_offset
469 add xl,temp
470 adc xh,_0
471 adc yl,_0
472 adc yh,_0
473
474 ; Load sector from Directory
475 call mmcReadSect
476 tst temp
477 breq fat_look_for_images
478
479 ; Read error: Block not found
480 clr temp
481 ret
482
483 ; Looks at a read directory block for image entrys
484 fat_look_for_images:
485
486 ldiw z,hostbuf
487 ldi temp2,0
488
489 fat_look_for_loop:
490 ldd temp,z+0
491 cpi temp,'C'
492 brne fat_look_not_ok
493
494 ldd temp,z+1
495 cpi temp,'P'
496 brne fat_look_not_ok
497
498 ldd temp,z+2
499 cpi temp,'M'
500 brne fat_look_not_ok
501
502 ldd temp,z+3
503 cpi temp,'D'
504 brne fat_look_not_ok
505
506 ldd temp,z+4
507 cpi temp,'S'
508 brne fat_look_not_ok
509
510 ldd temp,z+5
511 cpi temp,'K'
512 brne fat_look_not_ok
513
514 ldd temp,z+6
515 cpi temp,'_'
516 brne fat_look_not_ok
517
518 lds temp3,fat_last_dsk ; Get actual Diskname (A to Z)
519 ldd temp,z+7
520 cp temp,temp3
521 brne fat_look_not_ok
522
523 ldd temp,z+8
524 cpi temp,'I'
525 brne fat_look_not_ok
526
527 ldd temp,z+9
528 cpi temp,'M'
529 brne fat_look_not_ok
530
531 ldd temp,z+10
532 cpi temp,'G'
533 brne fat_look_not_ok
534
535 sts fat_clust_ptr ,zl
536 sts fat_clust_ptr+1,zh
537 sts fat_clust_ptr+2,temp2
538 jmp fat_store_new_entry
539
540 fat_scan_for_more:
541
542
543 .if FAT16_DEBUG > 1
544 printstring "At:Scann for more ",0
545 printnewline
546 .endif
547
548 lds zl ,fat_clust_ptr
549 lds zh ,fat_clust_ptr+1
550 lds temp2,fat_clust_ptr+2
551 fat_look_not_ok:
552
553 .if FAT16_DEBUG > 1
554 printstring "+",0
555 .endif
556
557 adiw z,32
558
559 inc temp2
560 cpi temp2,16 ; max entrys/sector
561 breq fat_scan_next_sector
562 jmp fat_look_for_loop
563
564 fat_scan_next_sector:
565
566 .if FAT16_DEBUG > 1
567 printstring "At:Scan next Sector",0
568 printnewline
569 .endif
570
571 lds temp3, fat_log_clust
572 lds temp4, fat_log_clust+1
573
574 sub temp3,temp2
575 sbc temp4,_0
576
577 sts fat_log_clust,temp3
578 sts fat_log_clust+1,temp4
579
580 cp temp3,_0
581 cpc temp4,_0
582 breq fat_scan_at_end
583
584 lds temp,fat_clust_offset
585 inc temp
586 sts fat_clust_offset,temp
587
588 rjmp fat_next_sector_loop
589
590 fat_scan_at_end:
591
592 .if FAT16_DEBUG > 1
593 printstring "At:Scan at end",0
594 printnewline
595 .endif
596
597 lds temp,fat_last_dsk
598 inc temp
599 sts fat_last_dsk,temp
600
601 ldi temp2,FAT16_LAST_IMAGENAME
602 cp temp,temp2
603 brge fat_scaned_last_disk
604
605 rjmp fat_scan_for_next_image
606
607 fat_scaned_last_disk:
608
609 rjmp fat_scan_end
610
611
612 ; Create new Partition Entry
613 fat_store_new_entry:
614
615 ; Found a valid image
616 .if FAT16_DEBUG > 1
617 printstring "Found a valid Image ! Z=",0
618 mov temp ,zl
619 mov temp2,zh
620 rcall printhexw
621 printnewline
622 .endif
623
624 ldiw y,hostparttbl
625 lds temp,ndisks
626
627 fat_look_store_loop:
628 cp temp,_0
629 breq fat_look_store
630
631 adiw y,PARTENTRY_SIZE
632 dec temp
633 jmp fat_look_store_loop
634
635 fat_look_store:
636 ; Set Type of Partition to FAT16- Fileimage
637 ldi temp,dskType_FAT
638 st y+,temp
639
640 .if FAT16_DEBUG > 1
641 printstring "ClusterID",0
642 .endif
643 ; Offset to Startcluster + 2
644 ldd temp,z+0x1A
645 st y+,temp
646 .if FAT16_DEBUG > 1
647 rcall printhex
648 .endif
649 ldd temp,z+0x1B
650 st y+,temp
651 .if FAT16_DEBUG > 1
652 rcall printhex
653 .endif
654 ldi temp,0
655 st y+,temp
656 st y+,temp
657
658 .if FAT16_DEBUG > 1
659 printnewline
660 .endif
661
662 ; Filesize in Bytes
663 ; ldd temp,z+0x1C
664 ; st y+,temp
665 ; ldd temp,z+0x1D
666 ; st y+,temp
667 ; ldd temp,z+0x1E
668 ; st y+,temp
669 ; ldd temp,z+0x1F
670 ; st y+,temp
671
672 ; Convert Filesize to ammount of sectors
673 ; (calc with 512byte/sector)
674 ldd xl,z+0x1D
675 ldd xh,z+0x1E
676 ldd zl,z+0x1F
677 mov zh,_0
678
679 lsr zh
680 ror zl
681 ror xh
682 ror xl
683
684 ; store ammount of sectors in partitiontable
685 st y+,xl
686 st y+,xh
687 st y+,zl
688 st y+,zh
689
690 .if FAT16_DEBUG > 1
691 ; Test finding of the first sector
692
693 ldd xl,z+0x1A
694 ldd xh,z+0x1B
695
696 rcall fat_gethostsec
697
698 printstring "Begin of Image at: ",0
699 mov temp ,yl
700 mov temp2,yh
701 rcall printhexw
702 mov temp ,xl
703 mov temp2,xh
704 rcall printhexw
705 printnewline
706
707 .endif
708 ; Check for another free entry in partition table
709 lds temp,ndisks
710 inc temp
711 sts ndisks,temp
712
713 cpi temp,MAXDISKS
714 breq fat_scan_end
715
716 jmp fat_scan_for_more
717
718 fat_scan_end:
719
720 ret
721
722
723 ; ============================================================================
724 ; Function: Cluster to HostSector
725 ; ============================================================================
726 ; Parameters: [in] xh,xl Cluster Number
727 ; [out] yh,yl,xh,xl Sector Number on Disk
728 ; ----------------------------------------------------------------------------
729 ; Registers :
730 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
731 ; [changes] temp
732 ; ----------------------------------------------------------------------------
733 ; Description:
734 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
735 ; ============================================================================
736 fat_gethostsec:
737
738 ; Get Offset into Data area of Disk
739 rcall fat_clusttosec
740
741
742 ; add begin of data area to offset
743 lds temp,fat_ptr2dat+0
744 add xl,temp
745 lds temp,fat_ptr2dat+1
746 adc xh,temp
747 lds temp,fat_ptr2dat+2
748 adc yl,temp
749 lds temp,fat_ptr2dat+3
750 adc yh,temp
751 ret
752
753 ; ============================================================================
754 ; Function: Cluster to Sector
755 ; ============================================================================
756 ; Registers: [in] xl,xh Cluster Number
757 ; [out] xl,xh,yl,yh Sector Number
758 ; Variables: [in] fat_clustersize Ammount of Sectors per Cluster
759 ; [out] temp =0
760 ; ----------------------------------------------------------------------------
761 ; Description:
762 ; Calculates the logical Sectornumber given the physical ClusterNumber
763 ; and the size of a Cluster un sectors.
764 ;
765 ; ! Only works with Clustersizes 2,4,8,16,32,64,128,512,1024 !
766 ; ============================================================================
767 fat_clusttosec:
768 clr yl
769 clr yh
770
771 ldi temp,2
772 sub xl,temp ; Substract the 2 reserved clusters
773 sbc xh,_0
774
775 lds temp,fat_clustersize
776 lsr temp
777
778 fat_c2s_loop:
779 tst temp
780 breq fat_c2s_end
781 lsr temp
782
783 lsl xl
784 rol xh
785 rol yl
786 rol yh
787 rjmp fat_c2s_loop
788
789 fat_c2s_end:
790 ret
791
792 ; ====================================================================
793 ; Function: Searches a physical Cluster, given the logical Cluster
794 ; ====================================================================
795 ; Registers: [in] xh,xl logical- Cluster
796 ; [out] yh,yl physical- Cluster
797 ; Variables:
798 ; --------------------------------------------------------------------
799 ; Description:
800 ; ====================================================================
801 fat_find_phsy_clust:
802 mov temp2,xl
803 lds xl,hostdsk
804
805 rcall dsk_getpartentry ; get partition entry
806 mov xl,temp2
807
808 ; Get First FAT- Cluster Number of Diskimage
809
810 ldd yl,z+1
811 ldd yh,z+2
812
813 .if FAT16_DBG_FAT > 0
814 printstring "Search log. Cluster ",0
815 mov temp,xl
816 mov temp2,xh
817 rcall printhexw
818 printnewline
819
820 printstring "Search phys. Cluster ",0
821 mov temp ,yl
822 mov temp2,yh
823 rcall printhexw
824 printnewline
825 .endif
826
827 fat_next_phsy_clust:
828 cp xl,_0
829 cpc xh,_0
830 breq fat_found_phsy_clust
831 ; Get Next Cluster from Fat
832
833 ; Trick: 512 Bytes Per Sector equals to 256 FAT- Entrys per Sector
834 ; so given: yl is the Offset within the FAT Sector
835 ; yh is the number off se FAT sector to Read
836
837 ; in zh,zl: Pointer to Word within the Sector to read
838 ; in yh..xl: Start sector number (LBA)
839 ; out zh,zl : word thats been read
840 push xl
841 push xh
842
843 ; Create FAT Offset Value
844 clr zh
845 mov zl,yl
846 lsl zl
847 rol zh
848 ; Get FAT Start
849 mov temp,yh
850 lds xl,fat_ptr2fat
851 lds xh,fat_ptr2fat+1
852 lds yl,fat_ptr2fat+2
853 lds yh,fat_ptr2fat+3
854 ; Add Cluster offset within sector
855 add xl,temp
856 adc xh,_0
857 adc yl,_0
858 adc yh,_0
859 call mmcReadWord
860
861 pop xh
862 pop xl
863
864 mov yl,zl
865 mov yh,zh
866
867 ; Check next logical Cluster
868 ldi zl,1
869 sub xl,zl
870 sbc xh,_0
871 rjmp fat_next_phsy_clust
872
873 ; Found the physical cluster
874 fat_found_phsy_clust:
875 .if FAT16_DBG_FAT > 0
876 printstring "Found phys. Cluster at:",0
877 mov temp,yl
878 mov temp2,yh
879 rcall printhexw
880 printnewline
881 .endif
882
883 ret
884
885 ; ============================================================================
886 ; Function: This Routine searches for the Sector within an Imagefile
887 ; ============================================================================
888 ; Registers: [out] xl,xh,yl,yh Pointer to the Sector on the SD-Card
889 ; [out] temp Error- Variable (0= No Error)
890 ; Variables: [in] hostdsk host disk #, (partition #)
891 ; [in] hostlba host block #, relative to part.start
892 ; [in] fat_last_dsk number of disk with entry in cache
893 ; [in] fat_log_clust last searched logical cluster
894 ; [in] fat_clust_offset offset within the cluster
895 ; [in] fat_clust_ptr sector of last real cluster
896 ; ----------------------------------------------------------------------------
897 ; Description:
898 ; This Routine uses the variables hostdsk and hostlba to find an Sector
899 ; in the Imagefile.
900 ; The CP/M Sector given within "hostlba" are splited to a logical Cluster-
901 ; Number and the Subsector within this logical Cluster.
902 ; logical Cluster Number = hostlba / fat_clustersize
903 ; The logical Cluster Number will be compared to the logical Cluster- Number
904 ; within the Cache. When this Clusters are the same and the DiskID's are
905 ; also the same, then the cached physical Sector will be used.
906 ; When the Clusters or the Disks don't match, a seek for the physical
907 ; Cluster is performed. This seek is done thru an access over the FAT of
908 ; the FAT16 Partition. The Routine starts at the first Cluster of the
909 ; Imagefile and goes along the linked list of Clusternumber till it reaches
910 ; the searched cluster. The found Clusternumber will be used to calculate
911 ; the Sektor where this Cluster lies on the SD- Card. Both the found physical
912 ; Cluster and the logical Cluster together with the physical Sectornumber
913 ; are stored in the cache.
914 ; The last step done is to add the SubSectorOffset to the found physical
915 ; Sector. This gives the pointer to the Sector to be read and or written.
916 ; ============================================================================
917
918 fat_hostparam:
919 lds xl,hostdsk
920
921
922 rcall dsk_getpartentry ; get partition entry
923
924 fat_hostlend:
925 lds temp ,hostlba
926 lds temp2,hostlba+1
927 lds temp3,hostlba+2
928
929
930 ldd xl,z+5 ; get size of disk in sectors
931 ldd xh,z+6
932 ldd yl,z+7
933
934 cp temp,xl ; check given sector against disksize
935 cpc temp2,xh
936 cpc temp3,yl
937 brcs fat_hp1
938
939 clr temp
940 ret
941
942 fat_hp1:
943 ; ################# Get logical Number of Cluster within the imagefile
944 ; printstring "calc log sector"
945 ; Get logical Sectornumber from temp
946 mov xl,temp
947 mov xh,temp2
948 mov yl,temp3
949 mov yh,_0
950 ; Divide logical Sectornumber by size of Cluster in sectors
951 lds zl,fat_clustersize
952 lsr zl
953 fat_search_clst_lp:
954 tst zl
955 breq fat_found_clst
956
957 lsr yh
958 ror yl
959 ror xh
960 ror xl
961
962 lsr zl
963
964 rjmp fat_search_clst_lp
965 fat_found_clst:
966 ; at this point xh and xl are carying the logical cluster number
967 ; printstring "find subsector"
968 ; ################# Get Subsector within the logical Cluster for later use
969 mov yl,xl
970 lds zl,fat_clustersize
971 lsr zl
972 fat_search_clst_lp2:
973 tst zl
974 breq fat_found_subsec
975 lsl yl
976
977 lsr zl
978 rjmp fat_search_clst_lp2
979
980 fat_found_subsec:
981 mov zl,temp
982 sub zl,yl
983 sts fat_clust_offset,zl
984
985 ; Check against last HOSTDISK searched
986 lds yl,fat_last_dsk
987 lds yh,hostdsk
988 cp yl,yh
989 brne fat_wrong_cache_clst
990
991 ; Check against last Cluster searched
992 lds yl,fat_log_clust
993 lds yh,fat_log_clust+1
994
995 cp yl,xl
996 brne fat_wrong_cache_clst
997 cp yh,xh
998 brne fat_wrong_cache_clst
999
1000 ; Last Cluster = searched Cluster -> get Sectornumber from cache
1001 lds xl,fat_clust_ptr
1002 lds xh,fat_clust_ptr+1
1003 lds yl,fat_clust_ptr+2
1004 lds yh,fat_clust_ptr+3
1005
1006 rjmp fat_add_offset
1007
1008 ; Cluster is not in cache, so we must search for it
1009 fat_wrong_cache_clst:
1010 lds yl,hostdsk
1011 sts fat_last_dsk,yl
1012 sts fat_log_clust,xl
1013 sts fat_log_clust+1,xh
1014
1015 ; Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
1016 rcall fat_find_phsy_clust
1017
1018 ; Get StartSector of "physical" Cluster
1019 mov xl,yl
1020 mov xh,yh
1021 rcall fat_gethostsec
1022 ; Found the physical sector
1023 .if FAT16_DBG_FAT > 0
1024 printstring "Found phys. Sector at:",0
1025 mov temp,yl
1026 mov temp2,yh
1027 rcall printhexw
1028 mov temp,xl
1029 mov temp2,xh
1030 rcall printhexw
1031 printnewline
1032 .endif
1033
1034 ; Save the found Sector for later use into cache
1035 sts fat_clust_ptr ,xl
1036 sts fat_clust_ptr+1,xh
1037 sts fat_clust_ptr+2,yl
1038 sts fat_clust_ptr+3,yh
1039
1040 ; Add- Subsector to Startsector
1041 fat_add_offset:
1042 lds zl,fat_clust_offset
1043 add xl,zl
1044 adc xh,_0
1045 adc yl,_0
1046 adc yh,_0
1047
1048 ; Found the physical sector
1049 .if FAT16_DBG_FAT > 0
1050 printstring "Sector with Offset at:",0
1051 mov temp,yl
1052 mov temp2,yh
1053 rcall printhexw
1054 mov temp,xl
1055 mov temp2,xh
1056 rcall printhexw
1057 printnewline
1058 .endif
1059
1060 ori temp,255
1061 fat_hpex:
1062 ret
1063
1064 ; ============================================================================
1065 ; Function: Does a Disk write operation
1066 ; ============================================================================
1067 ; Registers: [out] temp Error-Variable ( 0= No Error)
1068 ; Variables: [in] hostdsk host disk #, (partition #)
1069 ; [in] hostlba host block #, relative to part.start
1070 ; [in] hostbuf Sector to be written
1071 ; ----------------------------------------------------------------------------
1072 ; Description:
1073 ; This Routine writes a Sector to the Imagefile inside an FAT16 Partition.
1074 ; ============================================================================
1075
1076 fat_writehost:
1077 .if FAT16_RWDEBUG > 1
1078 printnewline
1079 printstring "host write "
1080 .endif
1081 rcall fat_hostparam
1082 breq fat_rdwr_err
1083
1084 ;call mmcWriteSect ; disabled till read is functioning
1085 tst temp
1086 breq fat_rdwr_ok
1087
1088 rcall mgr_init_partitions
1089 cbr temp,0x80
1090 breq fat_rdwr_err
1091
1092 rcall fat_hostparam
1093 breq fat_rdwr_err
1094 ;call mmcWriteSect ; disabled till read is functioning
1095 tst temp
1096 brne fat_rdwr_err
1097 rjmp fat_rdwr_ok
1098
1099 fat_rdwr_ok:
1100 sts erflag,_0
1101 ret
1102
1103 fat_rdwr_err:
1104 sts erflag,_255
1105 ret
1106
1107 ; ============================================================================
1108 ; Function: Does a Disk read operation
1109 ; ============================================================================
1110 ; Registers: none
1111 ; Variables: [in] hostdsk host disk #, (partition #)
1112 ; [in] hostlba host block #, relative to part.start
1113 ; [out] hostbuf Sector read by this routine
1114 ; ----------------------------------------------------------------------------
1115 ; Description:
1116 ; This Routine reads a Sector from the Imagefile inside an FAT16 Partition.
1117 ; ============================================================================
1118
1119 fat_readhost:
1120 .if FAT16_RWDEBUG > 1
1121 printnewline
1122 printstring "host read "
1123 .endif
1124
1125 rcall fat_hostparam
1126 breq fat_rdwr_err
1127
1128
1129 .if FAT16_RWDEBUG > 0
1130 printstring "Read Image Sector:"
1131 push temp4
1132 push temp3
1133 push temp2
1134 push temp
1135 movw temp,x
1136 movw temp3,y
1137 rcall print_ultoa
1138 pop temp
1139 pop temp2
1140 pop temp3
1141 pop temp4
1142 printnewline
1143 .endif
1144
1145 call mmcReadSect
1146 tst temp
1147 breq fat_rdwr_ok
1148
1149 rcall mgr_init_partitions
1150 cbr temp,0x80
1151 breq fat_rdwr_err
1152
1153 rcall fat_hostparam
1154 breq fat_rdwr_err
1155 call mmcReadSect
1156 tst temp
1157 brne fat_rdwr_err
1158
1159 #endif
1160