@@ -79,6 +79,25 @@ static const u32 homebrewSigPatched[5] = {
79
79
0x037C0010 // DCD 0x037C0010
80
80
};
81
81
82
+ // accelerator patch for IPC_SYNC
83
+ static const u32 homebrewAccelSig [4 ] = {
84
+ 0xD5060743 , // LSLS R3, R0, #0x1D
85
+ // BPL loc_37FA6DE
86
+ 0x881A4B07 , // LDR R3, =0x4000004
87
+ // LDRH R2, [R3]
88
+ 0x430A2120 , // ...
89
+ 0x0C120412 , // ...
90
+ };
91
+
92
+ static const u32 homebrewAccelSigPatched [4 ] = {
93
+ 0x4318231D , // MOVS R3, #0x1D
94
+ // ORRS R0, R3
95
+ 0x881A4B07 , // LDR R3, =0x4000004
96
+ // LDRH R2, [R3]
97
+ 0x430A2120 , // ...
98
+ 0x0C120412 , // ...
99
+ };
100
+
82
101
static const int MAX_HANDLER_SIZE = 50 ;
83
102
84
103
static u32 * hookInterruptHandler (u32 * addr , size_t size ) {
@@ -162,8 +181,38 @@ static u32* hookInterruptHandlerHomebrew (u32* addr, size_t size) {
162
181
return addr ;
163
182
}
164
183
184
+ static u32 * hookAccelIPCHomebrew (u32 * addr , size_t size ) {
185
+ u32 * end = addr + size /sizeof (u32 );
186
+
187
+ // Find the start of the handler
188
+ while (addr < end ) {
189
+ if ((addr [0 ] == homebrewAccelSig [0 ]) &&
190
+ (addr [1 ] == homebrewAccelSig [1 ]) &&
191
+ (addr [2 ] == homebrewAccelSig [2 ]) &&
192
+ (addr [3 ] == homebrewAccelSig [3 ]))
193
+ {
194
+ break ;
195
+ }
196
+ addr ++ ;
197
+ }
198
+
199
+ if (addr >= end ) {
200
+ return NULL ;
201
+ }
202
+
203
+ // patch the program
204
+ addr [0 ] = homebrewAccelSigPatched [0 ];
205
+ addr [1 ] = homebrewAccelSigPatched [1 ];
206
+ addr [2 ] = homebrewAccelSigPatched [2 ];
207
+ addr [3 ] = homebrewAccelSigPatched [3 ];
208
+
209
+ // The first entry in the table is for the Vblank handler, which is what we want
210
+ return addr ;
211
+ }
212
+
165
213
int hookNds (const tNDSHeader * ndsHeader , const u32 * cheatData , u32 * cheatEngineLocation , u32 * sdEngineLocation , u32 * wordCommandAddr ) {
166
214
u32 * hookLocation = NULL ;
215
+ u32 * hookAccel = NULL ;
167
216
168
217
nocashMessage ("hookNds" );
169
218
@@ -176,6 +225,14 @@ int hookNds (const tNDSHeader* ndsHeader, const u32* cheatData, u32* cheatEngine
176
225
return ERR_HOOK ;
177
226
}
178
227
228
+ hookAccel = hookAccelIPCHomebrew ((u32 * )ndsHeader -> arm7destination , ndsHeader -> arm7binarySize );
229
+
230
+ if (!hookAccel ) {
231
+ nocashMessage ("ACCEL_IPC_ERR" );
232
+ } else {
233
+ nocashMessage ("ACCEL_IPC_OK" );
234
+ }
235
+
179
236
copyLoop (sdEngineLocation , (u32 * )sdengine_bin , sdengine_bin_size );
180
237
181
238
sdEngineLocation [1 ] = myMemUncached (wordCommandAddr );
0 commit comments