Mercurial > vba-clojure
diff src/gba/Flash.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gba/Flash.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,285 @@ 1.4 +#include <cstdio> 1.5 +#include <cstring> 1.6 + 1.7 +#include "Flash.h" 1.8 +#include "GBA.h" 1.9 +#include "GBAGlobals.h" 1.10 +#include "Sram.h" 1.11 +#include "../common/System.h" 1.12 +#include "../common/Util.h" 1.13 + 1.14 +#define FLASH_READ_ARRAY 0 1.15 +#define FLASH_CMD_1 1 1.16 +#define FLASH_CMD_2 2 1.17 +#define FLASH_AUTOSELECT 3 1.18 +#define FLASH_CMD_3 4 1.19 +#define FLASH_CMD_4 5 1.20 +#define FLASH_CMD_5 6 1.21 +#define FLASH_ERASE_COMPLETE 7 1.22 +#define FLASH_PROGRAM 8 1.23 +#define FLASH_SETBANK 9 1.24 + 1.25 +u8 flashSaveMemory[0x20000 + 4]; 1.26 +int32 flashState = FLASH_READ_ARRAY; 1.27 +int32 flashReadState = FLASH_READ_ARRAY; 1.28 +int32 flashSize = 0x10000; 1.29 +int32 flashDeviceID = 0x1b; 1.30 +int32 flashManufacturerID = 0x32; 1.31 +int32 flashBank = 0; 1.32 + 1.33 +static variable_desc flashSaveData[] = { 1.34 + { &flashState, sizeof(int32) }, 1.35 + { &flashReadState, sizeof(int32) }, 1.36 + { &flashSaveMemory[0], 0x10000 }, 1.37 + { NULL, 0 } 1.38 +}; 1.39 + 1.40 +static variable_desc flashSaveData2[] = { 1.41 + { &flashState, sizeof(int32) }, 1.42 + { &flashReadState, sizeof(int32) }, 1.43 + { &flashSize, sizeof(int32) }, 1.44 + { &flashSaveMemory[0], 0x20000 }, 1.45 + { NULL, 0 } 1.46 +}; 1.47 + 1.48 +static variable_desc flashSaveData3[] = { 1.49 + { &flashState, sizeof(int32) }, 1.50 + { &flashReadState, sizeof(int32) }, 1.51 + { &flashSize, sizeof(int32) }, 1.52 + { &flashBank, sizeof(int32) }, 1.53 + { &flashSaveMemory[0], 0x20000 }, 1.54 + { NULL, 0 } 1.55 +}; 1.56 + 1.57 +void flashReset() 1.58 +{ 1.59 + flashState = FLASH_READ_ARRAY; 1.60 + flashReadState = FLASH_READ_ARRAY; 1.61 + flashBank = 0; 1.62 +} 1.63 + 1.64 +void flashErase() 1.65 +{ 1.66 + memset(flashSaveMemory, 0, 0x20000*sizeof(u8)); 1.67 + flashState = FLASH_READ_ARRAY; 1.68 + flashReadState = FLASH_READ_ARRAY; 1.69 + flashSize = 0x10000; 1.70 + flashDeviceID = 0x1b; 1.71 + flashManufacturerID = 0x32; 1.72 + flashBank = 0; 1.73 +} 1.74 + 1.75 +void flashSaveGame(gzFile gzFile) 1.76 +{ 1.77 + utilWriteData(gzFile, flashSaveData3); 1.78 +} 1.79 + 1.80 +void flashReadGame(gzFile gzFile, int version) 1.81 +{ 1.82 + if (version < SAVE_GAME_VERSION_5) 1.83 + utilReadData(gzFile, flashSaveData); 1.84 + else if (version < SAVE_GAME_VERSION_7) 1.85 + { 1.86 + utilReadData(gzFile, flashSaveData2); 1.87 + flashBank = 0; 1.88 + flashSetSize(flashSize); 1.89 + } 1.90 + else 1.91 + { 1.92 + utilReadData(gzFile, flashSaveData3); 1.93 + } 1.94 +} 1.95 + 1.96 +void flashSetSize(int size) 1.97 +{ 1.98 + // log("Setting flash size to %d\n", size); 1.99 + flashSize = size; 1.100 + if (size == 0x10000) 1.101 + { 1.102 + flashDeviceID = 0x1b; 1.103 + flashManufacturerID = 0x32; 1.104 + } 1.105 + else 1.106 + { 1.107 + flashDeviceID = 0x13; //0x09; 1.108 + flashManufacturerID = 0x62; //0xc2; 1.109 + } 1.110 +} 1.111 + 1.112 +u8 flashRead(u32 address) 1.113 +{ 1.114 + // log("Reading %08x from %08x\n", address, reg[15].I); 1.115 + // log("Current read state is %d\n", flashReadState); 1.116 + address &= 0xFFFF; 1.117 + 1.118 + switch (flashReadState) 1.119 + { 1.120 + case FLASH_READ_ARRAY: 1.121 + return flashSaveMemory[(flashBank << 16) + address]; 1.122 + case FLASH_AUTOSELECT: 1.123 + switch (address & 0xFF) 1.124 + { 1.125 + case 0: 1.126 + // manufacturer ID 1.127 + return u8(flashManufacturerID); 1.128 + case 1: 1.129 + // device ID 1.130 + return u8(flashDeviceID); 1.131 + } 1.132 + break; 1.133 + case FLASH_ERASE_COMPLETE: 1.134 + flashState = FLASH_READ_ARRAY; 1.135 + flashReadState = FLASH_READ_ARRAY; 1.136 + return 0xFF; 1.137 + } 1.138 + ; 1.139 + return 0; 1.140 +} 1.141 + 1.142 +void flashSaveDecide(u32 address, u8 byte) 1.143 +{ 1.144 + // log("Deciding save type %08x\n", address); 1.145 + if (address == 0x0e005555) 1.146 + { 1.147 + saveType = 2; 1.148 + cpuSaveGameFunc = flashWrite; 1.149 + } 1.150 + else 1.151 + { 1.152 + saveType = 1; 1.153 + cpuSaveGameFunc = sramWrite; 1.154 + } 1.155 + 1.156 + (*cpuSaveGameFunc)(address, byte); 1.157 +} 1.158 + 1.159 +void flashWrite(u32 address, u8 byte) 1.160 +{ 1.161 + // log("Writing %02x at %08x\n", byte, address); 1.162 + // log("Current state is %d\n", flashState); 1.163 + address &= 0xFFFF; 1.164 + switch (flashState) 1.165 + { 1.166 + case FLASH_READ_ARRAY: 1.167 + if (address == 0x5555 && byte == 0xAA) 1.168 + flashState = FLASH_CMD_1; 1.169 + break; 1.170 + case FLASH_CMD_1: 1.171 + if (address == 0x2AAA && byte == 0x55) 1.172 + flashState = FLASH_CMD_2; 1.173 + else 1.174 + flashState = FLASH_READ_ARRAY; 1.175 + break; 1.176 + case FLASH_CMD_2: 1.177 + if (address == 0x5555) 1.178 + { 1.179 + if (byte == 0x90) 1.180 + { 1.181 + flashState = FLASH_AUTOSELECT; 1.182 + flashReadState = FLASH_AUTOSELECT; 1.183 + } 1.184 + else if (byte == 0x80) 1.185 + { 1.186 + flashState = FLASH_CMD_3; 1.187 + } 1.188 + else if (byte == 0xF0) 1.189 + { 1.190 + flashState = FLASH_READ_ARRAY; 1.191 + flashReadState = FLASH_READ_ARRAY; 1.192 + } 1.193 + else if (byte == 0xA0) 1.194 + { 1.195 + flashState = FLASH_PROGRAM; 1.196 + } 1.197 + else if (byte == 0xB0 && flashSize == 0x20000) 1.198 + { 1.199 + flashState = FLASH_SETBANK; 1.200 + } 1.201 + else 1.202 + { 1.203 + flashState = FLASH_READ_ARRAY; 1.204 + flashReadState = FLASH_READ_ARRAY; 1.205 + } 1.206 + } 1.207 + else 1.208 + { 1.209 + flashState = FLASH_READ_ARRAY; 1.210 + flashReadState = FLASH_READ_ARRAY; 1.211 + } 1.212 + break; 1.213 + case FLASH_CMD_3: 1.214 + if (address == 0x5555 && byte == 0xAA) 1.215 + { 1.216 + flashState = FLASH_CMD_4; 1.217 + } 1.218 + else 1.219 + { 1.220 + flashState = FLASH_READ_ARRAY; 1.221 + flashReadState = FLASH_READ_ARRAY; 1.222 + } 1.223 + break; 1.224 + case FLASH_CMD_4: 1.225 + if (address == 0x2AAA && byte == 0x55) 1.226 + { 1.227 + flashState = FLASH_CMD_5; 1.228 + } 1.229 + else 1.230 + { 1.231 + flashState = FLASH_READ_ARRAY; 1.232 + flashReadState = FLASH_READ_ARRAY; 1.233 + } 1.234 + break; 1.235 + case FLASH_CMD_5: 1.236 + if (byte == 0x30) 1.237 + { 1.238 + // SECTOR ERASE 1.239 + memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)], 1.240 + 0, 1.241 + 0x1000); 1.242 + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; 1.243 + flashReadState = FLASH_ERASE_COMPLETE; 1.244 + } 1.245 + else if (byte == 0x10) 1.246 + { 1.247 + // CHIP ERASE 1.248 + memset(flashSaveMemory, 0, flashSize); 1.249 + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; 1.250 + flashReadState = FLASH_ERASE_COMPLETE; 1.251 + } 1.252 + else 1.253 + { 1.254 + flashState = FLASH_READ_ARRAY; 1.255 + flashReadState = FLASH_READ_ARRAY; 1.256 + } 1.257 + break; 1.258 + case FLASH_AUTOSELECT: 1.259 + if (byte == 0xF0) 1.260 + { 1.261 + flashState = FLASH_READ_ARRAY; 1.262 + flashReadState = FLASH_READ_ARRAY; 1.263 + } 1.264 + else if (address == 0x5555 && byte == 0xAA) 1.265 + flashState = FLASH_CMD_1; 1.266 + else 1.267 + { 1.268 + flashState = FLASH_READ_ARRAY; 1.269 + flashReadState = FLASH_READ_ARRAY; 1.270 + } 1.271 + break; 1.272 + case FLASH_PROGRAM: 1.273 + flashSaveMemory[(flashBank<<16)+address] = byte; 1.274 + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; 1.275 + flashState = FLASH_READ_ARRAY; 1.276 + flashReadState = FLASH_READ_ARRAY; 1.277 + break; 1.278 + case FLASH_SETBANK: 1.279 + if (address == 0) 1.280 + { 1.281 + flashBank = (byte & 1); 1.282 + } 1.283 + flashState = FLASH_READ_ARRAY; 1.284 + flashReadState = FLASH_READ_ARRAY; 1.285 + break; 1.286 + } 1.287 +} 1.288 +