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 ; ===========================================================================
33 ;-------------------------------- Defines for FAT16 Structures
34 #define PARTID_FAT16 0x0E
36 ;#define FAT16_BSO_SECSIZE 0x0b ; BootSectorOffset to Sectorsize Word
37 #define FAT16_BSO_CLUSTSZ 0x0d ; BootSectorOffset to Clustersize Byte
38 #define FAT16_BSO_RESSECT 0x0e ; BootSectorOffset to Number of Reserved Sectors
39 #define FAT16_BSO_VOLPTR 0x1c ; BootSectorOffset to First VolumeSector
40 #define FAT16_BSO_SECPERFAT 0x16 ; BootSectorOffset to Number of Sectors per Fat
41 #define FAT16_BSO_NUMFATCP 0x10 ; BootSectorOffset to Ammount of FAT Copys
42 #define FAT16_BSO_NUMDIRENT 0x11 ; BootSectorOffset to Max. Root Dir. Entrys
44 ;-------------------------------- Start of Data Segment
48 fat_partfound: .byte 1 ; (0= no fat partition found 1=found partition)
49 fat_parttbl: .byte 8 ; first fat16 partition entry (start sector, sector count)
50 ;fat_sectorsize: .byte 2 ; size of sector in bytes
51 fat_clustersize: .byte 1 ; sectors per cluster
52 fat_ressectors: .byte 2 ; number of reserved sectors
53 fat_secperfat: .byte 2 ; number of sectors per fat
54 fat_numfatcp: .byte 1 ; Number of FAT Copies
55 fat_numdirentrys:.byte 2 ; Max. ammount of Directory Entrys within Rootdirektory
56 fat_ptr2fat: .byte 4 ; pointer to the first fat sector
57 fat_ptr2dir: .byte 4 ; pointer to the first root directory sector
58 fat_ptr2dat: .byte 4 ; pointer to the first data sector
60 fat_last_dsk: .byte 1 ; number of disk with entry in cache
61 fat_log_clust: .byte 2 ; last searched logical cluster
62 fat_clust_offset: .byte 1 ; offset within the cluster
63 fat_clust_ptr: .byte 4; ; sector of last real cluster
64 ; ------------------------------- Start of Code Segment
67 ; ====================================================================
68 ; Function: Does a Disk read/write operation
69 ; ====================================================================
71 ; --------------------------------------------------------------------
73 ; Variables : [r] seekdsk Number of Disk to Read
74 ; [r] seeksec Sector to read
75 ; [r] seektrk Track to read
76 ; --------------------------------------------------------------------
78 ; ====================================================================
79 fat_init_partitiontable:
94 sts fat_log_clust+1,yl
98 ; ====================================================================
99 ; Function: Add's a FAT16 Partition for later Scanning
100 ; ====================================================================
102 ; --------------------------------------------------------------------
105 ; --------------------------------------------------------------------
107 ; This funktion sets the internal Variables to set Start and Size
108 ; of a given FAT16 Paritition. This Information will be used for a
109 ; later scanning of the Partition. See Function "fat_scan_partition"
110 ; for more information.
111 ; ====================================================================
115 printstring "fat16 part found",0
120 ; save variables on stack
124 ; set fat16 partition found flag
128 ; save data from first fat16 partition
131 ldd temp,z+PART_START
133 ldd temp,z+PART_START+1
135 ldd temp,z+PART_START+2
137 ldd temp,z+PART_START+3
142 ldd temp,z+PART_SIZE+1
144 ldd temp,z+PART_SIZE+2
146 ldd temp,z+PART_SIZE+3
150 ; reload variables from stack
156 ; ---------------------------------------------------------------------------
157 ; Read and Scann a FAT16 Partition for Imagedatefiles
158 ; ---------------------------------------------------------------------------
159 ; This Routine reads the Bootblock and scanns it for a Diskimage
160 ; Input Registers : none
161 ; Output Registers : none
162 ; Changes Variables: none
163 ; ---------------------------------------------------------------------------
169 printstring "fat16 scanning",0
173 ; Check if a FAT16 Partition was realy found
180 printstring "free entrys in ptable ?",0
184 ; Check for free Entrys in Partition table
190 printstring "read fat bootblock.",0
194 ; Scan partition start
201 ; Load first sector from Partition
204 breq fat_bootblock_check
206 ; Read error: Block not found
214 printstring "fat16 bootblock check",0
218 ; -> Size of Sectors fixed at 512 Bytes
219 ; Get ammount of Bytes per Sector
220 ; ldiw z,hostbuf+FAT16_BSO_SECSIZE
221 ; ldiw y,fat_sectorsize
228 ; printstring "Bytes per Sector ",0
233 ; Anzahl der Sectoren pro Cluster lesen
234 ldiw z,hostbuf+FAT16_BSO_CLUSTSZ
236 sts fat_clustersize,temp
239 printstring "Sectors per Cluster ",0
244 ; Anzahl der reservierten Sectoren
245 ldiw z,hostbuf+FAT16_BSO_RESSECT
247 sts fat_ressectors,temp ; low byte
249 sts fat_ressectors+1,temp2 ; high byte
252 printstring "Reserved Sectors__: ",0
257 ; Anzahl der Sectoren pro FAT
258 ldiw z,hostbuf+FAT16_BSO_SECPERFAT
260 sts fat_secperfat,temp ; low byte
262 sts fat_secperfat+1,temp2 ; high byte
265 printstring "Sectors per FAT__: ",0
270 ; Anzahl der FAT kopien
271 ldiw z,hostbuf+FAT16_BSO_NUMFATCP
273 sts fat_numfatcp,temp ; low byte
276 printstring "Ammount of FAT copies: ",0
281 ; Max. Anzahl der Dir. Enträge im Root Verz.
282 ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
284 sts fat_numdirentrys,temp ; low byte
286 sts fat_numdirentrys+1,temp2 ; high byte
289 printstring "Max. entrys in Rootdir.: ",0
294 ; Print begin of Volume
303 printstring "Begin of Volume at: ",0
313 ; Calculate begin of FAT within the Volume
314 lds temp ,fat_ressectors
315 lds temp2,fat_ressectors+1
334 printstring "Begin of FAT at___: ",0
344 ; Calculate begin of Root- Directory within the Volume
351 lds temp ,fat_secperfat
352 lds temp2,fat_secperfat+1
353 lds temp3,fat_numfatcp
357 breq fat_calc_dp_lend
376 printstring "Begin of DIR at___: ",0
386 ; Calculate begin of DATA Clusters within the Volume
387 ; Num. Dir.Sektors = (Num. of Dir. Entrys * 32) / Bytes per Sektor
389 ; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
391 lds zl,fat_numdirentrys ; low byte
392 lds zh,fat_numdirentrys+1 ; high byte
394 ; Num. Direntrys / 16
420 printstring "Begin of Data at__: ",0
430 ; Here Starts the Scann of the Directory for valid image Files.
437 ; Load first sector from Directory
440 breq fat_look_for_images
442 ; Read error: Block not found
446 ; Looks at a read directory block for image entrys
493 jmp fat_store_new_entry
501 cpi temp2,16 ; max entrys/sector
502 breq fat_scan_next_sector
503 jmp fat_look_for_loop
505 fat_scan_next_sector:
510 ; Create new Partition Entry
513 ; Found a valid image
515 printstring "Found a valid Image ! ",0
526 adiw y,PARTENTRY_SIZE
528 jmp fat_look_store_loop
531 ; Set Type of Partition to FAT16- Fileimage
535 ; Offset to Startcluster + 2
544 ; Filesize in Bytes - 2,4,8,16,32,64,128,256,512
554 ; Convert Filesize to ammount of sectors
565 ; store ammount of sectors in partitiontable
571 ; Check for another free entry in partition table
578 ; Test finding of the first sector
585 printstring "Begin of Image at: ",0
597 ; brne fat_scan_for_more
602 ; ====================================================================
603 ; Function: Cluster to HostSector
604 ; ====================================================================
605 ; Parameters: [in] xh,xl Cluster Number
606 ; [out] yh,yl,xh,xl Sector Number on Disk
607 ; --------------------------------------------------------------------
609 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
611 ; --------------------------------------------------------------------
613 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
614 ; ====================================================================
617 ; Get Offset into Data area of Disk
621 ; add begin of data area to offset
622 lds temp,fat_ptr2dat+0
624 lds temp,fat_ptr2dat+1
626 lds temp,fat_ptr2dat+2
628 lds temp,fat_ptr2dat+3
632 ; ====================================================================
633 ; Function: Cluster to Sector
634 ; ====================================================================
635 ; Parameters: [in] xl,xh Cluster Number
636 ; [out] xl,xh,yl,yh Sector Number
637 ; --------------------------------------------------------------------
639 ; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
641 ; --------------------------------------------------------------------
643 ; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
644 ; ====================================================================
650 sub xl,temp ; Substract the 2 reserved clusters
653 lds temp,fat_clustersize
669 ; ====================================================================
670 ; Function: Searches a physical Cluster, given the logical Cluster
671 ; ====================================================================
673 ; --------------------------------------------------------------------
674 ; Registers : [r] xh,xl logical- Cluster
675 ; [w] yh,yl physical- Cluster
676 ; --------------------------------------------------------------------
678 ; ====================================================================
683 rcall dsk_getpartentry ; get partition entry
686 ; Get First FAT- Cluster Number of Diskimage
694 breq fat_found_phsy_clust
695 ; Get Next Cluster from Fat
697 ; Trick: 512 Bytes Per Sector equals to 256 FAT- Entrys per Sector
698 ; so given: yl is the Offset within the FAT Sector
699 ; yh is the number off se FAT sector to Read
701 ; in zh,zl: Pointer to Word within the Sector to read
702 ; in yh..xl: Start sector number (LBA)
703 ; out zh,zl : word thats been read
707 ; Create FAT Offset Value
731 ; Check next logical Cluster
735 rjmp fat_next_phsy_clust
737 ; Found the physical cluster
738 fat_found_phsy_clust:
741 ; ====================================================================
742 ; Function: Does a Disk write operation
743 ; ====================================================================
745 ; --------------------------------------------------------------------
747 ; Variables : [r] seekdsk Number of Disk to Read
748 ; [r] seeksec Sector to read
749 ; [r] seektrk Track to read
750 ; hostdsk = host disk #, (partition #)
751 ; hostlba = host block #, relative to partition start
752 ; Read/Write "hostsize" bytes to/from hostbuf
753 ; --------------------------------------------------------------------
755 ; ====================================================================
767 rcall dsk_getpartentry ; get partition entry
780 ldd xl,z+5 ; get size of disk in sectors
784 cp temp,xl ; check given sector against disksize
790 printstring ", max: "
810 ; ################# Get logical Number of Cluster within the imagefile
811 ; printstring "calc log sector"
812 ; Get logical Sectornumber from temp
817 ; Divide logical Sectornumber by size of Cluster in sectors
818 lds zl, fat_clustersize
830 rjmp fat_search_clst_lp
832 ; at this point xh and xl are carying the logical cluster number
833 ; printstring "find subsector"
834 ; ################# Get Subsector within the logical Cluster for later use
836 lds zl, fat_clustersize
839 breq fat_found_subsec
843 rjmp fat_search_clst_lp2
848 sts fat_clust_offset,zl
850 ; Check against last HOSTDISK searched
854 brne fat_wrong_cache_clst
856 ; Check against last Cluster searched
858 lds yh,fat_log_clust+1
861 brne fat_wrong_cache_clst
863 brne fat_wrong_cache_clst
865 ; Last Cluster = searched Cluster -> get Sectornumber from cache
867 lds xh,fat_clust_ptr+1
868 lds yl,fat_clust_ptr+2
869 lds yh,fat_clust_ptr+3
873 ; ################# Cluster is not in cache, so we must search for it
874 fat_wrong_cache_clst:
878 sts fat_log_clust+1,xh
880 ; ################# Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
881 rcall fat_find_phsy_clust
883 ; ################# Get StartSector of "physical" Cluster
888 ; Save the found Sector for later use into cache
889 sts fat_clust_ptr ,xl
890 sts fat_clust_ptr+1,xh
891 sts fat_clust_ptr+2,yl
892 sts fat_clust_ptr+3,yh
894 ; Add- Subsector to Startsector
896 lds zl,fat_clust_offset
922 ; ====================================================================
923 ; Function: Does a Disk write operation
924 ; ====================================================================
926 ; --------------------------------------------------------------------
928 ; Variables : [r] seekdsk Number of Disk to Read
929 ; [r] seeksec Sector to read
930 ; [r] seektrk Track to read
931 ; --------------------------------------------------------------------
933 ; ====================================================================
938 printstring "host write "
943 ;call mmcWriteSect ; disabled till read is functioning
947 rcall mgr_init_partitions
953 ;call mmcWriteSect ; disabled till read is functioning
958 ; ====================================================================
959 ; Function: Does a Disk read operation
960 ; ====================================================================
962 ; --------------------------------------------------------------------
964 ; Variables : [r] seekdsk Number of Disk to Read
965 ; [r] seeksec Sector to read
966 ; [r] seektrk Track to read
967 ; --------------------------------------------------------------------
969 ; ====================================================================
974 printstring "host read "
981 printstring "Read Image Sector:"
999 rcall mgr_init_partitions