Mercurial > vba-linux
diff src/gba/EEprom.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/EEprom.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,210 @@ 1.4 +#include <cstring> 1.5 + 1.6 +#include "GBA.h" // for SAVE_GAME_VERSION_3 1.7 +#include "EEprom.h" 1.8 +#include "../common/System.h" 1.9 +#include "../common/Util.h" 1.10 + 1.11 +extern int32 cpuDmaCount; 1.12 + 1.13 +int32 eepromMode = EEPROM_IDLE; 1.14 +int32 eepromByte = 0; 1.15 +int32 eepromBits = 0; 1.16 +int32 eepromAddress = 0; 1.17 +u8 eepromData[0x2000]; 1.18 +u8 eepromBuffer[16]; 1.19 +bool8 eepromInUse = false; 1.20 +int32 eepromSize = 512; 1.21 + 1.22 +variable_desc eepromSaveData[] = { 1.23 + { &eepromMode, sizeof(int32) }, 1.24 + { &eepromByte, sizeof(int32) }, 1.25 + { &eepromBits, sizeof(int32) }, 1.26 + { &eepromAddress, sizeof(int32) }, 1.27 + { &eepromInUse, sizeof(bool8) }, 1.28 + { &eepromData[0], 512 }, 1.29 + { &eepromBuffer[0], 16 }, 1.30 + { NULL, 0 } 1.31 +}; 1.32 + 1.33 +void eepromReset() 1.34 +{ 1.35 + eepromMode = EEPROM_IDLE; 1.36 + eepromByte = 0; 1.37 + eepromBits = 0; 1.38 + eepromAddress = 0; 1.39 + eepromInUse = false; 1.40 + eepromSize = 512; 1.41 +} 1.42 + 1.43 +void eepromErase() 1.44 +{ 1.45 + memset(eepromData, 0, 0x2000*sizeof(u8)); 1.46 + eepromMode = EEPROM_IDLE; 1.47 + eepromByte = 0; 1.48 + eepromBits = 0; 1.49 + eepromAddress = 0; 1.50 + memset(eepromBuffer, 0, 16*sizeof(u8)); 1.51 + eepromInUse = false; 1.52 + eepromSize = 512; 1.53 +} 1.54 + 1.55 +void eepromSaveGame(gzFile gzFile) 1.56 +{ 1.57 + utilWriteData(gzFile, eepromSaveData); 1.58 + utilWriteInt(gzFile, eepromSize); 1.59 + utilGzWrite(gzFile, eepromData, 0x2000); 1.60 +} 1.61 + 1.62 +void eepromReadGame(gzFile gzFile, int version) 1.63 +{ 1.64 + utilReadData(gzFile, eepromSaveData); 1.65 + if (version >= SAVE_GAME_VERSION_3) 1.66 + { 1.67 + eepromSize = utilReadInt(gzFile); 1.68 + utilGzRead(gzFile, eepromData, 0x2000); 1.69 + } 1.70 + else 1.71 + { 1.72 + // prior to 0.7.1, only 4K EEPROM was supported 1.73 + eepromSize = 512; 1.74 + } 1.75 +} 1.76 + 1.77 +int eepromRead(u32 /* address */) 1.78 +{ 1.79 + switch (eepromMode) 1.80 + { 1.81 + case EEPROM_IDLE: 1.82 + case EEPROM_READADDRESS: 1.83 + case EEPROM_WRITEDATA: 1.84 + return 1; 1.85 + case EEPROM_READDATA: 1.86 + { 1.87 + eepromBits++; 1.88 + if (eepromBits == 4) 1.89 + { 1.90 + eepromMode = EEPROM_READDATA2; 1.91 + eepromBits = 0; 1.92 + eepromByte = 0; 1.93 + } 1.94 + return 0; 1.95 + } 1.96 + case EEPROM_READDATA2: 1.97 + { 1.98 + int data = 0; 1.99 + int address = eepromAddress << 3; 1.100 + int mask = 1 << (7 - (eepromBits & 7)); 1.101 + data = (eepromData[address+eepromByte] & mask) ? 1 : 0; 1.102 + eepromBits++; 1.103 + if ((eepromBits & 7) == 0) 1.104 + eepromByte++; 1.105 + if (eepromBits == 0x40) 1.106 + eepromMode = EEPROM_IDLE; 1.107 + return data; 1.108 + } 1.109 + default: 1.110 + return 0; 1.111 + } 1.112 + return 1; 1.113 +} 1.114 + 1.115 +void eepromWrite(u32 /* address */, u8 value) 1.116 +{ 1.117 + if (cpuDmaCount == 0) 1.118 + return; 1.119 + int bit = value & 1; 1.120 + switch (eepromMode) 1.121 + { 1.122 + case EEPROM_IDLE: 1.123 + eepromByte = 0; 1.124 + eepromBits = 1; 1.125 + eepromBuffer[eepromByte] = bit; 1.126 + eepromMode = EEPROM_READADDRESS; 1.127 + break; 1.128 + case EEPROM_READADDRESS: 1.129 + eepromBuffer[eepromByte] <<= 1; 1.130 + eepromBuffer[eepromByte] |= bit; 1.131 + eepromBits++; 1.132 + if ((eepromBits & 7) == 0) 1.133 + { 1.134 + eepromByte++; 1.135 + } 1.136 + if (cpuDmaCount == 0x11 || cpuDmaCount == 0x51) 1.137 + { 1.138 + if (eepromBits == 0x11) 1.139 + { 1.140 + eepromInUse = true; 1.141 + eepromSize = 0x2000; 1.142 + eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) | 1.143 + ((eepromBuffer[1] & 0xFF)); 1.144 + if (!(eepromBuffer[0] & 0x40)) 1.145 + { 1.146 + eepromBuffer[0] = bit; 1.147 + eepromBits = 1; 1.148 + eepromByte = 0; 1.149 + eepromMode = EEPROM_WRITEDATA; 1.150 + } 1.151 + else 1.152 + { 1.153 + eepromMode = EEPROM_READDATA; 1.154 + eepromByte = 0; 1.155 + eepromBits = 0; 1.156 + } 1.157 + } 1.158 + } 1.159 + else 1.160 + { 1.161 + if (eepromBits == 9) 1.162 + { 1.163 + eepromInUse = true; 1.164 + eepromAddress = (eepromBuffer[0] & 0x3F); 1.165 + if (!(eepromBuffer[0] & 0x40)) 1.166 + { 1.167 + eepromBuffer[0] = bit; 1.168 + eepromBits = 1; 1.169 + eepromByte = 0; 1.170 + eepromMode = EEPROM_WRITEDATA; 1.171 + } 1.172 + else 1.173 + { 1.174 + eepromMode = EEPROM_READDATA; 1.175 + eepromByte = 0; 1.176 + eepromBits = 0; 1.177 + } 1.178 + } 1.179 + } 1.180 + break; 1.181 + case EEPROM_READDATA: 1.182 + case EEPROM_READDATA2: 1.183 + // should we reset here? 1.184 + eepromMode = EEPROM_IDLE; 1.185 + break; 1.186 + case EEPROM_WRITEDATA: 1.187 + eepromBuffer[eepromByte] <<= 1; 1.188 + eepromBuffer[eepromByte] |= bit; 1.189 + eepromBits++; 1.190 + if ((eepromBits & 7) == 0) 1.191 + { 1.192 + eepromByte++; 1.193 + } 1.194 + if (eepromBits == 0x40) 1.195 + { 1.196 + eepromInUse = true; 1.197 + // write data; 1.198 + for (int i = 0; i < 8; i++) 1.199 + { 1.200 + eepromData[(eepromAddress << 3) + i] = eepromBuffer[i]; 1.201 + } 1.202 + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; 1.203 + } 1.204 + else if (eepromBits == 0x41) 1.205 + { 1.206 + eepromMode = EEPROM_IDLE; 1.207 + eepromByte = 0; 1.208 + eepromBits = 0; 1.209 + } 1.210 + break; 1.211 + } 1.212 +} 1.213 +