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