rename expr.cpp.h to expr.c.h
[rofl0r-VisualBoyAdvance.git] / src / Flash.c
bloba04adc4a48e1dd295e2175860e4c76962ecf668c
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004-2006 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include <stdio.h>
20 #include <memory.h>
21 #include "GBA.h"
22 #include "Globals.h"
23 #include "Flash.h"
24 #include "Sram.h"
25 #include "Util.h"
27 #define FLASH_READ_ARRAY 0
28 #define FLASH_CMD_1 1
29 #define FLASH_CMD_2 2
30 #define FLASH_AUTOSELECT 3
31 #define FLASH_CMD_3 4
32 #define FLASH_CMD_4 5
33 #define FLASH_CMD_5 6
34 #define FLASH_ERASE_COMPLETE 7
35 #define FLASH_PROGRAM 8
36 #define FLASH_SETBANK 9
38 u8 flashSaveMemory[0x20000];
39 int flashState = FLASH_READ_ARRAY;
40 int flashReadState = FLASH_READ_ARRAY;
41 int flashSize = 0x10000;
42 int flashDeviceID = 0x1b;
43 int flashManufacturerID = 0x32;
44 int flashBank = 0;
46 static variable_desc flashSaveData[] = {
47 { &flashState, sizeof(int) },
48 { &flashReadState, sizeof(int) },
49 { &flashSaveMemory[0], 0x10000 },
50 { NULL, 0 }
53 static variable_desc flashSaveData2[] = {
54 { &flashState, sizeof(int) },
55 { &flashReadState, sizeof(int) },
56 { &flashSize, sizeof(int) },
57 { &flashSaveMemory[0], 0x20000 },
58 { NULL, 0 }
61 static variable_desc flashSaveData3[] = {
62 { &flashState, sizeof(int) },
63 { &flashReadState, sizeof(int) },
64 { &flashSize, sizeof(int) },
65 { &flashBank, sizeof(int) },
66 { &flashSaveMemory[0], 0x20000 },
67 { NULL, 0 }
70 void flashInit()
72 memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
75 void flashReset()
77 flashState = FLASH_READ_ARRAY;
78 flashReadState = FLASH_READ_ARRAY;
79 flashBank = 0;
82 void flashSaveGame(gzFile gzFile)
84 utilWriteData(gzFile, flashSaveData3);
87 void flashReadGame(gzFile gzFile, int version)
89 if(version < SAVE_GAME_VERSION_5)
90 utilReadData(gzFile, flashSaveData);
91 else if(version < SAVE_GAME_VERSION_7) {
92 utilReadData(gzFile, flashSaveData2);
93 flashBank = 0;
94 flashSetSize(flashSize);
95 } else {
96 utilReadData(gzFile, flashSaveData3);
100 void flashSetSize(int size)
102 // log("Setting flash size to %d\n", size);
103 if(size == 0x10000) {
104 flashDeviceID = 0x1b;
105 flashManufacturerID = 0x32;
106 } else {
107 flashDeviceID = 0x13; //0x09;
108 flashManufacturerID = 0x62; //0xc2;
110 // Added to make 64k saves compatible with 128k ones
111 // (allow wrongfuly set 64k saves to work for Pokemon games)
112 if ((size == 0x20000) && (flashSize == 0x10000))
113 memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
114 flashSize = size;
117 u8 flashRead(u32 address)
119 // log("Reading %08x from %08x\n", address, reg[15].I);
120 // log("Current read state is %d\n", flashReadState);
121 address &= 0xFFFF;
123 switch(flashReadState) {
124 case FLASH_READ_ARRAY:
125 return flashSaveMemory[(flashBank << 16) + address];
126 case FLASH_AUTOSELECT:
127 switch(address & 0xFF) {
128 case 0:
129 // manufacturer ID
130 return flashManufacturerID;
131 case 1:
132 // device ID
133 return flashDeviceID;
135 break;
136 case FLASH_ERASE_COMPLETE:
137 flashState = FLASH_READ_ARRAY;
138 flashReadState = FLASH_READ_ARRAY;
139 return 0xFF;
141 return 0;
144 void flashSaveDecide(u32 address, u8 byte)
146 // log("Deciding save type %08x\n", address);
147 if(address == 0x0e005555) {
148 saveType = 2;
149 cpuSaveGameFunc = flashWrite;
150 } else {
151 saveType = 1;
152 cpuSaveGameFunc = sramWrite;
155 (*cpuSaveGameFunc)(address, byte);
158 void flashDelayedWrite(u32 address, u8 byte)
160 saveType = 2;
161 cpuSaveGameFunc = flashWrite;
162 flashWrite(address, byte);
165 void flashWrite(u32 address, u8 byte)
167 // log("Writing %02x at %08x\n", byte, address);
168 // log("Current state is %d\n", flashState);
169 address &= 0xFFFF;
170 switch(flashState) {
171 case FLASH_READ_ARRAY:
172 if(address == 0x5555 && byte == 0xAA)
173 flashState = FLASH_CMD_1;
174 break;
175 case FLASH_CMD_1:
176 if(address == 0x2AAA && byte == 0x55)
177 flashState = FLASH_CMD_2;
178 else
179 flashState = FLASH_READ_ARRAY;
180 break;
181 case FLASH_CMD_2:
182 if(address == 0x5555) {
183 if(byte == 0x90) {
184 flashState = FLASH_AUTOSELECT;
185 flashReadState = FLASH_AUTOSELECT;
186 } else if(byte == 0x80) {
187 flashState = FLASH_CMD_3;
188 } else if(byte == 0xF0) {
189 flashState = FLASH_READ_ARRAY;
190 flashReadState = FLASH_READ_ARRAY;
191 } else if(byte == 0xA0) {
192 flashState = FLASH_PROGRAM;
193 } else if(byte == 0xB0 && flashSize == 0x20000) {
194 flashState = FLASH_SETBANK;
195 } else {
196 flashState = FLASH_READ_ARRAY;
197 flashReadState = FLASH_READ_ARRAY;
199 } else {
200 flashState = FLASH_READ_ARRAY;
201 flashReadState = FLASH_READ_ARRAY;
203 break;
204 case FLASH_CMD_3:
205 if(address == 0x5555 && byte == 0xAA) {
206 flashState = FLASH_CMD_4;
207 } else {
208 flashState = FLASH_READ_ARRAY;
209 flashReadState = FLASH_READ_ARRAY;
211 break;
212 case FLASH_CMD_4:
213 if(address == 0x2AAA && byte == 0x55) {
214 flashState = FLASH_CMD_5;
215 } else {
216 flashState = FLASH_READ_ARRAY;
217 flashReadState = FLASH_READ_ARRAY;
219 break;
220 case FLASH_CMD_5:
221 if(byte == 0x30) {
222 // SECTOR ERASE
223 memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
225 0x1000);
226 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
227 flashReadState = FLASH_ERASE_COMPLETE;
228 } else if(byte == 0x10) {
229 // CHIP ERASE
230 memset(flashSaveMemory, 0, flashSize);
231 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
232 flashReadState = FLASH_ERASE_COMPLETE;
233 } else {
234 flashState = FLASH_READ_ARRAY;
235 flashReadState = FLASH_READ_ARRAY;
237 break;
238 case FLASH_AUTOSELECT:
239 if(byte == 0xF0) {
240 flashState = FLASH_READ_ARRAY;
241 flashReadState = FLASH_READ_ARRAY;
242 } else if(address == 0x5555 && byte == 0xAA)
243 flashState = FLASH_CMD_1;
244 else {
245 flashState = FLASH_READ_ARRAY;
246 flashReadState = FLASH_READ_ARRAY;
248 break;
249 case FLASH_PROGRAM:
250 flashSaveMemory[(flashBank<<16)+address] = byte;
251 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
252 flashState = FLASH_READ_ARRAY;
253 flashReadState = FLASH_READ_ARRAY;
254 break;
255 case FLASH_SETBANK:
256 if(address == 0) {
257 flashBank = (byte & 1);
259 flashState = FLASH_READ_ARRAY;
260 flashReadState = FLASH_READ_ARRAY;
261 break;