1 ; Various functions for the Interaction with the FAT16 Filesystem
3 ; Copyright (C) 2010 Frank Zoll
5 ; This file is part of avrcpm.
7 ; avrcpm is free software: you can redistribute it and/or modify it
8 ; under the terms of the GNU General Public License as published by
9 ; the Free Software Foundation, either version 3 of the License, or
10 ; (at your option) any later version.
12 ; avrcpm is distributed in the hope that it will be useful,
13 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ; GNU General Public License for more details.
17 ; You should have received a copy of the GNU General Public License
18 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
23 ; ===========================================================================
26 ; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation
27 ; The Functions below therefore assume a fixed Size of 512 Bytes per Sector.
28 ; ===========================================================================
31 #define FAT16_SUPPORT 1
38 ;-------------------------------- Defines for FAT16 Structures
39 #define PARTID_FAT16 0x0E
41 ;#define FAT16_BSO_SECSIZE 0x0b ; BootSectorOffset to Sectorsize Word
42 #define FAT16_BSO_CLUSTSZ 0x0d ; BootSectorOffset to Clustersize Byte
43 #define FAT16_BSO_RESSECT 0x0e ; BootSectorOffset to Number of Reserved Sectors
44 #define FAT16_BSO_VOLPTR 0x1c ; BootSectorOffset to First VolumeSector
45 #define FAT16_BSO_SECPERFAT 0x16 ; BootSectorOffset to Number of Sectors per Fat
46 #define FAT16_BSO_NUMFATCP 0x10 ; BootSectorOffset to Ammount of FAT Copys
47 #define FAT16_BSO_NUMDIRENT 0x11 ; BootSectorOffset to Max. Root Dir. Entrys
49 ;-------------------------------- Start of Data Segment
53 fat_partfound: .byte 1 ; (0= no fat partition found 1=found partition)
54 fat_parttbl: .byte 8 ; first fat16 partition entry (start sector, sector count)
55 ;fat_sectorsize: .byte 2 ; size of sector in bytes
56 fat_clustersize: .byte 1 ; sectors per cluster
57 fat_ressectors: .byte 2 ; number of reserved sectors
58 fat_secperfat: .byte 2 ; number of sectors per fat
59 fat_numfatcp: .byte 1 ; Number of FAT Copies
60 fat_numdirentrys:.byte 2 ; Max. ammount of Directory Entrys within Rootdirektory
61 fat_ptr2fat: .byte 4 ; pointer to the first fat sector
62 fat_ptr2dir: .byte 4 ; pointer to the first root directory sector
63 fat_ptr2dat: .byte 4 ; pointer to the first data sector
65 fat_last_dsk: .byte 1 ; number of disk with entry in cache
66 fat_log_clust: .byte 2 ; last searched logical cluster
67 fat_clust_offset: .byte 1 ; offset within the cluster
68 fat_clust_ptr: .byte 4; ; sector of last real cluster
69 ; ------------------------------- Start of Code Segment
72 ; ====================================================================
73 ; Function: Does a Disk read/write operation
74 ; ====================================================================
76 ; --------------------------------------------------------------------
78 ; Variables : [r] seekdsk Number of Disk to Read
79 ; [r] seeksec Sector to read
80 ; [r] seektrk Track to read
81 ; --------------------------------------------------------------------
83 ; ====================================================================
84 fat_init_partitiontable:
99 sts fat_log_clust+1,yl
103 ; ====================================================================
104 ; Function: Add's a FAT16 Partition for later Scanning
105 ; ====================================================================
107 ; --------------------------------------------------------------------
110 ; --------------------------------------------------------------------
112 ; This funktion sets the internal Variables to set Start and Size
113 ; of a given FAT16 Paritition. This Information will be used for a
114 ; later scanning of the Partition. See Function "fat_scan_partition"
115 ; for more information.
116 ; ====================================================================
120 printstring "fat16 part found",0
125 ; save variables on stack
129 ; set fat16 partition found flag
133 ; save data from first fat16 partition
136 ldd temp,z+PART_START
138 ldd temp,z+PART_START+1
140 ldd temp,z+PART_START+2
142 ldd temp,z+PART_START+3
147 ldd temp,z+PART_SIZE+1
149 ldd temp,z+PART_SIZE+2
151 ldd temp,z+PART_SIZE+3
155 ; reload variables from stack
161 ; ---------------------------------------------------------------------------
162 ; Read and Scann a FAT16 Partition for Imagedatefiles
163 ; ---------------------------------------------------------------------------
164 ; This Routine reads the Bootblock and scanns it for a Diskimage
165 ; Input Registers : none
166 ; Output Registers : none
167 ; Changes Variables: none
168 ; ---------------------------------------------------------------------------
174 printstring "fat16 scanning",0
178 ; Check if a FAT16 Partition was realy found
185 printstring "free entrys in ptable ?",0
189 ; Check for free Entrys in Partition table
195 printstring "read fat bootblock.",0
199 ; Scan partition start
206 ; Load first sector from Partition
209 breq fat_bootblock_check
211 ; Read error: Block not found
219 printstring "fat16 bootblock check",0
223 ; -> Size of Sectors fixed at 512 Bytes
224 ; Get ammount of Bytes per Sector
225 ; ldiw z,hostbuf+FAT16_BSO_SECSIZE
226 ; ldiw y,fat_sectorsize
233 ; printstring "Bytes per Sector ",0
238 ; Anzahl der Sectoren pro Cluster lesen
239 ldiw z,hostbuf+FAT16_BSO_CLUSTSZ
241 sts fat_clustersize,temp
244 printstring "Sectors per Cluster ",0
249 ; Anzahl der reservierten Sectoren
250 ldiw z,hostbuf+FAT16_BSO_RESSECT
252 sts fat_ressectors,temp ; low byte
254 sts fat_ressectors+1,temp2 ; high byte
257 printstring "Reserved Sectors__: ",0
262 ; Anzahl der Sectoren pro FAT
263 ldiw z,hostbuf+FAT16_BSO_SECPERFAT
265 sts fat_secperfat,temp ; low byte
267 sts fat_secperfat+1,temp2 ; high byte
270 printstring "Sectors per FAT__: ",0
275 ; Anzahl der FAT kopien
276 ldiw z,hostbuf+FAT16_BSO_NUMFATCP
278 sts fat_numfatcp,temp ; low byte
281 printstring "Ammount of FAT copies: ",0
286 ; Max. Anzahl der Dir. Enträge im Root Verz.
287 ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
289 sts fat_numdirentrys,temp ; low byte
291 sts fat_numdirentrys+1,temp2 ; high byte
294 printstring "Max. entrys in Rootdir.: ",0
299 ; Print begin of Volume
308 printstring "Begin of Volume at: ",0
318 ; Calculate begin of FAT within the Volume
319 lds temp ,fat_ressectors
320 lds temp2,fat_ressectors+1
339 printstring "Begin of FAT at___: ",0
349 ; Calculate begin of Root- Directory within the Volume
356 lds temp ,fat_secperfat
357 lds temp2,fat_secperfat+1
358 lds temp3,fat_numfatcp
362 breq fat_calc_dp_lend
381 printstring "Begin of DIR at___: ",0
391 ; Calculate begin of DATA Clusters within the Volume
392 ; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor
394 ; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
396 lds zl,fat_numdirentrys ; low byte
397 lds zh,fat_numdirentrys+1 ; high byte
399 ; Num. Direntrys / 16
425 printstring "Begin of Data at__: ",0
435 ; Here Starts the Scann of the Directory for valid image Files.
442 ; Load first sector from Directory
445 breq fat_look_for_images
447 ; Read error: Block not found
451 ; Looks at a read directory block for image entrys
498 jmp fat_store_new_entry
506 cpi temp2,16 ; max entrys/sector
507 breq fat_scan_next_sector
508 jmp fat_look_for_loop
510 fat_scan_next_sector:
515 ; Create new Partition Entry
518 ; Found a valid image
520 printstring "Found a valid Image ! ",0
531 adiw y,PARTENTRY_SIZE
533 jmp fat_look_store_loop
536 ; Set Type of Partition to FAT16- Fileimage
540 ; Offset to Startcluster + 2
549 ; Filesize in Bytes - 2,4,8,16,32,64,128,256,512
559 ; Convert Filesize to ammount of sectors
570 ; store ammount of sectors in partitiontable
576 ; Check for another free entry in partition table
583 ; Test finding of the first sector
590 printstring "Begin of Image at: ",0
602 ; brne fat_scan_for_more
607 ; ====================================================================
608 ; Function: Cluster to HostSector
609 ; ====================================================================
610 ; Parameters: [in] xh,xl Cluster Number
611 ; [out] yh,yl,xh,xl Sector Number on Disk
612 ; --------------------------------------------------------------------
614 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
616 ; --------------------------------------------------------------------
618 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
619 ; ====================================================================
622 ; Get Offset into Data area of Disk
626 ; add begin of data area to offset
627 lds temp,fat_ptr2dat+0
629 lds temp,fat_ptr2dat+1
631 lds temp,fat_ptr2dat+2
633 lds temp,fat_ptr2dat+3
637 ; ====================================================================
638 ; Function: Cluster to Sector
639 ; ====================================================================
640 ; Parameters: [in] xl,xh Cluster Number
641 ; [out] xl,xh,yl,yh Sector Number
642 ; --------------------------------------------------------------------
644 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
646 ; --------------------------------------------------------------------
648 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
649 ; ====================================================================
655 sub xl,temp ; Substract the 2 reserved clusters
658 lds temp,fat_clustersize
674 ; ====================================================================
675 ; Function: Searches a physical Cluster, given the logical Cluster
676 ; ====================================================================
678 ; --------------------------------------------------------------------
679 ; Registers : [r] xh,xl logical- Cluster
680 ; [w] yh,yl physical- Cluster
681 ; --------------------------------------------------------------------
683 ; ====================================================================
688 rcall dsk_getpartentry ; get partition entry
691 ; Get First FAT- Cluster Number of Diskimage
699 breq fat_found_phsy_clust
700 ; Get Next Cluster from Fat
702 ; Trick: 512 Bytes Per Sector equals to 256 FAT- Entrys per Sector
703 ; so given: yl is the Offset within the FAT Sector
704 ; yh is the number off se FAT sector to Read
706 ; in zh,zl: Pointer to Word within the Sector to read
707 ; in yh..xl: Start sector number (LBA)
708 ; out zh,zl : word thats been read
712 ; Create FAT Offset Value
736 ; Check next logical Cluster
740 rjmp fat_next_phsy_clust
742 ; Found the physical cluster
743 fat_found_phsy_clust:
746 ; ====================================================================
747 ; Function: Does a Disk write operation
748 ; ====================================================================
750 ; --------------------------------------------------------------------
752 ; Variables : [r] seekdsk Number of Disk to Read
753 ; [r] seeksec Sector to read
754 ; [r] seektrk Track to read
755 ; hostdsk = host disk #, (partition #)
756 ; hostlba = host block #, relative to partition start
757 ; Read/Write "hostsize" bytes to/from hostbuf
758 ; --------------------------------------------------------------------
760 ; ====================================================================
772 rcall dsk_getpartentry ; get partition entry
785 ldd xl,z+5 ; get size of disk in sectors
789 cp temp,xl ; check given sector against disksize
795 printstring ", max: "
815 ; ################# Get logical Number of Cluster within the imagefile
816 ; printstring "calc log sector"
817 ; Get logical Sectornumber from temp
822 ; Divide logical Sectornumber by size of Cluster in sectors
823 lds zl, fat_clustersize
835 rjmp fat_search_clst_lp
837 ; at this point xh and xl are carying the logical cluster number
838 ; printstring "find subsector"
839 ; ################# Get Subsector within the logical Cluster for later use
841 lds zl, fat_clustersize
844 breq fat_found_subsec
848 rjmp fat_search_clst_lp2
853 sts fat_clust_offset,zl
855 ; Check against last HOSTDISK searched
859 brne fat_wrong_cache_clst
861 ; Check against last Cluster searched
863 lds yh,fat_log_clust+1
866 brne fat_wrong_cache_clst
868 brne fat_wrong_cache_clst
870 ; Last Cluster = searched Cluster -> get Sectornumber from cache
872 lds xh,fat_clust_ptr+1
873 lds yl,fat_clust_ptr+2
874 lds yh,fat_clust_ptr+3
878 ; ################# Cluster is not in cache, so we must search for it
879 fat_wrong_cache_clst:
883 sts fat_log_clust+1,xh
885 ; ################# Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
886 rcall fat_find_phsy_clust
888 ; ################# Get StartSector of "physical" Cluster
893 ; Save the found Sector for later use into cache
894 sts fat_clust_ptr ,xl
895 sts fat_clust_ptr+1,xh
896 sts fat_clust_ptr+2,yl
897 sts fat_clust_ptr+3,yh
899 ; Add- Subsector to Startsector
901 lds zl,fat_clust_offset
927 ; ====================================================================
928 ; Function: Does a Disk write operation
929 ; ====================================================================
931 ; --------------------------------------------------------------------
933 ; Variables : [r] seekdsk Number of Disk to Read
934 ; [r] seeksec Sector to read
935 ; [r] seektrk Track to read
936 ; --------------------------------------------------------------------
938 ; ====================================================================
943 printstring "host write "
948 ;call mmcWriteSect ; disabled till read is functioning
952 rcall mgr_init_partitions
958 ;call mmcWriteSect ; disabled till read is functioning
963 ; ====================================================================
964 ; Function: Does a Disk read operation
965 ; ====================================================================
967 ; --------------------------------------------------------------------
969 ; Variables : [r] seekdsk Number of Disk to Read
970 ; [r] seeksec Sector to read
971 ; [r] seektrk Track to read
972 ; --------------------------------------------------------------------
974 ; ====================================================================
979 printstring "host read "
986 printstring "Read Image Sector:"
1004 rcall mgr_init_partitions