Mercurial > vba-clojure
view src/gba/EEprom.cpp @ 331:6ec288064d49
improved do-save-corruption
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 06 Apr 2012 12:18:58 -0500 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 #include <cstring>3 #include "GBA.h" // for SAVE_GAME_VERSION_34 #include "EEprom.h"5 #include "../common/System.h"6 #include "../common/Util.h"8 extern int32 cpuDmaCount;10 int32 eepromMode = EEPROM_IDLE;11 int32 eepromByte = 0;12 int32 eepromBits = 0;13 int32 eepromAddress = 0;14 u8 eepromData[0x2000];15 u8 eepromBuffer[16];16 bool8 eepromInUse = false;17 int32 eepromSize = 512;19 variable_desc eepromSaveData[] = {20 { &eepromMode, sizeof(int32) },21 { &eepromByte, sizeof(int32) },22 { &eepromBits, sizeof(int32) },23 { &eepromAddress, sizeof(int32) },24 { &eepromInUse, sizeof(bool8) },25 { &eepromData[0], 512 },26 { &eepromBuffer[0], 16 },27 { NULL, 0 }28 };30 void eepromReset()31 {32 eepromMode = EEPROM_IDLE;33 eepromByte = 0;34 eepromBits = 0;35 eepromAddress = 0;36 eepromInUse = false;37 eepromSize = 512;38 }40 void eepromErase()41 {42 memset(eepromData, 0, 0x2000*sizeof(u8));43 eepromMode = EEPROM_IDLE;44 eepromByte = 0;45 eepromBits = 0;46 eepromAddress = 0;47 memset(eepromBuffer, 0, 16*sizeof(u8));48 eepromInUse = false;49 eepromSize = 512;50 }52 void eepromSaveGame(gzFile gzFile)53 {54 utilWriteData(gzFile, eepromSaveData);55 utilWriteInt(gzFile, eepromSize);56 utilGzWrite(gzFile, eepromData, 0x2000);57 }59 void eepromReadGame(gzFile gzFile, int version)60 {61 utilReadData(gzFile, eepromSaveData);62 if (version >= SAVE_GAME_VERSION_3)63 {64 eepromSize = utilReadInt(gzFile);65 utilGzRead(gzFile, eepromData, 0x2000);66 }67 else68 {69 // prior to 0.7.1, only 4K EEPROM was supported70 eepromSize = 512;71 }72 }74 int eepromRead(u32 /* address */)75 {76 switch (eepromMode)77 {78 case EEPROM_IDLE:79 case EEPROM_READADDRESS:80 case EEPROM_WRITEDATA:81 return 1;82 case EEPROM_READDATA:83 {84 eepromBits++;85 if (eepromBits == 4)86 {87 eepromMode = EEPROM_READDATA2;88 eepromBits = 0;89 eepromByte = 0;90 }91 return 0;92 }93 case EEPROM_READDATA2:94 {95 int data = 0;96 int address = eepromAddress << 3;97 int mask = 1 << (7 - (eepromBits & 7));98 data = (eepromData[address+eepromByte] & mask) ? 1 : 0;99 eepromBits++;100 if ((eepromBits & 7) == 0)101 eepromByte++;102 if (eepromBits == 0x40)103 eepromMode = EEPROM_IDLE;104 return data;105 }106 default:107 return 0;108 }109 return 1;110 }112 void eepromWrite(u32 /* address */, u8 value)113 {114 if (cpuDmaCount == 0)115 return;116 int bit = value & 1;117 switch (eepromMode)118 {119 case EEPROM_IDLE:120 eepromByte = 0;121 eepromBits = 1;122 eepromBuffer[eepromByte] = bit;123 eepromMode = EEPROM_READADDRESS;124 break;125 case EEPROM_READADDRESS:126 eepromBuffer[eepromByte] <<= 1;127 eepromBuffer[eepromByte] |= bit;128 eepromBits++;129 if ((eepromBits & 7) == 0)130 {131 eepromByte++;132 }133 if (cpuDmaCount == 0x11 || cpuDmaCount == 0x51)134 {135 if (eepromBits == 0x11)136 {137 eepromInUse = true;138 eepromSize = 0x2000;139 eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |140 ((eepromBuffer[1] & 0xFF));141 if (!(eepromBuffer[0] & 0x40))142 {143 eepromBuffer[0] = bit;144 eepromBits = 1;145 eepromByte = 0;146 eepromMode = EEPROM_WRITEDATA;147 }148 else149 {150 eepromMode = EEPROM_READDATA;151 eepromByte = 0;152 eepromBits = 0;153 }154 }155 }156 else157 {158 if (eepromBits == 9)159 {160 eepromInUse = true;161 eepromAddress = (eepromBuffer[0] & 0x3F);162 if (!(eepromBuffer[0] & 0x40))163 {164 eepromBuffer[0] = bit;165 eepromBits = 1;166 eepromByte = 0;167 eepromMode = EEPROM_WRITEDATA;168 }169 else170 {171 eepromMode = EEPROM_READDATA;172 eepromByte = 0;173 eepromBits = 0;174 }175 }176 }177 break;178 case EEPROM_READDATA:179 case EEPROM_READDATA2:180 // should we reset here?181 eepromMode = EEPROM_IDLE;182 break;183 case EEPROM_WRITEDATA:184 eepromBuffer[eepromByte] <<= 1;185 eepromBuffer[eepromByte] |= bit;186 eepromBits++;187 if ((eepromBits & 7) == 0)188 {189 eepromByte++;190 }191 if (eepromBits == 0x40)192 {193 eepromInUse = true;194 // write data;195 for (int i = 0; i < 8; i++)196 {197 eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];198 }199 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;200 }201 else if (eepromBits == 0x41)202 {203 eepromMode = EEPROM_IDLE;204 eepromByte = 0;205 eepromBits = 0;206 }207 break;208 }209 }