| 1 | #include "vmc.h" | 
 
 
 
 
 | 2 |  | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | // Fat table functions | 
 
 
 
 
 | 5 |  | 
 
 
 
 
 | 6 | unsigned int getFatEntry ( int fd, unsigned int cluster, unsigned int* indir_fat_clusters, GetFat_Mode Mode ) | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 |  | 
 
 
 
 
 | 9 | int unit = ( fd == g_Vmc_Image[ 0 ].fd ) ? 0 : 1; | 
 
 
 
 
 | 10 |  | 
 
 
 
 
 | 11 | // The fat index, aka which cluster we want to know about | 
 
 
 
 
 | 12 | unsigned int fat_index = cluster; | 
 
 
 
 
 | 13 |  | 
 
 
 
 
 | 14 | // The offset in the fat cluster where we can find information about the sector | 
 
 
 
 
 | 15 | unsigned int fat_offset = fat_index % ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 16 |  | 
 
 
 
 
 | 17 | // Which fat cluster that the information would be in | 
 
 
 
 
 | 18 | unsigned int indirect_index = fat_index / ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 19 |  | 
 
 
 
 
 | 20 | // The offset in the indirect fat cluster that points to the fat table we are interested in | 
 
 
 
 
 | 21 | unsigned int indirect_offset = indirect_index % ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 22 |  | 
 
 
 
 
 | 23 | // This gives the location of the fat_offset inside of the indirect fat cluster list.  Each indirect fat cluster can point to | 
 
 
 
 
 | 24 | // 256 regular fat clusters, and each fat cluster holds information on 256 sectors. | 
 
 
 
 
 | 25 | unsigned int dbl_indirect_index = fat_index / (  ( g_Vmc_Image[ unit ].cluster_size / 4 ) * ( g_Vmc_Image[ unit ].cluster_size / 4 )  ); | 
 
 
 
 
 | 26 |  | 
 
 
 
 
 | 27 | // Cache indirect file table? ( Generally we will be accessing the first part of it for most virtual memory cards ) | 
 
 
 
 
 | 28 | // Get the data for the indirect fat cluster ( as indicated by dbl_indirect_index ) | 
 
 
 
 
 | 29 | unsigned int indirect_cluster_num        = indir_fat_clusters[ dbl_indirect_index ]; | 
 
 
 
 
 | 30 |  | 
 
 
 
 
 | 31 | if ( g_Vmc_Image[ unit ].last_idc != indirect_cluster_num ) | 
 
 
 
 
 | 32 | readCluster ( fd, ( unsigned char* ) g_Vmc_Image[ unit ].indirect_cluster, indirect_cluster_num ); | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | g_Vmc_Image[ unit ].last_idc = indirect_cluster_num; | 
 
 
 
 
 | 35 |  | 
 
 
 
 
 | 36 | // Get the data from the fat cluster ( pointed to by the indirect fat cluster ) | 
 
 
 
 
 | 37 | unsigned int fat_cluster_num = g_Vmc_Image[ unit ].indirect_cluster[ indirect_offset ]; | 
 
 
 
 
 | 38 |  | 
 
 
 
 
 | 39 | if ( g_Vmc_Image[ unit ].last_cluster != fat_cluster_num ) | 
 
 
 
 
 | 40 | readCluster ( fd, ( unsigned char* ) g_Vmc_Image[ unit ].fat_cluster, fat_cluster_num ); | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | g_Vmc_Image[ unit ].last_cluster = fat_cluster_num; | 
 
 
 
 
 | 43 |  | 
 
 
 
 
 | 44 | // Check if the entry in the fat table corresponds to a free cluster or a eof cluster | 
 
 
 
 
 | 45 | if ( g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] == FREE_CLUSTER || g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] == EOF_CLUSTER ) | 
 
 
 
 
 | 46 | return g_Vmc_Image[ unit ].fat_cluster[ fat_offset ]; | 
 
 
 
 
 | 47 |  | 
 
 
 
 
 | 48 | if ( Mode == FAT_MASK ) | 
 
 
 
 
 | 49 | { | 
 
 
 
 
 | 50 |  | 
 
 
 
 
 | 51 | if ( g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] & MASK_CLUSTER ) | 
 
 
 
 
 | 52 | { | 
 
 
 
 
 | 53 |  | 
 
 
 
 
 | 54 | return MASK_CLUSTER; | 
 
 
 
 
 | 55 |  | 
 
 
 
 
 | 56 | } | 
 
 
 
 
 | 57 | else | 
 
 
 
 
 | 58 | { | 
 
 
 
 
 | 59 |  | 
 
 
 
 
 | 60 | return 0; | 
 
 
 
 
 | 61 |  | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | } | 
 
 
 
 
 | 65 |  | 
 
 
 
 
 | 66 | // Return the fat entry, but remove the most significant bit. | 
 
 
 
 
 | 67 | return g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] & FREE_CLUSTER; | 
 
 
 
 
 | 68 |  | 
 
 
 
 
 | 69 | } | 
 
 
 
 
 | 70 |  | 
 
 
 
 
 | 71 | unsigned int setFatEntry ( int fd, unsigned int cluster, unsigned int value, unsigned int* indir_fat_clusters, SetFat_Mode Mode ) | 
 
 
 
 
 | 72 | { | 
 
 
 
 
 | 73 |  | 
 
 
 
 
 | 74 | int unit = ( fd == g_Vmc_Image[ 0 ].fd ) ? 0 : 1; | 
 
 
 
 
 | 75 |  | 
 
 
 
 
 | 76 | // The fat index, aka which cluster we want to know about | 
 
 
 
 
 | 77 | unsigned int fat_index = cluster; | 
 
 
 
 
 | 78 |  | 
 
 
 
 
 | 79 | // The offset in the fat cluster where we can find information about the sector | 
 
 
 
 
 | 80 | unsigned int fat_offset = fat_index % ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 81 |  | 
 
 
 
 
 | 82 | // Which fat cluster that the information would be in | 
 
 
 
 
 | 83 | unsigned int indirect_index = fat_index / ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 84 |  | 
 
 
 
 
 | 85 | // The offset in the indirect fat cluster that points to the fat table we are interested in | 
 
 
 
 
 | 86 | unsigned int indirect_offset = indirect_index % ( g_Vmc_Image[ unit ].cluster_size / 4 ); | 
 
 
 
 
 | 87 |  | 
 
 
 
 
 | 88 | // This gives the location of the fat_offset inside of the indirect fat cluster list.  Each indirect fat cluster can point to | 
 
 
 
 
 | 89 | // 256 regular fat clusters, and each fat cluster holds information on 256 sectors. | 
 
 
 
 
 | 90 | unsigned int dbl_indirect_index = fat_index / (  ( g_Vmc_Image[ unit ].cluster_size / 4 ) * ( g_Vmc_Image[ unit ].cluster_size / 4 )  ); | 
 
 
 
 
 | 91 |  | 
 
 
 
 
 | 92 | // Cache indirect file table? ( Generally we will be accessing the first part of it for most virtual memory cards | 
 
 
 
 
 | 93 | // Get the data for the indirect fat cluster ( as indicated by dbl_indirect_index ) | 
 
 
 
 
 | 94 | unsigned int indirect_cluster_num        = indir_fat_clusters[ dbl_indirect_index ]; | 
 
 
 
 
 | 95 |  | 
 
 
 
 
 | 96 | if ( g_Vmc_Image[ unit ].last_idc != indirect_cluster_num ) | 
 
 
 
 
 | 97 | readCluster ( fd, ( unsigned char* ) g_Vmc_Image[ unit ].indirect_cluster, indirect_cluster_num ); | 
 
 
 
 
 | 98 |  | 
 
 
 
 
 | 99 | g_Vmc_Image[ unit ].last_idc = indirect_cluster_num; | 
 
 
 
 
 | 100 |  | 
 
 
 
 
 | 101 | // Get the data from the fat cluster ( pointed to by the indirect fat cluster ) | 
 
 
 
 
 | 102 | unsigned int fat_cluster_num = g_Vmc_Image[ unit ].indirect_cluster[ indirect_offset ]; | 
 
 
 
 
 | 103 |  | 
 
 
 
 
 | 104 | if ( g_Vmc_Image[ unit ].last_cluster != fat_cluster_num ) | 
 
 
 
 
 | 105 | readCluster ( fd, ( unsigned char* ) g_Vmc_Image[ unit ].fat_cluster, fat_cluster_num ); | 
 
 
 
 
 | 106 |  | 
 
 
 
 
 | 107 | g_Vmc_Image[ unit ].last_cluster = fat_cluster_num; | 
 
 
 
 
 | 108 |  | 
 
 
 
 
 | 109 | if ( value == FREE_CLUSTER || value == EOF_CLUSTER || Mode == FAT_RESET ) | 
 
 
 
 
 | 110 | { | 
 
 
 
 
 | 111 |  | 
 
 
 
 
 | 112 | g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] = value; | 
 
 
 
 
 | 113 |  | 
 
 
 
 
 | 114 | } | 
 
 
 
 
 | 115 | else | 
 
 
 
 
 | 116 | { | 
 
 
 
 
 | 117 |  | 
 
 
 
 
 | 118 | g_Vmc_Image[ unit ].fat_cluster[ fat_offset ] = value | MASK_CLUSTER; | 
 
 
 
 
 | 119 |  | 
 
 
 
 
 | 120 | } | 
 
 
 
 
 | 121 |  | 
 
 
 
 
 | 122 | writeCluster ( fd, ( unsigned char* ) g_Vmc_Image[ unit ].fat_cluster, fat_cluster_num ); | 
 
 
 
 
 | 123 |  | 
 
 
 
 
 | 124 | // Update last free cluster | 
 
 
 
 
 | 125 | if ( ( value == FREE_CLUSTER && Mode == FAT_SET ) || ( Mode == FAT_RESET ) ) | 
 
 
 
 
 | 126 | { | 
 
 
 
 
 | 127 |  | 
 
 
 
 
 | 128 | if ( cluster < g_Vmc_Image[ unit ].last_free_cluster ) | 
 
 
 
 
 | 129 | { | 
 
 
 
 
 | 130 |  | 
 
 
 
 
 | 131 | g_Vmc_Image[ unit ].last_free_cluster = cluster; | 
 
 
 
 
 | 132 |  | 
 
 
 
 
 | 133 | } | 
 
 
 
 
 | 134 |  | 
 
 
 
 
 | 135 | } | 
 
 
 
 
 | 136 |  | 
 
 
 
 
 | 137 | return 0; | 
 
 
 
 
 | 138 |  | 
 
 
 
 
 | 139 | } |