RetroAchievements / rcheevos

Library to parse and evaluate achievements and leaderboards for RetroAchievements
MIT License
83 stars 31 forks source link

Add DTCM to DS/DSi Memory Maps #291

Open CasualPokePlayer opened 8 months ago

CasualPokePlayer commented 8 months ago

https://problemkaputt.de/gbatek.htm#dsmemorycontrolcacheandtcm https://problemkaputt.de/gbatek.htm#armcp15tightlycoupledmemorytcm

TCM is high speed memory on the ARM9 CPU itself. There are two types of TCM, one meant for Instructions (ITCM) and one meant for Data (DTCM). ITCM is probably unlikely to be useful for achievements, but DTCM seems to be useful. Okamiden for the DS appears to store all important savefile flags in this region rather than in Main RAM.

There is a question however where exactly should it be put. Should it be placed right after the Main RAM for each console (which would result in a odd memory map when comparing the two, and could be potentially problematic if you want to support running DSi enhanced games in either DS or DSi mode), or should it be placed after what would be the Main RAM for DSi, and leave a 12MiB hole for DS?

Jamiras commented 7 months ago

If I'm understanding the links you've provided, DTCM is 16KB stored somewhere between $27C0000 and $27FFFFF (or does the default base just shrink how much of the 16KB is available?).

As such, it should already be present in the DSi memory map, which covers $2000000-$2FFFFFF.

https://github.com/RetroAchievements/rcheevos/blob/0789bb7065126964dfb3b05b81d2f9a0b9a64466/src/rcheevos/consoleinfo.c#L652-L657

The DS memory map only covers $2000000-$23FFFFF

https://github.com/RetroAchievements/rcheevos/blob/0789bb7065126964dfb3b05b81d2f9a0b9a64466/src/rcheevos/consoleinfo.c#L645-L650

So we'd have to add a second region (probably the entire $27C0000-$27FFFFF) and it would be placed right after the main RAM.

static const rc_memory_region_t _rc_memory_regions_nintendo_ds[] = {
    { 0x000000U, 0x3FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
    { 0x400000U, 0x03FFFFU, 0x027C0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "DTCM" }
};
static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 2 };
CasualPokePlayer commented 7 months ago

Not quite, $27C0000 to $27FFFFF is a default for DS (probably not for DSi), but DTCM is movable (able to be based at any particular $0xxxx000 region), and overrides what is normally read where it is placed (on the DS $27C0000 to $27FFFFF would just be a Main RAM mirror if DTCM is moved away).

Jamiras commented 7 months ago

If the block doesn't have a fixed address, how will we find it in RetroArch? I'm guessing we'd have to assign it a virtual address outside the valid address space for the system.