1 #include <memory.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <ctype.h>
5 
6 #include "GBA.h"
7 #include "GBAinline.h"
8 #include "Cheats.h"
9 #include "Globals.h"
10 #include "../NLS.h"
11 #include "../Util.h"
12 
13 /**
14  * Gameshark code types: (based on AR v1.0)
15  *
16  * NNNNNNNN 001DC0DE - ID code for the game (game 4 character name) from ROM
17  * DEADFACE XXXXXXXX - changes decryption seeds // Not supported by VBA.
18  * 0AAAAAAA 000000YY - 8-bit constant write
19  * 1AAAAAAA 0000YYYY - 16-bit constant write
20  * 2AAAAAAA YYYYYYYY - 32-bit constant write
21  * 30XXAAAA YYYYYYYY - 32bit Group Write, 8/16/32bit Sub/Add (depending on the XX value).
22  * 6AAAAAAA Z000YYYY - 16-bit ROM Patch (address >> 1). Z selects the Rom Patching register.
23  *                   - AR v1/2 hardware only supports Z=0.
24  *                   - AR v3 hardware should support Z=0,1,2 or 3.
25  * 8A1AAAAA 000000YY - 8-bit button write
26  * 8A2AAAAA 0000YYYY - 16-bit button write
27  * 8A4AAAAA YYYYYYYY - 32-bit button write // BUGGY ! Only writes 00000000 on the AR v1.0.
28  * 80F00000 0000YYYY - button slow motion
29  * DAAAAAAA 00Z0YYYY - Z = 0 : if 16-bit value at address != YYYY skip next line
30  *                   - Z = 1 : if 16-bit value at address == YYYY skip next line
31  *                   - Z = 2 : if 16-bit value at address > YYYY (Unsigned) skip next line
32  *                   - Z = 3 : if 16-bit value at address < YYYY (Unsigned) skip next line
33  * E0CCYYYY ZAAAAAAA - Z = 0 : if 16-bit value at address != YYYY skip CC lines
34  *                   - Z = 1 : if 16-bit value at address == YYYY skip CC lines
35  *                   - Z = 2 : if 16-bit value at address > YYYY (Unsigned) skip CC lines
36  *                   - Z = 3 : if 16-bit value at address < YYYY (Unsigned) skip CC lines
37  * FAAAAAAA 0000YYYY - Master code function
38  *
39  *
40  *
41  * CodeBreaker codes types: (based on the CBA clone "Cheatcode S" v1.1)
42  *
43  * 0000AAAA 000Y - Game CRC (Y are flags: 8 - CRC, 2 - DI)
44  * 1AAAAAAA YYYY - Master Code function (store address at ((YYYY << 0x16)
45  *                 + 0x08000100))
46  * 2AAAAAAA YYYY - 16-bit or
47  * 3AAAAAAA YYYY - 8-bit constant write
48  * 4AAAAAAA YYYY - Slide code
49  * XXXXCCCC IIII   (C is count and I is address increment, X is value incr.)
50  * 5AAAAAAA CCCC - Super code (Write bytes to address, 2*CCCC is count)
51  * BBBBBBBB BBBB
52  * 6AAAAAAA YYYY - 16-bit and
53  * 7AAAAAAA YYYY - if address contains 16-bit value enable next code
54  * 8AAAAAAA YYYY - 16-bit constant write
55  * 9AAAAAAA YYYY - change decryption (when first code only?)
56  * AAAAAAAA YYYY - if address does not contain 16-bit value enable next code
57  * BAAAAAAA YYYY - if 16-bit value at address  <= YYYY skip next code
58  * CAAAAAAA YYYY - if 16-bit value at address  >= YYYY skip next code
59  * D00000X0 YYYY - if button keys ... enable next code (else skip next code)
60  * EAAAAAAA YYYY - increase 16/32bit value stored in address
61  * FAAAAAAA YYYY - if 16-bit value at address AND YYYY = 0 then skip next code
62  **/
63 
64 #define UNKNOWN_CODE                  -1
65 #define INT_8_BIT_WRITE               0
66 #define INT_16_BIT_WRITE              1
67 #define INT_32_BIT_WRITE              2
68 #define GSA_16_BIT_ROM_PATCH          3
69 #define GSA_8_BIT_GS_WRITE            4
70 #define GSA_16_BIT_GS_WRITE           5
71 #define GSA_32_BIT_GS_WRITE           6
72 #define CBA_IF_KEYS_PRESSED           7
73 #define CBA_IF_TRUE                   8
74 #define CBA_SLIDE_CODE                9
75 #define CBA_IF_FALSE                  10
76 #define CBA_AND                       11
77 #define GSA_8_BIT_GS_WRITE2           12
78 #define GSA_16_BIT_GS_WRITE2          13
79 #define GSA_32_BIT_GS_WRITE2          14
80 #define GSA_16_BIT_ROM_PATCH2C        15
81 #define GSA_8_BIT_SLIDE               16
82 #define GSA_16_BIT_SLIDE              17
83 #define GSA_32_BIT_SLIDE              18
84 #define GSA_8_BIT_IF_TRUE             19
85 #define GSA_32_BIT_IF_TRUE            20
86 #define GSA_8_BIT_IF_FALSE            21
87 #define GSA_32_BIT_IF_FALSE           22
88 #define GSA_8_BIT_FILL                23
89 #define GSA_16_BIT_FILL               24
90 #define GSA_8_BIT_IF_TRUE2            25
91 #define GSA_16_BIT_IF_TRUE2           26
92 #define GSA_32_BIT_IF_TRUE2           27
93 #define GSA_8_BIT_IF_FALSE2           28
94 #define GSA_16_BIT_IF_FALSE2          29
95 #define GSA_32_BIT_IF_FALSE2          30
96 #define GSA_SLOWDOWN                  31
97 #define CBA_ADD                       32
98 #define CBA_OR                        33
99 #define CBA_LT                        34
100 #define CBA_GT                        35
101 #define CBA_SUPER                     36
102 #define GSA_8_BIT_POINTER             37
103 #define GSA_16_BIT_POINTER            38
104 #define GSA_32_BIT_POINTER            39
105 #define GSA_8_BIT_ADD                 40
106 #define GSA_16_BIT_ADD                41
107 #define GSA_32_BIT_ADD                42
108 #define GSA_8_BIT_IF_LOWER_U          43
109 #define GSA_16_BIT_IF_LOWER_U         44
110 #define GSA_32_BIT_IF_LOWER_U         45
111 #define GSA_8_BIT_IF_HIGHER_U         46
112 #define GSA_16_BIT_IF_HIGHER_U        47
113 #define GSA_32_BIT_IF_HIGHER_U        48
114 #define GSA_8_BIT_IF_AND              49
115 #define GSA_16_BIT_IF_AND             50
116 #define GSA_32_BIT_IF_AND             51
117 #define GSA_8_BIT_IF_LOWER_U2         52
118 #define GSA_16_BIT_IF_LOWER_U2        53
119 #define GSA_32_BIT_IF_LOWER_U2        54
120 #define GSA_8_BIT_IF_HIGHER_U2        55
121 #define GSA_16_BIT_IF_HIGHER_U2       56
122 #define GSA_32_BIT_IF_HIGHER_U2       57
123 #define GSA_8_BIT_IF_AND2             58
124 #define GSA_16_BIT_IF_AND2            59
125 #define GSA_32_BIT_IF_AND2            60
126 #define GSA_ALWAYS                    61
127 #define GSA_ALWAYS2                   62
128 #define GSA_8_BIT_IF_LOWER_S          63
129 #define GSA_16_BIT_IF_LOWER_S         64
130 #define GSA_32_BIT_IF_LOWER_S         65
131 #define GSA_8_BIT_IF_HIGHER_S         66
132 #define GSA_16_BIT_IF_HIGHER_S        67
133 #define GSA_32_BIT_IF_HIGHER_S        68
134 #define GSA_8_BIT_IF_LOWER_S2         69
135 #define GSA_16_BIT_IF_LOWER_S2        70
136 #define GSA_32_BIT_IF_LOWER_S2        71
137 #define GSA_8_BIT_IF_HIGHER_S2        72
138 #define GSA_16_BIT_IF_HIGHER_S2       73
139 #define GSA_32_BIT_IF_HIGHER_S2       74
140 #define GSA_16_BIT_WRITE_IOREGS       75
141 #define GSA_32_BIT_WRITE_IOREGS       76
142 #define GSA_CODES_ON                  77
143 #define GSA_8_BIT_IF_TRUE3            78
144 #define GSA_16_BIT_IF_TRUE3           79
145 #define GSA_32_BIT_IF_TRUE3           80
146 #define GSA_8_BIT_IF_FALSE3           81
147 #define GSA_16_BIT_IF_FALSE3          82
148 #define GSA_32_BIT_IF_FALSE3          83
149 #define GSA_8_BIT_IF_LOWER_S3         84
150 #define GSA_16_BIT_IF_LOWER_S3        85
151 #define GSA_32_BIT_IF_LOWER_S3        86
152 #define GSA_8_BIT_IF_HIGHER_S3        87
153 #define GSA_16_BIT_IF_HIGHER_S3       88
154 #define GSA_32_BIT_IF_HIGHER_S3       89
155 #define GSA_8_BIT_IF_LOWER_U3         90
156 #define GSA_16_BIT_IF_LOWER_U3        91
157 #define GSA_32_BIT_IF_LOWER_U3        92
158 #define GSA_8_BIT_IF_HIGHER_U3        93
159 #define GSA_16_BIT_IF_HIGHER_U3       94
160 #define GSA_32_BIT_IF_HIGHER_U3       95
161 #define GSA_8_BIT_IF_AND3             96
162 #define GSA_16_BIT_IF_AND3            97
163 #define GSA_32_BIT_IF_AND3            98
164 #define GSA_ALWAYS3                   99
165 #define GSA_16_BIT_ROM_PATCH2D        100
166 #define GSA_16_BIT_ROM_PATCH2E        101
167 #define GSA_16_BIT_ROM_PATCH2F        102
168 #define GSA_GROUP_WRITE               103
169 #define GSA_32_BIT_ADD2               104
170 #define GSA_32_BIT_SUB2               105
171 #define GSA_16_BIT_IF_LOWER_OR_EQ_U   106
172 #define GSA_16_BIT_IF_HIGHER_OR_EQ_U  107
173 #define GSA_16_BIT_MIF_TRUE           108
174 #define GSA_16_BIT_MIF_FALSE          109
175 #define GSA_16_BIT_MIF_LOWER_OR_EQ_U  110
176 #define GSA_16_BIT_MIF_HIGHER_OR_EQ_U 111
177 #define MASTER_CODE                   112
178 #define CHEATS_16_BIT_WRITE           114
179 #define CHEATS_32_BIT_WRITE           115
180 
181 CheatsData cheatsList[MAX_CHEATS];
182 int cheatsNumber = 0;
183 u32 rompatch2addr [4];
184 u16 rompatch2val [4];
185 u16 rompatch2oldval [4];
186 
187 u8 cheatsCBASeedBuffer[0x30];
188 u32 cheatsCBASeed[4];
189 u32 cheatsCBATemporaryValue = 0;
190 u16 cheatsCBATable[256];
191 bool cheatsCBATableGenerated = false;
192 u16 super = 0;
193 extern u32 mastercode;
194 
195 u8 cheatsCBACurrentSeed[12] = {
196   0x00, 0x00, 0x00, 0x00,
197   0x00, 0x00, 0x00, 0x00,
198   0x00, 0x00, 0x00, 0x00
199 };
200 
201 u32 seeds_v1[4];
202 u32 seeds_v3[4];
203 
204 u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2);
205 
206 //seed tables for AR v1
207 u8 v1_deadtable1[256] = {
208 	0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37, 0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94,
209 	0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17, 0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B,
210 	0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF, 0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45,
211 	0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75, 0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9,
212 	0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F, 0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA,
213 	0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61, 0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E,
214 	0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20, 0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79,
215 	0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01, 0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31,
216 	0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9, 0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B,
217 	0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D, 0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB,
218 	0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62, 0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77,
219 	0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE, 0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93,
220 	0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15, 0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25,
221 	0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC, 0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52,
222 	0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08, 0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F,
223 	0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE, 0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50
224 };
225 u8 v1_deadtable2[256] = {
226 	0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C, 0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6,
227 	0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87, 0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1,
228 	0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59, 0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B,
229 	0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85, 0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48,
230 	0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A, 0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6,
231 	0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A, 0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8,
232 	0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6, 0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE,
233 	0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E, 0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39,
234 	0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35, 0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B,
235 	0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A, 0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4,
236 	0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F, 0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5,
237 	0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55, 0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90,
238 	0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D, 0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75,
239 	0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7, 0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76,
240 	0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6, 0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2,
241 	0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49, 0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C
242 };
243 
244 //seed tables for AR v3
245 u8 v3_deadtable1[256] = {
246     0xD0, 0xFF, 0xBA, 0xE5, 0xC1, 0xC7, 0xDB, 0x5B, 0x16, 0xE3, 0x6E, 0x26, 0x62, 0x31, 0x2E, 0x2A,
247     0xD1, 0xBB, 0x4A, 0xE6, 0xAE, 0x2F, 0x0A, 0x90, 0x29, 0x90, 0xB6, 0x67, 0x58, 0x2A, 0xB4, 0x45,
248     0x7B, 0xCB, 0xF0, 0x73, 0x84, 0x30, 0x81, 0xC2, 0xD7, 0xBE, 0x89, 0xD7, 0x4E, 0x73, 0x5C, 0xC7,
249     0x80, 0x1B, 0xE5, 0xE4, 0x43, 0xC7, 0x46, 0xD6, 0x6F, 0x7B, 0xBF, 0xED, 0xE5, 0x27, 0xD1, 0xB5,
250     0xD0, 0xD8, 0xA3, 0xCB, 0x2B, 0x30, 0xA4, 0xF0, 0x84, 0x14, 0x72, 0x5C, 0xFF, 0xA4, 0xFB, 0x54,
251     0x9D, 0x70, 0xE2, 0xFF, 0xBE, 0xE8, 0x24, 0x76, 0xE5, 0x15, 0xFB, 0x1A, 0xBC, 0x87, 0x02, 0x2A,
252     0x58, 0x8F, 0x9A, 0x95, 0xBD, 0xAE, 0x8D, 0x0C, 0xA5, 0x4C, 0xF2, 0x5C, 0x7D, 0xAD, 0x51, 0xFB,
253     0xB1, 0x22, 0x07, 0xE0, 0x29, 0x7C, 0xEB, 0x98, 0x14, 0xC6, 0x31, 0x97, 0xE4, 0x34, 0x8F, 0xCC,
254     0x99, 0x56, 0x9F, 0x78, 0x43, 0x91, 0x85, 0x3F, 0xC2, 0xD0, 0xD1, 0x80, 0xD1, 0x77, 0xA7, 0xE2,
255     0x43, 0x99, 0x1D, 0x2F, 0x8B, 0x6A, 0xE4, 0x66, 0x82, 0xF7, 0x2B, 0x0B, 0x65, 0x14, 0xC0, 0xC2,
256     0x1D, 0x96, 0x78, 0x1C, 0xC4, 0xC3, 0xD2, 0xB1, 0x64, 0x07, 0xD7, 0x6F, 0x02, 0xE9, 0x44, 0x31,
257     0xDB, 0x3C, 0xEB, 0x93, 0xED, 0x9A, 0x57, 0x05, 0xB9, 0x0E, 0xAF, 0x1F, 0x48, 0x11, 0xDC, 0x35,
258     0x6C, 0xB8, 0xEE, 0x2A, 0x48, 0x2B, 0xBC, 0x89, 0x12, 0x59, 0xCB, 0xD1, 0x18, 0xEA, 0x72, 0x11,
259     0x01, 0x75, 0x3B, 0xB5, 0x56, 0xF4, 0x8B, 0xA0, 0x41, 0x75, 0x86, 0x7B, 0x94, 0x12, 0x2D, 0x4C,
260     0x0C, 0x22, 0xC9, 0x4A, 0xD8, 0xB1, 0x8D, 0xF0, 0x55, 0x2E, 0x77, 0x50, 0x1C, 0x64, 0x77, 0xAA,
261     0x3E, 0xAC, 0xD3, 0x3D, 0xCE, 0x60, 0xCA, 0x5D, 0xA0, 0x92, 0x78, 0xC6, 0x51, 0xFE, 0xF9, 0x30
262 };
263 u8 v3_deadtable2[256] = {
264     0xAA, 0xAF, 0xF0, 0x72, 0x90, 0xF7, 0x71, 0x27, 0x06, 0x11, 0xEB, 0x9C, 0x37, 0x12, 0x72, 0xAA,
265     0x65, 0xBC, 0x0D, 0x4A, 0x76, 0xF6, 0x5C, 0xAA, 0xB0, 0x7A, 0x7D, 0x81, 0xC1, 0xCE, 0x2F, 0x9F,
266     0x02, 0x75, 0x38, 0xC8, 0xFC, 0x66, 0x05, 0xC2, 0x2C, 0xBD, 0x91, 0xAD, 0x03, 0xB1, 0x88, 0x93,
267     0x31, 0xC6, 0xAB, 0x40, 0x23, 0x43, 0x76, 0x54, 0xCA, 0xE7, 0x00, 0x96, 0x9F, 0xD8, 0x24, 0x8B,
268     0xE4, 0xDC, 0xDE, 0x48, 0x2C, 0xCB, 0xF7, 0x84, 0x1D, 0x45, 0xE5, 0xF1, 0x75, 0xA0, 0xED, 0xCD,
269     0x4B, 0x24, 0x8A, 0xB3, 0x98, 0x7B, 0x12, 0xB8, 0xF5, 0x63, 0x97, 0xB3, 0xA6, 0xA6, 0x0B, 0xDC,
270     0xD8, 0x4C, 0xA8, 0x99, 0x27, 0x0F, 0x8F, 0x94, 0x63, 0x0F, 0xB0, 0x11, 0x94, 0xC7, 0xE9, 0x7F,
271     0x3B, 0x40, 0x72, 0x4C, 0xDB, 0x84, 0x78, 0xFE, 0xB8, 0x56, 0x08, 0x80, 0xDF, 0x20, 0x2F, 0xB9,
272     0x66, 0x2D, 0x60, 0x63, 0xF5, 0x18, 0x15, 0x1B, 0x86, 0x85, 0xB9, 0xB4, 0x68, 0x0E, 0xC6, 0xD1,
273     0x8A, 0x81, 0x2B, 0xB3, 0xF6, 0x48, 0xF0, 0x4F, 0x9C, 0x28, 0x1C, 0xA4, 0x51, 0x2F, 0xD7, 0x4B,
274     0x17, 0xE7, 0xCC, 0x50, 0x9F, 0xD0, 0xD1, 0x40, 0x0C, 0x0D, 0xCA, 0x83, 0xFA, 0x5E, 0xCA, 0xEC,
275     0xBF, 0x4E, 0x7C, 0x8F, 0xF0, 0xAE, 0xC2, 0xD3, 0x28, 0x41, 0x9B, 0xC8, 0x04, 0xB9, 0x4A, 0xBA,
276     0x72, 0xE2, 0xB5, 0x06, 0x2C, 0x1E, 0x0B, 0x2C, 0x7F, 0x11, 0xA9, 0x26, 0x51, 0x9D, 0x3F, 0xF8,
277     0x62, 0x11, 0x2E, 0x89, 0xD2, 0x9D, 0x35, 0xB1, 0xE4, 0x0A, 0x4D, 0x93, 0x01, 0xA7, 0xD1, 0x2D,
278     0x00, 0x87, 0xE2, 0x2D, 0xA4, 0xE9, 0x0A, 0x06, 0x66, 0xF8, 0x1F, 0x44, 0x75, 0xB5, 0x6B, 0x1C,
279     0xFC, 0x31, 0x09, 0x48, 0xA3, 0xFF, 0x92, 0x12, 0x58, 0xE9, 0xFA, 0xAE, 0x4F, 0xE2, 0xB4, 0xCC
280 };
281 
282 #define debuggerReadMemory(addr) \
283   READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
284 
285 #define debuggerReadHalfWord(addr) \
286   READ16LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
287 
288 #define debuggerReadByte(addr) \
289   map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
290 
291 #define debuggerWriteMemory(addr, value) \
292   WRITE32LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value)
293 
294 #define debuggerWriteHalfWord(addr, value) \
295   WRITE16LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value)
296 
297 #define debuggerWriteByte(addr, value) \
298   map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value)
299 
300 
301 #define CHEAT_IS_HEX(a) ( ((a)>='A' && (a) <='F') || ((a) >='0' && (a) <= '9'))
302 
303 #define CHEAT_PATCH_ROM_16BIT(a,v) \
304   WRITE16LE(((u16 *)&rom[(a) & 0x1ffffff]), v);
305 
306 #define CHEAT_PATCH_ROM_32BIT(a,v) \
307   WRITE32LE(((u32 *)&rom[(a) & 0x1ffffff]), v);
308 
isMultilineWithData(int i)309 static bool isMultilineWithData(int i)
310 {
311   // we consider it a multiline code if it has more than one line of data
312   // otherwise, it can still be considered a single code
313   // (Only CBA codes can be true multilines !!!)
314   if(i < cheatsNumber && i >= 0)
315     switch(cheatsList[i].size) {
316     case INT_8_BIT_WRITE:
317     case INT_16_BIT_WRITE:
318     case INT_32_BIT_WRITE:
319     case GSA_16_BIT_ROM_PATCH:
320     case GSA_8_BIT_GS_WRITE:
321     case GSA_16_BIT_GS_WRITE:
322     case GSA_32_BIT_GS_WRITE:
323     case CBA_AND:
324     case CBA_IF_KEYS_PRESSED:
325     case CBA_IF_TRUE:
326     case CBA_IF_FALSE:
327     case GSA_8_BIT_IF_TRUE:
328     case GSA_32_BIT_IF_TRUE:
329     case GSA_8_BIT_IF_FALSE:
330     case GSA_32_BIT_IF_FALSE:
331     case GSA_8_BIT_FILL:
332     case GSA_16_BIT_FILL:
333     case GSA_8_BIT_IF_TRUE2:
334     case GSA_16_BIT_IF_TRUE2:
335     case GSA_32_BIT_IF_TRUE2:
336     case GSA_8_BIT_IF_FALSE2:
337     case GSA_16_BIT_IF_FALSE2:
338     case GSA_32_BIT_IF_FALSE2:
339     case GSA_SLOWDOWN:
340     case CBA_ADD:
341     case CBA_OR:
342     case CBA_LT:
343     case CBA_GT:
344     case GSA_8_BIT_POINTER:
345     case GSA_16_BIT_POINTER:
346     case GSA_32_BIT_POINTER:
347     case GSA_8_BIT_ADD:
348     case GSA_16_BIT_ADD:
349     case GSA_32_BIT_ADD:
350     case GSA_8_BIT_IF_LOWER_U:
351     case GSA_16_BIT_IF_LOWER_U:
352     case GSA_32_BIT_IF_LOWER_U:
353     case GSA_8_BIT_IF_HIGHER_U:
354     case GSA_16_BIT_IF_HIGHER_U:
355     case GSA_32_BIT_IF_HIGHER_U:
356     case GSA_8_BIT_IF_AND:
357     case GSA_16_BIT_IF_AND:
358     case GSA_32_BIT_IF_AND:
359     case GSA_8_BIT_IF_LOWER_U2:
360     case GSA_16_BIT_IF_LOWER_U2:
361     case GSA_32_BIT_IF_LOWER_U2:
362     case GSA_8_BIT_IF_HIGHER_U2:
363     case GSA_16_BIT_IF_HIGHER_U2:
364     case GSA_32_BIT_IF_HIGHER_U2:
365     case GSA_8_BIT_IF_AND2:
366     case GSA_16_BIT_IF_AND2:
367     case GSA_32_BIT_IF_AND2:
368     case GSA_ALWAYS:
369     case GSA_ALWAYS2:
370     case GSA_8_BIT_IF_LOWER_S:
371     case GSA_16_BIT_IF_LOWER_S:
372     case GSA_32_BIT_IF_LOWER_S:
373     case GSA_8_BIT_IF_HIGHER_S:
374     case GSA_16_BIT_IF_HIGHER_S:
375     case GSA_32_BIT_IF_HIGHER_S:
376     case GSA_8_BIT_IF_LOWER_S2:
377     case GSA_16_BIT_IF_LOWER_S2:
378     case GSA_32_BIT_IF_LOWER_S2:
379     case GSA_8_BIT_IF_HIGHER_S2:
380     case GSA_16_BIT_IF_HIGHER_S2:
381     case GSA_32_BIT_IF_HIGHER_S2:
382     case GSA_16_BIT_WRITE_IOREGS:
383     case GSA_32_BIT_WRITE_IOREGS:
384     case GSA_CODES_ON:
385     case GSA_8_BIT_IF_TRUE3:
386     case GSA_16_BIT_IF_TRUE3:
387     case GSA_32_BIT_IF_TRUE3:
388     case GSA_8_BIT_IF_FALSE3:
389     case GSA_16_BIT_IF_FALSE3:
390     case GSA_32_BIT_IF_FALSE3:
391     case GSA_8_BIT_IF_LOWER_S3:
392     case GSA_16_BIT_IF_LOWER_S3:
393     case GSA_32_BIT_IF_LOWER_S3:
394     case GSA_8_BIT_IF_HIGHER_S3:
395     case GSA_16_BIT_IF_HIGHER_S3:
396     case GSA_32_BIT_IF_HIGHER_S3:
397     case GSA_8_BIT_IF_LOWER_U3:
398     case GSA_16_BIT_IF_LOWER_U3:
399     case GSA_32_BIT_IF_LOWER_U3:
400     case GSA_8_BIT_IF_HIGHER_U3:
401     case GSA_16_BIT_IF_HIGHER_U3:
402     case GSA_32_BIT_IF_HIGHER_U3:
403     case GSA_8_BIT_IF_AND3:
404     case GSA_16_BIT_IF_AND3:
405     case GSA_32_BIT_IF_AND3:
406     case GSA_ALWAYS3:
407     case GSA_8_BIT_GS_WRITE2:
408     case GSA_16_BIT_GS_WRITE2:
409     case GSA_32_BIT_GS_WRITE2:
410     case GSA_16_BIT_ROM_PATCH2C:
411     case GSA_16_BIT_ROM_PATCH2D:
412     case GSA_16_BIT_ROM_PATCH2E:
413     case GSA_16_BIT_ROM_PATCH2F:
414     case GSA_8_BIT_SLIDE:
415     case GSA_16_BIT_SLIDE:
416     case GSA_32_BIT_SLIDE:
417     case GSA_GROUP_WRITE:
418     case GSA_32_BIT_ADD2:
419     case GSA_32_BIT_SUB2:
420     case GSA_16_BIT_IF_LOWER_OR_EQ_U:
421     case GSA_16_BIT_IF_HIGHER_OR_EQ_U:
422     case GSA_16_BIT_MIF_TRUE:
423     case GSA_16_BIT_MIF_FALSE:
424     case GSA_16_BIT_MIF_LOWER_OR_EQ_U:
425     case GSA_16_BIT_MIF_HIGHER_OR_EQ_U:
426     case MASTER_CODE:
427     case CHEATS_16_BIT_WRITE:
428     case CHEATS_32_BIT_WRITE:
429       return false;
430       // the codes below have two lines of data
431     case CBA_SLIDE_CODE:
432     case CBA_SUPER:
433       return true;
434     }
435   return false;
436 }
437 
getCodeLength(int num)438 static int getCodeLength(int num)
439 {
440   if(num >= cheatsNumber || num < 0)
441     return 1;
442 
443   // this is for all the codes that are true multiline
444   switch(cheatsList[num].size) {
445   case INT_8_BIT_WRITE:
446   case INT_16_BIT_WRITE:
447   case INT_32_BIT_WRITE:
448   case GSA_16_BIT_ROM_PATCH:
449   case GSA_8_BIT_GS_WRITE:
450   case GSA_16_BIT_GS_WRITE:
451   case GSA_32_BIT_GS_WRITE:
452   case CBA_AND:
453   case GSA_8_BIT_FILL:
454   case GSA_16_BIT_FILL:
455   case GSA_SLOWDOWN:
456   case CBA_ADD:
457   case CBA_OR:
458   case GSA_8_BIT_POINTER:
459   case GSA_16_BIT_POINTER:
460   case GSA_32_BIT_POINTER:
461   case GSA_8_BIT_ADD:
462   case GSA_16_BIT_ADD:
463   case GSA_32_BIT_ADD:
464   case GSA_CODES_ON:
465   case GSA_8_BIT_IF_TRUE3:
466   case GSA_16_BIT_IF_TRUE3:
467   case GSA_32_BIT_IF_TRUE3:
468   case GSA_8_BIT_IF_FALSE3:
469   case GSA_16_BIT_IF_FALSE3:
470   case GSA_32_BIT_IF_FALSE3:
471   case GSA_8_BIT_IF_LOWER_S3:
472   case GSA_16_BIT_IF_LOWER_S3:
473   case GSA_32_BIT_IF_LOWER_S3:
474   case GSA_8_BIT_IF_HIGHER_S3:
475   case GSA_16_BIT_IF_HIGHER_S3:
476   case GSA_32_BIT_IF_HIGHER_S3:
477   case GSA_8_BIT_IF_LOWER_U3:
478   case GSA_16_BIT_IF_LOWER_U3:
479   case GSA_32_BIT_IF_LOWER_U3:
480   case GSA_8_BIT_IF_HIGHER_U3:
481   case GSA_16_BIT_IF_HIGHER_U3:
482   case GSA_32_BIT_IF_HIGHER_U3:
483   case GSA_8_BIT_IF_AND3:
484   case GSA_16_BIT_IF_AND3:
485   case GSA_32_BIT_IF_AND3:
486   case GSA_8_BIT_IF_LOWER_U:
487   case GSA_16_BIT_IF_LOWER_U:
488   case GSA_32_BIT_IF_LOWER_U:
489   case GSA_8_BIT_IF_HIGHER_U:
490   case GSA_16_BIT_IF_HIGHER_U:
491   case GSA_32_BIT_IF_HIGHER_U:
492   case GSA_8_BIT_IF_AND:
493   case GSA_16_BIT_IF_AND:
494   case GSA_32_BIT_IF_AND:
495   case GSA_ALWAYS:
496   case GSA_8_BIT_IF_LOWER_S:
497   case GSA_16_BIT_IF_LOWER_S:
498   case GSA_32_BIT_IF_LOWER_S:
499   case GSA_8_BIT_IF_HIGHER_S:
500   case GSA_16_BIT_IF_HIGHER_S:
501   case GSA_32_BIT_IF_HIGHER_S:
502   case GSA_16_BIT_WRITE_IOREGS:
503   case GSA_32_BIT_WRITE_IOREGS:
504   case GSA_8_BIT_GS_WRITE2:
505   case GSA_16_BIT_GS_WRITE2:
506   case GSA_32_BIT_GS_WRITE2:
507   case GSA_16_BIT_ROM_PATCH2C:
508   case GSA_16_BIT_ROM_PATCH2D:
509   case GSA_16_BIT_ROM_PATCH2E:
510   case GSA_16_BIT_ROM_PATCH2F:
511   case GSA_8_BIT_SLIDE:
512   case GSA_16_BIT_SLIDE:
513   case GSA_32_BIT_SLIDE:
514   case GSA_8_BIT_IF_TRUE:
515   case GSA_32_BIT_IF_TRUE:
516   case GSA_8_BIT_IF_FALSE:
517   case GSA_32_BIT_IF_FALSE:
518   case CBA_LT:
519   case CBA_GT:
520   case CBA_IF_TRUE:
521   case CBA_IF_FALSE:
522   case GSA_8_BIT_IF_TRUE2:
523   case GSA_16_BIT_IF_TRUE2:
524   case GSA_32_BIT_IF_TRUE2:
525   case GSA_8_BIT_IF_FALSE2:
526   case GSA_16_BIT_IF_FALSE2:
527   case GSA_32_BIT_IF_FALSE2:
528   case GSA_8_BIT_IF_LOWER_U2:
529   case GSA_16_BIT_IF_LOWER_U2:
530   case GSA_32_BIT_IF_LOWER_U2:
531   case GSA_8_BIT_IF_HIGHER_U2:
532   case GSA_16_BIT_IF_HIGHER_U2:
533   case GSA_32_BIT_IF_HIGHER_U2:
534   case GSA_8_BIT_IF_AND2:
535   case GSA_16_BIT_IF_AND2:
536   case GSA_32_BIT_IF_AND2:
537   case GSA_ALWAYS2:
538   case GSA_8_BIT_IF_LOWER_S2:
539   case GSA_16_BIT_IF_LOWER_S2:
540   case GSA_32_BIT_IF_LOWER_S2:
541   case GSA_8_BIT_IF_HIGHER_S2:
542   case GSA_16_BIT_IF_HIGHER_S2:
543   case GSA_32_BIT_IF_HIGHER_S2:
544   case GSA_GROUP_WRITE:
545   case GSA_32_BIT_ADD2:
546   case GSA_32_BIT_SUB2:
547   case GSA_16_BIT_IF_LOWER_OR_EQ_U:
548   case GSA_16_BIT_IF_HIGHER_OR_EQ_U:
549   case GSA_16_BIT_MIF_TRUE:
550   case GSA_16_BIT_MIF_FALSE:
551   case GSA_16_BIT_MIF_LOWER_OR_EQ_U:
552   case GSA_16_BIT_MIF_HIGHER_OR_EQ_U:
553   case MASTER_CODE:
554   case CHEATS_16_BIT_WRITE:
555   case CHEATS_32_BIT_WRITE:
556   case UNKNOWN_CODE:
557     return 1;
558   case CBA_IF_KEYS_PRESSED:
559   case CBA_SLIDE_CODE:
560     return 2;
561   case CBA_SUPER:
562     return ((((cheatsList[num].value-1) & 0xFFFF)/3) + 1);
563   }
564   return 1;
565 }
566 
cheatsCheckKeys(u32 keys,u32 extended)567 int cheatsCheckKeys(u32 keys, u32 extended)
568 {
569   bool onoff = true;
570   int ticks = 0;
571   int i;
572   mastercode = 0;
573 
574   for (i = 0; i<4; i++)
575     if (rompatch2addr [i] != 0) {
576       CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2oldval [i]);
577       rompatch2addr [i] = 0;
578     }
579 
580   for (i = 0; i < cheatsNumber; i++) {
581     if(!cheatsList[i].enabled) {
582       // make sure we skip other lines in this code
583       i += getCodeLength(i)-1;
584       continue;
585     }
586     switch(cheatsList[i].size) {
587     case GSA_CODES_ON:
588       onoff = true;
589       break;
590     case GSA_SLOWDOWN:
591       // check if button was pressed and released, if so toggle our state
592       if((cheatsList[i].status & 4) && !(extended & 4))
593         cheatsList[i].status ^= 1;
594       if(extended & 4)
595         cheatsList[i].status |= 4;
596       else
597         cheatsList[i].status &= ~4;
598 
599       if(cheatsList[i].status & 1)
600         ticks += ((cheatsList[i].value  & 0xFFFF) * 7);
601       break;
602     case GSA_8_BIT_SLIDE:
603       i++;
604       if(i < cheatsNumber) {
605         u32 addr = cheatsList[i-1].value;
606         u8 value = cheatsList[i].rawaddress;
607         int vinc = (cheatsList[i].value >> 24) & 255;
608         int count = (cheatsList[i].value >> 16) & 255;
609         int ainc = (cheatsList[i].value & 0xffff);
610         while(count > 0) {
611           CPUWriteByte(addr, value);
612           value += vinc;
613           addr += ainc;
614           count--;
615         }
616       }
617       break;
618     case GSA_16_BIT_SLIDE:
619       i++;
620       if(i < cheatsNumber) {
621         u32 addr = cheatsList[i-1].value;
622         u16 value = cheatsList[i].rawaddress;
623         int vinc = (cheatsList[i].value >> 24) & 255;
624         int count = (cheatsList[i].value >> 16) & 255;
625         int ainc = (cheatsList[i].value & 0xffff)*2;
626         while(count > 0) {
627           CPUWriteHalfWord(addr, value);
628           value += vinc;
629           addr += ainc;
630           count--;
631         }
632       }
633       break;
634     case GSA_32_BIT_SLIDE:
635       i++;
636       if(i < cheatsNumber) {
637         u32 addr = cheatsList[i-1].value;
638         u32 value = cheatsList[i].rawaddress;
639         int vinc = (cheatsList[i].value >> 24) & 255;
640         int count = (cheatsList[i].value >> 16) & 255;
641         int ainc = (cheatsList[i].value & 0xffff)*4;
642         while(count > 0) {
643           CPUWriteMemory(addr, value);
644           value += vinc;
645           addr += ainc;
646           count--;
647         }
648       }
649       break;
650     case GSA_8_BIT_GS_WRITE2:
651       i++;
652       if(i < cheatsNumber) {
653         if(extended & 4) {
654           CPUWriteByte(cheatsList[i-1].value, cheatsList[i].address);
655         }
656       }
657       break;
658     case GSA_16_BIT_GS_WRITE2:
659       i++;
660       if(i < cheatsNumber) {
661         if(extended & 4) {
662           CPUWriteHalfWord(cheatsList[i-1].value, cheatsList[i].address);
663         }
664       }
665       break;
666     case GSA_32_BIT_GS_WRITE2:
667       i++;
668       if(i < cheatsNumber) {
669         if(extended & 4) {
670           CPUWriteMemory(cheatsList[i-1].value, cheatsList[i].address);
671         }
672       }
673       break;
674       case GSA_16_BIT_ROM_PATCH:
675         if((cheatsList[i].status & 1) == 0) {
676           if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
677             cheatsList[i].oldValue = CPUReadHalfWord(cheatsList[i].address);
678             cheatsList[i].status |= 1;
679             CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value);
680           }
681         }
682         break;
683     case GSA_16_BIT_ROM_PATCH2C:
684       i++;
685       if(i < cheatsNumber) {
686 		  rompatch2addr [0] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
687 		  rompatch2oldval [0] = CPUReadHalfWord(rompatch2addr [0]);
688 		  rompatch2val [0] = cheatsList[i].rawaddress & 0xFFFF;
689       }
690       break;
691     case GSA_16_BIT_ROM_PATCH2D:
692       i++;
693       if(i < cheatsNumber) {
694 		  rompatch2addr [1] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
695 		  rompatch2oldval [1] = CPUReadHalfWord(rompatch2addr [1]);
696 		  rompatch2val [1] = cheatsList[i].rawaddress & 0xFFFF;
697       }
698       break;
699     case GSA_16_BIT_ROM_PATCH2E:
700       i++;
701       if(i < cheatsNumber) {
702 		  rompatch2addr [2] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
703 		  rompatch2oldval [2] = CPUReadHalfWord(rompatch2addr [2]);
704 		  rompatch2val [2] = cheatsList[i].rawaddress & 0xFFFF;
705       }
706       break;
707     case GSA_16_BIT_ROM_PATCH2F:
708       i++;
709       if(i < cheatsNumber) {
710 		  rompatch2addr [3] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
711 		  rompatch2oldval [3] = CPUReadHalfWord(rompatch2addr [3]);
712 		  rompatch2val [3] = cheatsList[i].rawaddress & 0xFFFF;
713       }
714       break;
715     case MASTER_CODE:
716         mastercode = cheatsList[i].address;
717       break;
718     }
719     if (onoff) {
720       switch(cheatsList[i].size) {
721       case INT_8_BIT_WRITE:
722         CPUWriteByte(cheatsList[i].address, cheatsList[i].value);
723         break;
724       case INT_16_BIT_WRITE:
725         CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value);
726         break;
727       case INT_32_BIT_WRITE:
728         CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
729         break;
730       case GSA_8_BIT_GS_WRITE:
731         if(extended & 4) {
732           CPUWriteByte(cheatsList[i].address, cheatsList[i].value);
733         }
734         break;
735       case GSA_16_BIT_GS_WRITE:
736         if(extended & 4) {
737           CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value);
738         }
739         break;
740       case GSA_32_BIT_GS_WRITE:
741         if(extended & 4) {
742           CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
743         }
744         break;
745       case CBA_IF_KEYS_PRESSED:
746         {
747           u16 value = cheatsList[i].value;
748           u32 addr = cheatsList[i].address;
749           if((addr & 0xF0) == 0x20) {
750             if((keys & value) == 0) {
751               i++;
752 			}
753 		  } else if((addr & 0xF0) == 0x10) {
754             if((keys & value) == value) {
755               i++;
756 			}
757 		  } else if((addr & 0xF0) == 0x00) {
758             if(((~keys) & 0x3FF) == value) {
759               i++;
760 			}
761 		  }
762 		}
763         break;
764       case CBA_IF_TRUE:
765         if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
766           i++;
767         }
768         break;
769       case CBA_SLIDE_CODE:
770 		{
771           u32 address = cheatsList[i].address;
772           u16 value = cheatsList[i].value;
773           i++;
774           if(i < cheatsNumber) {
775             int count = ((cheatsList[i].address - 1) & 0xFFFF);
776             u16 vinc = (cheatsList[i].address >> 16) & 0xFFFF;
777             int inc = cheatsList[i].value;
778             for(int x = 0; x <= count ; x++) {
779               CPUWriteHalfWord(address, value);
780               address += inc;
781               value += vinc;
782 			}
783 		  }
784 		}
785         break;
786       case CBA_IF_FALSE:
787         if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value){
788           i++;
789         }
790       break;
791       case CBA_AND:
792         CPUWriteHalfWord(cheatsList[i].address,
793                          CPUReadHalfWord(cheatsList[i].address) &
794                          cheatsList[i].value);
795         break;
796       case GSA_8_BIT_IF_TRUE:
797         if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) {
798           i++;
799         }
800         break;
801       case GSA_32_BIT_IF_TRUE:
802         if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) {
803           i++;
804         }
805         break;
806       case GSA_8_BIT_IF_FALSE:
807         if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) {
808           i++;
809         }
810         break;
811       case GSA_32_BIT_IF_FALSE:
812         if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) {
813           i++;
814         }
815         break;
816       case GSA_8_BIT_FILL:
817 		{
818           u32 addr = cheatsList[i].address;
819           u8 v = cheatsList[i].value & 0xff;
820           u32 end = addr + (cheatsList[i].value >> 8);
821           do {
822             CPUWriteByte(addr, v);
823             addr++;
824 		  } while (addr <= end);
825 		}
826         break;
827       case GSA_16_BIT_FILL:
828 		{
829           u32 addr = cheatsList[i].address;
830           u16 v = cheatsList[i].value & 0xffff;
831           u32 end = addr + ((cheatsList[i].value >> 16) << 1);
832           do {
833             CPUWriteHalfWord(addr, v);
834             addr+=2;
835 		  } while (addr <= end);
836 		}
837         break;
838       case GSA_8_BIT_IF_TRUE2:
839         if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) {
840           i+=2;
841         }
842         break;
843       case GSA_16_BIT_IF_TRUE2:
844         if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
845           i+=2;
846         }
847         break;
848       case GSA_32_BIT_IF_TRUE2:
849         if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) {
850           i+=2;
851         }
852         break;
853       case GSA_8_BIT_IF_FALSE2:
854         if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) {
855           i+=2;
856         }
857         break;
858       case GSA_16_BIT_IF_FALSE2:
859         if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) {
860           i+=2;
861         }
862         break;
863       case GSA_32_BIT_IF_FALSE2:
864         if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) {
865           i+=2;
866         }
867         break;
868       case CBA_ADD:
869         if ((cheatsList[i].address & 1) == 0) {
870           CPUWriteHalfWord(cheatsList[i].address,
871                            CPUReadHalfWord(cheatsList[i].address) +
872                            cheatsList[i].value);
873         } else {
874           CPUWriteMemory(cheatsList[i].address & 0x0FFFFFFE,
875                            CPUReadMemory(cheatsList[i].address & 0x0FFFFFFE) +
876                            cheatsList[i].value);
877         }
878         break;
879       case CBA_OR:
880         CPUWriteHalfWord(cheatsList[i].address,
881                          CPUReadHalfWord(cheatsList[i].address) |
882                          cheatsList[i].value);
883         break;
884       case CBA_GT:
885         if (!(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value)){
886           i++;
887         }
888         break;
889       case CBA_LT:
890         if (!(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value)){
891           i++;
892         }
893         break;
894       case CBA_SUPER:
895 		{
896           int count = 2*((cheatsList[i].value -1) & 0xFFFF)+1;
897           u32 address = cheatsList[i].address;
898           for(int x = 0; x <= count; x++) {
899             u8 b;
900             int res = x % 6;
901 		    if (res==0)
902 		 	  i++;
903             if(res < 4)
904               b = (cheatsList[i].address >> (24-8*res)) & 0xFF;
905             else
906               b = (cheatsList[i].value >> (8 - 8*(res-4))) & 0xFF;
907             CPUWriteByte(address, b);
908             address++;
909 		  }
910 		}
911         break;
912       case GSA_8_BIT_POINTER :
913         if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) ||
914             ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000)))
915         {
916           CPUWriteByte(CPUReadMemory(cheatsList[i].address)+((cheatsList[i].value & 0xFFFFFF00) >> 8),
917                        cheatsList[i].value & 0xFF);
918         }
919         break;
920       case GSA_16_BIT_POINTER :
921         if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) ||
922             ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000)))
923         {
924           CPUWriteHalfWord(CPUReadMemory(cheatsList[i].address)+((cheatsList[i].value & 0xFFFF0000) >> 15),
925                        cheatsList[i].value & 0xFFFF);
926         }
927         break;
928       case GSA_32_BIT_POINTER :
929         if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) ||
930             ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000)))
931         {
932           CPUWriteMemory(CPUReadMemory(cheatsList[i].address),
933                        cheatsList[i].value);
934         }
935         break;
936       case GSA_8_BIT_ADD :
937         CPUWriteByte(cheatsList[i].address,
938                     ((cheatsList[i].value & 0xFF) + CPUReadMemory(cheatsList[i].address)) & 0xFF);
939         break;
940       case GSA_16_BIT_ADD :
941         CPUWriteHalfWord(cheatsList[i].address,
942                         ((cheatsList[i].value & 0xFFFF) + CPUReadMemory(cheatsList[i].address)) & 0xFFFF);
943         break;
944       case GSA_32_BIT_ADD :
945         CPUWriteMemory(cheatsList[i].address ,
946                        (cheatsList[i].value + CPUReadMemory(cheatsList[i].address)) & 0xFFFFFFFF);
947         break;
948       case GSA_8_BIT_IF_LOWER_U:
949         if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) {
950           i++;
951         }
952         break;
953       case GSA_16_BIT_IF_LOWER_U:
954         if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) {
955           i++;
956         }
957         break;
958       case GSA_32_BIT_IF_LOWER_U:
959         if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) {
960           i++;
961         }
962         break;
963       case GSA_8_BIT_IF_HIGHER_U:
964         if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) {
965           i++;
966         }
967         break;
968       case GSA_16_BIT_IF_HIGHER_U:
969         if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) {
970           i++;
971         }
972         break;
973       case GSA_32_BIT_IF_HIGHER_U:
974         if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) {
975           i++;
976         }
977         break;
978       case GSA_8_BIT_IF_AND:
979         if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) {
980           i++;
981         }
982         break;
983       case GSA_16_BIT_IF_AND:
984         if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) {
985           i++;
986         }
987         break;
988       case GSA_32_BIT_IF_AND:
989         if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) {
990           i++;
991         }
992         break;
993       case GSA_8_BIT_IF_LOWER_U2:
994         if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) {
995           i+=2;
996         }
997         break;
998       case GSA_16_BIT_IF_LOWER_U2:
999         if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) {
1000           i+=2;
1001         }
1002         break;
1003       case GSA_32_BIT_IF_LOWER_U2:
1004         if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) {
1005           i+=2;
1006         }
1007         break;
1008       case GSA_8_BIT_IF_HIGHER_U2:
1009         if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) {
1010           i+=2;
1011         }
1012         break;
1013       case GSA_16_BIT_IF_HIGHER_U2:
1014         if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) {
1015           i+=2;
1016         }
1017         break;
1018       case GSA_32_BIT_IF_HIGHER_U2:
1019         if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) {
1020           i+=2;
1021         }
1022         break;
1023       case GSA_8_BIT_IF_AND2:
1024         if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) {
1025           i+=2;
1026         }
1027         break;
1028       case GSA_16_BIT_IF_AND2:
1029         if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) {
1030           i+=2;
1031         }
1032         break;
1033       case GSA_32_BIT_IF_AND2:
1034         if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) {
1035           i+=2;
1036         }
1037         break;
1038       case GSA_ALWAYS:
1039         i++;
1040         break;
1041       case GSA_ALWAYS2:
1042         i+=2;
1043         break;
1044       case GSA_8_BIT_IF_LOWER_S:
1045         if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) {
1046           i++;
1047         }
1048         break;
1049       case GSA_16_BIT_IF_LOWER_S:
1050         if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) {
1051           i++;
1052         }
1053         break;
1054       case GSA_32_BIT_IF_LOWER_S:
1055         if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) {
1056           i++;
1057         }
1058         break;
1059       case GSA_8_BIT_IF_HIGHER_S:
1060         if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) {
1061           i++;
1062         }
1063         break;
1064       case GSA_16_BIT_IF_HIGHER_S:
1065         if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) {
1066           i++;
1067         }
1068         break;
1069       case GSA_32_BIT_IF_HIGHER_S:
1070         if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) {
1071           i++;
1072         }
1073         break;
1074       case GSA_8_BIT_IF_LOWER_S2:
1075         if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) {
1076           i+=2;
1077         }
1078         break;
1079       case GSA_16_BIT_IF_LOWER_S2:
1080         if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) {
1081           i+=2;
1082         }
1083         break;
1084       case GSA_32_BIT_IF_LOWER_S2:
1085         if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) {
1086           i+=2;
1087         }
1088         break;
1089       case GSA_8_BIT_IF_HIGHER_S2:
1090         if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) {
1091           i+=2;
1092         }
1093         break;
1094       case GSA_16_BIT_IF_HIGHER_S2:
1095         if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) {
1096           i+=2;
1097         }
1098         break;
1099       case GSA_32_BIT_IF_HIGHER_S2:
1100         if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) {
1101           i+=2;
1102         }
1103         break;
1104       case GSA_16_BIT_WRITE_IOREGS:
1105         if ((cheatsList[i].address <= 0x3FF) && (cheatsList[i].address != 0x6) &&
1106             (cheatsList[i].address != 0x130))
1107           ioMem[cheatsList[i].address & 0x3FE]=cheatsList[i].value & 0xFFFF;
1108         break;
1109       case GSA_32_BIT_WRITE_IOREGS:
1110         if (cheatsList[i].address<=0x3FF)
1111         {
1112           if (((cheatsList[i].address & 0x3FC) != 0x6) && ((cheatsList[i].address & 0x3FC) != 0x130))
1113             ioMem[cheatsList[i].address & 0x3FC]= (cheatsList[i].value & 0xFFFF);
1114           if ((((cheatsList[i].address & 0x3FC)+2) != 0x6) && ((cheatsList[i].address & 0x3FC) +2) != 0x130)
1115             ioMem[(cheatsList[i].address & 0x3FC) + 2 ]= ((cheatsList[i].value>>16 ) & 0xFFFF);
1116         }
1117         break;
1118       case GSA_8_BIT_IF_TRUE3:
1119         if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) {
1120           onoff=false;
1121         }
1122         break;
1123       case GSA_16_BIT_IF_TRUE3:
1124         if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
1125           onoff=false;
1126         }
1127         break;
1128       case GSA_32_BIT_IF_TRUE3:
1129         if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) {
1130           onoff=false;
1131         }
1132         break;
1133       case GSA_8_BIT_IF_FALSE3:
1134         if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) {
1135           onoff=false;
1136         }
1137         break;
1138       case GSA_16_BIT_IF_FALSE3:
1139         if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) {
1140           onoff=false;
1141         }
1142         break;
1143       case GSA_32_BIT_IF_FALSE3:
1144         if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) {
1145           onoff=false;
1146         }
1147         break;
1148       case GSA_8_BIT_IF_LOWER_S3:
1149         if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) {
1150           onoff=false;
1151         }
1152         break;
1153       case GSA_16_BIT_IF_LOWER_S3:
1154         if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) {
1155           onoff=false;
1156         }
1157         break;
1158       case GSA_32_BIT_IF_LOWER_S3:
1159         if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) {
1160           onoff=false;
1161         }
1162         break;
1163       case GSA_8_BIT_IF_HIGHER_S3:
1164         if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) {
1165           onoff=false;
1166         }
1167         break;
1168       case GSA_16_BIT_IF_HIGHER_S3:
1169         if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) {
1170           onoff=false;
1171         }
1172         break;
1173       case GSA_32_BIT_IF_HIGHER_S3:
1174         if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) {
1175           onoff=false;
1176         }
1177         break;
1178       case GSA_8_BIT_IF_LOWER_U3:
1179         if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) {
1180           onoff=false;
1181         }
1182         break;
1183       case GSA_16_BIT_IF_LOWER_U3:
1184         if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) {
1185           onoff=false;
1186         }
1187         break;
1188       case GSA_32_BIT_IF_LOWER_U3:
1189         if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) {
1190           onoff=false;
1191         }
1192         break;
1193       case GSA_8_BIT_IF_HIGHER_U3:
1194         if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) {
1195           onoff=false;
1196         }
1197         break;
1198       case GSA_16_BIT_IF_HIGHER_U3:
1199         if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) {
1200           onoff=false;
1201         }
1202         break;
1203       case GSA_32_BIT_IF_HIGHER_U3:
1204         if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) {
1205           onoff=false;
1206         }
1207         break;
1208       case GSA_8_BIT_IF_AND3:
1209         if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) {
1210           onoff=false;
1211         }
1212         break;
1213       case GSA_16_BIT_IF_AND3:
1214         if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) {
1215           onoff=false;
1216         }
1217         break;
1218       case GSA_32_BIT_IF_AND3:
1219         if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) {
1220           onoff=false;
1221         }
1222         break;
1223       case GSA_ALWAYS3:
1224         if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) {
1225           onoff=false;
1226         }
1227         break;
1228       case GSA_GROUP_WRITE:
1229       	{
1230           int count = ((cheatsList[i].address) & 0xFFFE) +1;
1231           u32 value = cheatsList[i].value;
1232 		  if (count==0)
1233 			  i++;
1234 		  else
1235             for (int x = 1; x <= count; x++) {
1236 				if ((x % 2) ==0){
1237 					if (x<count)
1238 						i++;
1239 					CPUWriteMemory(cheatsList[i].rawaddress, value);
1240 				}
1241 				else
1242 					CPUWriteMemory(cheatsList[i].value, value);
1243 			}
1244 		}
1245 		break;
1246       case GSA_32_BIT_ADD2:
1247         CPUWriteMemory(cheatsList[i].value ,
1248                        (CPUReadMemory(cheatsList[i].value) + cheatsList[i+1].rawaddress) & 0xFFFFFFFF);
1249         i++;
1250 		break;
1251       case GSA_32_BIT_SUB2:
1252         CPUWriteMemory(cheatsList[i].value ,
1253                        (CPUReadMemory(cheatsList[i].value) - cheatsList[i+1].rawaddress) & 0xFFFFFFFF);
1254         i++;
1255 		break;
1256       case GSA_16_BIT_IF_LOWER_OR_EQ_U:
1257         if(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value) {
1258           i++;
1259         }
1260         break;
1261       case GSA_16_BIT_IF_HIGHER_OR_EQ_U:
1262         if(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) {
1263           i++;
1264         }
1265         break;
1266       case GSA_16_BIT_MIF_TRUE:
1267         if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
1268           i+=((cheatsList[i].rawaddress >> 0x10) & 0xFF);
1269         }
1270         break;
1271       case GSA_16_BIT_MIF_FALSE:
1272         if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) {
1273           i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF;
1274         }
1275         break;
1276       case GSA_16_BIT_MIF_LOWER_OR_EQ_U:
1277         if(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value) {
1278           i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF;
1279         }
1280         break;
1281       case GSA_16_BIT_MIF_HIGHER_OR_EQ_U:
1282         if(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) {
1283           i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF;
1284         }
1285         break;
1286       case CHEATS_16_BIT_WRITE:
1287         if ((cheatsList[i].address>>24)>=0x08) {
1288           CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value);
1289         } else {
1290           CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value);
1291         }
1292         break;
1293       case CHEATS_32_BIT_WRITE:
1294         if ((cheatsList[i].address>>24)>=0x08) {
1295           CHEAT_PATCH_ROM_32BIT(cheatsList[i].address, cheatsList[i].value);
1296         } else {
1297           CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
1298         }
1299         break;
1300       }
1301     }
1302   }
1303   for (i = 0; i<4; i++)
1304     if (rompatch2addr [i] != 0)
1305       CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2val [i]);
1306   return ticks;
1307 }
1308 
cheatsAdd(const char * codeStr,const char * desc,u32 rawaddress,u32 address,u32 value,int code,int size)1309 void cheatsAdd(const char *codeStr,
1310                const char *desc,
1311                u32 rawaddress,
1312                u32 address,
1313                u32 value,
1314                int code,
1315                int size)
1316 {
1317   if(cheatsNumber < MAX_CHEATS) {
1318     int x = cheatsNumber;
1319     cheatsList[x].code = code;
1320     cheatsList[x].size = size;
1321     cheatsList[x].rawaddress = rawaddress;
1322     cheatsList[x].address = address;
1323     cheatsList[x].value = value;
1324     strcpy(cheatsList[x].codestring, codeStr);
1325     strcpy(cheatsList[x].desc, desc);
1326     cheatsList[x].enabled = true;
1327     cheatsList[x].status = 0;
1328 
1329     // we only store the old value for this simple codes. ROM patching
1330     // is taken care when it actually patches the ROM
1331     switch(cheatsList[x].size) {
1332     case INT_8_BIT_WRITE:
1333       cheatsList[x].oldValue = CPUReadByte(address);
1334       break;
1335     case INT_16_BIT_WRITE:
1336       cheatsList[x].oldValue = CPUReadHalfWord(address);
1337       break;
1338     case INT_32_BIT_WRITE:
1339       cheatsList[x].oldValue = CPUReadMemory(address);
1340       break;
1341     case CHEATS_16_BIT_WRITE:
1342       cheatsList[x].oldValue = CPUReadHalfWord(address);
1343       break;
1344     case CHEATS_32_BIT_WRITE:
1345       cheatsList[x].oldValue = CPUReadMemory(address);
1346       break;
1347     }
1348     cheatsNumber++;
1349   }
1350 }
1351 
cheatsDelete(int number,bool restore)1352 void cheatsDelete(int number, bool restore)
1353 {
1354   if(number < cheatsNumber && number >= 0) {
1355     int x = number;
1356 
1357     if(restore) {
1358       switch(cheatsList[x].size) {
1359       case INT_8_BIT_WRITE:
1360         CPUWriteByte(cheatsList[x].address, (u8)cheatsList[x].oldValue);
1361         break;
1362       case INT_16_BIT_WRITE:
1363         CPUWriteHalfWord(cheatsList[x].address, (u16)cheatsList[x].oldValue);
1364         break;
1365       case INT_32_BIT_WRITE:
1366         CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue);
1367         break;
1368       case CHEATS_16_BIT_WRITE:
1369         if ((cheatsList[x].address>>24)>=0x08) {
1370           CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, cheatsList[x].oldValue);
1371         } else {
1372           CPUWriteHalfWord(cheatsList[x].address, cheatsList[x].oldValue);
1373         }
1374         break;
1375       case CHEATS_32_BIT_WRITE:
1376         if ((cheatsList[x].address>>24)>=0x08) {
1377           CHEAT_PATCH_ROM_32BIT(cheatsList[x].address, cheatsList[x].oldValue);
1378         } else {
1379           CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue);
1380         }
1381       case GSA_16_BIT_ROM_PATCH:
1382         if(cheatsList[x].status & 1) {
1383           cheatsList[x].status &= ~1;
1384           CHEAT_PATCH_ROM_16BIT(cheatsList[x].address,
1385                                 cheatsList[x].oldValue);
1386         }
1387         break;
1388       case GSA_16_BIT_ROM_PATCH2C:
1389       case GSA_16_BIT_ROM_PATCH2D:
1390       case GSA_16_BIT_ROM_PATCH2E:
1391       case GSA_16_BIT_ROM_PATCH2F:
1392         if(cheatsList[x].status & 1) {
1393           cheatsList[x].status &= ~1;
1394         }
1395         break;
1396       case MASTER_CODE:
1397         mastercode=0;
1398         break;
1399       }
1400     }
1401     if((x+1) <  cheatsNumber) {
1402       memcpy(&cheatsList[x], &cheatsList[x+1], sizeof(CheatsData)*
1403              (cheatsNumber-x-1));
1404     }
1405     cheatsNumber--;
1406   }
1407 }
1408 
cheatsDeleteAll(bool restore)1409 void cheatsDeleteAll(bool restore)
1410 {
1411   for(int i = cheatsNumber-1; i >= 0; i--) {
1412     cheatsDelete(i, restore);
1413   }
1414 }
1415 
cheatsEnable(int i)1416 void cheatsEnable(int i)
1417 {
1418   if(i >= 0 && i < cheatsNumber) {
1419     cheatsList[i].enabled = true;
1420     mastercode = 0;
1421   }
1422 }
1423 
cheatsDisable(int i)1424 void cheatsDisable(int i)
1425 {
1426   if(i >= 0 && i < cheatsNumber) {
1427     switch(cheatsList[i].size) {
1428     case GSA_16_BIT_ROM_PATCH:
1429       if(cheatsList[i].status & 1) {
1430         cheatsList[i].status &= ~1;
1431         CHEAT_PATCH_ROM_16BIT(cheatsList[i].address,
1432                               cheatsList[i].oldValue);
1433       }
1434       break;
1435     case GSA_16_BIT_ROM_PATCH2C:
1436     case GSA_16_BIT_ROM_PATCH2D:
1437     case GSA_16_BIT_ROM_PATCH2E:
1438     case GSA_16_BIT_ROM_PATCH2F:
1439       if(cheatsList[i].status & 1) {
1440         cheatsList[i].status &= ~1;
1441       }
1442       break;
1443     case MASTER_CODE:
1444         mastercode=0;
1445       break;
1446     }
1447     cheatsList[i].enabled = false;
1448   }
1449 }
1450 
cheatsVerifyCheatCode(const char * code,const char * desc)1451 bool cheatsVerifyCheatCode(const char *code, const char *desc)
1452 {
1453   size_t len = strlen(code);
1454   if(len != 11 && len != 13 && len != 17) {
1455     systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': wrong length"), code);
1456     return false;
1457   }
1458 
1459   if(code[8] != ':') {
1460     systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': no colon"), code);
1461     return false;
1462   }
1463 
1464   size_t i;
1465   for(i = 0; i < 8; i++) {
1466     if(!CHEAT_IS_HEX(code[i])) {
1467       // wrong cheat
1468       systemMessage(MSG_INVALID_CHEAT_CODE,
1469                     N_("Invalid cheat code '%s': first part is not hex"), code);
1470       return false;
1471     }
1472   }
1473   for(i = 9; i < len; i++) {
1474     if(!CHEAT_IS_HEX(code[i])) {
1475       // wrong cheat
1476       systemMessage(MSG_INVALID_CHEAT_CODE,
1477                     N_("Invalid cheat code '%s' second part is not hex"), code);
1478       return false;
1479     }
1480   }
1481 
1482   u32 address = 0;
1483   u32 value = 0;
1484 
1485   char buffer[10];
1486   strncpy(buffer, code, 8);
1487   buffer[8] = 0;
1488   sscanf(buffer, "%x", &address);
1489 
1490   switch(address >> 24) {
1491   case 0x02:
1492   case 0x03:
1493   case 0x04:
1494   case 0x05:
1495   case 0x06:
1496   case 0x07:
1497   case 0x08:
1498   case 0x09:
1499   case 0x0A:
1500   case 0x0B:
1501   case 0x0C:
1502   case 0x0D:
1503     break;
1504   default:
1505     systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS,
1506                   N_("Invalid cheat code address: %08x"),
1507                   address);
1508     return false;
1509   }
1510 
1511   strncpy(buffer, &code[9], 8);
1512   sscanf(buffer, "%x", &value);
1513   int type = 0;
1514   if(len == 13)
1515     type = 114;
1516   if(len == 17)
1517     type = 115;
1518   cheatsAdd(code, desc, address, address, value, type, type);
1519   return true;
1520 }
1521 
cheatsAddCheatCode(const char * code,const char * desc)1522 void cheatsAddCheatCode(const char *code, const char *desc)
1523 {
1524   cheatsVerifyCheatCode(code, desc);
1525 }
1526 
cheatsGSAGetDeadface(bool v3)1527 u16 cheatsGSAGetDeadface(bool v3)
1528 {
1529   for(int i = cheatsNumber-1; i >= 0; i--)
1530     if ((cheatsList[i].address == 0xDEADFACE) && (cheatsList[i].code == (v3 ? 257 : 256)))
1531       return cheatsList[i].value & 0xFFFF;
1532 	return 0;
1533 }
1534 
cheatsGSAChangeEncryption(u16 value,bool v3)1535 void cheatsGSAChangeEncryption(u16 value, bool v3) {
1536 	int i;
1537 	u8 *deadtable1, *deadtable2;
1538 
1539 	if (v3) {
1540 		deadtable1 = (u8*)(&v3_deadtable1);
1541 		deadtable2 = (u8*)(&v3_deadtable2);
1542 	        for (i = 0; i < 4; i++)
1543 		  seeds_v3[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2);
1544 	}
1545 	else {
1546 		deadtable1 = (u8*)(&v1_deadtable1);
1547 		deadtable2 = (u8*)(&v1_deadtable2);
1548 		for (i = 0; i < 4; i++){
1549 		  seeds_v1[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2);
1550 		}
1551 	}
1552 }
1553 
seed_gen(u8 upper,u8 seed,u8 * deadtable1,u8 * deadtable2)1554 u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2) {
1555 	int i;
1556 	u32 newseed = 0;
1557 
1558 	for (i = 0; i < 4; i++)
1559 		newseed = ((newseed << 8) | ((deadtable1[(i + upper) & 0xFF] + deadtable2[seed]) & 0xFF));
1560 
1561 	return newseed;
1562 }
1563 
cheatsDecryptGSACode(u32 & address,u32 & value,bool v3)1564 void cheatsDecryptGSACode(u32& address, u32& value, bool v3)
1565 {
1566   u32 rollingseed = 0xC6EF3720;
1567   u32 *seeds = v3 ? seeds_v3 : seeds_v1;
1568 
1569   int bitsleft = 32;
1570   while (bitsleft > 0) {
1571     value -= ((((address << 4) + seeds[2]) ^ (address + rollingseed)) ^
1572               ((address >> 5) + seeds[3]));
1573     address -= ((((value << 4) + seeds[0]) ^ (value + rollingseed)) ^
1574                 ((value >> 5) + seeds[1]));
1575     rollingseed -= 0x9E3779B9;
1576     bitsleft--;
1577   }
1578 }
1579 
cheatsAddGSACode(const char * code,const char * desc,bool v3)1580 void cheatsAddGSACode(const char *code, const char *desc, bool v3)
1581 {
1582   if(strlen(code) != 16) {
1583     // wrong cheat
1584     systemMessage(MSG_INVALID_GSA_CODE,
1585                   N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY"));
1586     return;
1587   }
1588 
1589   int i;
1590   for(i = 0; i < 16; i++) {
1591     if(!CHEAT_IS_HEX(code[i])) {
1592       // wrong cheat
1593       systemMessage(MSG_INVALID_GSA_CODE,
1594                     N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY"));
1595       return;
1596     }
1597   }
1598 
1599   char buffer[10];
1600   strncpy(buffer, code, 8);
1601   buffer[8] = 0;
1602   u32 address;
1603   sscanf(buffer, "%x", &address);
1604   strncpy(buffer, &code[8], 8);
1605   buffer[8] = 0;
1606   u32 value;
1607   sscanf(buffer, "%x", &value);
1608   cheatsGSAChangeEncryption(cheatsGSAGetDeadface (v3), v3);
1609   cheatsDecryptGSACode(address, value, v3);
1610 
1611   if(value == 0x1DC0DE) {
1612     u32 gamecode = READ32LE(((u32 *)&rom[0xac]));
1613     if(gamecode != address) {
1614       char buffer[5];
1615       *((u32 *)buffer) = address;
1616       buffer[4] = 0;
1617       char buffer2[5];
1618       *((u32 *)buffer2) = READ32LE(((u32 *)&rom[0xac]));
1619       buffer2[4] = 0;
1620       systemMessage(MSG_GBA_CODE_WARNING, N_("Warning: cheats are for game %s. Current game is %s.\nCodes may not work correctly."),
1621                     buffer, buffer2);
1622     }
1623     cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, v3 ? 257 : 256,
1624               UNKNOWN_CODE);
1625     return;
1626   }
1627   if(isMultilineWithData(cheatsNumber-1)) {
1628     cheatsAdd(code, desc, address, address, value, v3 ? 257 : 256, UNKNOWN_CODE);
1629     return;
1630   }
1631   if(v3) {
1632     int type = ((address >> 25) & 127) | ((address >> 17) & 0x80);
1633     u32 addr = (address & 0x00F00000) << 4 | (address & 0x0003FFFF);
1634     u16 mcode = (address>>24 & 0xFF);
1635 
1636     if ((mcode & 0xFE) == 0xC4)
1637     {
1638       cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | (0x08000000),
1639         value, 257, MASTER_CODE);
1640       mastercode = (address & 0x1FFFFFF) | (0x08000000);
1641     }
1642     else
1643     switch(type) {
1644     case 0x00:
1645       if(address == 0) {
1646         type = (value >> 25) & 127;
1647         addr = (value & 0x00F00000) << 4 | (value & 0x0003FFFF);
1648         switch(type) {
1649         case 0x04:
1650           cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_SLOWDOWN);
1651           break;
1652         case 0x08:
1653           cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_GS_WRITE2);
1654           break;
1655         case 0x09:
1656           cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_GS_WRITE2);
1657           break;
1658         case 0x0a:
1659           cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_GS_WRITE2);
1660           break;
1661         case 0x0c:
1662           cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2C);
1663           break;
1664         case 0x0d:
1665           cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2D);
1666           break;
1667         case 0x0e:
1668           cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2E);
1669           break;
1670         case 0x0f:
1671           cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2F);
1672           break;
1673         case 0x20:
1674           cheatsAdd(code, desc, address, 0, addr, 257, GSA_CODES_ON);
1675           break;
1676         case 0x40:
1677           cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_SLIDE);
1678           break;
1679         case 0x41:
1680           cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_SLIDE);
1681           break;
1682         case 0x42:
1683           cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_SLIDE);
1684           break;
1685         default:
1686           cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE);
1687           break;
1688         }
1689       } else
1690         cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_FILL);
1691       break;
1692     case 0x01:
1693       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_FILL);
1694       break;
1695     case 0x02:
1696       cheatsAdd(code, desc, address, addr, value, 257, INT_32_BIT_WRITE);
1697       break;
1698     case 0x04:
1699       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE);
1700       break;
1701     case 0x05:
1702       cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_TRUE);
1703       break;
1704     case 0x06:
1705       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE);
1706       break;
1707     case 0x07:
1708       cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS);
1709       break;
1710     case 0x08:
1711       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE);
1712       break;
1713     case 0x09:
1714       cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_FALSE);
1715       break;
1716     case 0x0a:
1717       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE);
1718       break;
1719     case 0xc:
1720       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S);
1721       break;
1722     case 0xd:
1723       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S);
1724       break;
1725     case 0xe:
1726       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S);
1727       break;
1728     case 0x10:
1729       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S);
1730       break;
1731     case 0x11:
1732       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S);
1733       break;
1734     case 0x12:
1735       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S);
1736       break;
1737     case 0x14:
1738       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U);
1739       break;
1740     case 0x15:
1741       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U);
1742       break;
1743     case 0x16:
1744       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U);
1745       break;
1746     case 0x18:
1747       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U);
1748       break;
1749     case 0x19:
1750       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U);
1751       break;
1752     case 0x1A:
1753       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U);
1754       break;
1755     case 0x1C:
1756       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND);
1757       break;
1758     case 0x1D:
1759       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND);
1760       break;
1761     case 0x1E:
1762       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND);
1763       break;
1764     case 0x20:
1765       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_POINTER);
1766       break;
1767     case 0x21:
1768       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_POINTER);
1769       break;
1770     case 0x22:
1771       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_POINTER);
1772       break;
1773     case 0x24:
1774       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE2);
1775       break;
1776     case 0x25:
1777       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE2);
1778       break;
1779     case 0x26:
1780       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE2);
1781       break;
1782     case 0x27:
1783       cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS2);
1784       break;
1785     case 0x28:
1786       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE2);
1787       break;
1788     case 0x29:
1789       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE2);
1790       break;
1791     case 0x2a:
1792       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE2);
1793       break;
1794     case 0x2c:
1795       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S2);
1796       break;
1797     case 0x2d:
1798       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S2);
1799       break;
1800     case 0x2e:
1801       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S2);
1802       break;
1803     case 0x30:
1804       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S2);
1805       break;
1806     case 0x31:
1807       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S2);
1808       break;
1809     case 0x32:
1810       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S2);
1811       break;
1812     case 0x34:
1813       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U2);
1814       break;
1815     case 0x35:
1816       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U2);
1817       break;
1818     case 0x36:
1819       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U2);
1820       break;
1821     case 0x38:
1822       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U2);
1823       break;
1824     case 0x39:
1825       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U2);
1826       break;
1827     case 0x3A:
1828       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U2);
1829       break;
1830     case 0x3C:
1831       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND2);
1832       break;
1833     case 0x3D:
1834       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND2);
1835       break;
1836     case 0x3E:
1837       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND2);
1838       break;
1839     case 0x40:
1840       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_ADD);
1841       break;
1842     case 0x41:
1843       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_ADD);
1844       break;
1845     case 0x42:
1846       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_ADD);
1847       break;
1848     case 0x44:
1849       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE3);
1850       break;
1851     case 0x45:
1852       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE3);
1853       break;
1854     case 0x46:
1855       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE3);
1856       break;
1857 	  case 0x47:
1858       cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS3);
1859       break;
1860     case 0x48:
1861       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE3);
1862       break;
1863     case 0x49:
1864       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE3);
1865       break;
1866     case 0x4a:
1867       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE3);
1868       break;
1869     case 0x4c:
1870       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S3);
1871       break;
1872     case 0x4d:
1873       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S3);
1874       break;
1875     case 0x4e:
1876       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S3);
1877       break;
1878     case 0x50:
1879       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S3);
1880       break;
1881     case 0x51:
1882       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S3);
1883       break;
1884     case 0x52:
1885       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S3);
1886       break;
1887     case 0x54:
1888       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U3);
1889       break;
1890     case 0x55:
1891       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U3);
1892       break;
1893     case 0x56:
1894       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U3);
1895       break;
1896     case 0x58:
1897       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U3);
1898       break;
1899     case 0x59:
1900       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U3);
1901       break;
1902     case 0x5a:
1903       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U3);
1904       break;
1905     case 0x5c:
1906       cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND3);
1907       break;
1908     case 0x5d:
1909       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND3);
1910       break;
1911     case 0x5e:
1912       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND3);
1913       break;
1914     case 0x63:
1915       cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_WRITE_IOREGS);
1916       break;
1917     case 0xE3:
1918       cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_WRITE_IOREGS);
1919       break;
1920     default:
1921       cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE);
1922       break;
1923     }
1924   } else {
1925     int type = (address >> 28) & 15;
1926     switch(type) {
1927     case 0:
1928     case 1:
1929     case 2:
1930       cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, type);
1931       break;
1932     case 3:
1933 	  switch ((address >> 0x10) & 0xFF){
1934 	  case 0x00:
1935         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_GROUP_WRITE);
1936 	    break;
1937 	  case 0x10:
1938 	    cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFF, 256, GSA_32_BIT_ADD );
1939 	    break;
1940 	  case 0x20:
1941 	    cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFF)+1), 256, GSA_32_BIT_ADD );
1942 	    break;
1943 	  case 0x30:
1944 	    cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, GSA_32_BIT_ADD );
1945 	    break;
1946 	  case 0x40:
1947 	    cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFFFF)+1), 256, GSA_32_BIT_ADD );
1948 	    break;
1949 	  case 0x50:
1950 	    cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_ADD2);
1951 	    break;
1952 	  case 0x60:
1953 	    cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_SUB2);
1954 	    break;
1955       default:
1956         // unsupported code
1957         cheatsAdd(code, desc, address, address, value, 256,
1958                   UNKNOWN_CODE);
1959         break;
1960       }
1961       break;
1962     case 6:
1963       address <<= 1;
1964       type = (value >> 24) & 0xFF;
1965       if(type == 0x00) {
1966         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256,
1967                   GSA_16_BIT_ROM_PATCH);
1968         break;
1969       }
1970       // unsupported code
1971       cheatsAdd(code, desc, address, address, value, 256,
1972                 UNKNOWN_CODE);
1973       break;
1974     case 8:
1975       switch((address >> 20) & 15) {
1976       case 1:
1977         cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256,
1978                   GSA_8_BIT_GS_WRITE);
1979         break;
1980       case 2:
1981         cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256,
1982                   GSA_16_BIT_GS_WRITE);
1983         break;
1984       case 4:
1985 		// This code is buggy : the value is always set to 0 !
1986         cheatsAdd(code, desc, address, address & 0x0F0FFFFF, 0, 256,
1987                   GSA_32_BIT_GS_WRITE);
1988         break;
1989       case 15:
1990         cheatsAdd(code, desc, address, 0, value & 0xFFFF, 256, GSA_SLOWDOWN);
1991         break;
1992       default:
1993         // unsupported code
1994         cheatsAdd(code, desc, address, address, value, 256,
1995                   UNKNOWN_CODE);
1996         break;
1997       }
1998       break;
1999     case 0x0d:
2000       if(address != 0xDEADFACE) {
2001         switch((value >> 20) & 0xF) {
2002         case 0:
2003         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256,
2004                   CBA_IF_TRUE);
2005           break;
2006         case 1:
2007         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256,
2008                   CBA_IF_FALSE);
2009           break;
2010         case 2:
2011         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256,
2012                   GSA_16_BIT_IF_LOWER_OR_EQ_U);
2013           break;
2014         case 3:
2015         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256,
2016                   GSA_16_BIT_IF_HIGHER_OR_EQ_U);
2017           break;
2018         default:
2019         // unsupported code
2020         cheatsAdd(code, desc, address, address, value, 256,
2021                   UNKNOWN_CODE);
2022           break;
2023 		}
2024       } else
2025         cheatsAdd(code, desc, address, address, value, 256,
2026                   UNKNOWN_CODE);
2027       break;
2028     case 0x0e:
2029       switch((value >> 28) & 0xF) {
2030       case 0:
2031       cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256,
2032                 GSA_16_BIT_MIF_TRUE);
2033         break;
2034       case 1:
2035       cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256,
2036                 GSA_16_BIT_MIF_FALSE);
2037         break;
2038       case 2:
2039       cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256,
2040                 GSA_16_BIT_MIF_LOWER_OR_EQ_U);
2041         break;
2042       case 3:
2043       cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256,
2044                 GSA_16_BIT_MIF_HIGHER_OR_EQ_U);
2045         break;
2046       default:
2047         // unsupported code
2048         cheatsAdd(code, desc, address, address, value, 256,
2049                   UNKNOWN_CODE);
2050         break;
2051       }
2052       break;
2053       case 0x0f:
2054         cheatsAdd(code, desc, address, (address & 0xFFFFFFF), value, 256, MASTER_CODE);
2055         mastercode = (address & 0xFFFFFFF);
2056         break;
2057       default:
2058       // unsupported code
2059       cheatsAdd(code, desc, address, address, value, 256,
2060                 UNKNOWN_CODE);
2061       break;
2062     }
2063   }
2064 }
2065 
cheatsImportGSACodeFile(const char * name,int game,bool v3)2066 bool cheatsImportGSACodeFile(const char *name, int game, bool v3)
2067 {
2068   FILE *f = fopen(name, "rb");
2069   if(!f)
2070     return false;
2071 
2072   int games = 0;
2073   int len = 0;
2074   fseek(f, 0x1e, SEEK_CUR);
2075   fread(&games, 1, 4, f);
2076   bool found = false;
2077   int g = 0;
2078   while(games > 0) {
2079     if(g == game) {
2080       found = true;
2081       break;
2082     }
2083     fread(&len, 1, 4, f);
2084     fseek(f,len,SEEK_CUR);
2085     int codes = 0;
2086     fread(&codes, 1, 4, f);
2087     while(codes > 0) {
2088       fread(&len, 1, 4, f);
2089       fseek(f, len, SEEK_CUR);
2090       fseek(f, 8, SEEK_CUR);
2091       fread(&len, 1, 4, f);
2092       fseek(f, len*12, SEEK_CUR);
2093       codes--;
2094     }
2095     games--;
2096     g++;
2097   }
2098   if(found) {
2099     char desc[256];
2100     char code[17];
2101     fread(&len, 1, 4, f);
2102     fseek(f, len, SEEK_CUR);
2103     int codes = 0;
2104     fread(&codes, 1, 4, f);
2105     while(codes > 0) {
2106       fread(&len, 1, 4, f);
2107       fread(desc, 1, len, f);
2108       desc[len] =0;
2109       desc[31] = 0;
2110       fread(&len, 1, 4, f);
2111       fseek(f, len, SEEK_CUR);
2112       fseek(f, 4, SEEK_CUR);
2113       fread(&len, 1, 4, f);
2114       while(len) {
2115         fseek(f, 4, SEEK_CUR);
2116         fread(code, 1, 8, f);
2117         fseek(f, 4, SEEK_CUR);
2118         fread(&code[8], 1, 8, f);
2119         code[16] = 0;
2120         cheatsAddGSACode(code, desc, v3);
2121         len -= 2;
2122       }
2123       codes--;
2124     }
2125   }
2126   fclose(f);
2127   return false;
2128 }
2129 
cheatsCBAReverseArray(u8 * array,u8 * dest)2130 void cheatsCBAReverseArray(u8 *array, u8 *dest)
2131 {
2132   dest[0] = array[3];
2133   dest[1] = array[2];
2134   dest[2] = array[1];
2135   dest[3] = array[0];
2136   dest[4] = array[5];
2137   dest[5] = array[4];
2138 }
2139 
chatsCBAScramble(u8 * array,int count,u8 b)2140 void chatsCBAScramble(u8 *array, int count, u8 b)
2141 {
2142   u8 *x = array + (count >> 3);
2143   u8 *y = array + (b >> 3);
2144   u32 z = *x & (1 << (count & 7));
2145   u32 x0 = (*x & (~(1 << (count & 7))));
2146   if (z != 0)
2147     z = 1;
2148   if ((*y & (1 << (b & 7))) != 0)
2149     x0 |= (1 << (count & 7));
2150   *x = x0;
2151   u32 temp = *y & (~(1 << (b & 7)));
2152   if (z != 0)
2153     temp |= (1 << (b & 7));
2154   *y = temp;
2155 }
2156 
cheatsCBAGetValue(u8 * array)2157 u32 cheatsCBAGetValue(u8 *array)
2158 {
2159   return array[0] | array[1]<<8 | array[2] << 16 | array[3]<<24;
2160 }
2161 
cheatsCBAGetData(u8 * array)2162 u16 cheatsCBAGetData(u8 *array)
2163 {
2164   return array[4] | array[5]<<8;
2165 }
2166 
cheatsCBAArrayToValue(u8 * array,u8 * dest)2167 void cheatsCBAArrayToValue(u8 *array, u8 *dest)
2168 {
2169   dest[0] = array[3];
2170   dest[1] = array[2];
2171   dest[2] = array[1];
2172   dest[3] = array[0];
2173   dest[4] = array[5];
2174   dest[5] = array[4];
2175 }
2176 
cheatsCBAParseSeedCode(u32 address,u32 value,u32 * array)2177 void cheatsCBAParseSeedCode(u32 address, u32 value, u32 *array)
2178 {
2179   array[0] = 1;
2180   array[1] = value & 0xFF;
2181   array[2] = (address >> 0x10) & 0xFF;
2182   array[3] = (value >> 8) & 0xFF;
2183   array[4] = (address >> 0x18) & 0x0F;
2184   array[5] = address & 0xFFFF;
2185   array[6] = address;
2186   array[7] = value;
2187 }
2188 
cheatsCBAEncWorker()2189 u32 cheatsCBAEncWorker()
2190 {
2191   u32 x = (cheatsCBATemporaryValue * 0x41c64e6d) + 0x3039;
2192   u32 y = (x * 0x41c64e6d) + 0x3039;
2193   u32 z = x >> 0x10;
2194   x = ((y >> 0x10) & 0x7fff) << 0x0f;
2195   z = (z << 0x1e) | x;
2196   x = (y * 0x41c64e6d) + 0x3039;
2197   cheatsCBATemporaryValue = x;
2198   return z | ((x >> 0x10) & 0x7fff);
2199 }
2200 
2201 #define ROR(v, s) \
2202   (((v) >> (s)) | (((v) & ((1 << (s))-1)) << (32 - (s))))
2203 
cheatsCBACalcIndex(u32 x,u32 y)2204 u32 cheatsCBACalcIndex(u32 x, u32 y)
2205 {
2206   if(y != 0) {
2207     if(y == 1)
2208       x = 0;
2209     else if(x == y)
2210       x = 0;
2211     if(y < 1)
2212       return x;
2213     else if(x < y)
2214       return x;
2215     u32 x0 = 1;
2216 
2217     while(y < 0x10000000) {
2218       if(y < x) {
2219         y = y << 4;
2220         x0 = x0 << 4;
2221       } else break;
2222     }
2223 
2224     while(y < 0x80000000) {
2225       if(y < x) {
2226         y = y << 1;
2227         x0 = x0 << 1;
2228       } else break;
2229     }
2230 
2231   loop:
2232     u32 z = 0;
2233     if(x >= y)
2234       x -= y;
2235     if(x >= (y >> 1)) {
2236       x -= (y >> 1);
2237       z |= ROR(x0, 1);
2238     }
2239     if(x >= (y >> 2)) {
2240       x -= (y >> 2);
2241       z |= ROR(x0, 2);
2242     }
2243     if(x >= (y >> 3)) {
2244       x -= (y >> 3);
2245       z |= ROR(x0, 3);
2246     }
2247 
2248     u32 temp = x0;
2249 
2250     if(x != 0) {
2251       x0 = x0 >> 4;
2252       if(x0 != 0) {
2253         y = y >> 4;
2254         goto loop;
2255       }
2256     }
2257 
2258     z = z & 0xe0000000;
2259 
2260     if(z != 0) {
2261       if((temp & 7) == 0)
2262         return x;
2263     } else
2264       return x;
2265 
2266     if((z & ROR(temp, 3)) != 0)
2267       x += y >> 3;
2268     if((z & ROR(temp, 2)) != 0)
2269       x += y >> 2;
2270     if((z & ROR(temp, 1)) != 0)
2271       x += y >> 1;
2272     return x;
2273   } else {
2274   }
2275   // should not happen in the current code
2276   return 0;
2277 }
2278 
cheatsCBAUpdateSeedBuffer(u32 a,u8 * buffer,int count)2279 void cheatsCBAUpdateSeedBuffer(u32 a, u8 *buffer, int count)
2280 {
2281   int i;
2282   for(i = 0; i < count; i++)
2283     buffer[i] = i;
2284   for(i = 0; (u32)i < a; i++) {
2285     u32 a = cheatsCBACalcIndex(cheatsCBAEncWorker(), count);
2286     u32 b = cheatsCBACalcIndex(cheatsCBAEncWorker(), count);
2287     u32 t = buffer[a];
2288     buffer[a] = buffer[b];
2289     buffer[b] = t;
2290   }
2291 }
2292 
cheatsCBAChangeEncryption(u32 * seed)2293 void cheatsCBAChangeEncryption(u32 *seed)
2294 {
2295   int i;
2296 
2297   cheatsCBATemporaryValue = (seed[1] ^ 0x1111);
2298   cheatsCBAUpdateSeedBuffer(0x50, cheatsCBASeedBuffer, 0x30);
2299   cheatsCBATemporaryValue = 0x4efad1c3;
2300 
2301   for(i = 0; (u32)i < seed[4]; i++) {
2302     cheatsCBATemporaryValue = cheatsCBAEncWorker();
2303   }
2304   cheatsCBASeed[2] = cheatsCBAEncWorker();
2305   cheatsCBASeed[3] = cheatsCBAEncWorker();
2306 
2307   cheatsCBATemporaryValue = seed[3] ^ 0xf254;
2308 
2309   for(i = 0; (u32)i < seed[3]; i++) {
2310     cheatsCBATemporaryValue = cheatsCBAEncWorker();
2311   }
2312 
2313   cheatsCBASeed[0] = cheatsCBAEncWorker();
2314   cheatsCBASeed[1] = cheatsCBAEncWorker();
2315 
2316   *((u32 *)&cheatsCBACurrentSeed[0]) = seed[6];
2317   *((u32 *)&cheatsCBACurrentSeed[4]) = seed[7];
2318   *((u32 *)&cheatsCBACurrentSeed[8]) = 0;
2319 }
2320 
cheatsCBAGenValue(u32 x,u32 y,u32 z)2321 u16 cheatsCBAGenValue(u32 x, u32 y, u32 z)
2322 {
2323   y <<= 0x10;
2324   z <<= 0x10;
2325   x <<= 0x18;
2326   u32 x0 = (int)y >> 0x10;
2327   z = (int)z >> 0x10;
2328   x = (int)x >> 0x10;
2329   for(int i = 0; i < 8; i++) {
2330     u32 temp = z ^ x;
2331     if ((int)temp >= 0) {
2332       temp = z << 0x11;
2333     }
2334     else {
2335       temp = z << 0x01;
2336       temp ^= x0;
2337       temp = temp << 0x10;
2338     }
2339     z = (int)temp >> 0x10;
2340     temp = x << 0x11;
2341     x = (int)temp >> 0x10;
2342   }
2343   return z & 0xffff;
2344 }
2345 
cheatsCBAGenTable()2346 void cheatsCBAGenTable() {
2347   for (int i = 0; i < 0x100; i++) {
2348     cheatsCBATable[i] = cheatsCBAGenValue(i, 0x1021, 0);
2349   }
2350   cheatsCBATableGenerated = true;
2351 }
2352 
cheatsCBACalcCRC(u8 * rom,int count)2353 u16 cheatsCBACalcCRC(u8 *rom, int count)
2354 {
2355   u32 crc = 0xffffffff;
2356 
2357   if (count & 3) {
2358     // 0x08000EAE
2359   } else {
2360     count = (count >> 2) - 1;
2361     if(count != -1) {
2362       while(count != -1) {
2363         crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18)
2364                                                ^ *rom++]) << 0x10) >> 0x10;
2365         crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18)
2366                                                ^ *rom++]) << 0x10) >> 0x10;
2367         crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18)
2368                                                ^ *rom++]) << 0x10) >> 0x10;
2369         crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18)
2370                                                ^ *rom++]) << 0x10) >> 0x10;
2371         count--;
2372       }
2373     }
2374   }
2375   return crc & 0xffff;
2376 }
2377 
cheatsCBADecrypt(u8 * decrypt)2378 void cheatsCBADecrypt(u8 *decrypt)
2379 {
2380   u8 buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
2381   u8 *array = &buffer[1];
2382 
2383   cheatsCBAReverseArray(decrypt, array);
2384 
2385   for(int count = 0x2f; count >= 0; count--) {
2386     chatsCBAScramble(array, count, cheatsCBASeedBuffer[count]);
2387   }
2388   cheatsCBAArrayToValue(array, decrypt);
2389   *((u32 *)decrypt) = cheatsCBAGetValue(decrypt) ^
2390     cheatsCBASeed[0];
2391   *((u16 *)(decrypt+4)) = (cheatsCBAGetData(decrypt) ^
2392                            cheatsCBASeed[1]) & 0xffff;
2393 
2394   cheatsCBAReverseArray(decrypt, array);
2395 
2396   u32 cs = cheatsCBAGetValue(cheatsCBACurrentSeed);
2397   for(int i = 0; i <= 4; i++) {
2398     array[i] = ((cs >> 8) ^ array[i+1]) ^ array[i] ;
2399   }
2400 
2401   array[5] = (cs >> 8) ^ array[5];
2402 
2403   for(int j = 5; j >=0; j--) {
2404     array[j] = (cs ^ array[j-1]) ^ array[j];
2405   }
2406 
2407   cheatsCBAArrayToValue(array, decrypt);
2408 
2409   *((u32 *)decrypt) = cheatsCBAGetValue(decrypt)
2410     ^ cheatsCBASeed[2];
2411   *((u16 *)(decrypt+4)) = (cheatsCBAGetData(decrypt)
2412                            ^ cheatsCBASeed[3]) & 0xffff;
2413 }
2414 
cheatsCBAGetCount()2415 int cheatsCBAGetCount()
2416 {
2417   int count = 0;
2418   for(int i = 0; i < cheatsNumber; i++) {
2419     if(cheatsList[i].code == 512)
2420       count++;
2421   }
2422   return count;
2423 }
2424 
cheatsCBAShouldDecrypt()2425 bool cheatsCBAShouldDecrypt()
2426 {
2427   for(int i = 0; i < cheatsNumber; i++) {
2428     if(cheatsList[i].code == 512) {
2429       return (cheatsList[i].codestring[0] == '9');
2430     }
2431   }
2432   return false;
2433 }
2434 
cheatsAddCBACode(const char * code,const char * desc)2435 void cheatsAddCBACode(const char *code, const char *desc)
2436 {
2437   if(strlen(code) != 13) {
2438     // wrong cheat
2439     systemMessage(MSG_INVALID_CBA_CODE,
2440                   N_("Invalid CBA code. Format is XXXXXXXX YYYY."));
2441     return;
2442   }
2443 
2444   int i;
2445   for(i = 0; i < 8; i++) {
2446     if(!CHEAT_IS_HEX(code[i])) {
2447       // wrong cheat
2448       systemMessage(MSG_INVALID_CBA_CODE,
2449                     N_("Invalid CBA code. Format is XXXXXXXX YYYY."));
2450       return;
2451     }
2452   }
2453 
2454   if(code[8] != ' ') {
2455     systemMessage(MSG_INVALID_CBA_CODE,
2456                   N_("Invalid CBA code. Format is XXXXXXXX YYYY."));
2457     return;
2458   }
2459 
2460   for(i = 9; i < 13; i++) {
2461     if(!CHEAT_IS_HEX(code[i])) {
2462       // wrong cheat
2463       systemMessage(MSG_INVALID_CBA_CODE,
2464                     N_("Invalid CBA code. Format is XXXXXXXX YYYY."));
2465       return;
2466     }
2467   }
2468 
2469   char buffer[10];
2470   strncpy(buffer, code, 8);
2471   buffer[8] = 0;
2472   u32 address;
2473   sscanf(buffer, "%x", &address);
2474   strncpy(buffer, &code[9], 4);
2475   buffer[4] = 0;
2476   u32 value;
2477   sscanf(buffer, "%x", &value);
2478 
2479   u8 array[8] = {
2480     static_cast<u8>(address & 255),
2481     static_cast<u8>((address >> 8) & 255),
2482     static_cast<u8>((address >> 16) & 255),
2483     static_cast<u8>((address >> 24) & 255),
2484     static_cast<u8>((value & 255)),
2485     static_cast<u8>((value >> 8) & 255),
2486     0,
2487     0
2488   };
2489 
2490   if(cheatsCBAGetCount() == 0 &&
2491      (address >> 28) == 9) {
2492     u32 seed[8];
2493     cheatsCBAParseSeedCode(address, value, seed);
2494     cheatsCBAChangeEncryption(seed);
2495     cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, UNKNOWN_CODE);
2496   } else {
2497     if(cheatsCBAShouldDecrypt())
2498       cheatsCBADecrypt(array);
2499 
2500     address = READ32LE(((u32 *)array));
2501     value = READ16LE(((u16 *)&array[4]));
2502 
2503     int type = (address >> 28) & 15;
2504 
2505     if(isMultilineWithData(cheatsNumber-1) || (super>0)) {
2506       cheatsAdd(code, desc, address, address, value, 512, UNKNOWN_CODE);
2507 	  if (super>0)
2508 		  super-= 1;
2509       return;
2510     }
2511 
2512     switch(type) {
2513     case 0x00:
2514       {
2515         if(!cheatsCBATableGenerated)
2516           cheatsCBAGenTable();
2517         u32 crc = cheatsCBACalcCRC(rom, 0x10000);
2518         if(crc != address) {
2519           systemMessage(MSG_CBA_CODE_WARNING,
2520                         N_("Warning: Codes seem to be for a different game.\nCodes may not work correctly."));
2521         }
2522         cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512,
2523                   UNKNOWN_CODE);
2524       }
2525       break;
2526     case 0x01:
2527       cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | 0x08000000, value, 512, MASTER_CODE);
2528       mastercode = (address & 0x1FFFFFF) | 0x08000000;
2529       break;
2530     case 0x02:
2531       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2532                 CBA_OR);
2533       break;
2534     case 0x03:
2535       cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512,
2536                 INT_8_BIT_WRITE);
2537       break;
2538     case 0x04:
2539       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2540                 CBA_SLIDE_CODE);
2541       break;
2542     case 0x05:
2543 		cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2544                   CBA_SUPER);
2545 		super = getCodeLength(cheatsNumber-1);
2546       break;
2547     case 0x06:
2548       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2549                 CBA_AND);
2550       break;
2551     case 0x07:
2552       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2553                 CBA_IF_TRUE);
2554       break;
2555     case 0x08:
2556       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2557                 INT_16_BIT_WRITE);
2558       break;
2559     case 0x0a:
2560       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2561                 CBA_IF_FALSE);
2562       break;
2563     case 0x0b:
2564       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2565                 CBA_GT);
2566       break;
2567     case 0x0c:
2568       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2569                 CBA_LT);
2570       break;
2571     case 0x0d:
2572 		if ((address & 0xF0)<0x30)
2573       cheatsAdd(code, desc, address, address & 0xF0, value, 512,
2574                 CBA_IF_KEYS_PRESSED);
2575       break;
2576     case 0x0e:
2577       cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0x8000 ? value | 0xFFFF0000 : value, 512,
2578                 CBA_ADD);
2579       break;
2580     case 0x0f:
2581       cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
2582                 GSA_16_BIT_IF_AND);
2583       break;
2584     default:
2585       // unsupported code
2586       cheatsAdd(code, desc, address, address & 0xFFFFFFFF, value, 512,
2587                 UNKNOWN_CODE);
2588       break;
2589     }
2590   }
2591 }
2592 
2593 #ifndef __LIBRETRO__
cheatsSaveGame(gzFile file)2594 void cheatsSaveGame(gzFile file)
2595 {
2596   utilWriteInt(file, cheatsNumber);
2597 
2598   utilGzWrite(file, cheatsList, sizeof(cheatsList));
2599 }
2600 
cheatsReadGame(gzFile file,int version)2601 void cheatsReadGame(gzFile file, int version)
2602 {
2603   cheatsNumber = 0;
2604 
2605   cheatsNumber = utilReadInt(file);
2606 
2607   if (version > 8)
2608     utilGzRead(file, cheatsList, sizeof(cheatsList));
2609 
2610 
2611   bool firstCodeBreaker = true;
2612 
2613   for(int i = 0; i < cheatsNumber; i++) {
2614     if (version <9)
2615     {
2616         cheatsList[i].code = utilReadInt(file);
2617         cheatsList[i].size = utilReadInt(file);
2618         cheatsList[i].status = utilReadInt(file);
2619         cheatsList[i].enabled = utilReadInt(file) ? true : false;
2620         utilGzRead(file, &cheatsList[i].address, sizeof(u32));
2621         cheatsList[i].rawaddress = cheatsList[i].address;
2622         utilGzRead(file, &cheatsList[i].value, sizeof(u32));
2623         utilGzRead(file, &cheatsList[i].oldValue, sizeof(u32));
2624         utilGzRead(file, &cheatsList[i].codestring, 20*sizeof(char));
2625         utilGzRead(file, &cheatsList[i].desc, 32*sizeof(char));
2626     }
2627 
2628     cheatsList[i].status = 0;
2629     if(!cheatsList[i].codestring[0]) {
2630       switch(cheatsList[i].size) {
2631       case 0:
2632         sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address,
2633                 cheatsList[i].value);
2634         break;
2635       case 1:
2636         sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address,
2637                 cheatsList[i].value);
2638         break;
2639       case 2:
2640         sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address,
2641                 cheatsList[i].value);
2642         break;
2643       }
2644     }
2645 
2646     if(cheatsList[i].enabled) {
2647       cheatsEnable(i);
2648     }
2649 
2650     if(cheatsList[i].code == 512 && firstCodeBreaker) {
2651       firstCodeBreaker = false;
2652       char buffer[10];
2653       strncpy(buffer, cheatsList[i].codestring, 8);
2654       buffer[8] = 0;
2655       u32 address;
2656       sscanf(buffer, "%x", &address);
2657       if((address >> 28) == 9) {
2658         strncpy(buffer, &cheatsList[i].codestring[9], 4);
2659         buffer[4] = 0;
2660         u32 value;
2661         sscanf(buffer, "%x", &value);
2662 
2663         u32 seed[8];
2664         cheatsCBAParseSeedCode(address, value, seed);
2665         cheatsCBAChangeEncryption(seed);
2666       }
2667     }
2668   }
2669 }
2670 
2671 
2672 // skip the cheat list data
cheatsReadGameSkip(gzFile file,int version)2673 void cheatsReadGameSkip( gzFile file, int version )
2674 {
2675   int nCheats = 0;
2676   nCheats = utilReadInt( file );
2677 
2678   if( version >= 9 ) {
2679     utilGzSeek( file, sizeof( cheatsList ), SEEK_CUR );
2680   }
2681 
2682   for( int i = 0; i < nCheats; i++ ) {
2683     if( version < 9 ) {
2684       utilGzSeek( file, ( 7 * sizeof(int) ) + ( 52 * sizeof(char) ), SEEK_CUR );
2685     }
2686   }
2687 }
2688 
2689 
cheatsSaveCheatList(const char * file)2690 void cheatsSaveCheatList(const char *file)
2691 {
2692   if(cheatsNumber == 0)
2693     return;
2694   FILE *f = fopen(file, "wb");
2695   if(f == NULL)
2696     return;
2697   int version = 1;
2698   fwrite(&version, 1, sizeof(version), f);
2699   int type = 1;
2700   fwrite(&type, 1, sizeof(type), f);
2701   fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f);
2702   fwrite(cheatsList, 1, sizeof(CheatsData) * cheatsNumber, f);
2703   fclose(f);
2704 }
2705 
cheatsLoadCheatList(const char * file)2706 bool cheatsLoadCheatList(const char *file)
2707 {
2708 
2709   int count = 0;
2710 
2711   FILE *f = fopen(file, "rb");
2712 
2713   if(f == NULL)
2714     return false;
2715 
2716   int version = 0;
2717 
2718   if(fread(&version, 1, sizeof(version), f) != sizeof(version)) {
2719     fclose(f);
2720     return false;
2721   }
2722 
2723   if(version != 1) {
2724     systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_VERSION,
2725                   N_("Unsupported cheat list version %d"), version);
2726     fclose(f);
2727     return false;
2728   }
2729 
2730   int type = 0;
2731   if(fread(&type, 1, sizeof(type), f) != sizeof(type)) {
2732     fclose(f);
2733     return false;
2734   }
2735 
2736 
2737   if((type != 0) && (type != 1)) {
2738     systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE,
2739                   N_("Unsupported cheat list type %d"), type);
2740     fclose(f);
2741     return false;
2742   }
2743 
2744   if(fread(&count, 1, sizeof(count), f) != sizeof(count)) {
2745     fclose(f);
2746     return false;
2747   }
2748   if (type == 1)
2749   {
2750     if(fread(cheatsList, 1, sizeof(cheatsList), f) > sizeof(cheatsList)) {
2751       fclose(f);
2752       return false;
2753     }
2754   }
2755   else if (type == 0)
2756   {
2757     for(int i = 0; i < count; i++) {
2758       fread(&cheatsList[i].code, 1, sizeof(int),f);
2759       fread(&cheatsList[i].size, 1, sizeof(int),f);
2760       fread(&cheatsList[i].status, 1, sizeof(int),f);
2761       fread(&cheatsList[i].enabled, 1, sizeof(int),f);
2762       cheatsList[i].enabled = cheatsList[i].enabled ? true : false;
2763       fread(&cheatsList[i].address, 1, sizeof(u32),f);
2764       cheatsList[i].rawaddress = cheatsList[i].address;
2765       fread(&cheatsList[i].value, 1, sizeof(u32),f);
2766       fread(&cheatsList[i].oldValue, 1, sizeof(u32),f);
2767       fread(&cheatsList[i].codestring, 1, 20*sizeof(char),f);
2768       if(fread(&cheatsList[i].desc, 1, 32*sizeof(char),f) != 32*sizeof(char)) {
2769         fclose(f);
2770         return false;
2771       }
2772     }
2773   }
2774 
2775   bool firstCodeBreaker = true;
2776 
2777   for(int i = 0; i < count; i++) {
2778     cheatsList[i].status = 0; // remove old status as it is not used
2779     if(!cheatsList[i].codestring[0]) {
2780       switch(cheatsList[i].size) {
2781       case 0:
2782         sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address,
2783                 cheatsList[i].value);
2784         break;
2785       case 1:
2786         sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address,
2787                 cheatsList[i].value);
2788         break;
2789       case 2:
2790         sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address,
2791                 cheatsList[i].value);
2792         break;
2793       }
2794     }
2795 
2796     if(cheatsList[i].code == 512 && firstCodeBreaker) {
2797       firstCodeBreaker = false;
2798       char buffer[10];
2799       strncpy(buffer, cheatsList[i].codestring, 8);
2800       buffer[8] = 0;
2801       u32 address;
2802       sscanf(buffer, "%x", &address);
2803       if((address >> 28) == 9) {
2804         strncpy(buffer, &cheatsList[i].codestring[9], 4);
2805         buffer[4] = 0;
2806         u32 value;
2807         sscanf(buffer, "%x", &value);
2808 
2809         u32 seed[8];
2810         cheatsCBAParseSeedCode(address, value, seed);
2811         cheatsCBAChangeEncryption(seed);
2812       }
2813     }
2814   }
2815   cheatsNumber = count;
2816   fclose(f);
2817   return true;
2818 }
2819 #endif
2820 
2821 extern int cpuNextEvent;
2822 
2823 extern void debuggerBreakOnWrite(u32 , u32, u32, int, int);
2824 
2825 #ifdef BKPT_SUPPORT
cheatsGetType(u32 address)2826 static u8 cheatsGetType(u32 address)
2827 {
2828   switch(address >> 24) {
2829   case 2:
2830     return freezeWorkRAM[address & 0x3FFFF];
2831   case 3:
2832     return freezeInternalRAM[address & 0x7FFF];
2833   case 5:
2834     return freezePRAM[address & 0x3FC];
2835   case 6:
2836     if (address > 0x06010000)
2837       return freezeVRAM[address & 0x17FFF];
2838     else
2839       return freezeVRAM[address & 0x1FFFF];
2840   case 7:
2841     return freezeOAM[address & 0x3FC];
2842   }
2843   return 0;
2844 }
2845 #endif
2846 
cheatsWriteMemory(u32 address,u32 value)2847 void cheatsWriteMemory(u32 address, u32 value)
2848 {
2849 #ifdef BKPT_SUPPORT
2850   if(cheatsNumber == 0) {
2851     int type = cheatsGetType(address);
2852     u32 oldValue = debuggerReadMemory(address);
2853     if(type == 1 || (type == 2 && oldValue != value)) {
2854       debuggerBreakOnWrite(address, oldValue, value, 2, type);
2855       cpuNextEvent = 0;
2856     }
2857     debuggerWriteMemory(address, value);
2858   }
2859 #endif
2860 }
2861 
cheatsWriteHalfWord(u32 address,u16 value)2862 void cheatsWriteHalfWord(u32 address, u16 value)
2863 {
2864 #ifdef BKPT_SUPPORT
2865   if(cheatsNumber == 0) {
2866     int type = cheatsGetType(address);
2867     u16 oldValue = debuggerReadHalfWord(address);
2868     if(type == 1 || (type == 2 && oldValue != value)) {
2869       debuggerBreakOnWrite(address, oldValue, value, 1, type);
2870       cpuNextEvent = 0;
2871     }
2872     debuggerWriteHalfWord(address, value);
2873   }
2874 #endif
2875 }
2876 
cheatsWriteByte(u32 address,u8 value)2877 void cheatsWriteByte(u32 address, u8 value)
2878 {
2879 #ifdef BKPT_SUPPORT
2880   if(cheatsNumber == 0) {
2881     int type = cheatsGetType(address);
2882     u8 oldValue = debuggerReadByte(address);
2883     if(type == 1 || (type == 2 && oldValue != value)) {
2884       debuggerBreakOnWrite(address, oldValue, value, 0, type);
2885       cpuNextEvent = 0;
2886     }
2887     debuggerWriteByte(address, value);
2888   }
2889 #endif
2890 }
2891