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