summaryrefslogtreecommitdiff
path: root/berry_fix/payload/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'berry_fix/payload/src/main.c')
-rw-r--r--berry_fix/payload/src/main.c289
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();
+}