view src/gba/Flash.cpp @ 395:6ab872c5a7e7

set H for real
author Robert McIntyre <rlm@mit.edu>
date Fri, 13 Apr 2012 04:37:12 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include <cstdio>
2 #include <cstring>
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"
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
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;
30 static variable_desc flashSaveData[] = {
31 { &flashState, sizeof(int32) },
32 { &flashReadState, sizeof(int32) },
33 { &flashSaveMemory[0], 0x10000 },
34 { NULL, 0 }
35 };
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 };
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 };
54 void flashReset()
55 {
56 flashState = FLASH_READ_ARRAY;
57 flashReadState = FLASH_READ_ARRAY;
58 flashBank = 0;
59 }
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 }
72 void flashSaveGame(gzFile gzFile)
73 {
74 utilWriteData(gzFile, flashSaveData3);
75 }
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 }
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 }
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;
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 }
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 }
153 (*cpuSaveGameFunc)(address, byte);
154 }
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 }