Mercurial > vba-linux
view src/gba/Flash.cpp @ 39:3e36553d0cbf
got some speedruns to work!
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 05 Mar 2012 16:37:38 -0600 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 #include <cstdio>2 #include <cstring>4 #include "Flash.h"5 #include "GBA.h"6 #include "GBAGlobals.h"7 #include "Sram.h"8 #include "../common/System.h"9 #include "../common/Util.h"11 #define FLASH_READ_ARRAY 012 #define FLASH_CMD_1 113 #define FLASH_CMD_2 214 #define FLASH_AUTOSELECT 315 #define FLASH_CMD_3 416 #define FLASH_CMD_4 517 #define FLASH_CMD_5 618 #define FLASH_ERASE_COMPLETE 719 #define FLASH_PROGRAM 820 #define FLASH_SETBANK 922 u8 flashSaveMemory[0x20000 + 4];23 int32 flashState = FLASH_READ_ARRAY;24 int32 flashReadState = FLASH_READ_ARRAY;25 int32 flashSize = 0x10000;26 int32 flashDeviceID = 0x1b;27 int32 flashManufacturerID = 0x32;28 int32 flashBank = 0;30 static variable_desc flashSaveData[] = {31 { &flashState, sizeof(int32) },32 { &flashReadState, sizeof(int32) },33 { &flashSaveMemory[0], 0x10000 },34 { NULL, 0 }35 };37 static variable_desc flashSaveData2[] = {38 { &flashState, sizeof(int32) },39 { &flashReadState, sizeof(int32) },40 { &flashSize, sizeof(int32) },41 { &flashSaveMemory[0], 0x20000 },42 { NULL, 0 }43 };45 static variable_desc flashSaveData3[] = {46 { &flashState, sizeof(int32) },47 { &flashReadState, sizeof(int32) },48 { &flashSize, sizeof(int32) },49 { &flashBank, sizeof(int32) },50 { &flashSaveMemory[0], 0x20000 },51 { NULL, 0 }52 };54 void flashReset()55 {56 flashState = FLASH_READ_ARRAY;57 flashReadState = FLASH_READ_ARRAY;58 flashBank = 0;59 }61 void flashErase()62 {63 memset(flashSaveMemory, 0, 0x20000*sizeof(u8));64 flashState = FLASH_READ_ARRAY;65 flashReadState = FLASH_READ_ARRAY;66 flashSize = 0x10000;67 flashDeviceID = 0x1b;68 flashManufacturerID = 0x32;69 flashBank = 0;70 }72 void flashSaveGame(gzFile gzFile)73 {74 utilWriteData(gzFile, flashSaveData3);75 }77 void flashReadGame(gzFile gzFile, int version)78 {79 if (version < SAVE_GAME_VERSION_5)80 utilReadData(gzFile, flashSaveData);81 else if (version < SAVE_GAME_VERSION_7)82 {83 utilReadData(gzFile, flashSaveData2);84 flashBank = 0;85 flashSetSize(flashSize);86 }87 else88 {89 utilReadData(gzFile, flashSaveData3);90 }91 }93 void flashSetSize(int size)94 {95 // log("Setting flash size to %d\n", size);96 flashSize = size;97 if (size == 0x10000)98 {99 flashDeviceID = 0x1b;100 flashManufacturerID = 0x32;101 }102 else103 {104 flashDeviceID = 0x13; //0x09;105 flashManufacturerID = 0x62; //0xc2;106 }107 }109 u8 flashRead(u32 address)110 {111 // log("Reading %08x from %08x\n", address, reg[15].I);112 // log("Current read state is %d\n", flashReadState);113 address &= 0xFFFF;115 switch (flashReadState)116 {117 case FLASH_READ_ARRAY:118 return flashSaveMemory[(flashBank << 16) + address];119 case FLASH_AUTOSELECT:120 switch (address & 0xFF)121 {122 case 0:123 // manufacturer ID124 return u8(flashManufacturerID);125 case 1:126 // device ID127 return u8(flashDeviceID);128 }129 break;130 case FLASH_ERASE_COMPLETE:131 flashState = FLASH_READ_ARRAY;132 flashReadState = FLASH_READ_ARRAY;133 return 0xFF;134 }135 ;136 return 0;137 }139 void flashSaveDecide(u32 address, u8 byte)140 {141 // log("Deciding save type %08x\n", address);142 if (address == 0x0e005555)143 {144 saveType = 2;145 cpuSaveGameFunc = flashWrite;146 }147 else148 {149 saveType = 1;150 cpuSaveGameFunc = sramWrite;151 }153 (*cpuSaveGameFunc)(address, byte);154 }156 void flashWrite(u32 address, u8 byte)157 {158 // log("Writing %02x at %08x\n", byte, address);159 // log("Current state is %d\n", flashState);160 address &= 0xFFFF;161 switch (flashState)162 {163 case FLASH_READ_ARRAY:164 if (address == 0x5555 && byte == 0xAA)165 flashState = FLASH_CMD_1;166 break;167 case FLASH_CMD_1:168 if (address == 0x2AAA && byte == 0x55)169 flashState = FLASH_CMD_2;170 else171 flashState = FLASH_READ_ARRAY;172 break;173 case FLASH_CMD_2:174 if (address == 0x5555)175 {176 if (byte == 0x90)177 {178 flashState = FLASH_AUTOSELECT;179 flashReadState = FLASH_AUTOSELECT;180 }181 else if (byte == 0x80)182 {183 flashState = FLASH_CMD_3;184 }185 else if (byte == 0xF0)186 {187 flashState = FLASH_READ_ARRAY;188 flashReadState = FLASH_READ_ARRAY;189 }190 else if (byte == 0xA0)191 {192 flashState = FLASH_PROGRAM;193 }194 else if (byte == 0xB0 && flashSize == 0x20000)195 {196 flashState = FLASH_SETBANK;197 }198 else199 {200 flashState = FLASH_READ_ARRAY;201 flashReadState = FLASH_READ_ARRAY;202 }203 }204 else205 {206 flashState = FLASH_READ_ARRAY;207 flashReadState = FLASH_READ_ARRAY;208 }209 break;210 case FLASH_CMD_3:211 if (address == 0x5555 && byte == 0xAA)212 {213 flashState = FLASH_CMD_4;214 }215 else216 {217 flashState = FLASH_READ_ARRAY;218 flashReadState = FLASH_READ_ARRAY;219 }220 break;221 case FLASH_CMD_4:222 if (address == 0x2AAA && byte == 0x55)223 {224 flashState = FLASH_CMD_5;225 }226 else227 {228 flashState = FLASH_READ_ARRAY;229 flashReadState = FLASH_READ_ARRAY;230 }231 break;232 case FLASH_CMD_5:233 if (byte == 0x30)234 {235 // SECTOR ERASE236 memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],237 0,238 0x1000);239 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;240 flashReadState = FLASH_ERASE_COMPLETE;241 }242 else if (byte == 0x10)243 {244 // CHIP ERASE245 memset(flashSaveMemory, 0, flashSize);246 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;247 flashReadState = FLASH_ERASE_COMPLETE;248 }249 else250 {251 flashState = FLASH_READ_ARRAY;252 flashReadState = FLASH_READ_ARRAY;253 }254 break;255 case FLASH_AUTOSELECT:256 if (byte == 0xF0)257 {258 flashState = FLASH_READ_ARRAY;259 flashReadState = FLASH_READ_ARRAY;260 }261 else if (address == 0x5555 && byte == 0xAA)262 flashState = FLASH_CMD_1;263 else264 {265 flashState = FLASH_READ_ARRAY;266 flashReadState = FLASH_READ_ARRAY;267 }268 break;269 case FLASH_PROGRAM:270 flashSaveMemory[(flashBank<<16)+address] = byte;271 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;272 flashState = FLASH_READ_ARRAY;273 flashReadState = FLASH_READ_ARRAY;274 break;275 case FLASH_SETBANK:276 if (address == 0)277 {278 flashBank = (byte & 1);279 }280 flashState = FLASH_READ_ARRAY;281 flashReadState = FLASH_READ_ARRAY;282 break;283 }284 }