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