remove more unportable ASM, obsoleting C_CORE define
[rofl0r-VisualBoyAdvance.git] / src / EEprom.c
blobb83cdfb8552bc76655701f36b6650134510c6de7
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2005 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 <memory.h>
20 #include "GBA.h"
21 #include "EEprom.h"
22 #include "Util.h"
24 extern int cpuDmaCount;
26 int eepromMode = EEPROM_IDLE;
27 int eepromByte = 0;
28 int eepromBits = 0;
29 int eepromAddress = 0;
30 u8 eepromData[0x2000];
31 u8 eepromBuffer[16];
32 bool eepromInUse = false;
33 int eepromSize = 512;
35 variable_desc eepromSaveData[] = {
36 { &eepromMode, sizeof(int) },
37 { &eepromByte, sizeof(int) },
38 { &eepromBits , sizeof(int) },
39 { &eepromAddress , sizeof(int) },
40 { &eepromInUse, sizeof(bool) },
41 { &eepromData[0], 512 },
42 { &eepromBuffer[0], 16 },
43 { NULL, 0 }
46 void eepromInit()
48 memset(eepromData, 255, sizeof(eepromData));
51 void eepromReset()
53 eepromMode = EEPROM_IDLE;
54 eepromByte = 0;
55 eepromBits = 0;
56 eepromAddress = 0;
57 eepromInUse = false;
58 eepromSize = 512;
61 void eepromSaveGame(gzFile gzFile)
63 utilWriteData(gzFile, eepromSaveData);
64 utilWriteInt(gzFile, eepromSize);
65 utilGzWrite(gzFile, eepromData, 0x2000);
68 void eepromReadGame(gzFile gzFile, int version)
70 utilReadData(gzFile, eepromSaveData);
71 if(version >= SAVE_GAME_VERSION_3) {
72 eepromSize = utilReadInt(gzFile);
73 utilGzRead(gzFile, eepromData, 0x2000);
74 } else {
75 // prior to 0.7.1, only 4K EEPROM was supported
76 eepromSize = 512;
81 int eepromRead(u32 unused/* address */)
83 switch(eepromMode) {
84 case EEPROM_IDLE:
85 case EEPROM_READADDRESS:
86 case EEPROM_WRITEDATA:
87 return 1;
88 case EEPROM_READDATA:
90 eepromBits++;
91 if(eepromBits == 4) {
92 eepromMode = EEPROM_READDATA2;
93 eepromBits = 0;
94 eepromByte = 0;
96 return 0;
98 case EEPROM_READDATA2:
100 int data = 0;
101 int address = eepromAddress << 3;
102 int mask = 1 << (7 - (eepromBits & 7));
103 data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
104 eepromBits++;
105 if((eepromBits & 7) == 0)
106 eepromByte++;
107 if(eepromBits == 0x40)
108 eepromMode = EEPROM_IDLE;
109 return data;
111 default:
112 return 0;
114 return 1;
117 void eepromWrite(u32 unused/* address */, u8 value)
119 if(cpuDmaCount == 0)
120 return;
121 int bit = value & 1;
122 switch(eepromMode) {
123 case EEPROM_IDLE:
124 eepromByte = 0;
125 eepromBits = 1;
126 eepromBuffer[eepromByte] = bit;
127 eepromMode = EEPROM_READADDRESS;
128 break;
129 case EEPROM_READADDRESS:
130 eepromBuffer[eepromByte] <<= 1;
131 eepromBuffer[eepromByte] |= bit;
132 eepromBits++;
133 if((eepromBits & 7) == 0) {
134 eepromByte++;
136 if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
137 if(eepromBits == 0x11) {
138 eepromInUse = true;
139 eepromSize = 0x2000;
140 eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
141 ((eepromBuffer[1] & 0xFF));
142 if(!(eepromBuffer[0] & 0x40)) {
143 eepromBuffer[0] = bit;
144 eepromBits = 1;
145 eepromByte = 0;
146 eepromMode = EEPROM_WRITEDATA;
147 } else {
148 eepromMode = EEPROM_READDATA;
149 eepromByte = 0;
150 eepromBits = 0;
153 } else {
154 if(eepromBits == 9) {
155 eepromInUse = true;
156 eepromAddress = (eepromBuffer[0] & 0x3F);
157 if(!(eepromBuffer[0] & 0x40)) {
158 eepromBuffer[0] = bit;
159 eepromBits = 1;
160 eepromByte = 0;
161 eepromMode = EEPROM_WRITEDATA;
162 } else {
163 eepromMode = EEPROM_READDATA;
164 eepromByte = 0;
165 eepromBits = 0;
169 break;
170 case EEPROM_READDATA:
171 case EEPROM_READDATA2:
172 // should we reset here?
173 eepromMode = EEPROM_IDLE;
174 break;
175 case EEPROM_WRITEDATA:
176 eepromBuffer[eepromByte] <<= 1;
177 eepromBuffer[eepromByte] |= bit;
178 eepromBits++;
179 if((eepromBits & 7) == 0) {
180 eepromByte++;
182 if(eepromBits == 0x40) {
183 eepromInUse = true;
184 // write data;
185 for(int i = 0; i < 8; i++) {
186 eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
188 systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
189 } else if(eepromBits == 0x41) {
190 eepromMode = EEPROM_IDLE;
191 eepromByte = 0;
192 eepromBits = 0;
194 break;