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 +