Beispiel #1
0
// Initialize the library - locates the first FAT16 partition,
// loads the relevant part of its boot sector to calculate
// values needed for operation, and finally positions the
// file reading routines to the start of root directory entries
char fat16_init() {
    char i;
    unsigned long root_start;
    
    fat16_seek(0x1BE);
        
    for(i=0; i<4; i++) {        
        fat16_read(sizeof(PartitionTable));
        
        if(FAT16_part->partition_type == 4 || 
           FAT16_part->partition_type == 6 ||
           FAT16_part->partition_type == 14)
            break;
    }
    
    if(i == 4) // none of the partitions were FAT16
        return FAT16_ERR_NO_PARTITION_FOUND;
    
    fat16_state.fat_start = 512 * FAT16_part->start_sector; // temporary
    
    fat16_seek(fat16_state.fat_start + FAT16_BOOT_OFFSET);
    fat16_read(sizeof(Fat16BootSectorFragment));
    
    if(FAT16_boot->sector_size != 512)
        return FAT16_ERR_INVALID_SECTOR_SIZE;
    
    fat16_state.fat_start += FAT16_boot->reserved_sectors * 512;
    
    root_start = fat16_state.fat_start + FAT16_boot->fat_size_sectors * 
        FAT16_boot->number_of_fats * 512;
    
    fat16_state.data_start = root_start + FAT16_boot->root_dir_entries * 
        sizeof(Fat16Entry);
        
    fat16_state.sectors_per_cluster = FAT16_boot->sectors_per_cluster;
    
    // Prepare for fat16_open_file(), cluster is not needed
    fat16_state.file_left = FAT16_boot->root_dir_entries * sizeof(Fat16Entry);
    fat16_state.cluster_left = 0xFFFFFFFF; // avoid FAT lookup with root dir

#ifdef DEBUG    
    printf("FAT start at %08X, root dir at %08X, data at %08X\n", 
           fat16_state.fat_start, root_start, fat16_state.data_start);
#endif
           
    fat16_seek(root_start);

    return 0;
}
Beispiel #2
0
char fat16_read_file(char bytes) { // returns the bytes read
#ifdef DEBUG   
    //printf("fat16_read_file: Cluster %d, bytes left %d/%d\n", fat16_state.cluster, fat16_state.file_left, fat16_state.cluster_left);
#endif
 
    if(fat16_state.file_left == 0)
        return 0;
    
    if(fat16_state.cluster_left == 0) {
        fat16_seek(fat16_state.fat_start + fat16_state.cluster*2);
        fat16_read(2);
        
        fat16_state.cluster = FAT16_ushort[0];
        fat16_state.cluster_left = fat16_state.sectors_per_cluster * 512;
        
        if(fat16_state.cluster == 0xFFFF) { // end of cluster chain
            fat16_state.file_left = 0;
            return 0;
        }
            
        // Go to first cluster
        fat16_seek(fat16_state.data_start + (fat16_state.cluster-2) * 
            fat16_state.sectors_per_cluster * 512);
        
#ifdef DEBUG    
        printf("Next cluster %d\n", fat16_state.cluster);
#endif
    }
    
    if(bytes > fat16_state.file_left)
        bytes = fat16_state.file_left;
    if(bytes > fat16_state.cluster_left)
        bytes = fat16_state.cluster_left;
        
    bytes = fat16_read(bytes);
    
    fat16_state.file_left -= bytes;
    fat16_state.cluster_left -= bytes;

#ifdef DEBUG   
    //printf("%d bytes read: Cluster %d, bytes left %d/%d\n", bytes, fat16_state.cluster, fat16_state.file_left, fat16_state.cluster_left);
#endif
    
    return bytes;
}
Beispiel #3
0
struct img_resource *img_load(struct fat16_handle *h, char *name)
{
	int rv;
	struct fat16_file fd;
	struct img_resource *r;
	
	printf("Loading image resource %s... ", name);
	if (fat16_open_by_name(h, &fd, name) == -1)
	{
		printf("not found?\r\n");
		return NULL;
	} 
	
	r = malloc(sizeof(*r));
	if (!r)
	{
		printf("out of memory?\r\n");
		return NULL;
	}
	
	r->pixels_orig = malloc(fd.len + 64);
	if (!r->pixels_orig)
	{
		printf("out of memory?\r\n");
		return NULL;
	}
	
	r->pixels = (unsigned int *)(((unsigned int)r->pixels_orig + 63) & ~63);

	rv = fat16_read(&fd, (void *)r, 8);
	
	rv = fat16_read(&fd, (void *)r->pixels, fd.len - 8);
	if (rv != fd.len - 8) {
		printf("short read (%d)\r\n", rv);
		free(r);
		return NULL;
	}

	printf("%dx%d image (pixels at %08x)\r\n", r->w, r->h, r->pixels);
	
	return r;
}
Beispiel #4
0
uint32_t fat16_open_file(struct fat16_buffer* buffer, const char* filename, const char* extension)
{
	for (uint16_t file_index = 0; file_index < 512; ++file_index)
	{
		uint8_t pos;
		fat16_seek(buffer, buffer->directory_start + (file_index * 32));
		fat16_read(buffer, 32);

		// attributes is non-zero on files.
		if (buffer->data[11] > 0)
		{
			for (pos = 0; pos < 8; ++pos)
			{
				if (buffer->data[pos] != filename[pos])
				{
					break;
				}
			}

			if (pos == 8)
			{
				// found the entry!
				for (pos = 0; pos < 3; ++pos)
				{
					if (buffer->data[8 + pos] != extension[pos])
					{
						break;
					}
				}

				if (pos == 3)
				{
					// 2 bytes for cluster at buffer.data[26]
					// 4 bytes for file size at buffer.data[28]
					buffer->cluster_offset = 0;
					buffer->current_cluster = (buffer->data[26] | ((uint16_t)buffer->data[27]) << 8);
					buffer->file_left = (buffer->data[28] |
						((uint32_t)buffer->data[29]) << 8 |
						((uint32_t)buffer->data[30]) << 16 |
						((uint32_t)buffer->data[31]) << 24);
					return buffer->file_left;
				}
			}
		}
	}
	return 0;
} // fat16_open_file
Beispiel #5
0
uint8_t fat16_read_file(struct fat16_buffer* buffer, uint8_t* data)
{
	if (buffer->file_left == 0)
	{
		return 0;
	}

	if (buffer->cluster_offset == FAT16_CLUSTER_SIZE)
	{
		// look up the next cluster (current cluster * 2 bytes)
		fat16_seek(buffer, buffer->fat_start + buffer->current_cluster * 2);
		fat16_read16(buffer, &buffer->current_cluster);
		buffer->cluster_offset = 0;
		if (buffer->current_cluster == 0xffff)
		{
			// done reading!
			return 0;
		}
	}

	uint32_t data_start = buffer->directory_start + 16384;
	data_start += ((buffer->current_cluster - 2) * FAT16_CLUSTER_SIZE) + buffer->cluster_offset;

	fat16_seek(buffer, data_start);

	uint8_t bytes_to_read;
	if (buffer->file_left > FAT16_BUFFER_SIZE)
	{
		bytes_to_read = FAT16_BUFFER_SIZE;
	}
	else
	{
		bytes_to_read = buffer->file_left;
	}
	fat16_read(buffer, bytes_to_read);
	for (uint8_t index = 0; index < bytes_to_read; ++index)
	{
		data[index] = buffer->data[index];
	}

	buffer->cluster_offset += bytes_to_read;
	buffer->file_left -= bytes_to_read;
	return bytes_to_read;
} // fat16_read_file