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