Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_next_cluster() not completly implemented #7

Open
megatron-uk opened this issue Sep 15, 2015 · 0 comments
Open

get_next_cluster() not completly implemented #7

megatron-uk opened this issue Sep 15, 2015 · 0 comments

Comments

@megatron-uk
Copy link
Owner

This function, which reads the next cluster from the FAT, is not fully implemented. Only directories/files within the first cluster are reachable for now.

Current code is:

get_next_cluster(dir_entry, set)
char*   dir_entry;
char    set;
{

    /*
        Given a directory entry, read the FAT to see what its next cluster in the chain is.
        How to find a FAT entry for a cluster 
        A FAT entry is 32bits
        128 entries per sector (assuming sector = 512bytes)

        cluster_number == FAT entry number

        e.g. cluster_number 255
            255 / 128 = 1..... 
            sector = fs_fat_lba_begin + 1
            read sector 

        Input:
            char*   dir_entry   - pointer to directory entry structure.
            char    set         - if true, updates directory entry current cluster and current sector fields.

        Returns:
            0 on success and detection of the available next cluster.
            Non-zero on cluster not found or no next cluster.
    */

    char    fat_sector_lba[4];
    char    fat_sector_offset[4];
    char    skip_sectors[4];
    char    end_of_file[4];
    char    skip_records[4];
    char    next_cluster[4];

    end_of_file[0] = 0xFF;
    end_of_file[1] = 0xFF;
    end_of_file[2] = 0xFF;
    end_of_file[3] = 0xFF;

    restore_sector_buffer(0);

    zero_int32(fat_sector_lba);
    zero_int32(fat_sector_offset);
    zero_int32(skip_sectors);
    zero_int32(skip_records);

    /* Take a copy of the current cluster number - eg 255 */    
    copy_int32(fat_sector_offset, dir_entry + FILE_Cur_Cluster_os);

    /* Divide by 128 to get number of sectors in the FAT before the one that holds our desired cluster chain - eg 1 */
    div_pow_int32(fat_sector_offset, 7);

    /* Multiply the number of sectors found by the number of fat entries in one sector - eg 1 x 128 */
    mul_int32_int8(skip_sectors, fat_sector_offset, CLUSTER_FAT_ENTRIES_SECT);

    /* Subtract that number from the current cluster number - eg 255 - 128 = 127 
    This is how many 32bit records we need to skip in the sector buffer until we get to the one we want */
    sub_int32(skip_records, fat_sector_offset, skip_sectors);

    /* Add the offset onto the start sector for the fat to let the hardware know what sector of the disk to read */
    add_int32(fat_sector_lba, fs_fat_lba_begin, fat_sector_offset);

    everdrive_error = disk_read_single_sector(int32_to_int16_lsb(fat_sector_lba), int32_to_int16_msb(fat_sector_lba), sector_buffer);
    if (everdrive_error != ERR_NONE){
        return ERR_IO_ERROR;
    } else {
        /* TO DO - cannot use a 32bit number as an offset....*/
        memcpy(next_cluster, sector_buffer + (skip_records * CLUSTER_FAT_ENTRY_SIZE), CLUSTER_FAT_ENTRY_SIZE);
        /* test if valid next cluster */
        if (gte_int32(next_cluster, end_of_file)){
            /* invalid - current cluster is marked as last */
            return 1;   
        }
        /* if valid and if set then update cluster number */
        if (set == 1){
            /* update dir entry */
            /* TO DO - cannot use a 32bit number as an offset....*/
            mul_int32_int8(,skip_records, CLUSTER_FAT_ENTRY_SIZE)
            memcpy(dir_entry + FILE_Cur_Cluster_os, sector_buffer + sector_buffer_offset, FILE_Cur_Cluster_sz);

            /* correct endian-ness */
            swap_int32(dir_entry + FILE_Cur_Cluster_os);
            return 0;
        }
        /* if valid return 0 == next cluster found */
        return 0;
    }
}

There are some issues to work out - using the result of a 32bit multiply/add/subtract as an offset in a memcpy operation, for one.

Also need to refer back to the FAT docs I was using to make sure this logic for finding the next cluster in the chain is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant