diff options
Diffstat (limited to 'berry_fix/payload/src/main.c')
-rw-r--r-- | berry_fix/payload/src/main.c | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/berry_fix/payload/src/main.c b/berry_fix/payload/src/main.c new file mode 100644 index 000000000..249150665 --- /dev/null +++ b/berry_fix/payload/src/main.c @@ -0,0 +1,289 @@ +#include <gba/gba.h> +#include "global.h" +#include "main.h" +#include "rtc.h" +#include "flash.h" + +static s32 gInitialWaitTimer; +IntrFunc gIntrTable[16]; +u16 gHeldKeys; +u16 gNewKeys; +u8 gIntrVector[0x100]; +u32 gUpdateSuccessful; +u32 gUnknown_3001194; +u32 gUnknown_30011A0[0x19]; +u32 gMainCallbackState; +u32 gGameVersion; + +EWRAM_DATA u8 gSharedMem[0x8000] = {}; + +void IntrMain(void); +void ReadKeys(void); +void dummy_intr_0(void); +void dummy_intr_1(void); +void main_callback(u32 *, void *, void *); + + +const char gBerryFixGameCode[] = "AGBJ"; +const IntrFunc gIntrFuncPointers[] = { + dummy_intr_0, + dummy_intr_1, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + dummy_intr_0, + NULL, + NULL, + NULL +}; +const char gVersionData[][2] = { + {'J', 1}, + {'E', 2}, + {'D', 1}, + {'F', 1}, + {'I', 1}, + {'S', 1} +}; +const char gRubyTitleAndCode[] = "POKEMON RUBYAXV"; +const char gSapphireTitleAndCode[] = "POKEMON SAPPAXP"; +const u16 sDebugPals[20] = { + RGB(00, 00, 00), + RGB(31, 00, 00), + RGB(00, 31, 00), + RGB(00, 00, 31) +}; +const u16 sDebugDigitsGfx[] = INCBIN_U16("graphics/debug_digits.4bpp"); + +void AgbMain(void) +{ + RegisterRamReset(0x1E); + DmaCopy32(3, gIntrFuncPointers, gIntrTable, sizeof gIntrFuncPointers); + DmaCopy32(3, IntrMain, gIntrVector, sizeof(gIntrVector)); + INTR_VECTOR = gIntrVector; + REG_IE = INTR_FLAG_VBLANK; + if (*RomHeaderMagic == 0x96 && *(u32 *)RomHeaderGameCode == *(u32 *)gBerryFixGameCode) + REG_IE |= INTR_FLAG_GAMEPAK; + REG_DISPSTAT = DISPSTAT_VBLANK_INTR; + REG_IME = INTR_FLAG_VBLANK; + msg_load_gfx(); + gMainCallbackState = MAINCB_INIT; + gUnknown_3001194 = 0; + for (;;) + { + VBlankIntrWait(); + ReadKeys(); + main_callback(&gMainCallbackState, gUnknown_30011A0, gSharedMem); + } +} + +void dummy_intr_1(void) +{} + +void dummy_intr_0(void) +{} + +void ReadKeys(void) +{ + u16 keyInput = REG_KEYINPUT ^ KEYS_MASK; + gNewKeys = keyInput & ~gHeldKeys; + gHeldKeys = keyInput; +} + +void fill_palette(const u8 * src, u16 * dest, u8 value) +{ + s32 i; + for (i = 0; src[i] != 0; i++) + dest[i] = src[i] | value << 12; +} + +bool32 berry_fix_memcmp(const char * src1, const char * src2, size_t size) +{ + s32 i; + for (i = 0; i < size; i++) + { + if (src1[i] != src2[i]) + return FALSE; + } + return TRUE; +} + +s32 validate_rom_header_internal(void) +{ + char languageCode = *(RomHeaderGameCode + 3); + s32 softwareVersion = *RomHeaderSoftwareVersion; + s32 shouldUpdate = -1; + s32 i; + for (i = 0; i < ARRAY_COUNT(gVersionData); i++) + { + if (languageCode == gVersionData[i][0]) + { + if (softwareVersion >= gVersionData[i][1]) + { + shouldUpdate = 0; + } + else + { + shouldUpdate = 1; + } + break; + } + } + if (shouldUpdate != -1) + { + if (berry_fix_memcmp(RomHeaderGameTitle, gRubyTitleAndCode, 15) == TRUE) + { + if (shouldUpdate == 0) + return RUBY_NONEED; + else + { + gGameVersion = VERSION_RUBY; + return RUBY_UPDATABLE; + } + } + else if (berry_fix_memcmp(RomHeaderGameTitle, gSapphireTitleAndCode, 15) == TRUE) + { + if (shouldUpdate == 0) + return SAPPHIRE_NONEED; + else + { + gGameVersion = VERSION_SAPPHIRE; + return SAPPHIRE_UPDATABLE; + } + } + } + return INVALID; +} + +s32 validate_rom_header(void) +{ + if (*RomHeaderMakerCode == '0' && *(RomHeaderMakerCode + 1) == '1' && *RomHeaderMagic == 0x96) + return validate_rom_header_internal(); + else + return INVALID; +} + +void main_callback(u32 * state, void * unused1, void * unused2) +{ + u8 year; + switch (*state) + { + case MAINCB_INIT: + msg_display(MSGBOX_WILL_NOW_UPDATE); + if (++gInitialWaitTimer >= 180) + { + gInitialWaitTimer = 0; + gUpdateSuccessful = 0; + switch (validate_rom_header()) + { + case SAPPHIRE_UPDATABLE: + case RUBY_UPDATABLE: // Should Update Ruby + ++(*state); // MAINCB_CHECK_RTC + break; + case INVALID: // Invalid header + *state = MAINCB_ERROR; + break; + case SAPPHIRE_NONEED: // Should not update Sapphire + case RUBY_NONEED: // Should not update Ruby + *state = MAINCB_NO_NEED_TO_FIX; + break; + } + } + break; + case MAINCB_CHECK_RTC: + if (!rtc_maincb_is_rtc_working()) + *state = MAINCB_ERROR; + else + ++(*state); // MAINCB_CHECK_FLASH + break; + case MAINCB_CHECK_FLASH: + if (flash_maincb_ident_is_valid() == TRUE) + ++(*state); // MAINCB_READ_SAVE + else + *state = MAINCB_ERROR; + break; + case MAINCB_READ_SAVE: + if (flash_maincb_read_save(0) == SAVE_STATUS_OK) + ++(*state); // MAINCB_CHECK_TIME + else + *state = MAINCB_ERROR; + break; + case MAINCB_CHECK_TIME: + if (rtc_maincb_is_time_since_last_berry_update_positive(&year) == TRUE) + { + if (year == 0) + ++(*state); // MAINCB_FIX_DATE + else + *state = MAINCB_CHECK_PACIFIDLOG_TM; + } + else + { + if (year != 1) + *state = MAINCB_YEAR_MAKES_NO_SENSE; + else + ++(*state); // MAINCB_FIX_DATE + } + break; + case MAINCB_FIX_DATE: + rtc_maincb_fix_date(); + gUpdateSuccessful |= 1; + *state = MAINCB_CHECK_PACIFIDLOG_TM; + break; + case MAINCB_CHECK_PACIFIDLOG_TM: + if (flash_maincb_check_need_reset_pacifidlog_tm() == TRUE) + *state = MAINCB_FINISHED; + else + *state = MAINCB_FIX_PACIFIDLOG_TM; + break; + case MAINCB_FIX_PACIFIDLOG_TM: + msg_display(MSGBOX_UPDATING); + if (flash_maincb_reset_pacifidlog_tm() == TRUE) + { + gUpdateSuccessful |= 1; + *state = MAINCB_FINISHED; + } + else + *state = MAINCB_ERROR; + break; + case MAINCB_FINISHED: + if (gUpdateSuccessful == 0) + *state = MAINCB_NO_NEED_TO_FIX; + else + msg_display(MSGBOX_HAS_BEEN_UPDATED); + break; + case MAINCB_NO_NEED_TO_FIX: + msg_display(MSGBOX_NO_NEED_TO_UPDATE); + break; + case MAINCB_YEAR_MAKES_NO_SENSE: + msg_display(MSGBOX_UNABLE_TO_UPDATE); + break; + case MAINCB_ERROR: + msg_display(MSGBOX_UNABLE_TO_UPDATE); + break; + } +} + +void DBG_LoadDigitsPal(void) +{ + const u16 * src; + s32 i; + register vu16 * dest asm("r3") = (vu16 *)BG_PLTT + 1; + DmaFill16(3, RGB(31, 31, 31), (vu16 *)BG_PLTT, BG_PLTT_SIZE); + src = sDebugPals; + for (i = 0; i < 4; i++) + { + *dest = *src; + dest += 16; + src++; + } +} + +void DBG_LoadDigits(void) +{ + DmaFill16(3, 0x1111, (void *)VRAM + 0x8420, 0x1800); + DmaCopy32(3, sDebugDigitsGfx, (void *)VRAM + 0x8600, 0x200); + DBG_LoadDigitsPal(); +} |