Mercurial > vba-clojure
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 #include <cstdio> | |
2 #include <cstring> | |
3 | |
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" | |
10 | |
11 #define FLASH_READ_ARRAY 0 | |
12 #define FLASH_CMD_1 1 | |
13 #define FLASH_CMD_2 2 | |
14 #define FLASH_AUTOSELECT 3 | |
15 #define FLASH_CMD_3 4 | |
16 #define FLASH_CMD_4 5 | |
17 #define FLASH_CMD_5 6 | |
18 #define FLASH_ERASE_COMPLETE 7 | |
19 #define FLASH_PROGRAM 8 | |
20 #define FLASH_SETBANK 9 | |
21 | |
22 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; | |
29 | |
30 static variable_desc flashSaveData[] = { | |
31 { &flashState, sizeof(int32) }, | |
32 { &flashReadState, sizeof(int32) }, | |
33 { &flashSaveMemory[0], 0x10000 }, | |
34 { NULL, 0 } | |
35 }; | |
36 | |
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 }; | |
44 | |
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 }; | |
53 | |
54 void flashReset() | |
55 { | |
56 flashState = FLASH_READ_ARRAY; | |
57 flashReadState = FLASH_READ_ARRAY; | |
58 flashBank = 0; | |
59 } | |
60 | |
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 } | |
71 | |
72 void flashSaveGame(gzFile gzFile) | |
73 { | |
74 utilWriteData(gzFile, flashSaveData3); | |
75 } | |
76 | |
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 else | |
88 { | |
89 utilReadData(gzFile, flashSaveData3); | |
90 } | |
91 } | |
92 | |
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 else | |
103 { | |
104 flashDeviceID = 0x13; //0x09; | |
105 flashManufacturerID = 0x62; //0xc2; | |
106 } | |
107 } | |
108 | |
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; | |
114 | |
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 ID | |
124 return u8(flashManufacturerID); | |
125 case 1: | |
126 // device ID | |
127 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 } | |
138 | |
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 else | |
148 { | |
149 saveType = 1; | |
150 cpuSaveGameFunc = sramWrite; | |
151 } | |
152 | |
153 (*cpuSaveGameFunc)(address, byte); | |
154 } | |
155 | |
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 else | |
171 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 else | |
199 { | |
200 flashState = FLASH_READ_ARRAY; | |
201 flashReadState = FLASH_READ_ARRAY; | |
202 } | |
203 } | |
204 else | |
205 { | |
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 else | |
216 { | |
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 else | |
227 { | |
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 ERASE | |
236 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 ERASE | |
245 memset(flashSaveMemory, 0, flashSize); | |
246 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; | |
247 flashReadState = FLASH_ERASE_COMPLETE; | |
248 } | |
249 else | |
250 { | |
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 else | |
264 { | |
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 } | |
285 |