; Various functions for the Interaction with the FAT16 Filesystem
;
; Copyright (C) 2010 Frank Zoll
+; Copyright (C) 2010 Sprite_tm
+; Copyright (C) 2010 Leo C.
;
; This file is part of avrcpm.
;
; $Id$
;
-; ===========================================================================
+; ============================================================================
; Prelimitary !
; °°°°°°°°°°°°°
; Size of a Sector is fixed to 512 Bytes by Base - MMC Driver implementation
; The Functions below therefore assume a fixed Size of 512 Bytes per Sector.
-; ===========================================================================
-
-#ifndef FAT16_SUPPORT
- #define FAT16_SUPPORT 1
- #define FAT16_DEBUG 2
-#endif
+; ============================================================================
#if FAT16_SUPPORT
-;-------------------------------- Defines for FAT16 Structures
-#define PARTID_FAT16 0x0E
-
-;#define FAT16_BSO_SECSIZE 0x0b ; BootSectorOffset to Sectorsize Word
-#define FAT16_BSO_CLUSTSZ 0x0d ; BootSectorOffset to Clustersize Byte
-#define FAT16_BSO_RESSECT 0x0e ; BootSectorOffset to Number of Reserved Sectors
-#define FAT16_BSO_VOLPTR 0x1c ; BootSectorOffset to First VolumeSector
-#define FAT16_BSO_SECPERFAT 0x16 ; BootSectorOffset to Number of Sectors per Fat
-#define FAT16_BSO_NUMFATCP 0x10 ; BootSectorOffset to Ammount of FAT Copys
-#define FAT16_BSO_NUMDIRENT 0x11 ; BootSectorOffset to Max. Root Dir. Entrys
+; ############################################################################
+; Defines for FAT16 Structures
+; ############################################################################
-;-------------------------------- Start of Data Segment
+#define PARTID_FAT16 0x0E
+/*These are the Offsets to the Variables within the Bootsector of a FAT16
+ Partition.
+ */
+;#define FAT16_BSO_SECSIZE 0x0b ; Offset to Sectorsize Word
+#define FAT16_BSO_CLUSTSZ 0x0d ; Offset to Clustersize Byte
+#define FAT16_BSO_RESSECT 0x0e ; Offset to Number of Reserved Sectors
+#define FAT16_BSO_VOLPTR 0x1c ; Offset to First VolumeSector
+#define FAT16_BSO_SECPERFAT 0x16 ; Offset to Number of Sectors per Fat
+#define FAT16_BSO_NUMFATCP 0x10 ; Offset to Ammount of FAT Copys
+#define FAT16_BSO_NUMDIRENT 0x11 ; Offset to Max. Root Dir. Entrys
+#define FAT16_FIRST_IMAGENAME 'A' ; First letter of filename to search
+#define FAT16_LAST_IMAGENAME 'Z' ; Last letter of filename to search
+
+; ############################################################################
+; Start of Data Segment
+; ############################################################################
.dseg
-fat_partfound: .byte 1 ; (0= no fat partition found 1=found partition)
-fat_parttbl: .byte 8 ; first fat16 partition entry (start sector, sector count)
-;fat_sectorsize: .byte 2 ; size of sector in bytes
-fat_clustersize: .byte 1 ; sectors per cluster
-fat_ressectors: .byte 2 ; number of reserved sectors
-fat_secperfat: .byte 2 ; number of sectors per fat
-fat_numfatcp: .byte 1 ; Number of FAT Copies
-fat_numdirentrys:.byte 2 ; Max. ammount of Directory Entrys within Rootdirektory
-fat_ptr2fat: .byte 4 ; pointer to the first fat sector
-fat_ptr2dir: .byte 4 ; pointer to the first root directory sector
-fat_ptr2dat: .byte 4 ; pointer to the first data sector
-
-fat_last_dsk: .byte 1 ; number of disk with entry in cache
-fat_log_clust: .byte 2 ; last searched logical cluster
-fat_clust_offset: .byte 1 ; offset within the cluster
-fat_clust_ptr: .byte 4; ; sector of last real cluster
-; ------------------------------- Start of Code Segment
+fat_partfound: .byte 1 ; (partition: 0= no found 1=found )
+fat_parttbl: .byte 4 ; first fat16 partition entry
+ ; only startsector is needed
+fat_clustersize: .byte 1 ; sectors per cluster
+fat_numdirentrys:.byte 2 ; Max. num. of entrys within Rootdirektory
+fat_ptr2fat: .byte 4 ; pointer to the first fat sector
+fat_ptr2dat: .byte 4 ; pointer to the first data sector
+
+/*These variables define a cache that holds the last Cluster and Sector
+ thats been searched vor. To save some of the valuabe SRAM- Space these
+ variables also are used as temporary variables by the function
+ fat_scan_partition.
+ */
+fat_last_dsk: .byte 1 ; number of disk with entry in cache
+fat_log_clust: .byte 2 ; last searched logical cluster
+fat_clust_offset: .byte 1 ; offset within the cluster
+fat_clust_ptr: .byte 4; ; sector of last real cluster
+
+
+; ############################################################################
+; Start of Code Segment
+; ############################################################################
.cseg
-; ====================================================================
-; Function: Does a Disk read/write operation
-; ====================================================================
+; ============================================================================
+; Function: Initialize internal FAT-Partition Variables
+; ============================================================================
; Parameters
-; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
+; ----------------------------------------------------------------------------
+; Registers : none
+; Variables : [out] fat_parttabl
+; ----------------------------------------------------------------------------
; Description:
-; ====================================================================
+; This Routine initializes the internal Variables, that point to the
+; first Found FAT16 Partition.
+; ============================================================================
fat_init_partitiontable:
- sts fat_partfound,_0
+ sts fat_partfound,_0
ldiw y,fat_parttbl
st y+,_0
st y+,_0
st y+,_0
st y+,_0
- st y+,_0
- st y+,_0
- st y+,_0
- st y+,_0
+ ret
+
+; ============================================================================
+; Function: Resets the Cache
+; ============================================================================
+; Parameters
+; ----------------------------------------------------------------------------
+; Registers : none
+; Variables : [out] fat_log_clust
+; [out] fat_last_dsk
+; ----------------------------------------------------------------------------
+; Description:
+; This Routine resets the internal Cache- Variables. After reset, the
+; next read or write Command will initialize a scan of the FAT of
+; the FAT16-Partition for the given sector.
+; ============================================================================
+fat_reset_cache:
+ push yl
ldi yl,0xFF
- sts fat_log_clust ,yl
+ sts fat_log_clust ,yl
sts fat_log_clust+1,yl
sts fat_last_dsk ,yl
+ pop yl
ret
-; ====================================================================
-; Function: Add's a FAT16 Partition for later Scanning
-; ====================================================================
+; ============================================================================
+; Function: Saves FAT16 Partitiondata for later Scanning
+; ============================================================================
; Parameters
-; --------------------------------------------------------------------
-; Registers :
-; Variables :
-; --------------------------------------------------------------------
+; ----------------------------------------------------------------------------
+; Registers : [in] z Pointer to the Partitondata
+; Variables : [out] fat_partfound Boolean for "Partition found"
+; [out] fat_parttbl Pointer to Partitiontable
+; ----------------------------------------------------------------------------
; Description:
-; This funktion sets the internal Variables to set Start and Size
+; This funktion sets the internal Variables to the Start and Size
; of a given FAT16 Paritition. This Information will be used for a
; later scanning of the Partition. See Function "fat_scan_partition"
; for more information.
-; ====================================================================
+; ============================================================================
fat_add_partition:
.if FAT16_DEBUG > 0
; save data from first fat16 partition
ldiw y,fat_parttbl
- ldd temp,z+PART_START
- st y+,temp
- ldd temp,z+PART_START+1
- st y+,temp
- ldd temp,z+PART_START+2
- st y+,temp
- ldd temp,z+PART_START+3
- st y+,temp
-
- ldd temp,z+PART_SIZE
- st y+,temp
- ldd temp,z+PART_SIZE+1
- st y+,temp
- ldd temp,z+PART_SIZE+2
- st y+,temp
- ldd temp,z+PART_SIZE+3
- st y+,temp
-
+ ldd temp,z+PART_START
+ st y+,temp
+ ldd temp,z+PART_START+1
+ st y+,temp
+ ldd temp,z+PART_START+2
+ st y+,temp
+ ldd temp,z+PART_START+3
+ st y+,temp
; reload variables from stack
- pop yh
+ pop yh
pop yl
ret
-; ---------------------------------------------------------------------------
+; ============================================================================
; Read and Scann a FAT16 Partition for Imagedatefiles
-; ---------------------------------------------------------------------------
+; ============================================================================
+; Registers : none
+; Variables : none
+; ----------------------------------------------------------------------------
; This Routine reads the Bootblock and scanns it for a Diskimage
-; Input Registers : none
-; Output Registers : none
-; Changes Variables: none
-; ---------------------------------------------------------------------------
+; ============================================================================
fat_scan_partition:
.endif
; Check if a FAT16 Partition was realy found
- lds yl,fat_partfound
+ lds yl,fat_partfound
cpi yl,1
brne fat_scan_error
.endif
; Check for free Entrys in Partition table
- lds yl,ndisks
- cpi yl,MAXDISKS
+ lds yl,ndisks
+ cpi yl,MAXDISKS
breq fat_scan_error
.if FAT16_DEBUG > 0
; Scan partition start
ldiw z,fat_parttbl
- ldd xl,z+0
- ldd xh,z+1
- ldd yl,z+2
- ldd yh,z+3
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
; Load first sector from Partition
rcall mmcReadSect
- tst temp
+ tst temp
breq fat_bootblock_check
; Read error: Block not found
fat_scan_error:
- clr temp
+ clr temp
ret
fat_bootblock_check:
printnewline
.endif
-; -> Size of Sectors fixed at 512 Bytes
-; Get ammount of Bytes per Sector
-; ldiw z,hostbuf+FAT16_BSO_SECSIZE
-; ldiw y,fat_sectorsize
-; ld temp,z
-; st y+, temp
-; ldd temp2,z+1
-; st y , temp2
-;
-;.if FAT16_DEBUG > 0
-; printstring "Bytes per Sector ",0
-; rcall printhexw
-; printnewline
-;.endif
-
-; Anzahl der Sectoren pro Cluster lesen
+; get sectors per cluster from bootblock
ldiw z,hostbuf+FAT16_BSO_CLUSTSZ
- ld temp,z
+ ld temp,z
sts fat_clustersize,temp
.if FAT16_DEBUG > 0
printnewline
.endif
-; Anzahl der reservierten Sectoren
- ldiw z,hostbuf+FAT16_BSO_RESSECT
- ld temp,z+
- sts fat_ressectors,temp ; low byte
- ld temp2,z
- sts fat_ressectors+1,temp2 ; high byte
-
-.if FAT16_DEBUG > 0
- printstring "Reserved Sectors__: ",0
- rcall printhexw
- printnewline
-.endif
-
-; Anzahl der Sectoren pro FAT
- ldiw z,hostbuf+FAT16_BSO_SECPERFAT
- ld temp,z+
- sts fat_secperfat,temp ; low byte
- ld temp2,z
- sts fat_secperfat+1,temp2 ; high byte
-
-.if FAT16_DEBUG > 0
- printstring "Sectors per FAT__: ",0
- rcall printhexw
- printnewline
-.endif
-
-; Anzahl der FAT kopien
+; get num of FAT Tables from bootblock
ldiw z,hostbuf+FAT16_BSO_NUMFATCP
- ld temp,z
- sts fat_numfatcp,temp ; low byte
+ ld temp,z
+ sts fat_last_dsk,temp ; low byte
.if FAT16_DEBUG > 0
printstring "Ammount of FAT copies: ",0
printnewline
.endif
-; Max. Anzahl der Dir. Enträge im Root Verz.
+; get max num of entrys in root direktory from bootblock
ldiw z,hostbuf+FAT16_BSO_NUMDIRENT
- ld temp,z+
- sts fat_numdirentrys,temp ; low byte
- ld temp2,z
- sts fat_numdirentrys+1,temp2 ; high byte
+ ld temp,z+
+ sts fat_numdirentrys,temp ; low byte
+ ld temp2,z
+ sts fat_numdirentrys+1,temp2 ; high byte
.if FAT16_DEBUG > 0
printstring "Max. entrys in Rootdir.: ",0
printnewline
.endif
-; Print begin of Volume
+; Print begin of Volume
.if FAT16_DEBUG > 1
ldiw z,fat_parttbl
- ldd xl,z+0
- ldd xh,z+1
- ldd yl,z+2
- ldd yh,z+3
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
printstring "Begin of Volume at: ",0
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
+ mov temp ,yl
+ mov temp2,yh
+ rcall printhexw
+ mov temp ,xl
+ mov temp2,xh
+ rcall printhexw
+ printnewline
+.endif
+
+; get num of sectors per FAT-Table from bootblock
+ ldiw z,hostbuf+FAT16_BSO_SECPERFAT
+ ld temp,z+
+ sts fat_log_clust,temp ; low byte
+ ld temp2,z
+ sts fat_log_clust+1,temp2 ; high byte
+
+.if FAT16_DEBUG > 0
+ printstring "Sectors per FAT__: ",0
rcall printhexw
printnewline
.endif
-; Calculate begin of FAT within the Volume
- lds temp ,fat_ressectors
- lds temp2,fat_ressectors+1
+; get num of reseved sectors from bootblock
+ ldiw z,hostbuf+FAT16_BSO_RESSECT
+ ld temp,z+
+ ld temp2,z
+; Calculate begin of FAT within the Volume
ldiw z,fat_parttbl
- ldd xl,z+0
- ldd xh,z+1
- ldd yl,z+2
- ldd yh,z+3
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
- add xl,temp
+ add xl,temp
adc xh,temp2
- adc yl,_0
- adc yh,_0
+ adc yl,_0
+ adc yh,_0
- sts fat_ptr2fat ,xl
- sts fat_ptr2fat+1,xh
- sts fat_ptr2fat+2,yl
- sts fat_ptr2fat+3,yh
+ sts fat_ptr2fat ,xl
+ sts fat_ptr2fat+1,xh
+ sts fat_ptr2fat+2,yl
+ sts fat_ptr2fat+3,yh
.if FAT16_DEBUG > 1
printstring "Begin of FAT at___: ",0
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ mov temp ,yl
+ mov temp2,yh
+ rcall printhexw
+ mov temp ,xl
+ mov temp2,xh
+ rcall printhexw
printnewline
.endif
; Calculate begin of Root- Directory within the Volume
ldiw z,fat_ptr2fat
- ldd xl,z+0
- ldd xh,z+1
- ldd yl,z+2
- ldd yh,z+3
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
- lds temp ,fat_secperfat
- lds temp2,fat_secperfat+1
- lds temp3,fat_numfatcp
+ lds temp ,fat_log_clust
+ lds temp2,fat_log_clust+1
+ lds temp3,fat_last_dsk
fat_calc_dp_loop:
- cp temp3,_0
+ cp temp3,_0
breq fat_calc_dp_lend
- add xl,temp
- adc xh,temp2
- adc yl,_0
- adc yh,_0
+ add xl,temp
+ adc xh,temp2
+ adc yl,_0
+ adc yh,_0
- dec temp3
+ dec temp3
- jmp fat_calc_dp_loop
+ rjmp fat_calc_dp_loop
fat_calc_dp_lend:
- sts fat_ptr2dir ,xl
- sts fat_ptr2dir+1,xh
- sts fat_ptr2dir+2,yl
- sts fat_ptr2dir+3,yh
+ sts fat_clust_ptr ,xl
+ sts fat_clust_ptr+1,xh
+ sts fat_clust_ptr+2,yl
+ sts fat_clust_ptr+3,yh
.if FAT16_DEBUG > 1
printstring "Begin of DIR at___: ",0
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ mov temp ,yl
+ mov temp2,yh
+ rcall printhexw
+ mov temp ,xl
+ mov temp2,xh
+ rcall printhexw
printnewline
.endif
; Sectorsize is fixed at 512 Bytes, makes 16 Entrys per Sektor
- lds zl,fat_numdirentrys ; low byte
- lds zh,fat_numdirentrys+1 ; high byte
+ lds zl,fat_numdirentrys ; low byte
+ lds zh,fat_numdirentrys+1 ; high byte
; Num. Direntrys / 16
- lsr zh
- ror zl
- lsr zh
- ror zl
- lsr zh
- ror zl
- lsr zh
- ror zl
-
- lds xl,fat_ptr2dir
- lds xh,fat_ptr2dir+1
- lds yl,fat_ptr2dir+2
- lds yh,fat_ptr2dir+3
-
- add xl,zl
- adc xh,zh
- adc yl,_0
- adc yh,_0
-
- sts fat_ptr2dat ,xl
- sts fat_ptr2dat+1,xh
- sts fat_ptr2dat+2,yl
- sts fat_ptr2dat+3,yh
+ lsr zh
+ ror zl
+ lsr zh
+ ror zl
+ lsr zh
+ ror zl
+ lsr zh
+ ror zl
+
+ lds xl,fat_clust_ptr
+ lds xh,fat_clust_ptr+1
+ lds yl,fat_clust_ptr+2
+ lds yh,fat_clust_ptr+3
+
+ add xl,zl
+ adc xh,zh
+ adc yl,_0
+ adc yh,_0
+
+ sts fat_ptr2dat ,xl
+ sts fat_ptr2dat+1,xh
+ sts fat_ptr2dat+2,yl
+ sts fat_ptr2dat+3,yh
.if FAT16_DEBUG > 1
printstring "Begin of Data at__: ",0
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ mov temp ,yl
+ mov temp2,yh
+ rcall printhexw
+ mov temp ,xl
+ mov temp2,xh
+ rcall printhexw
printnewline
.endif
; Here Starts the Scann of the Directory for valid image Files.
- lds xl,fat_ptr2dir
- lds xh,fat_ptr2dir+1
- lds yl,fat_ptr2dir+2
- lds yh,fat_ptr2dir+3
+; Init Image-Namecounter
+ ldi temp,FAT16_FIRST_IMAGENAME
+ sts fat_last_dsk,temp
+
+fat_scan_for_next_image:
+
+; Init Offset into Directory-Sectors
+ ldi temp,0
+ sts fat_clust_offset,temp
+
+; Init counter for number of entry left to scan
+ lds temp,fat_numdirentrys
+ sts fat_log_clust ,temp
+
+ lds temp,fat_numdirentrys+1
+ sts fat_log_clust+1,temp
+
+fat_next_sector_loop:
+; Get a Pointer to the first Directory sector
+ lds xl,fat_clust_ptr
+ lds xh,fat_clust_ptr+1
+ lds yl,fat_clust_ptr+2
+ lds yh,fat_clust_ptr+3
-; Load first sector from Directory
- call mmcReadSect
- tst temp
+; Add actual offset
+ lds temp,fat_clust_offset
+ add xl,temp
+ adc xh,_0
+ adc yl,_0
+ adc yh,_0
+
+; Load sector from Directory
+ lcall mmcReadSect
+ tst temp
breq fat_look_for_images
; Read error: Block not found
- clr temp
+ clr temp
ret
; Looks at a read directory block for image entrys
fat_look_for_images:
ldiw z,hostbuf
- ldi temp2,0
+ ldi temp2,0
fat_look_for_loop:
ldd temp,z+0
- cpi temp,'C'
+ cpi temp,'C'
brne fat_look_not_ok
- ldd temp,z+1
- cpi temp,'P'
+ ldd temp,z+1
+ cpi temp,'P'
brne fat_look_not_ok
- ldd temp,z+2
- cpi temp,'M'
+ ldd temp,z+2
+ cpi temp,'M'
brne fat_look_not_ok
- ldd temp,z+3
- cpi temp,'D'
+ ldd temp,z+3
+ cpi temp,'D'
brne fat_look_not_ok
- ldd temp,z+4
- cpi temp,'S'
+ ldd temp,z+4
+ cpi temp,'S'
brne fat_look_not_ok
- ldd temp,z+5
- cpi temp,'K'
+ ldd temp,z+5
+ cpi temp,'K'
brne fat_look_not_ok
- ldd temp,z+6
- cpi temp,'_'
+ ldd temp,z+6
+ cpi temp,'_'
brne fat_look_not_ok
- ldd temp,z+8
- cpi temp,'I'
+ lds temp3,fat_last_dsk ; Get actual Diskname (A to Z)
+ ldd temp,z+7
+ cp temp,temp3
brne fat_look_not_ok
- ldd temp,z+9
- cpi temp,'M'
+ ldd temp,z+8
+ cpi temp,'I'
brne fat_look_not_ok
- ldd temp,z+10
- cpi temp,'G'
+ ldd temp,z+9
+ cpi temp,'M'
brne fat_look_not_ok
- jmp fat_store_new_entry
+ ldd temp,z+10
+ cpi temp,'G'
+ brne fat_look_not_ok
+ sts fat_clust_ptr ,zl
+ sts fat_clust_ptr+1,zh
+ sts fat_clust_ptr+2,temp2
+ rjmp fat_store_new_entry
+
+fat_scan_for_more:
+
+ lds zl ,fat_clust_ptr
+ lds zh ,fat_clust_ptr+1
+ lds temp2,fat_clust_ptr+2
fat_look_not_ok:
-
- //ldi temp,32
- addiw z,32
+
+ adiw z,32
- inc temp2
- cpi temp2,16 ; max entrys/sector
+ inc temp2
+ cpi temp2,16 ; max entrys/sector
breq fat_scan_next_sector
- jmp fat_look_for_loop
+ rjmp fat_look_for_loop
fat_scan_next_sector:
- ret
+
+ lds temp3, fat_log_clust
+ lds temp4, fat_log_clust+1
+
+ sub temp3,temp2
+ sbc temp4,_0
+
+ sts fat_log_clust,temp3
+ sts fat_log_clust+1,temp4
+
+ cp temp3,_0
+ cpc temp4,_0
+ breq fat_scan_at_end
+
+ lds temp,fat_clust_offset
+ inc temp
+ sts fat_clust_offset,temp
+
+ rjmp fat_next_sector_loop
+
+fat_scan_at_end:
+
+ lds temp,fat_last_dsk
+ inc temp
+ sts fat_last_dsk,temp
+
+ ldi temp2,FAT16_LAST_IMAGENAME
+ cp temp,temp2
+ brge fat_scaned_last_disk
+
+ rjmp fat_scan_for_next_image
+
+fat_scaned_last_disk:
+
+ rjmp fat_scan_end
; Create new Partition Entry
; Found a valid image
.if FAT16_DEBUG > 1
- printstring "Found a valid Image ! ",0
+ printstring "Found a valid Image ! Z=",0
+ mov temp ,zl
+ mov temp2,zh
+ rcall printhexw
printnewline
.endif
ldiw y,hostparttbl
- lds temp,ndisks
+ lds temp,ndisks
fat_look_store_loop:
- cp temp,_0
+ cp temp,_0
breq fat_look_store
adiw y,PARTENTRY_SIZE
- dec temp
- jmp fat_look_store_loop
+ dec temp
+ rjmp fat_look_store_loop
fat_look_store:
; Set Type of Partition to FAT16- Fileimage
- ldi temp,dskType_FAT
+ ldi temp,dskType_FAT
st y+,temp
+
; Offset to Startcluster + 2
ldd temp,z+0x1A
st y+,temp
+
ldd temp,z+0x1B
st y+,temp
+
ldi temp,0
st y+,temp
st y+,temp
-; Filesize in Bytes - 2,4,8,16,32,64,128,256,512
+; Filesize in Bytes
; ldd temp,z+0x1C
; st y+,temp
; ldd temp,z+0x1D
; st y+,temp
; Convert Filesize to ammount of sectors
+; (calc with 512byte/sector)
ldd xl,z+0x1D
ldd xh,z+0x1E
ldd zl,z+0x1F
mov zh,_0
lsr zh
- ror zl
- ror xh
- ror xl
+ ror zl
+ ror xh
+ ror xl
; store ammount of sectors in partitiontable
- st y+,xl
- st y+,xh
- st y+,zl
- st y+,zh
-
-; Check for another free entry in partition table
- lds temp,ndisks
- inc temp
- sts ndisks,temp
-
+ st y+,xl
+ st y+,xh
+ st y+,zl
+ st y+,zh
.if FAT16_DEBUG > 1
; Test finding of the first sector
+
ldd xl,z+0x1A
ldd xh,z+0x1B
- ldi zl,0
rcall fat_gethostsec
printstring "Begin of Image at: ",0
- mov temp ,yl
- mov temp2,yh
- rcall printhexw
- mov temp ,xl
- mov temp2,xh
- rcall printhexw
+ mov temp ,yl
+ mov temp2,yh
+ rcall printhexw
+ mov temp ,xl
+ mov temp2,xh
+ rcall printhexw
printnewline
.endif
+; Check for another free entry in partition table
+ lds temp,ndisks
+ inc temp
+ sts ndisks,temp
-; cp temp,MAXDISKS
-; brne fat_scan_for_more
+ cpi temp,MAXDISKS
+ breq fat_scan_end
+
+ rjmp fat_scan_for_more
+
+fat_scan_end:
ret
-; ====================================================================
+; ============================================================================
; Function: Cluster to HostSector
-; ====================================================================
-; Parameters: [in] xh,xl Cluster Number
-; [out] yh,yl,xh,xl Sector Number on Disk
-; --------------------------------------------------------------------
+; ============================================================================
+; Parameters: [in] xh,xl Cluster Number
+; [out] yh,yl,xh,xl Sector Number on Disk
+; ----------------------------------------------------------------------------
; Registers :
; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
-; [changes] temp
-; --------------------------------------------------------------------
+; [changes] temp
+; ----------------------------------------------------------------------------
; Description:
; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
-; ====================================================================
+; ============================================================================
fat_gethostsec:
; Get Offset into Data area of Disk
; add begin of data area to offset
- lds temp,fat_ptr2dat+0
- add xl,temp
- lds temp,fat_ptr2dat+1
- adc xh,temp
- lds temp,fat_ptr2dat+2
- adc yl,temp
- lds temp,fat_ptr2dat+3
- adc yh,temp
+ lds temp,fat_ptr2dat+0
+ add xl,temp
+ lds temp,fat_ptr2dat+1
+ adc xh,temp
+ lds temp,fat_ptr2dat+2
+ adc yl,temp
+ lds temp,fat_ptr2dat+3
+ adc yh,temp
ret
-; ====================================================================
+; ============================================================================
; Function: Cluster to Sector
-; ====================================================================
-; Parameters: [in] xl,xh Cluster Number
-; [out] xl,xh,yl,yh Sector Number
-; --------------------------------------------------------------------
-; Registers :
-; Variables : [used] fat_clustersize Ammount of Sectors per Cluster
-; [changes] temp
-; --------------------------------------------------------------------
+; ============================================================================
+; Registers: [in] xl,xh Cluster Number
+; [out] xl,xh,yl,yh Sector Number
+; Variables: [in] fat_clustersize Ammount of Sectors per Cluster
+; [out] temp =0
+; ----------------------------------------------------------------------------
; Description:
+; Calculates the logical Sectornumber given the physical ClusterNumber
+; and the size of a Cluster un sectors.
+;
; ! Only works with Clustersizes 2,4,8,16,32,64,128 !
-; ====================================================================
+; ============================================================================
fat_clusttosec:
clr yl
- clr yh
+ clr yh
- ldi temp,2
- sub xl,temp ; Substract the 2 reserved clusters
- sbc xh,_0
+ ldi temp,2
+ sub xl,temp ; Substract the 2 reserved clusters
+ sbc xh,_0
- lds temp,fat_clustersize
+ lds temp,fat_clustersize
+ lsr temp
fat_c2s_loop:
- tst temp
+ tst temp
breq fat_c2s_end
- lsr temp
+ lsr temp
- lsl xl
- rol xh
- rol yl
- rol yh
+ lsl xl
+ rol xh
+ rol yl
+ rol yh
rjmp fat_c2s_loop
fat_c2s_end:
; ====================================================================
; Function: Searches a physical Cluster, given the logical Cluster
; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : [r] xh,xl logical- Cluster
-; [w] yh,yl physical- Cluster
+; Registers: [in] xh,xl logical- Cluster
+; [out] yh,yl physical- Cluster
+; Variables:
; --------------------------------------------------------------------
; Description:
; ====================================================================
fat_find_phsy_clust:
mov temp2,xl
- lds xl,hostdsk
+ lds xl,hostdsk
rcall dsk_getpartentry ; get partition entry
mov xl,temp2
; Get First FAT- Cluster Number of Diskimage
- ldd xl,z+1
- ldd xh,z+2
+ ldd yl,z+1
+ ldd yh,z+2
+
+.if FAT16_DBG_FAT > 0
+ printstring "Search log. Cluster ",0
+ mov temp,xl
+ mov temp2,xh
+ lcall printhexw
+ printnewline
+
+ printstring "Search phys. Cluster ",0
+ mov temp ,yl
+ mov temp2,yh
+ lcall printhexw
+ printnewline
+.endif
fat_next_phsy_clust:
- cp xl,_0
- cpc xh,_0
+ cp xl,_0
+ cpc xh,_0
breq fat_found_phsy_clust
; Get Next Cluster from Fat
; in zh,zl: Pointer to Word within the Sector to read
; in yh..xl: Start sector number (LBA)
; out zh,zl : word thats been read
- push xl
- push xh
+ push xl
+ push xh
; Create FAT Offset Value
clr zh
- mov zl,yl
+ mov zl,yl
lsl zl
- rol zh
+ rol zh
; Get FAT Start
- mov temp,yh
- lds xl,fat_ptr2fat
- lds xh,fat_ptr2fat+1
- lds yl,fat_ptr2fat+2
- lds yh,fat_ptr2fat+3
-; Add Sector offset
+ mov temp,yh
+ lds xl,fat_ptr2fat
+ lds xh,fat_ptr2fat+1
+ lds yl,fat_ptr2fat+2
+ lds yh,fat_ptr2fat+3
+; Add Cluster offset within sector
add xl,temp
adc xh,_0
- adc yl,_0
- adc yh,_0
- call mmcReadWord
+ adc yl,_0
+ adc yh,_0
+ lcall mmcReadWord
- pop xh
- pop xl
+ pop xh
+ pop xl
- mov yl,zl
- mov yh,zh
+ mov yl,zl
+ mov yh,zh
; Check next logical Cluster
- ldi zl,1
- sub xl,zl
- sbc xh,_0
+ ldi zl,1
+ sub xl,zl
+ sbc xh,_0
rjmp fat_next_phsy_clust
; Found the physical cluster
-fat_found_phsy_clust:
+fat_found_phsy_clust:
+
+.if FAT16_DBG_FAT > 0
+ printstring "Found phys. Cluster at:",0
+ mov temp,yl
+ mov temp2,yh
+ lcall printhexw
+ printnewline
+.endif
+
ret
-; ====================================================================
-; Function: Does a Disk write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; hostdsk = host disk #, (partition #)
-; hostlba = host block #, relative to partition start
-; Read/Write "hostsize" bytes to/from hostbuf
-; --------------------------------------------------------------------
+; ============================================================================
+; Function: This Routine searches for the Sector within an Imagefile
+; ============================================================================
+; Registers: [out] xl,xh,yl,yh Pointer to the Sector on the SD-Card
+; [out] temp Error- Variable (0= No Error)
+; Variables: [in] hostdsk host disk #, (partition #)
+; [in] hostlba host block #, relative to part.start
+; [in] fat_last_dsk number of disk with entry in cache
+; [in] fat_log_clust last searched logical cluster
+; [in] fat_clust_offset offset within the cluster
+; [in] fat_clust_ptr sector of last real cluster
+; ----------------------------------------------------------------------------
; Description:
-; ====================================================================
+; This Routine uses the variables hostdsk and hostlba to find an Sector
+; in the Imagefile.
+; The CP/M Sector given within "hostlba" are splited to a logical Cluster-
+; Number and the Subsector within this logical Cluster.
+; logical Cluster Number = hostlba / fat_clustersize
+; The logical Cluster Number will be compared to the logical Cluster- Number
+; within the Cache. When this Clusters are the same and the DiskID's are
+; also the same, then the cached physical Sector will be used.
+; When the Clusters or the Disks don't match, a seek for the physical
+; Cluster is performed. This seek is done thru an access over the FAT of
+; the FAT16 Partition. The Routine starts at the first Cluster of the
+; Imagefile and goes along the linked list of Clusternumber till it reaches
+; the searched cluster. The found Clusternumber will be used to calculate
+; the Sektor where this Cluster lies on the SD- Card. Both the found physical
+; Cluster and the logical Cluster together with the physical Sectornumber
+; are stored in the cache.
+; The last step done is to add the SubSectorOffset to the found physical
+; Sector. This gives the pointer to the Sector to be read and or written.
+; ============================================================================
fat_hostparam:
- lds xl,hostdsk
+ lds xl,hostdsk
-.if HOSTRW_DEBUG
- mov temp,xl
- subi temp,-('A')
- rcall uartputc
- printstring ": "
-.endif
- rcall dsk_getpartentry ; get partition entry
+ rcall dsk_getpartentry ; get partition entry
fat_hostlend:
- lds temp ,hostlba
- lds temp2,hostlba+1
- lds temp3,hostlba+2
-
-.if HOSTRW_DEBUG
- printstring "lba: "
- clr temp4
- rcall print_ultoa
-.endif
+ lds temp ,hostlba
+ lds temp2,hostlba+1
+ lds temp3,hostlba+2
+
- ldd xl,z+5 ; get size of disk in sectors
- ldd xh,z+6
- ldd yl,z+7
+ ldd xl,z+5 ; get size of disk in sectors
+ ldd xh,z+6
+ ldd yl,z+7
- cp temp,xl ; check given sector against disksize
- cpc temp2,xh
- cpc temp3,yl
+ cp temp,xl ; check given sector against disksize
+ cpc temp2,xh
+ cpc temp3,yl
brcs fat_hp1
-.if HOSTRW_DEBUG
- printstring ", max: "
- push temp4
- push temp3
- push temp2
- push temp
- movw temp,x
- mov temp3,yl
- clr temp4
- rcall print_ultoa
- pop temp
- pop temp2
- pop temp3
- pop temp4
- printstring " "
-.endif
-
- clr temp
+ clr temp
ret
fat_hp1:
mov yl,temp3
mov yh,_0
; Divide logical Sectornumber by size of Cluster in sectors
- lds zl, fat_clustersize
+ lds zl,fat_clustersize
+ lsr zl
fat_search_clst_lp:
- tst zl
+ tst zl
breq fat_found_clst
- lsr yh
- ror yl
- ror xh
- ror xl
+ lsr yh
+ ror yl
+ ror xh
+ ror xl
- lsr zl
+ lsr zl
- rjmp fat_search_clst_lp
+ rjmp fat_search_clst_lp
+
fat_found_clst:
; at this point xh and xl are carying the logical cluster number
; printstring "find subsector"
; ################# Get Subsector within the logical Cluster for later use
- mov yl,xl
- lds zl, fat_clustersize
+ mov yl,xl
+ lds zl,fat_clustersize
+ lsr zl
fat_search_clst_lp2:
- tst zl
+ tst zl
breq fat_found_subsec
- lsl yl
+ lsl yl
- lsr zl
+ lsr zl
rjmp fat_search_clst_lp2
fat_found_subsec:
- mov zl,temp
- sub zl,yl
- sts fat_clust_offset,zl
+ mov zl,temp
+ sub zl,yl
+ sts fat_clust_offset,zl
; Check against last HOSTDISK searched
- lds yl,fat_last_dsk
- lds yh,hostdsk
- cp yl,yh
+ lds yl,fat_last_dsk
+ lds yh,hostdsk
+ cp yl,yh
brne fat_wrong_cache_clst
; Check against last Cluster searched
- lds yl,fat_log_clust
- lds yh,fat_log_clust+1
+ lds yl,fat_log_clust
+ lds yh,fat_log_clust+1
- cp yl,xl
+ cp yl,xl
brne fat_wrong_cache_clst
- cp yh,xh
+ cp yh,xh
brne fat_wrong_cache_clst
; Last Cluster = searched Cluster -> get Sectornumber from cache
- lds xl,fat_clust_ptr
- lds xh,fat_clust_ptr+1
- lds yl,fat_clust_ptr+2
- lds yh,fat_clust_ptr+3
+ lds xl,fat_clust_ptr
+ lds xh,fat_clust_ptr+1
+ lds yl,fat_clust_ptr+2
+ lds yh,fat_clust_ptr+3
rjmp fat_add_offset
-; ################# Cluster is not in cache, so we must search for it
+; Cluster is not in cache, so we must search for it
fat_wrong_cache_clst:
- lds yl,hostdsk
- sts fat_last_dsk,yl
- sts fat_log_clust,xl
- sts fat_log_clust+1,xh
+ lds yl,hostdsk
+ sts fat_last_dsk,yl
+ sts fat_log_clust,xl
+ sts fat_log_clust+1,xh
-; ################# Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
+; Map Logical Cluster-Number to "Physical" Cluster Number using the FAT
rcall fat_find_phsy_clust
-; ################# Get StartSector of "physical" Cluster
+; Get StartSector of "physical" Cluster
mov xl,yl
- mov xh,yh
+ mov xh,yh
rcall fat_gethostsec
+; Found the physical sector
+.if FAT16_DBG_FAT > 0
+ printstring "Found phys. Sector at:",0
+ mov temp,yl
+ mov temp2,yh
+ lcall printhexw
+ mov temp,xl
+ mov temp2,xh
+ lcall printhexw
+ printnewline
+.endif
+
; Save the found Sector for later use into cache
- sts fat_clust_ptr ,xl
- sts fat_clust_ptr+1,xh
- sts fat_clust_ptr+2,yl
- sts fat_clust_ptr+3,yh
+ sts fat_clust_ptr ,xl
+ sts fat_clust_ptr+1,xh
+ sts fat_clust_ptr+2,yl
+ sts fat_clust_ptr+3,yh
; Add- Subsector to Startsector
fat_add_offset:
- lds zl,fat_clust_offset
- add xl,zl
- adc xh,_0
- adc yl,_0
- adc yh,_0
-
-.if HOSTRW_DEBUG
- printstring ", abs:"
- push temp4
- push temp3
- push temp2
- push temp
- movw temp,x
- movw temp3,y
- rcall print_ultoa
- pop temp
- pop temp2
- pop temp3
- pop temp4
- printstring " "
+ lds zl,fat_clust_offset
+ add xl,zl
+ adc xh,_0
+ adc yl,_0
+ adc yh,_0
+
+; Found the physical sector
+.if FAT16_DBG_FAT > 0
+ printstring "Sector with Offset at:",0
+ mov temp,yl
+ mov temp2,yh
+ lcall printhexw
+ mov temp,xl
+ mov temp2,xh
+ lcall printhexw
+ printnewline
.endif
- ori temp,255
+ ori temp,255
fat_hpex:
ret
-; ====================================================================
+; ============================================================================
; Function: Does a Disk write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
+; ============================================================================
+; Registers: [out] temp Error-Variable ( 0= No Error)
+; Variables: [in] hostdsk host disk #, (partition #)
+; [in] hostlba host block #, relative to part.start
+; [in] hostbuf Sector to be written
+; ----------------------------------------------------------------------------
; Description:
-; ====================================================================
+; This Routine writes a Sector to the Imagefile inside an FAT16 Partition.
+; ============================================================================
fat_writehost:
-.if HOSTRW_DEBUG
+.if FAT16_RWDEBUG > 1
printnewline
printstring "host write "
.endif
rcall fat_hostparam
breq fat_rdwr_err
- ;call mmcWriteSect ; disabled till read is functioning
- tst temp
+ call mmcWriteSect
+ tst temp
breq fat_rdwr_ok
+ rjmp fat_rdwr_err ; skip disk change detection code
+
+; After a second thought, the following code doesn't make sense, because
+; disk change (change of one or more disk images) can not reliably detected.
+; At least with the existing code.
+
+
+
rcall mgr_init_partitions
- cbr temp,0x80
+ cbr temp,0x80
breq fat_rdwr_err
rcall fat_hostparam
breq fat_rdwr_err
- ;call mmcWriteSect ; disabled till read is functioning
- tst temp
+ call mmcWriteSect ; disabled till read is functioning
+ tst temp
brne fat_rdwr_err
rjmp fat_rdwr_ok
-; ====================================================================
+fat_rdwr_ok:
+ sts erflag,_0
+ ret
+
+fat_rdwr_err:
+ sts erflag,_255
+ ret
+
+; ============================================================================
; Function: Does a Disk read operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers : none
-; Variables : [r] seekdsk Number of Disk to Read
-; [r] seeksec Sector to read
-; [r] seektrk Track to read
-; --------------------------------------------------------------------
+; ============================================================================
+; Registers: none
+; Variables: [in] hostdsk host disk #, (partition #)
+; [in] hostlba host block #, relative to part.start
+; [out] hostbuf Sector read by this routine
+; ----------------------------------------------------------------------------
; Description:
-; ====================================================================
+; This Routine reads a Sector from the Imagefile inside an FAT16 Partition.
+; ============================================================================
fat_readhost:
-.if HOSTRW_DEBUG
+.if FAT16_RWDEBUG > 1
printnewline
printstring "host read "
.endif
rcall fat_hostparam
breq fat_rdwr_err
- \r
+
+.if FAT16_RWDEBUG > 0
printstring "Read Image Sector:"
push temp4
push temp3
push temp
movw temp,x
movw temp3,y
- rcall print_ultoa
- pop temp
- pop temp2
- pop temp3
- pop temp4
- printstring " "
+ lcall print_ultoa
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ printnewline
+.endif
- call mmcReadSect
- tst temp
+ lcall mmcReadSect
+ tst temp
breq fat_rdwr_ok
+ rjmp fat_rdwr_err ; skip disk change detection code
+
rcall mgr_init_partitions
- cbr temp,0x80
+ cbr temp,0x80
breq fat_rdwr_err
rcall fat_hostparam
breq fat_rdwr_err
- call mmcReadSect
- tst temp
+ lcall mmcReadSect
+ tst temp
brne fat_rdwr_err
-fat_rdwr_ok:
- sts erflag,_0
- ret
-
-fat_rdwr_err:
- sts erflag,_255
- ret
#endif
+