Skip to content

Commit 28d45ff

Browse files
committed
MelonDS: use 16 and 32 bit reads/writes for system bus when possible and update SafeToPeek. This makes most things readable and writable from BizHawk.
Resolves #3121 except for the problematic addresses listed in SafeToPeek.
1 parent 8833c7d commit 28d45ff

File tree

2 files changed

+92
-16
lines changed

2 files changed

+92
-16
lines changed

Assets/dll/melonDS.wbx.zst

-23.4 KB
Binary file not shown.

waterbox/melon/BizDebugging.cpp

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "BizTypes.h"
99
#include "dthumb.h"
1010

11+
#include <type_traits>
1112
#include <waterboxcore.h>
1213

1314
melonDS::NDS* CurrentNDS;
@@ -164,11 +165,22 @@ static bool SafeToPeek(u32 addr)
164165
case 0x04000601:
165166
case 0x04000602:
166167
case 0x04000603:
168+
case 0x04100000:
167169
return false;
168170
}
169171
}
170172
else // arm7
171173
{
174+
switch (addr)
175+
{
176+
case 0x04000130:
177+
case 0x04000131:
178+
case 0x04000134:
179+
case 0x04000136:
180+
case 0x04000137:
181+
return false;
182+
}
183+
172184
if (addr >= 0x04800000 && addr <= 0x04810000)
173185
{
174186
if (addr & 1) addr--;
@@ -181,26 +193,38 @@ static bool SafeToPeek(u32 addr)
181193
return true;
182194
}
183195

184-
static void ARM9Access(u8* buffer, s64 address, s64 count, bool write)
196+
template <typename access_size>
197+
static void ARM9AccessSized(access_size* buffer, s64 address, s64 count, bool write)
185198
{
199+
static_assert(
200+
std::is_same<access_size, u32>::value ||
201+
std::is_same<access_size, u16>::value ||
202+
std::is_same<access_size, u8>::value
203+
);
204+
186205
if (write)
187206
{
188207
while (count--)
189208
{
190209
if (address < CurrentNDS->ARM9.ITCMSize)
191210
{
192-
CurrentNDS->ARM9.ITCM[address & (melonDS::ITCMPhysicalSize - 1)] = *buffer;
211+
*(access_size*)&(CurrentNDS->ARM9.ITCM[address & (melonDS::ITCMPhysicalSize - 1)]) = *buffer;
193212
}
194213
else if ((address & CurrentNDS->ARM9.DTCMMask) == CurrentNDS->ARM9.DTCMBase)
195214
{
196-
CurrentNDS->ARM9.DTCM[address & (melonDS::DTCMPhysicalSize - 1)] = *buffer;
215+
*(access_size*)&(CurrentNDS->ARM9.DTCM[address & (melonDS::DTCMPhysicalSize - 1)]) = *buffer;
197216
}
198217
else
199218
{
200-
CurrentNDS->ARM9Write8(address, *buffer);
219+
if constexpr (std::is_same<access_size, u32>::value)
220+
CurrentNDS->ARM9Write32(address, *buffer);
221+
else if constexpr (std::is_same<access_size, u16>::value)
222+
CurrentNDS->ARM9Write16(address, *buffer);
223+
else if constexpr (std::is_same<access_size, u8>::value)
224+
CurrentNDS->ARM9Write8(address, *buffer);
201225
}
202226

203-
address++;
227+
address += sizeof(access_size);
204228
buffer++;
205229
}
206230
}
@@ -210,46 +234,98 @@ static void ARM9Access(u8* buffer, s64 address, s64 count, bool write)
210234
{
211235
if (address < CurrentNDS->ARM9.ITCMSize)
212236
{
213-
*buffer = CurrentNDS->ARM9.ITCM[address & (melonDS::ITCMPhysicalSize - 1)];
237+
*buffer = *(access_size*)&(CurrentNDS->ARM9.ITCM[address & (melonDS::ITCMPhysicalSize - 1)]);
214238
}
215239
else if ((address & CurrentNDS->ARM9.DTCMMask) == CurrentNDS->ARM9.DTCMBase)
216240
{
217-
*buffer = CurrentNDS->ARM9.DTCM[address & (melonDS::DTCMPhysicalSize - 1)];
241+
*buffer = *(access_size*)&(CurrentNDS->ARM9.DTCM[address & (melonDS::DTCMPhysicalSize - 1)]);
218242
}
219243
else
220244
{
221-
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM9Read8(address) : 0;
245+
if constexpr (std::is_same<access_size, u32>::value)
246+
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM9Read32(address) : 0;
247+
else if constexpr (std::is_same<access_size, u16>::value)
248+
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM9Read16(address) : 0;
249+
else if constexpr (std::is_same<access_size, u8>::value)
250+
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM9Read8(address) : 0;
222251
}
223252

224-
address++;
253+
address += sizeof(access_size);
225254
buffer++;
226255
}
227256
}
228257
}
258+
static void ARM9Access(u8* buffer, s64 address, s64 count, bool write)
259+
{
260+
if (((u64)buffer & 3) == 0 && (count & 3) == 0 && (address & 3) == 0)
261+
{
262+
ARM9AccessSized<u32>((u32*)buffer, address, count >> 2, write);
263+
}
264+
else if (((u64)buffer & 1) == 0 && (count & 1) == 0 && (address & 1) == 0)
265+
{
266+
ARM9AccessSized<u16>((u16*)buffer, address, count >> 1, write);
267+
}
268+
else
269+
{
270+
ARM9AccessSized<u8>(buffer, address, count, write);
271+
}
272+
}
229273

