3DS reverse engineering

Discussion of development of software for any "obsolete" computer or video game system.
TuxSH
Posts: 1
Joined: Tue May 19, 2020 12:47 pm

Re: 3DS reverse engineering

Post by TuxSH » Mon Jun 01, 2020 1:45 pm

I've added a few regs: You can find a fully commented sleep mode entry function: I've made some other changes as well.
Hope this helps.

profi200
Posts: 46
Joined: Fri May 10, 2019 4:48 am

Re: 3DS reverse engineering

Post by profi200 » Mon Jun 22, 2020 3:51 pm

Another little puzzle piece. The GBA RTC on 3DS works a little different than you think. You need to set the base BCD date and time and the regs you named "HEX" contain the offset from this base. This can be confirmed by for example setting the time and date to the correct current one and then starting a new save in one of the RTC enabled Pokémon games. The offset will increase quite high as the game resets the RTC to 1.1.2000 00:00.

Legacy Process9 does set the current BCD date and time and uses the offset it stores along the savegame. I currently don't do that and set the date and time with offset 0. Looks like i can get away with this and it's still working.

From source/arm9/hardware/lgy.c:

Code: Select all

Result LGY_setGbaRtc(const GbaRtc rtc)
{
	// Set base time and date.
	REG_LGY_GBA_RTC_BCD_TIME = rtc.time;
	REG_LGY_GBA_RTC_BCD_DATE = rtc.date;

	//while(REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_BUSY);
	//REG_LGY_GBA_RTC_CNT = 0; // Legacy P9 does this. Useless?
	REG_LGY_GBA_RTC_HEX_TIME = 1u<<15; // Time offset 0 and 24h format.
	REG_LGY_GBA_RTC_HEX_DATE = 0;      // Date offset 0.
	REG_LGY_GBA_RTC_CNT = LGY_RTC_CNT_WR;
	while(REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_BUSY);

	if(REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_WR_ERR) return RES_GBA_RTC_ERR;
	else                                         return RES_OK;
}

Result LGY_getGbaRtc(GbaRtc *const out)
{
	//while(REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_BUSY);
	//REG_LGY_GBA_RTC_CNT = 0; // Legacy P9 does this. Useless?
	REG_LGY_GBA_RTC_CNT = LGY_RTC_CNT_RD;
	while(REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_BUSY);

	if((REG_LGY_GBA_RTC_CNT & LGY_RTC_CNT_WR_ERR) == 0u)
	{
		out->time = REG_LGY_GBA_RTC_BCD_TIME;
		out->date = REG_LGY_GBA_RTC_BCD_DATE;

		return RES_OK;
	}

	return RES_GBA_RTC_ERR;
}

Also another strange thing i found. Setting bit 7 in REG_LGY_GBA_RTC_HEX_TIME makes the entire(?) GBA hardware hang no matter if at runtime or before doing the final switch to GBA mode. It just dies including graphics and sound. This seems unrecoverable (could not get it to work at all after setting this bit).

Post Reply