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