230-
static void ARM7Access(u8* buffer, s64 address, s64 count, bool write)
274+
template <typename access_size>
275+
static void ARM7AccessSized(access_size* buffer, s64 address, s64 count, bool write)
231276
{
277+
static_assert(
278+
std::is_same<access_size, u32>::value ||
279+
std::is_same<access_size, u16>::value ||
280+
std::is_same<access_size, u8>::value
281+
);
282+
232283
if (write)
233284
{
234285
while (count--)
235286
{
236-
CurrentNDS->ARM7Write8(address, *buffer);
237-
238-
address++;
287+
if constexpr (std::is_same<access_size, u32>::value)
288+
CurrentNDS->ARM7Write32(address, *buffer);
289+
else if constexpr (std::is_same<access_size, u16>::value)
290+
CurrentNDS->ARM7Write16(address, *buffer);
291+
else if constexpr (std::is_same<access_size, u8>::value)
292+
CurrentNDS->ARM7Write8(address, *buffer);
293+
294+
address += sizeof(access_size);
239295
buffer++;
240296
}
241297
}
242298
else
243299
{
244300
while (count--)
245301
{
246-
*buffer = SafeToPeek<false>(address) ? CurrentNDS->ARM7Read8(address) : 0;
247-
248-
address++;
302+
if constexpr (std::is_same<access_size, u32>::value)
303+
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM7Read32(address) : 0;
304+
else if constexpr (std::is_same<access_size, u16>::value)
305+
*buffer = SafeToPeek<true>(address) ? CurrentNDS->ARM7Read16(address) : 0;
306+
else if constexpr (std::is_same<access_size, u8>::value)
307+
*buffer = SafeToPeek<false>(address) ? CurrentNDS->ARM7Read8(address) : 0;
308+
309+
address += sizeof(access_size);
249310
buffer++;
250311
}
251312
}
252313
}
314+
static void ARM7Access(u8* buffer, s64 address, s64 count, bool write)
315+
{
316+
if (((u64)buffer & 3) == 0 && (count & 3) == 0 && (address & 3) == 0)
317+
{
318+
ARM7AccessSized<u32>((u32*)buffer, address, count >> 2, write);
319+
}
320+
else if (((u64)buffer & 1) == 0 && (count & 1) == 0 && (address & 1) == 0)
321+
{
322+
ARM7AccessSized<u16>((u16*)buffer, address, count >> 1, write);
323+
}
324+
else
325+
{
326+
ARM7AccessSized<u8>(buffer, address, count, write);
327+
}
328+
}
253329

254330
ECL_EXPORT void GetMemoryAreas(MemoryArea *m)
255331
{

0 commit comments

Comments
 (0)