summaryrefslogtreecommitdiff
path: root/berry_fix/payload/include
diff options
context:
space:
mode:
Diffstat (limited to 'berry_fix/payload/include')
-rw-r--r--berry_fix/payload/include/constants/game_stat.h56
-rw-r--r--berry_fix/payload/include/constants/vars.h196
-rw-r--r--berry_fix/payload/include/flash.h55
-rw-r--r--berry_fix/payload/include/gba/defines.h87
-rw-r--r--berry_fix/payload/include/gba/flash_internal.h85
-rw-r--r--berry_fix/payload/include/gba/gba.h12
-rw-r--r--berry_fix/payload/include/gba/io_reg.h770
-rw-r--r--berry_fix/payload/include/gba/isagbprint.h50
-rw-r--r--berry_fix/payload/include/gba/m4a_internal.h467
-rw-r--r--berry_fix/payload/include/gba/macro.h247
-rw-r--r--berry_fix/payload/include/gba/multiboot.h55
-rw-r--r--berry_fix/payload/include/gba/syscall.h57
-rw-r--r--berry_fix/payload/include/gba/types.h146
-rw-r--r--berry_fix/payload/include/global.berry.h62
-rw-r--r--berry_fix/payload/include/global.fieldmap.h317
-rw-r--r--berry_fix/payload/include/global.h875
-rw-r--r--berry_fix/payload/include/main.h45
-rw-r--r--berry_fix/payload/include/pokemon.h154
-rw-r--r--berry_fix/payload/include/rtc.h15
-rw-r--r--berry_fix/payload/include/siirtc.h54
20 files changed, 3805 insertions, 0 deletions
diff --git a/berry_fix/payload/include/constants/game_stat.h b/berry_fix/payload/include/constants/game_stat.h
new file mode 100644
index 000000000..47d703d85
--- /dev/null
+++ b/berry_fix/payload/include/constants/game_stat.h
@@ -0,0 +1,56 @@
+#ifndef GUARD_CONSTANTS_GAME_STAT_H
+#define GUARD_CONSTANTS_GAME_STAT_H
+
+#define GAME_STAT_SAVED_GAME 0
+#define GAME_STAT_FIRST_HOF_PLAY_TIME 1
+#define GAME_STAT_STARTED_TRENDS 2
+#define GAME_STAT_PLANTED_BERRIES 3
+#define GAME_STAT_TRADED_BIKES 4
+#define GAME_STAT_STEPS 5
+#define GAME_STAT_GOT_INTERVIEWED 6
+#define GAME_STAT_TOTAL_BATTLES 7
+#define GAME_STAT_WILD_BATTLES 8
+#define GAME_STAT_TRAINER_BATTLES 9
+#define GAME_STAT_ENTERED_HOF 10
+#define GAME_STAT_POKEMON_CAPTURES 11
+#define GAME_STAT_FISHING_CAPTURES 12
+#define GAME_STAT_HATCHED_EGGS 13
+#define GAME_STAT_EVOLVED_POKEMON 14
+#define GAME_STAT_USED_POKECENTER 15
+#define GAME_STAT_RESTED_AT_HOME 16
+#define GAME_STAT_ENTERED_SAFARI_ZONE 17
+#define GAME_STAT_USED_CUT 18
+#define GAME_STAT_USED_ROCK_SMASH 19
+#define GAME_STAT_MOVED_SECRET_BASE 20
+#define GAME_STAT_POKEMON_TRADES 21
+#define GAME_STAT_UNKNOWN_22 22
+#define GAME_STAT_LINK_BATTLE_WINS 23
+#define GAME_STAT_LINK_BATTLE_LOSSES 24
+#define GAME_STAT_LINK_BATTLE_DRAWS 25
+#define GAME_STAT_USED_SPLASH 26
+#define GAME_STAT_USED_STRUGGLE 27
+#define GAME_STAT_SLOT_JACKPOTS 28
+#define GAME_STAT_CONSECUTIVE_ROULETTE_WINS 29
+#define GAME_STAT_ENTERED_BATTLE_TOWER 30
+#define GAME_STAT_UNKNOWN_31 31
+#define GAME_STAT_BATTLE_TOWER_BEST_STREAK 32
+#define GAME_STAT_POKEBLOCKS 33
+#define GAME_STAT_POKEBLOCKS_WITH_FRIENDS 34
+#define GAME_STAT_WON_LINK_CONTEST 35
+#define GAME_STAT_ENTERED_CONTEST 36
+#define GAME_STAT_WON_CONTEST 37
+#define GAME_STAT_SHOPPED 38
+#define GAME_STAT_USED_ITEMFINDER 39
+#define GAME_STAT_GOT_RAINED_ON 40
+#define GAME_STAT_CHECKED_POKEDEX 41
+#define GAME_STAT_RECEIVED_RIBBONS 42
+#define GAME_STAT_JUMPED_DOWN_LEDGES 43
+#define GAME_STAT_WATCHED_TV 44
+#define GAME_STAT_CHECKED_CLOCK 45
+#define GAME_STAT_WON_POKEMON_LOTTERY 46
+#define GAME_STAT_USED_DAYCARE 47
+#define GAME_STAT_RODE_CABLE_CAR 48
+#define GAME_STAT_ENTERED_HOT_SPRINGS 49
+#define NUM_GAME_STATS 50
+
+#endif // GUARD_CONSTANTS_GAME_STAT_H
diff --git a/berry_fix/payload/include/constants/vars.h b/berry_fix/payload/include/constants/vars.h
new file mode 100644
index 000000000..4b40c1d8c
--- /dev/null
+++ b/berry_fix/payload/include/constants/vars.h
@@ -0,0 +1,196 @@
+#ifndef GUARD_CONSTANTS_VARS_H
+#define GUARD_CONSTANTS_VARS_H
+
+#define VAR_0x3F20 0x3F20
+
+#define VARS_START 0x4000
+
+// temporary vars
+// The first 0x10 vars are are temporary--they are cleared every time a map is loaded.
+#define VAR_TEMP_0 0x4000
+#define VAR_TEMP_1 0x4001
+#define VAR_TEMP_2 0x4002
+#define VAR_TEMP_3 0x4003
+#define VAR_TEMP_4 0x4004
+#define VAR_TEMP_5 0x4005
+#define VAR_TEMP_6 0x4006
+#define VAR_TEMP_7 0x4007
+#define VAR_TEMP_8 0x4008
+#define VAR_TEMP_9 0x4009
+#define VAR_TEMP_A 0x400A
+#define VAR_TEMP_B 0x400B
+#define VAR_TEMP_C 0x400C
+#define VAR_TEMP_D 0x400D
+#define VAR_TEMP_E 0x400E
+#define VAR_TEMP_F 0x400F
+
+// object gfx id vars
+// These 0x10 vars are used to dynamically control a event object's sprite.
+// For example, the rival's sprite id is dynamically set based on the player's gender.
+// See VarGetEventObjectGraphicsId().
+#define VAR_OBJ_GFX_ID_0 0x4010
+#define VAR_OBJ_GFX_ID_1 0x4011
+#define VAR_OBJ_GFX_ID_2 0x4012
+#define VAR_OBJ_GFX_ID_3 0x4013
+#define VAR_OBJ_GFX_ID_4 0x4014
+#define VAR_OBJ_GFX_ID_5 0x4015
+#define VAR_OBJ_GFX_ID_6 0x4016
+#define VAR_OBJ_GFX_ID_7 0x4017
+#define VAR_OBJ_GFX_ID_8 0x4018
+#define VAR_OBJ_GFX_ID_9 0x4019
+#define VAR_OBJ_GFX_ID_A 0x401A
+#define VAR_OBJ_GFX_ID_B 0x401B
+#define VAR_OBJ_GFX_ID_C 0x401C
+#define VAR_OBJ_GFX_ID_D 0x401D
+#define VAR_OBJ_GFX_ID_E 0x401E
+#define VAR_OBJ_GFX_ID_F 0x401F
+
+// general purpose vars
+#define VAR_RECYCLE_GOODS 0x4020
+#define VAR_REPEL_STEP_COUNT 0x4021
+#define VAR_ICE_STEP_COUNT 0x4022
+#define VAR_STARTER_MON 0x4023 // 0=Treecko, 1=Torchic, 2=Mudkip
+#define VAR_MIRAGE_RND_H 0x4024
+#define VAR_MIRAGE_RND_L 0x4025
+#define VAR_SECRET_BASE_MAP 0x4026
+#define VAR_CYCLING_ROAD_RECORD_COLLISIONS 0x4027
+#define VAR_CYCLING_ROAD_RECORD_TIME_L 0x4028
+#define VAR_CYCLING_ROAD_RECORD_TIME_H 0x4029
+#define VAR_HAPPINESS_STEP_COUNTER 0x402A
+#define VAR_POISON_STEP_COUNTER 0x402B
+#define VAR_RESET_RTC_ENABLE 0x402C
+#define VAR_ENIGMA_BERRY_AVAILABLE 0x402D
+
+#define VAR_DAYS 0x4040
+#define VAR_FANCLUB_UNKNOWN_1 0x4041 // TODO: document these two fanclub vars
+#define VAR_FANCLUB_UNKNOWN_2 0x4042
+#define VAR_DEPT_STORE_FLOOR 0x4043
+#define VAR_TRICK_HOUSE_ROOMS_COMPLETED 0x4044
+#define VAR_LOTTERY_PRIZE 0x4045
+#define VAR_NATIONAL_DEX 0x4046
+#define VAR_SHROOMISH_SIZE_RECORD 0x4047
+#define VAR_ASH_GATHER_COUNT 0x4048
+#define VAR_BIRCH_STATE 0x4049
+#define VAR_CRUISE_STEP_COUNT 0x404A
+#define VAR_LOTTERY_RND_L 0x404B
+#define VAR_LOTTERY_RND_H 0x404C
+
+#define VAR_BARBOACH_SIZE_RECORD 0x404F
+#define VAR_LITTLEROOT_STATE 0x4050
+#define VAR_ROUTE102_ACCESSIBLE 0x4051
+
+#define VAR_LAVARIDGE_RIVAL_STATE 0x4053
+#define VAR_CURRENT_SECRET_BASE 0x4054
+
+#define VAR_PETALBURG_STATE 0x4057
+#define VAR_SLATEPORT_STATE 0x4058
+
+#define VAR_RUSTBORO_STATE 0x405A
+
+#define VAR_SOOTOPOLIS_STATE 0x405E
+
+#define VAR_ROUTE101_STATE 0x4060
+
+#define VAR_ROUTE103_STATE 0x4062
+
+#define VAR_ROUTE110_STATE 0x4069
+
+#define VAR_ROUTE116_STATE 0x406F
+
+#define VAR_ROUTE118_STATE 0x4071
+#define VAR_ROUTE119_STATE 0x4072
+
+#define VAR_ROUTE121_STATE 0x4074
+#define VAR_ROUTE128_STATE 0x407B
+
+#define VAR_LITTLEROOT_HOUSES_STATE 0x4082 // TODO: needs more investigation
+
+#define VAR_BIRCH_LAB_STATE 0x4084
+#define VAR_PETALBURG_GYM_STATE 0x4085
+#define VAR_LINK_CONTEST_ROOM_STATE 0x4086
+#define VAR_CABLE_CLUB_STATE 0x4087
+#define VAR_CONTEST_LOCATION 0x4088
+#define VAR_MAP_SCENE_SIX_ISLAND_POKEMON_CENTER_1F 0x4089 // TODO: related to decorations
+#define VAR_CONTEST_PRIZE_PICKUP 0x408A
+
+#define VAR_LITTLEROOT_HOUSES_STATE_2 0x408C // TODO: needs more investigation
+#define VAR_LITTLEROOT_RIVAL_STATE 0x408D
+#define VAR_BOARD_BRINEY_BOAT_ROUTE104_STATE 0x408E
+#define VAR_DEVON_CORP_3F_STATE 0x408F
+#define VAR_BRINEY_HOUSE_STATE 0x4090
+
+#define VAR_LITTLEROOT_INTRO_STATE 0x4092
+#define VAR_MAUVILLE_GYM_STATE 0x4093
+#define VAR_LILYCOVE_MUSEUM_2F_STATE 0x4094
+#define VAR_LILYCOVE_FAN_CLUB_STATE 0x4095
+#define VAR_BRINEY_LOCATION 0x4096
+#define VAR_0x4097 0x4097 // TODO: related to creating new secret base
+#define VAR_PETALBURG_WOODS_STATE 0x4098
+#define VAR_LILYCOVE_CONTEST_LOBBY_STATE 0x4099
+#define VAR_RUSTURF_TUNNEL_STATE 0x409a
+#define VAR_CAVE_OF_ORIGIN_B4F_STATE 0x409B
+#define VAR_ELITE_4_STATE 0x409C
+
+#define VAR_SLATEPORT_HARBOR_STATE 0x40A0
+
+#define VAR_SEAFLOOR_CAVERN_STATE 0x40A2
+#define VAR_CABLE_CAR_STATION_STATE 0x40A3
+#define VAR_SAFARI_ZONE_STATE 0x40A4
+#define VAR_TRICK_HOUSE_ENTRANCE_STATE 0x40A5
+#define VAR_TRICK_HOUSE_ENTRANCE_STATE_2 0x40A6
+#define VAR_TRICK_HOUSE_ENTRANCE_STATE_3 0x40A7
+
+#define VAR_CYCLING_CHALLENGE_STATE 0x40A9
+#define VAR_SLATEPORT_MUSEUM_1F_STATE 0x40AA
+#define VAR_TRICK_HOUSE_PUZZLE_1_STATE 0x40AB
+#define VAR_TRICK_HOUSE_PUZZLE_2_STATE 0x40AC
+#define VAR_TRICK_HOUSE_PUZZLE_3_STATE 0x40AD
+#define VAR_TRICK_HOUSE_PUZZLE_4_STATE 0x40AE
+#define VAR_TRICK_HOUSE_PUZZLE_5_STATE 0x40AF
+#define VAR_TRICK_HOUSE_PUZZLE_6_STATE 0x40B0
+#define VAR_TRICK_HOUSE_PUZZLE_7_STATE 0x40B1
+#define VAR_TRICK_HOUSE_PUZZLE_8_STATE 0x40B2
+#define VAR_WEATHER_INSTITUTE_STATE 0x40B3
+#define VAR_PORTHOLE_STATE 0x40B4
+#define VAR_TRICK_HOUSE_STATE 0x40B5 // TODO: needs some further investigation
+#define VAR_TRICK_HOUSE_PUZZLE_7_STATE_2 0x40B6
+#define VAR_SLATEPORT_FAN_CLUB_STATE 0x40B7
+
+#define VAR_MT_PYRE_STATE 0x40B9
+#define VAR_NEW_MAUVILLE_STATE 0x40BA
+
+#define VAR_BRAVO_TRAINER_BATTLE_TOWER_ON 0x40BC
+#define VAR_JAGGED_PASS_VOLCANIC_ASH_WEATHER 0x40BD
+#define VAR_GLASS_WORKSHOP_STATE 0x40BE
+#define VAR_METEOR_FALLS_STATE 0x40BF
+#define VAR_GAME_CORNER_STATE 0x40C0
+#define VAR_TRICK_HOUSE_PRIZE_PICKUP 0x40C1
+#define VAR_PACIFIDLOG_TM_RECEIVED_DAY 0x40C2
+#define VAR_VICTORY_ROAD_1F_STATE 0x40C3
+#define VAR_FOSSIL_RESURRECTION_STATE 0x40C4
+#define VAR_WHICH_FOSSIL_REVIVED 0x40C5
+#define VAR_STEVENS_HOUSE_STATE 0x40C6
+#define VAR_OLDALE_STATE 0x40C7
+
+// special vars
+// They are commonly used as parameters to commands, or return values from commands.
+#define VAR_SPECIAL_0 0x8000
+#define VAR_SPECIAL_1 0x8001
+#define VAR_SPECIAL_2 0x8002
+#define VAR_SPECIAL_3 0x8003
+#define VAR_SPECIAL_4 0x8004
+#define VAR_SPECIAL_5 0x8005
+#define VAR_SPECIAL_6 0x8006
+#define VAR_SPECIAL_7 0x8007
+#define VAR_SPECIAL_8 0x8008
+#define VAR_SPECIAL_9 0x8009
+#define VAR_SPECIAL_A 0x800A
+#define VAR_SPECIAL_B 0x800B
+#define FACING 0x800C
+#define RESULT 0x800D
+#define ITEM_ID 0x800E
+#define LAST_TALKED 0x800F
+#define CONTEST_RANK 0x8010
+#define CONTEST_CATEGORY 0x8011
+
+#endif // GUARD_CONSTANTS_VARS_H
diff --git a/berry_fix/payload/include/flash.h b/berry_fix/payload/include/flash.h
new file mode 100644
index 000000000..7fc35896d
--- /dev/null
+++ b/berry_fix/payload/include/flash.h
@@ -0,0 +1,55 @@
+#ifndef GUARD_FLASH_H
+#define GUARD_FLASH_H
+
+#include "gba/gba.h"
+
+enum
+{
+ SECTOR_DAMAGED,
+ SECTOR_OK,
+ SECTOR_CHECK, // unused
+};
+
+enum MsgBoxUpdateMessage
+{
+ MSGBOX_WILL_NOW_UPDATE = 0,
+ MSGBOX_HAS_BEEN_UPDATED,
+ MSGBOX_UNABLE_TO_UPDATE,
+ MSGBOX_NO_NEED_TO_UPDATE,
+ MSGBOX_UPDATING
+};
+
+struct SaveSector
+{
+ u8 data[0xFF4];
+ u16 id;
+ u16 checksum;
+ u32 signature;
+ u32 counter;
+}; // size is 0x1000
+
+// headless save section?
+struct UnkSaveSection
+{
+ u8 data[0xFF4];
+ u32 signature;
+}; // size is 0xFF8
+
+#define eSaveSection ((struct SaveSector *)0x2020000)
+
+#define NUM_SECTORS_PER_SAVE_SLOT 14 // Number of sectors occupied by a save slot
+#define FILE_SIGNATURE 0x08012025
+
+#define SAVE_STATUS_EMPTY 0
+#define SAVE_STATUS_OK 1
+#define SAVE_STATUS_NO_FLASH 4
+#define SAVE_STATUS_ERROR 0xFF
+
+bool32 flash_maincb_ident_is_valid(void);
+bool8 flash_maincb_read_save(u32);
+void msg_load_gfx(void);
+void msg_display(enum MsgBoxUpdateMessage);
+bool32 flash_maincb_check_need_reset_pacifidlog_tm(void);
+bool32 flash_maincb_reset_pacifidlog_tm(void);
+
+#endif //GUARD_FLASH_H
diff --git a/berry_fix/payload/include/gba/defines.h b/berry_fix/payload/include/gba/defines.h
new file mode 100644
index 000000000..289518cf3
--- /dev/null
+++ b/berry_fix/payload/include/gba/defines.h
@@ -0,0 +1,87 @@
+#ifndef GUARD_GBA_DEFINES
+#define GUARD_GBA_DEFINES
+
+#include <stddef.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define BSS_DATA __attribute__((section(".bss")))
+#define IWRAM_DATA __attribute__((section("iwram_data")))
+#define EWRAM_DATA __attribute__((section("ewram_data")))
+#define UNUSED __attribute__((unused))
+#define NAKED __attribute__((naked))
+
+#define ALIGNED(n) __attribute__((aligned(n)))
+
+#define SOUND_INFO_PTR (*(struct SoundInfo **)0x3007FF0)
+#define INTR_CHECK (*(u16 *)0x3007FF8)
+#define INTR_VECTOR (*(void **)0x3007FFC)
+
+#define EWRAM_START 0x02000000
+#define EWRAM_END (EWRAM_START + 0x40000)
+#define IWRAM_START 0x03000000
+#define IWRAM_END (IWRAM_START + 0x8000)
+
+#define PLTT 0x5000000
+#define PLTT_SIZE 0x400
+
+#define BG_PLTT PLTT
+#define BG_PLTT_SIZE 0x200
+
+#define OBJ_PLTT (PLTT + 0x200)
+#define OBJ_PLTT_SIZE 0x200
+
+#define VRAM 0x6000000
+#define VRAM_SIZE 0x18000
+
+#define BG_VRAM VRAM
+#define BG_VRAM_SIZE 0x10000
+#define BG_CHAR_SIZE 0x4000
+#define BG_SCREEN_SIZE 0x800
+#define BG_CHAR_ADDR(n) (void *)(BG_VRAM + (0x4000 * (n)))
+#define BG_SCREEN_ADDR(n) (void *)(BG_VRAM + (0x800 * (n)))
+#define BG_TILE_ADDR(n) (void *)(BG_VRAM + (0x80 * (n)))
+
+#define BG_TILE_H_FLIP(n) (0x400 + (n))
+#define BG_TILE_V_FLIP(n) (0x800 + (n))
+
+// text-mode BG
+#define OBJ_VRAM0 (void *)(VRAM + 0x10000)
+#define OBJ_VRAM0_SIZE 0x8000
+
+// bitmap-mode BG
+#define OBJ_VRAM1 (void *)(VRAM + 0x14000)
+#define OBJ_VRAM1_SIZE 0x4000
+
+#define OAM 0x7000000
+#define OAM_SIZE 0x400
+
+#define ROM_HEADER_SIZE 0xC0
+
+#define DISPLAY_WIDTH 240
+#define DISPLAY_HEIGHT 160
+
+#define TILE_SIZE_4BPP 32
+#define TILE_SIZE_8BPP 64
+
+#define TILE_OFFSET_4BPP(n) ((n) * TILE_SIZE_4BPP)
+#define TILE_OFFSET_8BPP(n) ((n) * TILE_SIZE_8BPP)
+
+#define TOTAL_OBJ_TILE_COUNT 1024
+
+#define RGB(r, g, b) ((r) | ((g) << 5) | ((b) << 10))
+#define RGB2(r, g, b) (((b) << 10) | ((g) << 5) | (r))
+#define _RGB(r, g, b) ((((b) & 0x1F) << 10) + (((g) & 0x1F) << 5) + ((r) & 0x1F))
+
+#define RGB_BLACK RGB(0, 0, 0)
+#define RGB_WHITE RGB(31, 31, 31)
+#define RGB_RED RGB(31, 0, 0)
+#define RGB_GREEN RGB(0, 31, 0)
+#define RGB_BLUE RGB(0, 0, 31)
+#define RGB_YELLOW RGB(31, 31, 0)
+#define RGB_MAGENTA RGB(31, 0, 31)
+#define RGB_CYAN RGB(0, 31, 31)
+#define RGB_WHITEALPHA (RGB_WHITE | 0x8000)
+
+#endif // GUARD_GBA_DEFINES
diff --git a/berry_fix/payload/include/gba/flash_internal.h b/berry_fix/payload/include/gba/flash_internal.h
new file mode 100644
index 000000000..6fbec31f1
--- /dev/null
+++ b/berry_fix/payload/include/gba/flash_internal.h
@@ -0,0 +1,85 @@
+#ifndef GUARD_GBA_FLASH_INTERNAL_H
+#define GUARD_GBA_FLASH_INTERNAL_H
+
+#include "gba/gba.h"
+
+#define FLASH_BASE ((u8 *)0xE000000)
+
+#define FLASH_WRITE(addr, data) ((*(vu8 *)(FLASH_BASE + (addr))) = (data))
+
+#define FLASH_ROM_SIZE_1M 131072 // 1 megabit ROM
+
+#define SECTORS_PER_BANK 16
+
+struct FlashSector
+{
+ u32 size;
+ u8 shift;
+ u16 count;
+ u16 top;
+};
+
+struct FlashType {
+ u32 romSize;
+ struct FlashSector sector;
+ u16 wait[2]; // game pak bus read/write wait
+
+ // TODO: add support for anonymous unions/structs if possible
+ union {
+ struct {
+ u8 makerId;
+ u8 deviceId;
+ } separate;
+ u16 joined;
+ } ids;
+};
+
+struct FlashSetupInfo
+{
+ u16 (*programFlashByte)(u16, u32, u8);
+ u16 (*programFlashSector)(u16, void *);
+ u16 (*eraseFlashChip)(void);
+ u16 (*eraseFlashSector)(u16);
+ u16 (*WaitForFlashWrite)(u8, u8 *, u8);
+ const u16 *maxTime;
+ struct FlashType type;
+};
+
+extern u16 gFlashNumRemainingBytes;
+
+extern u16 (*ProgramFlashByte)(u16, u32, u8);
+extern u16 (*ProgramFlashSector)(u16, void *);
+extern u16 (*EraseFlashChip)(void);
+extern u16 (*EraseFlashSector)(u16);
+extern u16 (*WaitForFlashWrite)(u8, u8 *, u8);
+extern const u16 *gFlashMaxTime;
+extern const struct FlashType *gFlash;
+
+extern u8 (*PollFlashStatus)(u8 *);
+extern u8 gFlashTimeoutFlag;
+
+extern const struct FlashSetupInfo MX29L010;
+extern const struct FlashSetupInfo LE26FV10N1TS;
+extern const struct FlashSetupInfo DefaultFlash;
+
+void SwitchFlashBank(u8 bankNum);
+u16 ReadFlashId(void);
+void StartFlashTimer(u8 phase);
+void SetReadFlash1(u16 *dest);
+void StopFlashTimer(void);
+u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void));
+u32 ProgramFlashSectorAndVerify(u16 sectorNum, u8 *src);
+void ReadFlash(u16 sectorNum, u32 offset, void *dest, u32 size);
+u32 ProgramFlashSectorAndVerifyNBytes(u16 sectorNum, void *dataSrc, u32 n);
+
+u16 WaitForFlashWrite_Common(u8 phase, u8 *addr, u8 lastData);
+
+u16 EraseFlashChip_MX(void);
+u16 EraseFlashSector_MX(u16 sectorNum);
+u16 ProgramFlashByte_MX(u16 sectorNum, u32 offset, u8 data);
+u16 ProgramFlashSector_MX(u16 sectorNum, void *src);
+
+// agb_flash_1m
+u32 IdentifyFlash(void);
+
+#endif // GUARD_GBA_FLASH_INTERNAL_H
diff --git a/berry_fix/payload/include/gba/gba.h b/berry_fix/payload/include/gba/gba.h
new file mode 100644
index 000000000..349344031
--- /dev/null
+++ b/berry_fix/payload/include/gba/gba.h
@@ -0,0 +1,12 @@
+#ifndef GUARD_GBA_GBA_H
+#define GUARD_GBA_GBA_H
+
+#include "gba/defines.h"
+#include "gba/io_reg.h"
+#include "gba/types.h"
+#include "gba/multiboot.h"
+#include "gba/syscall.h"
+#include "gba/macro.h"
+#include "gba/isagbprint.h"
+
+#endif // GUARD_GBA_GBA_H
diff --git a/berry_fix/payload/include/gba/io_reg.h b/berry_fix/payload/include/gba/io_reg.h
new file mode 100644
index 000000000..df79b084d
--- /dev/null
+++ b/berry_fix/payload/include/gba/io_reg.h
@@ -0,0 +1,770 @@
+#ifndef GUARD_GBA_IO_REG_H
+#define GUARD_GBA_IO_REG_H
+
+#define REG_BASE 0x4000000 // I/O register base address
+
+// I/O register offsets
+
+#define REG_OFFSET_DISPCNT 0x0
+#define REG_OFFSET_DISPSTAT 0x4
+#define REG_OFFSET_VCOUNT 0x6
+#define REG_OFFSET_BG0CNT 0x8
+#define REG_OFFSET_BG1CNT 0xa
+#define REG_OFFSET_BG2CNT 0xc
+#define REG_OFFSET_BG3CNT 0xe
+#define REG_OFFSET_BG0HOFS 0x10
+#define REG_OFFSET_BG0VOFS 0x12
+#define REG_OFFSET_BG1HOFS 0x14
+#define REG_OFFSET_BG1VOFS 0x16
+#define REG_OFFSET_BG2HOFS 0x18
+#define REG_OFFSET_BG2VOFS 0x1a
+#define REG_OFFSET_BG3HOFS 0x1c
+#define REG_OFFSET_BG3VOFS 0x1e
+#define REG_OFFSET_BG2PA 0x20
+#define REG_OFFSET_BG2PB 0x22
+#define REG_OFFSET_BG2PC 0x24
+#define REG_OFFSET_BG2PD 0x26
+#define REG_OFFSET_BG2X 0x28
+#define REG_OFFSET_BG2X_L 0x28
+#define REG_OFFSET_BG2X_H 0x2a
+#define REG_OFFSET_BG2Y 0x2c
+#define REG_OFFSET_BG2Y_L 0x2c
+#define REG_OFFSET_BG2Y_H 0x2e
+#define REG_OFFSET_BG3PA 0x30
+#define REG_OFFSET_BG3PB 0x32
+#define REG_OFFSET_BG3PC 0x34
+#define REG_OFFSET_BG3PD 0x36
+#define REG_OFFSET_BG3X 0x38
+#define REG_OFFSET_BG3X_L 0x38
+#define REG_OFFSET_BG3X_H 0x3a
+#define REG_OFFSET_BG3Y 0x3c
+#define REG_OFFSET_BG3Y_L 0x3c
+#define REG_OFFSET_BG3Y_H 0x3e
+#define REG_OFFSET_WIN0H 0x40
+#define REG_OFFSET_WIN1H 0x42
+#define REG_OFFSET_WIN0V 0x44
+#define REG_OFFSET_WIN1V 0x46
+#define REG_OFFSET_WININ 0x48
+#define REG_OFFSET_WINOUT 0x4a
+#define REG_OFFSET_MOSAIC 0x4c
+#define REG_OFFSET_BLDCNT 0x50
+#define REG_OFFSET_BLDALPHA 0x52
+#define REG_OFFSET_BLDY 0x54
+
+#define REG_OFFSET_SOUND1CNT_L 0x60
+#define REG_OFFSET_NR10 0x60
+#define REG_OFFSET_SOUND1CNT_H 0x62
+#define REG_OFFSET_NR11 0x62
+#define REG_OFFSET_NR12 0x63
+#define REG_OFFSET_SOUND1CNT_X 0x64
+#define REG_OFFSET_NR13 0x64
+#define REG_OFFSET_NR14 0x65
+#define REG_OFFSET_SOUND2CNT_L 0x68
+#define REG_OFFSET_NR21 0x68
+#define REG_OFFSET_NR22 0x69
+#define REG_OFFSET_SOUND2CNT_H 0x6c
+#define REG_OFFSET_NR23 0x6c
+#define REG_OFFSET_NR24 0x6d
+#define REG_OFFSET_SOUND3CNT_L 0x70
+#define REG_OFFSET_NR30 0x70
+#define REG_OFFSET_SOUND3CNT_H 0x72
+#define REG_OFFSET_NR31 0x72
+#define REG_OFFSET_NR32 0x73
+#define REG_OFFSET_SOUND3CNT_X 0x74
+#define REG_OFFSET_NR33 0x74
+#define REG_OFFSET_NR34 0x75
+#define REG_OFFSET_SOUND4CNT_L 0x78
+#define REG_OFFSET_NR41 0x78
+#define REG_OFFSET_NR42 0x79
+#define REG_OFFSET_SOUND4CNT_H 0x7c
+#define REG_OFFSET_NR43 0x7c
+#define REG_OFFSET_NR44 0x7d
+#define REG_OFFSET_SOUNDCNT_L 0x80
+#define REG_OFFSET_NR50 0x80
+#define REG_OFFSET_NR51 0x81
+#define REG_OFFSET_SOUNDCNT_H 0x82
+#define REG_OFFSET_SOUNDCNT_X 0x84
+#define REG_OFFSET_NR52 0x84
+#define REG_OFFSET_SOUNDBIAS 0x88
+#define REG_OFFSET_SOUNDBIAS_L 0x88
+#define REG_OFFSET_SOUNDBIAS_H 0x89
+#define REG_OFFSET_WAVE_RAM0 0x90
+#define REG_OFFSET_WAVE_RAM1 0x94
+#define REG_OFFSET_WAVE_RAM2 0x98
+#define REG_OFFSET_WAVE_RAM3 0x9c
+#define REG_OFFSET_FIFO_A 0xa0
+#define REG_OFFSET_FIFO_B 0xa4
+
+#define REG_OFFSET_DMA0 0xb0
+#define REG_OFFSET_DMA0SAD 0xb0
+#define REG_OFFSET_DMA0SAD_L 0xb0
+#define REG_OFFSET_DMA0SAD_H 0xb2
+#define REG_OFFSET_DMA0DAD 0xb4
+#define REG_OFFSET_DMA0DAD_L 0xb4
+#define REG_OFFSET_DMA0DAD_H 0xb6
+#define REG_OFFSET_DMA0CNT 0xb8
+#define REG_OFFSET_DMA0CNT_L 0xb8
+#define REG_OFFSET_DMA0CNT_H 0xba
+#define REG_OFFSET_DMA1 0xbc
+#define REG_OFFSET_DMA1SAD 0xbc
+#define REG_OFFSET_DMA1SAD_L 0xbc
+#define REG_OFFSET_DMA1SAD_H 0xbe
+#define REG_OFFSET_DMA1DAD 0xc0
+#define REG_OFFSET_DMA1DAD_L 0xc0
+#define REG_OFFSET_DMA1DAD_H 0xc2
+#define REG_OFFSET_DMA1CNT 0xc4
+#define REG_OFFSET_DMA1CNT_L 0xc4
+#define REG_OFFSET_DMA1CNT_H 0xc6
+#define REG_OFFSET_DMA2 0xc8
+#define REG_OFFSET_DMA2SAD 0xc8
+#define REG_OFFSET_DMA2SAD_L 0xc8
+#define REG_OFFSET_DMA2SAD_H 0xca
+#define REG_OFFSET_DMA2DAD 0xcc
+#define REG_OFFSET_DMA2DAD_L 0xcc
+#define REG_OFFSET_DMA2DAD_H 0xce
+#define REG_OFFSET_DMA2CNT 0xd0
+#define REG_OFFSET_DMA2CNT_L 0xd0
+#define REG_OFFSET_DMA2CNT_H 0xd2
+#define REG_OFFSET_DMA3 0xd4
+#define REG_OFFSET_DMA3SAD 0xd4
+#define REG_OFFSET_DMA3SAD_L 0xd4
+#define REG_OFFSET_DMA3SAD_H 0xd6
+#define REG_OFFSET_DMA3DAD 0xd8
+#define REG_OFFSET_DMA3DAD_L 0xd8
+#define REG_OFFSET_DMA3DAD_H 0xda
+#define REG_OFFSET_DMA3CNT 0xdc
+#define REG_OFFSET_DMA3CNT_L 0xdc
+#define REG_OFFSET_DMA3CNT_H 0xde
+
+#define REG_OFFSET_TMCNT 0x100
+#define REG_OFFSET_TMCNT_L 0x100
+#define REG_OFFSET_TMCNT_H 0x102
+#define REG_OFFSET_TM0CNT 0x100
+#define REG_OFFSET_TM0CNT_L 0x100
+#define REG_OFFSET_TM0CNT_H 0x102
+#define REG_OFFSET_TM1CNT 0x104
+#define REG_OFFSET_TM1CNT_L 0x104
+#define REG_OFFSET_TM1CNT_H 0x106
+#define REG_OFFSET_TM2CNT 0x108
+#define REG_OFFSET_TM2CNT_L 0x108
+#define REG_OFFSET_TM2CNT_H 0x10a
+#define REG_OFFSET_TM3CNT 0x10c
+#define REG_OFFSET_TM3CNT_L 0x10c
+#define REG_OFFSET_TM3CNT_H 0x10e
+
+#define REG_OFFSET_SIOCNT 0x128
+#define REG_OFFSET_SIODATA8 0x12a
+#define REG_OFFSET_SIODATA32 0x120
+#define REG_OFFSET_SIOMLT_SEND 0x12a
+#define REG_OFFSET_SIOMLT_RECV 0x120
+#define REG_OFFSET_SIOMULTI0 0x120
+#define REG_OFFSET_SIOMULTI1 0x122
+#define REG_OFFSET_SIOMULTI2 0x124
+#define REG_OFFSET_SIOMULTI3 0x126
+
+#define REG_OFFSET_KEYINPUT 0x130
+#define REG_OFFSET_KEYCNT 0x132
+
+#define REG_OFFSET_RCNT 0x134
+
+#define REG_OFFSET_JOYCNT 0x140
+#define REG_OFFSET_JOYSTAT 0x158
+#define REG_OFFSET_JOY_RECV 0x150
+#define REG_OFFSET_JOY_RECV_L 0x150
+#define REG_OFFSET_JOY_RECV_H 0x152
+#define REG_OFFSET_JOY_TRANS 0x154
+#define REG_OFFSET_JOY_TRANS_L 0x154
+#define REG_OFFSET_JOY_TRANS_H 0x156
+
+#define REG_OFFSET_IME 0x208
+#define REG_OFFSET_IE 0x200
+#define REG_OFFSET_IF 0x202
+
+#define REG_OFFSET_WAITCNT 0x204
+
+// I/O register addresses
+
+#define REG_ADDR_DISPCNT (REG_BASE + REG_OFFSET_DISPCNT)
+#define REG_ADDR_DISPSTAT (REG_BASE + REG_OFFSET_DISPSTAT)
+#define REG_ADDR_VCOUNT (REG_BASE + REG_OFFSET_VCOUNT)
+#define REG_ADDR_BG0CNT (REG_BASE + REG_OFFSET_BG0CNT)
+#define REG_ADDR_BG1CNT (REG_BASE + REG_OFFSET_BG1CNT)
+#define REG_ADDR_BG2CNT (REG_BASE + REG_OFFSET_BG2CNT)
+#define REG_ADDR_BG3CNT (REG_BASE + REG_OFFSET_BG3CNT)
+#define REG_ADDR_BG0HOFS (REG_BASE + REG_OFFSET_BG0HOFS)
+#define REG_ADDR_BG0VOFS (REG_BASE + REG_OFFSET_BG0VOFS)
+#define REG_ADDR_BG1HOFS (REG_BASE + REG_OFFSET_BG1HOFS)
+#define REG_ADDR_BG1VOFS (REG_BASE + REG_OFFSET_BG1VOFS)
+#define REG_ADDR_BG2HOFS (REG_BASE + REG_OFFSET_BG2HOFS)
+#define REG_ADDR_BG2VOFS (REG_BASE + REG_OFFSET_BG2VOFS)
+#define REG_ADDR_BG3HOFS (REG_BASE + REG_OFFSET_BG3HOFS)
+#define REG_ADDR_BG3VOFS (REG_BASE + REG_OFFSET_BG3VOFS)
+#define REG_ADDR_BG2PA (REG_BASE + REG_OFFSET_BG2PA)
+#define REG_ADDR_BG2PB (REG_BASE + REG_OFFSET_BG2PB)
+#define REG_ADDR_BG2PC (REG_BASE + REG_OFFSET_BG2PC)
+#define REG_ADDR_BG2PD (REG_BASE + REG_OFFSET_BG2PD)
+#define REG_ADDR_BG2X (REG_BASE + REG_OFFSET_BG2X)
+#define REG_ADDR_BG2X_L (REG_BASE + REG_OFFSET_BG2X_L)
+#define REG_ADDR_BG2X_H (REG_BASE + REG_OFFSET_BG2X_H)
+#define REG_ADDR_BG2Y (REG_BASE + REG_OFFSET_BG2Y)
+#define REG_ADDR_BG2Y_L (REG_BASE + REG_OFFSET_BG2Y_L)
+#define REG_ADDR_BG2Y_H (REG_BASE + REG_OFFSET_BG2Y_H)
+#define REG_ADDR_BG3PA (REG_BASE + REG_OFFSET_BG3PA)
+#define REG_ADDR_BG3PB (REG_BASE + REG_OFFSET_BG3PB)
+#define REG_ADDR_BG3PC (REG_BASE + REG_OFFSET_BG3PC)
+#define REG_ADDR_BG3PD (REG_BASE + REG_OFFSET_BG3PD)
+#define REG_ADDR_BG3X (REG_BASE + REG_OFFSET_BG3X)
+#define REG_ADDR_BG3X_L (REG_BASE + REG_OFFSET_BG3X_L)
+#define REG_ADDR_BG3X_H (REG_BASE + REG_OFFSET_BG3X_H)
+#define REG_ADDR_BG3Y (REG_BASE + REG_OFFSET_BG3Y)
+#define REG_ADDR_BG3Y_L (REG_BASE + REG_OFFSET_BG3Y_L)
+#define REG_ADDR_BG3Y_H (REG_BASE + REG_OFFSET_BG3Y_H)
+#define REG_ADDR_WIN0H (REG_BASE + REG_OFFSET_WIN0H)
+#define REG_ADDR_WIN1H (REG_BASE + REG_OFFSET_WIN1H)
+#define REG_ADDR_WIN0V (REG_BASE + REG_OFFSET_WIN0V)
+#define REG_ADDR_WIN1V (REG_BASE + REG_OFFSET_WIN1V)
+#define REG_ADDR_WININ (REG_BASE + REG_OFFSET_WININ)
+#define REG_ADDR_WINOUT (REG_BASE + REG_OFFSET_WINOUT)
+#define REG_ADDR_MOSAIC (REG_BASE + REG_OFFSET_MOSAIC)
+#define REG_ADDR_BLDCNT (REG_BASE + REG_OFFSET_BLDCNT)
+#define REG_ADDR_BLDALPHA (REG_BASE + REG_OFFSET_BLDALPHA)
+#define REG_ADDR_BLDY (REG_BASE + REG_OFFSET_BLDY)
+
+#define REG_ADDR_SOUND1CNT_L (REG_BASE + REG_OFFSET_SOUND1CNT_L)
+#define REG_ADDR_NR10 (REG_BASE + REG_OFFSET_NR10)
+#define REG_ADDR_SOUND1CNT_H (REG_BASE + REG_OFFSET_SOUND1CNT_H)
+#define REG_ADDR_NR11 (REG_BASE + REG_OFFSET_NR11)
+#define REG_ADDR_NR12 (REG_BASE + REG_OFFSET_NR12)
+#define REG_ADDR_SOUND1CNT_X (REG_BASE + REG_OFFSET_SOUND1CNT_X)
+#define REG_ADDR_NR13 (REG_BASE + REG_OFFSET_NR13)
+#define REG_ADDR_NR14 (REG_BASE + REG_OFFSET_NR14)
+#define REG_ADDR_SOUND2CNT_L (REG_BASE + REG_OFFSET_SOUND2CNT_L)
+#define REG_ADDR_NR21 (REG_BASE + REG_OFFSET_NR21)
+#define REG_ADDR_NR22 (REG_BASE + REG_OFFSET_NR22)
+#define REG_ADDR_SOUND2CNT_H (REG_BASE + REG_OFFSET_SOUND2CNT_H)
+#define REG_ADDR_NR23 (REG_BASE + REG_OFFSET_NR23)
+#define REG_ADDR_NR24 (REG_BASE + REG_OFFSET_NR24)
+#define REG_ADDR_SOUND3CNT_L (REG_BASE + REG_OFFSET_SOUND3CNT_L)
+#define REG_ADDR_NR30 (REG_BASE + REG_OFFSET_NR30)
+#define REG_ADDR_SOUND3CNT_H (REG_BASE + REG_OFFSET_SOUND3CNT_H)
+#define REG_ADDR_NR31 (REG_BASE + REG_OFFSET_NR31)
+#define REG_ADDR_NR32 (REG_BASE + REG_OFFSET_NR32)
+#define REG_ADDR_SOUND3CNT_X (REG_BASE + REG_OFFSET_SOUND3CNT_X)
+#define REG_ADDR_NR33 (REG_BASE + REG_OFFSET_NR33)
+#define REG_ADDR_NR34 (REG_BASE + REG_OFFSET_NR34)
+#define REG_ADDR_SOUND4CNT_L (REG_BASE + REG_OFFSET_SOUND4CNT_L)
+#define REG_ADDR_NR41 (REG_BASE + REG_OFFSET_NR41)
+#define REG_ADDR_NR42 (REG_BASE + REG_OFFSET_NR42)
+#define REG_ADDR_SOUND4CNT_H (REG_BASE + REG_OFFSET_SOUND4CNT_H)
+#define REG_ADDR_NR43 (REG_BASE + REG_OFFSET_NR43)
+#define REG_ADDR_NR44 (REG_BASE + REG_OFFSET_NR44)
+#define REG_ADDR_SOUNDCNT_L (REG_BASE + REG_OFFSET_SOUNDCNT_L)
+#define REG_ADDR_NR50 (REG_BASE + REG_OFFSET_NR50)
+#define REG_ADDR_NR51 (REG_BASE + REG_OFFSET_NR51)
+#define REG_ADDR_SOUNDCNT_H (REG_BASE + REG_OFFSET_SOUNDCNT_H)
+#define REG_ADDR_SOUNDCNT_X (REG_BASE + REG_OFFSET_SOUNDCNT_X)
+#define REG_ADDR_NR52 (REG_BASE + REG_OFFSET_NR52)
+#define REG_ADDR_SOUNDBIAS (REG_BASE + REG_OFFSET_SOUNDBIAS)
+#define REG_ADDR_SOUNDBIAS_L (REG_BASE + REG_OFFSET_SOUNDBIAS_L)
+#define REG_ADDR_SOUNDBIAS_H (REG_BASE + REG_OFFSET_SOUNDBIAS_H)
+#define REG_ADDR_WAVE_RAM0 (REG_BASE + REG_OFFSET_WAVE_RAM0)
+#define REG_ADDR_WAVE_RAM1 (REG_BASE + REG_OFFSET_WAVE_RAM1)
+#define REG_ADDR_WAVE_RAM2 (REG_BASE + REG_OFFSET_WAVE_RAM2)
+#define REG_ADDR_WAVE_RAM3 (REG_BASE + REG_OFFSET_WAVE_RAM3)
+#define REG_ADDR_FIFO_A (REG_BASE + REG_OFFSET_FIFO_A)
+#define REG_ADDR_FIFO_B (REG_BASE + REG_OFFSET_FIFO_B)
+
+#define REG_ADDR_DMA0 (REG_BASE + REG_OFFSET_DMA0)
+#define REG_ADDR_DMA0SAD (REG_BASE + REG_OFFSET_DMA0SAD)
+#define REG_ADDR_DMA0DAD (REG_BASE + REG_OFFSET_DMA0DAD)
+#define REG_ADDR_DMA0CNT (REG_BASE + REG_OFFSET_DMA0CNT)
+#define REG_ADDR_DMA0CNT_L (REG_BASE + REG_OFFSET_DMA0CNT_L)
+#define REG_ADDR_DMA0CNT_H (REG_BASE + REG_OFFSET_DMA0CNT_H)
+#define REG_ADDR_DMA1 (REG_BASE + REG_OFFSET_DMA1)
+#define REG_ADDR_DMA1SAD (REG_BASE + REG_OFFSET_DMA1SAD)
+#define REG_ADDR_DMA1DAD (REG_BASE + REG_OFFSET_DMA1DAD)
+#define REG_ADDR_DMA1CNT (REG_BASE + REG_OFFSET_DMA1CNT)
+#define REG_ADDR_DMA1CNT_L (REG_BASE + REG_OFFSET_DMA1CNT_L)
+#define REG_ADDR_DMA1CNT_H (REG_BASE + REG_OFFSET_DMA1CNT_H)
+#define REG_ADDR_DMA2 (REG_BASE + REG_OFFSET_DMA2)
+#define REG_ADDR_DMA2SAD (REG_BASE + REG_OFFSET_DMA2SAD)
+#define REG_ADDR_DMA2DAD (REG_BASE + REG_OFFSET_DMA2DAD)
+#define REG_ADDR_DMA2CNT (REG_BASE + REG_OFFSET_DMA2CNT)
+#define REG_ADDR_DMA2CNT_L (REG_BASE + REG_OFFSET_DMA2CNT_L)
+#define REG_ADDR_DMA2CNT_H (REG_BASE + REG_OFFSET_DMA2CNT_H)
+#define REG_ADDR_DMA3 (REG_BASE + REG_OFFSET_DMA3)
+#define REG_ADDR_DMA3SAD (REG_BASE + REG_OFFSET_DMA3SAD)
+#define REG_ADDR_DMA3DAD (REG_BASE + REG_OFFSET_DMA3DAD)
+#define REG_ADDR_DMA3CNT (REG_BASE + REG_OFFSET_DMA3CNT)
+#define REG_ADDR_DMA3CNT_L (REG_BASE + REG_OFFSET_DMA3CNT_L)
+#define REG_ADDR_DMA3CNT_H (REG_BASE + REG_OFFSET_DMA3CNT_H)
+
+#define REG_ADDR_TMCNT (REG_BASE + REG_OFFSET_TMCNT)
+#define REG_ADDR_TMCNT_L (REG_BASE + REG_OFFSET_TMCNT_L)
+#define REG_ADDR_TMCNT_H (REG_BASE + REG_OFFSET_TMCNT_H)
+#define REG_ADDR_TM0CNT (REG_BASE + REG_OFFSET_TM0CNT)
+#define REG_ADDR_TM0CNT_L (REG_BASE + REG_OFFSET_TM0CNT_L)
+#define REG_ADDR_TM0CNT_H (REG_BASE + REG_OFFSET_TM0CNT_H)
+#define REG_ADDR_TM1CNT (REG_BASE + REG_OFFSET_TM1CNT)
+#define REG_ADDR_TM1CNT_L (REG_BASE + REG_OFFSET_TM1CNT_L)
+#define REG_ADDR_TM1CNT_H (REG_BASE + REG_OFFSET_TM1CNT_H)
+#define REG_ADDR_TM2CNT (REG_BASE + REG_OFFSET_TM2CNT)
+#define REG_ADDR_TM2CNT_L (REG_BASE + REG_OFFSET_TM2CNT_L)
+#define REG_ADDR_TM2CNT_H (REG_BASE + REG_OFFSET_TM2CNT_H)
+#define REG_ADDR_TM3CNT (REG_BASE + REG_OFFSET_TM3CNT)
+#define REG_ADDR_TM3CNT_L (REG_BASE + REG_OFFSET_TM3CNT_L)
+#define REG_ADDR_TM3CNT_H (REG_BASE + REG_OFFSET_TM3CNT_H)
+
+#define REG_ADDR_SIOCNT (REG_BASE + REG_OFFSET_SIOCNT)
+#define REG_ADDR_SIODATA8 (REG_BASE + REG_OFFSET_SIODATA8)
+#define REG_ADDR_SIODATA32 (REG_BASE + REG_OFFSET_SIODATA32)
+#define REG_ADDR_SIOMLT_SEND (REG_BASE + REG_OFFSET_SIOMLT_SEND)
+#define REG_ADDR_SIOMLT_RECV (REG_BASE + REG_OFFSET_SIOMLT_RECV)
+#define REG_ADDR_SIOMULTI0 (REG_BASE + REG_OFFSET_SIOMULTI0)
+#define REG_ADDR_SIOMULTI1 (REG_BASE + REG_OFFSET_SIOMULTI1)
+#define REG_ADDR_SIOMULTI2 (REG_BASE + REG_OFFSET_SIOMULTI2)
+#define REG_ADDR_SIOMULTI3 (REG_BASE + REG_OFFSET_SIOMULTI3)
+
+#define REG_ADDR_KEYINPUT (REG_BASE + REG_OFFSET_KEYINPUT)
+#define REG_ADDR_KEYCNT (REG_BASE + REG_OFFSET_KEYCNT)
+
+#define REG_ADDR_RCNT (REG_BASE + REG_OFFSET_RCNT)
+
+#define REG_ADDR_JOYCNT (REG_BASE + REG_OFFSET_JOYCNT)
+#define REG_ADDR_JOYSTAT (REG_BASE + REG_OFFSET_JOYSTAT)
+#define REG_ADDR_JOY_RECV (REG_BASE + REG_OFFSET_JOY_RECV)
+#define REG_ADDR_JOY_RECV_L (REG_BASE + REG_OFFSET_JOY_RECV_L)
+#define REG_ADDR_JOY_RECV_H (REG_BASE + REG_OFFSET_JOY_RECV_H)
+#define REG_ADDR_JOY_TRANS (REG_BASE + REG_OFFSET_JOY_TRANS)
+#define REG_ADDR_JOY_TRANS_L (REG_BASE + REG_OFFSET_JOY_TRANS_L)
+#define REG_ADDR_JOY_TRANS_H (REG_BASE + REG_OFFSET_JOY_TRANS_H)
+
+#define REG_ADDR_IME (REG_BASE + REG_OFFSET_IME)
+#define REG_ADDR_IE (REG_BASE + REG_OFFSET_IE)
+#define REG_ADDR_IF (REG_BASE + REG_OFFSET_IF)
+
+#define REG_ADDR_WAITCNT (REG_BASE + REG_OFFSET_WAITCNT)
+
+// I/O registers
+
+#define REG_DISPCNT (*(vu16 *)REG_ADDR_DISPCNT)
+#define REG_DISPSTAT (*(vu16 *)REG_ADDR_DISPSTAT)
+#define REG_VCOUNT (*(vu16 *)REG_ADDR_VCOUNT)
+#define REG_BG0CNT (*(vu16 *)REG_ADDR_BG0CNT)
+#define REG_BG1CNT (*(vu16 *)REG_ADDR_BG1CNT)
+#define REG_BG2CNT (*(vu16 *)REG_ADDR_BG2CNT)
+#define REG_BG3CNT (*(vu16 *)REG_ADDR_BG3CNT)
+#define REG_BG0HOFS (*(vu16 *)REG_ADDR_BG0HOFS)
+#define REG_BG0VOFS (*(vu16 *)REG_ADDR_BG0VOFS)
+#define REG_BG1HOFS (*(vu16 *)REG_ADDR_BG1HOFS)
+#define REG_BG1VOFS (*(vu16 *)REG_ADDR_BG1VOFS)
+#define REG_BG2HOFS (*(vu16 *)REG_ADDR_BG2HOFS)
+#define REG_BG2VOFS (*(vu16 *)REG_ADDR_BG2VOFS)
+#define REG_BG3HOFS (*(vu16 *)REG_ADDR_BG3HOFS)
+#define REG_BG3VOFS (*(vu16 *)REG_ADDR_BG3VOFS)
+#define REG_BG2PA (*(vu16 *)REG_ADDR_BG2PA)
+#define REG_BG2PB (*(vu16 *)REG_ADDR_BG2PB)
+#define REG_BG2PC (*(vu16 *)REG_ADDR_BG2PC)
+#define REG_BG2PD (*(vu16 *)REG_ADDR_BG2PD)
+#define REG_BG2X (*(vu32 *)REG_ADDR_BG2X)
+#define REG_BG2X_L (*(vu16 *)REG_ADDR_BG2X_L)
+#define REG_BG2X_H (*(vu16 *)REG_ADDR_BG2X_H)
+#define REG_BG2Y (*(vu32 *)REG_ADDR_BG2Y)
+#define REG_BG2Y_L (*(vu16 *)REG_ADDR_BG2Y_L)
+#define REG_BG2Y_H (*(vu16 *)REG_ADDR_BG2Y_H)
+#define REG_BG3PA (*(vu16 *)REG_ADDR_BG3PA)
+#define REG_BG3PB (*(vu16 *)REG_ADDR_BG3PB)
+#define REG_BG3PC (*(vu16 *)REG_ADDR_BG3PC)
+#define REG_BG3PD (*(vu16 *)REG_ADDR_BG3PD)
+#define REG_BG3X (*(vu32 *)REG_ADDR_BG3X)
+#define REG_BG3X_L (*(vu16 *)REG_ADDR_BG3X_L)
+#define REG_BG3X_H (*(vu16 *)REG_ADDR_BG3X_H)
+#define REG_BG3Y (*(vu32 *)REG_ADDR_BG3Y)
+#define REG_BG3Y_L (*(vu16 *)REG_ADDR_BG3Y_L)
+#define REG_BG3Y_H (*(vu16 *)REG_ADDR_BG3Y_H)
+#define REG_WIN0H (*(vu16 *)REG_ADDR_WIN0H)
+#define REG_WIN1H (*(vu16 *)REG_ADDR_WIN1H)
+#define REG_WIN0V (*(vu16 *)REG_ADDR_WIN0V)
+#define REG_WIN1V (*(vu16 *)REG_ADDR_WIN1V)
+#define REG_WININ (*(vu16 *)REG_ADDR_WININ)
+#define REG_WINOUT (*(vu16 *)REG_ADDR_WINOUT)
+#define REG_MOSAIC (*(vu16 *)REG_ADDR_MOSAIC)
+#define REG_BLDCNT (*(vu16 *)REG_ADDR_BLDCNT)
+#define REG_BLDALPHA (*(vu16 *)REG_ADDR_BLDALPHA)
+#define REG_BLDY (*(vu16 *)REG_ADDR_BLDY)
+
+#define REG_SOUND1CNT_L (*(vu16 *)REG_ADDR_SOUND1CNT_L)
+#define REG_NR10 (*(vu8 *)REG_ADDR_NR10)
+#define REG_SOUND1CNT_H (*(vu16 *)REG_ADDR_SOUND1CNT_H)
+#define REG_NR11 (*(vu8 *)REG_ADDR_NR11)
+#define REG_NR12 (*(vu8 *)REG_ADDR_NR12)
+#define REG_SOUND1CNT_X (*(vu16 *)REG_ADDR_SOUND1CNT_X)
+#define REG_NR13 (*(vu8 *)REG_ADDR_NR13)
+#define REG_NR14 (*(vu8 *)REG_ADDR_NR14)
+#define REG_SOUND2CNT_L (*(vu16 *)REG_ADDR_SOUND2CNT_L)
+#define REG_NR21 (*(vu8 *)REG_ADDR_NR21)
+#define REG_NR22 (*(vu8 *)REG_ADDR_NR22)
+#define REG_SOUND2CNT_H (*(vu16 *)REG_ADDR_SOUND2CNT_H)
+#define REG_NR23 (*(vu8 *)REG_ADDR_NR23)
+#define REG_NR24 (*(vu8 *)REG_ADDR_NR24)
+#define REG_SOUND3CNT_L (*(vu16 *)REG_ADDR_SOUND3CNT_L)
+#define REG_NR30 (*(vu8 *)REG_ADDR_NR30)
+#define REG_SOUND3CNT_H (*(vu16 *)REG_ADDR_SOUND3CNT_H)
+#define REG_NR31 (*(vu8 *)REG_ADDR_NR31)
+#define REG_NR32 (*(vu8 *)REG_ADDR_NR32)
+#define REG_SOUND3CNT_X (*(vu16 *)REG_ADDR_SOUND3CNT_X)
+#define REG_NR33 (*(vu8 *)REG_ADDR_NR33)
+#define REG_NR34 (*(vu8 *)REG_ADDR_NR34)
+#define REG_SOUND4CNT_L (*(vu16 *)REG_ADDR_SOUND4CNT_L)
+#define REG_NR41 (*(vu8 *)REG_ADDR_NR41)
+#define REG_NR42 (*(vu8 *)REG_ADDR_NR42)
+#define REG_SOUND4CNT_H (*(vu16 *)REG_ADDR_SOUND4CNT_H)
+#define REG_NR43 (*(vu8 *)REG_ADDR_NR43)
+#define REG_NR44 (*(vu8 *)REG_ADDR_NR44)
+#define REG_SOUNDCNT_L (*(vu16 *)REG_ADDR_SOUNDCNT_L)
+#define REG_NR50 (*(vu8 *)REG_ADDR_NR50)
+#define REG_NR51 (*(vu8 *)REG_ADDR_NR51)
+#define REG_SOUNDCNT_H (*(vu16 *)REG_ADDR_SOUNDCNT_H)
+#define REG_SOUNDCNT_X (*(vu16 *)REG_ADDR_SOUNDCNT_X)
+#define REG_NR52 (*(vu8 *)REG_ADDR_NR52)
+#define REG_SOUNDBIAS (*(vu16 *)REG_ADDR_SOUNDBIAS)
+#define REG_SOUNDBIAS_L (*(vu8 *)REG_ADDR_SOUNDBIAS_L)
+#define REG_SOUNDBIAS_H (*(vu8 *)REG_ADDR_SOUNDBIAS_H)
+#define REG_WAVE_RAM0 (*(vu32 *)REG_ADDR_WAVE_RAM0)
+#define REG_WAVE_RAM1 (*(vu32 *)REG_ADDR_WAVE_RAM1)
+#define REG_WAVE_RAM2 (*(vu32 *)REG_ADDR_WAVE_RAM2)
+#define REG_WAVE_RAM3 (*(vu32 *)REG_ADDR_WAVE_RAM3)
+#define REG_FIFO_A (*(vu32 *)REG_ADDR_FIFO_A)
+#define REG_FIFO_B (*(vu32 *)REG_ADDR_FIFO_B)
+
+#define REG_DMA0SAD (*(vu32 *)REG_ADDR_DMA0SAD)
+#define REG_DMA0DAD (*(vu32 *)REG_ADDR_DMA0DAD)
+#define REG_DMA0CNT (*(vu32 *)REG_ADDR_DMA0CNT)
+#define REG_DMA0CNT_L (*(vu16 *)REG_ADDR_DMA0CNT_L)
+#define REG_DMA0CNT_H (*(vu16 *)REG_ADDR_DMA0CNT_H)
+
+#define REG_DMA1SAD (*(vu32 *)REG_ADDR_DMA1SAD)
+#define REG_DMA1DAD (*(vu32 *)REG_ADDR_DMA1DAD)
+#define REG_DMA1CNT (*(vu32 *)REG_ADDR_DMA1CNT)
+#define REG_DMA1CNT_L (*(vu16 *)REG_ADDR_DMA1CNT_L)
+#define REG_DMA1CNT_H (*(vu16 *)REG_ADDR_DMA1CNT_H)
+
+#define REG_DMA2SAD (*(vu32 *)REG_ADDR_DMA2SAD)
+#define REG_DMA2DAD (*(vu32 *)REG_ADDR_DMA2DAD)
+#define REG_DMA2CNT (*(vu32 *)REG_ADDR_DMA2CNT)
+#define REG_DMA2CNT_L (*(vu16 *)REG_ADDR_DMA2CNT_L)
+#define REG_DMA2CNT_H (*(vu16 *)REG_ADDR_DMA2CNT_H)
+
+#define REG_DMA3SAD (*(vu32 *)REG_ADDR_DMA3SAD)
+#define REG_DMA3DAD (*(vu32 *)REG_ADDR_DMA3DAD)
+#define REG_DMA3CNT (*(vu32 *)REG_ADDR_DMA3CNT)
+#define REG_DMA3CNT_L (*(vu16 *)REG_ADDR_DMA3CNT_L)
+#define REG_DMA3CNT_H (*(vu16 *)REG_ADDR_DMA3CNT_H)
+
+#define REG_TMCNT(n) (*(vu16 *)(REG_ADDR_TMCNT + ((n) * 4)))
+#define REG_TMCNT_L(n) (*(vu16 *)(REG_ADDR_TMCNT_L + ((n) * 4)))
+#define REG_TMCNT_H(n) (*(vu16 *)(REG_ADDR_TMCNT_H + ((n) * 4)))
+#define REG_TM0CNT (*(vu32 *)REG_ADDR_TM0CNT)
+#define REG_TM0CNT_L (*(vu16 *)REG_ADDR_TM0CNT_L)
+#define REG_TM0CNT_H (*(vu16 *)REG_ADDR_TM0CNT_H)
+#define REG_TM1CNT (*(vu32 *)REG_ADDR_TM1CNT)
+#define REG_TM1CNT_L (*(vu16 *)REG_ADDR_TM1CNT_L)
+#define REG_TM1CNT_H (*(vu16 *)REG_ADDR_TM1CNT_H)
+#define REG_TM2CNT (*(vu32 *)REG_ADDR_TM2CNT)
+#define REG_TM2CNT_L (*(vu16 *)REG_ADDR_TM2CNT_L)
+#define REG_TM2CNT_H (*(vu16 *)REG_ADDR_TM2CNT_H)
+#define REG_TM3CNT (*(vu32 *)REG_ADDR_TM3CNT)
+#define REG_TM3CNT_L (*(vu16 *)REG_ADDR_TM3CNT_L)
+#define REG_TM3CNT_H (*(vu16 *)REG_ADDR_TM3CNT_H)
+
+#define REG_SIOCNT (*(vu16 *)REG_ADDR_SIOCNT)
+#define REG_SIODATA8 (*(vu16 *)REG_ADDR_SIODATA8)
+#define REG_SIODATA32 (*(vu32 *)REG_ADDR_SIODATA32)
+#define REG_SIOMLT_SEND (*(vu16 *)REG_ADDR_SIOMLT_SEND)
+#define REG_SIOMLT_RECV (*(vu64 *)REG_ADDR_SIOMLT_RECV)
+#define REG_SIOMULTI0 (*(vu16 *)REG_ADDR_SIOMULTI0)
+#define REG_SIOMULTI1 (*(vu16 *)REG_ADDR_SIOMULTI1)
+#define REG_SIOMULTI2 (*(vu16 *)REG_ADDR_SIOMULTI2)
+#define REG_SIOMULTI3 (*(vu16 *)REG_ADDR_SIOMULTI3)
+
+#define REG_KEYINPUT (*(vu16 *)REG_ADDR_KEYINPUT)
+#define REG_KEYCNT (*(vu16 *)REG_ADDR_KEYCNT)
+
+#define REG_RCNT (*(vu16 *)REG_ADDR_RCNT)
+
+#define REG_IME (*(vu16 *)REG_ADDR_IME)
+#define REG_IE (*(vu16 *)REG_ADDR_IE)
+#define REG_IF (*(vu16 *)REG_ADDR_IF)
+
+#define REG_WAITCNT (*(vu16 *)REG_ADDR_WAITCNT)
+
+// I/O register fields
+
+// DISPCNT
+#define DISPCNT_MODE_0 0x0000 // BG0: text, BG1: text, BG2: text, BG3: text
+#define DISPCNT_MODE_1 0x0001 // BG0: text, BG1: text, BG2: affine, BG3: off
+#define DISPCNT_MODE_2 0x0002 // BG0: off, BG1: off, BG2: affine, BG3: affine
+#define DISPCNT_MODE_3 0x0003 // Bitmap mode, 240x160, BGR555 color
+#define DISPCNT_MODE_4 0x0004 // Bitmap mode, 240x160, 256 color palette
+#define DISPCNT_MODE_5 0x0005 // Bitmap mode, 160x128, BGR555 color
+#define DISPCNT_HBLANK_INTERVAL 0x0020 // Allow access to OAM during H-Blank
+#define DISPCNT_OBJ_1D_MAP 0x0040
+#define DISPCNT_FORCED_BLANK 0x0080
+#define DISPCNT_BG0_ON 0x0100
+#define DISPCNT_BG1_ON 0x0200
+#define DISPCNT_BG2_ON 0x0400
+#define DISPCNT_BG3_ON 0x0800
+#define DISPCNT_BG_ALL_ON 0x0F00
+#define DISPCNT_OBJ_ON 0x1000
+#define DISPCNT_WIN0_ON 0x2000
+#define DISPCNT_WIN1_ON 0x4000
+#define DISPCNT_OBJWIN_ON 0x8000
+
+// DISPSTAT
+#define DISPSTAT_VBLANK 0x0001 // in V-Blank
+#define DISPSTAT_HBLANK 0x0002 // in H-Blank
+#define DISPSTAT_VCOUNT 0x0004 // V-Count match
+#define DISPSTAT_VBLANK_INTR 0x0008 // V-Blank interrupt enabled
+#define DISPSTAT_HBLANK_INTR 0x0010 // H-Blank interrupt enabled
+#define DISPSTAT_VCOUNT_INTR 0x0020 // V-Count interrupt enabled
+
+// BGCNT
+#define BGCNT_PRIORITY(n) (n) // Values 0 - 3. Lower priority BGs will be drawn on top of higher priority BGs.
+#define BGCNT_CHARBASE(n) ((n) << 2) // Values 0 - 3. Base block for tile pixel data.
+#define BGCNT_MOSAIC 0x0040
+#define BGCNT_16COLOR 0x0000 // 4 bits per pixel
+#define BGCNT_256COLOR 0x0080 // 8 bits per pixel
+#define BGCNT_SCREENBASE(n) ((n) << 8) // Values 0 - 31. Base block for tile map.
+#define BGCNT_WRAP 0x2000 // Only affects affine BGs. Text BGs wrap by default.
+#define BGCNT_TXT256x256 0x0000 // Internal screen size size of text mode BG in pixels.
+#define BGCNT_TXT512x256 0x4000
+#define BGCNT_TXT256x512 0x8000
+#define BGCNT_TXT512x512 0xC000
+#define BGCNT_AFF128x128 0x0000 // Internal screen size size of affine mode BG in pixels.
+#define BGCNT_AFF256x256 0x4000
+#define BGCNT_AFF512x512 0x8000
+#define BGCNT_AFF1024x1024 0xC000
+
+// WININ/OUT
+#define WININ_WIN0_BG0 (1 << 0)
+#define WININ_WIN0_BG1 (1 << 1)
+#define WININ_WIN0_BG2 (1 << 2)
+#define WININ_WIN0_BG3 (1 << 3)
+#define WININ_WIN0_BG_ALL (WININ_WIN0_BG0 | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3)
+#define WININ_WIN0_OBJ (1 << 4)
+#define WININ_WIN0_CLR (1 << 5)
+#define WININ_WIN1_BG0 (1 << 8)
+#define WININ_WIN1_BG1 (1 << 9)
+#define WININ_WIN1_BG2 (1 << 10)
+#define WININ_WIN1_BG3 (1 << 11)
+#define WININ_WIN1_BG_ALL (WININ_WIN1_BG0 | WININ_WIN1_BG1 | WININ_WIN1_BG2 | WININ_WIN1_BG3)
+#define WININ_WIN1_OBJ (1 << 12)
+#define WININ_WIN1_CLR (1 << 13)
+
+#define WINOUT_WIN01_BG0 (1 << 0)
+#define WINOUT_WIN01_BG1 (1 << 1)
+#define WINOUT_WIN01_BG2 (1 << 2)
+#define WINOUT_WIN01_BG3 (1 << 3)
+#define WINOUT_WIN01_BG_ALL (WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3)
+#define WINOUT_WIN01_OBJ (1 << 4)
+#define WINOUT_WIN01_CLR (1 << 5)
+#define WINOUT_WINOBJ_BG0 (1 << 8)
+#define WINOUT_WINOBJ_BG1 (1 << 9)
+#define WINOUT_WINOBJ_BG2 (1 << 10)
+#define WINOUT_WINOBJ_BG3 (1 << 11)
+#define WINOUT_WINOBJ_BG_ALL (WINOUT_WINOBJ_BG0 | WINOUT_WINOBJ_BG1 | WINOUT_WINOBJ_BG2 | WINOUT_WINOBJ_BG3)
+#define WINOUT_WINOBJ_OBJ (1 << 12)
+#define WINOUT_WINOBJ_CLR (1 << 13)
+
+#define WIN_RANGE(a, b) (((a) << 8) | (b))
+#define WIN_RANGE2(a, b) ((b) | ((a) << 8))
+
+// BLDCNT
+// Bits 0-5 select layers for the 1st target
+#define BLDCNT_TGT1_BG0 (1 << 0)
+#define BLDCNT_TGT1_BG1 (1 << 1)
+#define BLDCNT_TGT1_BG2 (1 << 2)
+#define BLDCNT_TGT1_BG3 (1 << 3)
+#define BLDCNT_TGT1_OBJ (1 << 4)
+#define BLDCNT_TGT1_BD (1 << 5)
+#define BLDCNT_TGT1_ALL (BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD)
+// Bits 6-7 select the special effect
+#define BLDCNT_EFFECT_NONE (0 << 6) // no special effect
+#define BLDCNT_EFFECT_BLEND (1 << 6) // 1st+2nd targets mixed (controlled by BLDALPHA)
+#define BLDCNT_EFFECT_LIGHTEN (2 << 6) // 1st target becomes whiter (controlled by BLDY)
+#define BLDCNT_EFFECT_DARKEN (3 << 6) // 1st target becomes blacker (controlled by BLDY)
+// Bits 8-13 select layers for the 2nd target
+#define BLDCNT_TGT2_BG0 (1 << 8)
+#define BLDCNT_TGT2_BG1 (1 << 9)
+#define BLDCNT_TGT2_BG2 (1 << 10)
+#define BLDCNT_TGT2_BG3 (1 << 11)
+#define BLDCNT_TGT2_OBJ (1 << 12)
+#define BLDCNT_TGT2_BD (1 << 13)
+#define BLDCNT_TGT2_ALL (BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD)
+
+// BLDALPHA
+#define BLDALPHA_BLEND(target1, target2) (((target2) << 8) | (target1))
+
+// SOUNDCNT_H
+#define SOUND_CGB_MIX_QUARTER 0x0000
+#define SOUND_CGB_MIX_HALF 0x0001
+#define SOUND_CGB_MIX_FULL 0x0002
+#define SOUND_A_MIX_HALF 0x0000
+#define SOUND_A_MIX_FULL 0x0004
+#define SOUND_B_MIX_HALF 0x0000
+#define SOUND_B_MIX_FULL 0x0008
+#define SOUND_ALL_MIX_FULL 0x000E
+#define SOUND_A_RIGHT_OUTPUT 0x0100
+#define SOUND_A_LEFT_OUTPUT 0x0200
+#define SOUND_A_TIMER_0 0x0000
+#define SOUND_A_TIMER_1 0x0400
+#define SOUND_A_FIFO_RESET 0x0800
+#define SOUND_B_RIGHT_OUTPUT 0x1000
+#define SOUND_B_LEFT_OUTPUT 0x2000
+#define SOUND_B_TIMER_0 0x0000
+#define SOUND_B_TIMER_1 0x4000
+#define SOUND_B_FIFO_RESET 0x8000
+
+// SOUNDCNT_X
+#define SOUND_1_ON 0x0001
+#define SOUND_2_ON 0x0002
+#define SOUND_3_ON 0x0004
+#define SOUND_4_ON 0x0008
+#define SOUND_MASTER_ENABLE 0x0080
+
+// DMA
+#define DMA_DEST_INC 0x0000
+#define DMA_DEST_DEC 0x0020
+#define DMA_DEST_FIXED 0x0040
+#define DMA_DEST_RELOAD 0x0060
+#define DMA_SRC_INC 0x0000
+#define DMA_SRC_DEC 0x0080
+#define DMA_SRC_FIXED 0x0100
+#define DMA_REPEAT 0x0200
+#define DMA_16BIT 0x0000
+#define DMA_32BIT 0x0400
+#define DMA_DREQ_ON 0x0800
+#define DMA_START_NOW 0x0000
+#define DMA_START_VBLANK 0x1000
+#define DMA_START_HBLANK 0x2000
+#define DMA_START_SPECIAL 0x3000
+#define DMA_START_MASK 0x3000
+#define DMA_INTR_ENABLE 0x4000
+#define DMA_ENABLE 0x8000
+
+// timer
+#define TIMER_1CLK 0x00
+#define TIMER_64CLK 0x01
+#define TIMER_256CLK 0x02
+#define TIMER_1024CLK 0x03
+#define TIMER_INTR_ENABLE 0x40
+#define TIMER_ENABLE 0x80
+
+// serial
+#define SIO_ID 0x0030 // Communication ID
+
+#define SIO_8BIT_MODE 0x0000 // Normal 8-bit communication mode
+#define SIO_32BIT_MODE 0x1000 // Normal 32-bit communication mode
+#define SIO_MULTI_MODE 0x2000 // Multi-player communication mode
+#define SIO_UART_MODE 0x3000 // UART communication mode
+
+#define SIO_9600_BPS 0x0000 // baud rate 9600 bps
+#define SIO_38400_BPS 0x0001 // 38400 bps
+#define SIO_57600_BPS 0x0002 // 57600 bps
+#define SIO_115200_BPS 0x0003 // 115200 bps
+
+#define SIO_MULTI_SI 0x0004 // Multi-player communication SI terminal
+#define SIO_MULTI_SD 0x0008 // SD terminal
+#define SIO_MULTI_BUSY 0x0080
+
+#define SIO_ERROR 0x0040 // Detect error
+#define SIO_START 0x0080 // Start transfer
+#define SIO_ENABLE 0x0080 // Enable SIO
+
+#define SIO_INTR_ENABLE 0x4000
+
+#define SIO_MULTI_SI_SHIFT 2
+#define SIO_MULTI_SI_MASK 0x1
+#define SIO_MULTI_DI_SHIFT 3
+#define SIO_MULTI_DI_MASK 0x1
+
+// keys
+#define A_BUTTON 0x0001
+#define B_BUTTON 0x0002
+#define SELECT_BUTTON 0x0004
+#define START_BUTTON 0x0008
+#define DPAD_RIGHT 0x0010
+#define DPAD_LEFT 0x0020
+#define DPAD_UP 0x0040
+#define DPAD_DOWN 0x0080
+#define R_BUTTON 0x0100
+#define L_BUTTON 0x0200
+#define KEYS_MASK 0x03FF
+#define KEY_INTR_ENABLE 0x0400
+#define KEY_OR_INTR 0x0000
+#define KEY_AND_INTR 0x8000
+#define DPAD_ANY ((DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN))
+#define JOY_EXCL_DPAD 0x030F
+
+// interrupt flags
+#define INTR_FLAG_VBLANK (1 << 0)
+#define INTR_FLAG_HBLANK (1 << 1)
+#define INTR_FLAG_VCOUNT (1 << 2)
+#define INTR_FLAG_TIMER0 (1 << 3)
+#define INTR_FLAG_TIMER1 (1 << 4)
+#define INTR_FLAG_TIMER2 (1 << 5)
+#define INTR_FLAG_TIMER3 (1 << 6)
+#define INTR_FLAG_SERIAL (1 << 7)
+#define INTR_FLAG_DMA0 (1 << 8)
+#define INTR_FLAG_DMA1 (1 << 9)
+#define INTR_FLAG_DMA2 (1 << 10)
+#define INTR_FLAG_DMA3 (1 << 11)
+#define INTR_FLAG_KEYPAD (1 << 12)
+#define INTR_FLAG_GAMEPAK (1 << 13)
+
+// WAITCNT
+#define WAITCNT_SRAM_4 (0 << 0)
+#define WAITCNT_SRAM_3 (1 << 0)
+#define WAITCNT_SRAM_2 (2 << 0)
+#define WAITCNT_SRAM_8 (3 << 0)
+#define WAITCNT_SRAM_MASK (3 << 0)
+
+#define WAITCNT_WS0_N_4 (0 << 2)
+#define WAITCNT_WS0_N_3 (1 << 2)
+#define WAITCNT_WS0_N_2 (2 << 2)
+#define WAITCNT_WS0_N_8 (3 << 2)
+#define WAITCNT_WS0_N_MASK (3 << 2)
+
+#define WAITCNT_WS0_S_2 (0 << 4)
+#define WAITCNT_WS0_S_1 (1 << 4)
+
+#define WAITCNT_WS1_N_4 (0 << 5)
+#define WAITCNT_WS1_N_3 (1 << 5)
+#define WAITCNT_WS1_N_2 (2 << 5)
+#define WAITCNT_WS1_N_8 (3 << 5)
+#define WAITCNT_WS1_N_MASK (3 << 5)
+
+#define WAITCNT_WS1_S_4 (0 << 7)
+#define WAITCNT_WS1_S_1 (1 << 7)
+
+#define WAITCNT_WS2_N_4 (0 << 8)
+#define WAITCNT_WS2_N_3 (1 << 8)
+#define WAITCNT_WS2_N_2 (2 << 8)
+#define WAITCNT_WS2_N_8 (3 << 8)
+#define WAITCNT_WS2_N_MASK (3 << 8)
+
+#define WAITCNT_WS2_S_8 (0 << 10)
+#define WAITCNT_WS2_S_1 (1 << 10)
+
+#define WAITCNT_PHI_OUT_NONE (0 << 11)
+#define WAITCNT_PHI_OUT_4MHZ (1 << 11)
+#define WAITCNT_PHI_OUT_8MHZ (2 << 11)
+#define WAITCNT_PHI_OUT_16MHZ (3 << 11)
+#define WAITCNT_PHI_OUT_MASK (3 << 11)
+
+#define WAITCNT_PREFETCH_ENABLE (1 << 14)
+
+#define WAITCNT_AGB (0 << 15)
+#define WAITCNT_CGB (1 << 15)
+
+#endif // GUARD_GBA_IO_REG_H
diff --git a/berry_fix/payload/include/gba/isagbprint.h b/berry_fix/payload/include/gba/isagbprint.h
new file mode 100644
index 000000000..c5eb456c3
--- /dev/null
+++ b/berry_fix/payload/include/gba/isagbprint.h
@@ -0,0 +1,50 @@
+#ifndef GUARD_GBA_ISAGBPRINT_H
+#define GUARD_GBA_ISAGBPRINT_H
+
+#ifdef NDEBUG
+#define AGBPrintInit()
+#define AGBPutc(cChr)
+#define AGBPrint(pBuf)
+#define AGBPrintf(pBuf, ...)
+#define AGBPrintFlush1Block()
+#define AGBPrintFlush()
+#define AGBAssert(pFile, nLine, pExpression, nStopProgram)
+#else
+void AGBPrintInit(void);
+void AGBPutc(const char cChr);
+void AGBPrint(const char *pBuf);
+void AGBPrintf(const char *pBuf, ...);
+void AGBPrintFlush1Block(void);
+void AGBPrintFlush(void);
+void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram);
+#endif
+
+#undef AGB_ASSERT
+#ifdef NDEBUG
+#define AGB_ASSERT(exp)
+#else
+#define AGB_ASSERT(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 1);
+#endif
+
+#undef AGB_WARNING
+#ifdef NDEBUG
+#define AGB_WARNING(exp)
+#else
+#define AGB_WARNING(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 0);
+#endif
+
+// for matching purposes
+
+#ifdef NDEBUG
+#define AGB_ASSERT_EX(exp, file, line)
+#else
+#define AGB_ASSERT_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 1);
+#endif
+
+#ifdef NDEBUG
+#define AGB_WARNING_EX(exp, file, line)
+#else
+#define AGB_WARNING_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 0);
+#endif
+
+#endif // GUARD_GBA_ISAGBPRINT_H
diff --git a/berry_fix/payload/include/gba/m4a_internal.h b/berry_fix/payload/include/gba/m4a_internal.h
new file mode 100644
index 000000000..339a0774e
--- /dev/null
+++ b/berry_fix/payload/include/gba/m4a_internal.h
@@ -0,0 +1,467 @@
+#ifndef GUARD_GBA_M4A_INTERNAL_H
+#define GUARD_GBA_M4A_INTERNAL_H
+
+#include "gba/gba.h"
+
+// ASCII encoding of 'Smsh' in reverse
+// This is presumably short for SMASH, the developer of MKS4AGB.
+#define ID_NUMBER 0x68736D53
+
+#define C_V 0x40 // center value for PAN, BEND, and TUNE
+
+#define SOUND_MODE_REVERB_VAL 0x0000007F
+#define SOUND_MODE_REVERB_SET 0x00000080
+#define SOUND_MODE_MAXCHN 0x00000F00
+#define SOUND_MODE_MAXCHN_SHIFT 8
+#define SOUND_MODE_MASVOL 0x0000F000
+#define SOUND_MODE_MASVOL_SHIFT 12
+#define SOUND_MODE_FREQ_05734 0x00010000
+#define SOUND_MODE_FREQ_07884 0x00020000
+#define SOUND_MODE_FREQ_10512 0x00030000
+#define SOUND_MODE_FREQ_13379 0x00040000
+#define SOUND_MODE_FREQ_15768 0x00050000
+#define SOUND_MODE_FREQ_18157 0x00060000
+#define SOUND_MODE_FREQ_21024 0x00070000
+#define SOUND_MODE_FREQ_26758 0x00080000
+#define SOUND_MODE_FREQ_31536 0x00090000
+#define SOUND_MODE_FREQ_36314 0x000A0000
+#define SOUND_MODE_FREQ_40137 0x000B0000
+#define SOUND_MODE_FREQ_42048 0x000C0000
+#define SOUND_MODE_FREQ 0x000F0000
+#define SOUND_MODE_FREQ_SHIFT 16
+#define SOUND_MODE_DA_BIT_9 0x00800000
+#define SOUND_MODE_DA_BIT_8 0x00900000
+#define SOUND_MODE_DA_BIT_7 0x00A00000
+#define SOUND_MODE_DA_BIT_6 0x00B00000
+#define SOUND_MODE_DA_BIT 0x00B00000
+#define SOUND_MODE_DA_BIT_SHIFT 20
+
+struct WaveData
+{
+ u16 type;
+ u16 status;
+ u32 freq;
+ u32 loopStart;
+ u32 size; // number of samples
+ s8 data[1]; // samples
+};
+
+#define TONEDATA_TYPE_CGB 0x07
+#define TONEDATA_TYPE_FIX 0x08
+#define TONEDATA_TYPE_SPL 0x40 // key split
+#define TONEDATA_TYPE_RHY 0x80 // rhythm
+
+#define TONEDATA_P_S_PAN 0xc0
+#define TONEDATA_P_S_PAM TONEDATA_P_S_PAN
+
+struct ToneData
+{
+ u8 type;
+ u8 key;
+ u8 length; // sound length (compatible sound)
+ u8 pan_sweep; // pan or sweep (compatible sound ch. 1)
+ struct WaveData *wav;
+ u8 attack;
+ u8 decay;
+ u8 sustain;
+ u8 release;
+};
+
+struct CgbChannel
+{
+ u8 sf;
+ u8 ty;
+ u8 rightVolume;
+ u8 leftVolume;
+ u8 at;
+ u8 de;
+ u8 su;
+ u8 re;
+ u8 ky;
+ u8 ev;
+ u8 eg;
+ u8 ec;
+ u8 echoVolume;
+ u8 echoLength;
+ u8 d1;
+ u8 d2;
+ u8 gt;
+ u8 mk;
+ u8 ve;
+ u8 pr;
+ u8 rp;
+ u8 d3[3];
+ u8 d5;
+ u8 sg;
+ u8 n4;
+ u8 pan;
+ u8 panMask;
+ u8 mo;
+ u8 le;
+ u8 sw;
+ u32 fr;
+ u32 wp;
+ u32 cp;
+ u32 tp;
+ u32 pp;
+ u32 np;
+ u8 d4[8];
+};
+
+struct MusicPlayerTrack;
+
+struct SoundChannel
+{
+ u8 status;
+ u8 type;
+ u8 rightVolume;
+ u8 leftVolume;
+ u8 attack;
+ u8 decay;
+ u8 sustain;
+ u8 release;
+ u8 ky;
+ u8 ev;
+ u8 er;
+ u8 el;
+ u8 echoVolume;
+ u8 echoLength;
+ u8 d1;
+ u8 d2;
+ u8 gt;
+ u8 mk;
+ u8 ve;
+ u8 pr;
+ u8 rp;
+ u8 d3[3];
+ u32 ct;
+ u32 fw;
+ u32 freq;
+ struct WaveData *wav;
+ u32 cp;
+ struct MusicPlayerTrack *track;
+ u32 pp;
+ u32 np;
+ u32 d4;
+ u16 xpi;
+ u16 xpc;
+};
+
+#define MAX_DIRECTSOUND_CHANNELS 12
+
+#define PCM_DMA_BUF_SIZE 1584 // size of Direct Sound buffer
+
+struct SoundInfo
+{
+ // This field is normally equal to ID_NUMBER but it is set to other
+ // values during sensitive operations for locking purposes.
+ // This field should be volatile but isn't. This could potentially cause
+ // race conditions.
+ u32 ident;
+
+ vu8 pcmDmaCounter;
+
+ // Direct Sound
+ u8 reverb;
+ u8 maxChans;
+ u8 masterVolume;
+ u8 freq;
+
+ u8 mode;
+ u8 c15;
+ u8 pcmDmaPeriod; // number of V-blanks per PCM DMA
+ u8 maxLines;
+ u8 gap[3];
+ s32 pcmSamplesPerVBlank;
+ s32 pcmFreq;
+ s32 divFreq;
+ struct CgbChannel *cgbChans;
+ u32 func;
+ u32 intp;
+ void (*CgbSound)(void);
+ void (*CgbOscOff)(u8);
+ u32 (*MidiKeyToCgbFreq)(u8, u8, u8);
+ u32 MPlayJumpTable;
+ u32 plynote;
+ u32 ExtVolPit;
+ u8 gap2[16];
+ struct SoundChannel chans[MAX_DIRECTSOUND_CHANNELS];
+ s8 pcmBuffer[PCM_DMA_BUF_SIZE * 2];
+};
+
+struct SongHeader
+{
+ u8 trackCount;
+ u8 blockCount;
+ u8 priority;
+ u8 reverb;
+ struct ToneData *tone;
+ u8 *part[1];
+};
+
+struct PokemonCrySong
+{
+ u8 trackCount;
+ u8 blockCount;
+ u8 priority;
+ u8 reverb;
+ struct ToneData *tone;
+ u8 *part[2];
+ u8 gap;
+ u8 part0; // 0x11
+ u8 tuneValue; // 0x12
+ u8 gotoCmd; // 0x13
+ u32 gotoTarget; // 0x14
+ u8 part1; // 0x18
+ u8 tuneValue2; // 0x19
+ u8 cont[2]; // 0x1A
+ u8 volCmd; // 0x1C
+ u8 volumeValue; // 0x1D
+ u8 unkCmd0D[2]; // 0x1E
+ u32 unkCmd0DParam; // 0x20
+ u8 xreleCmd[2]; // 0x24
+ u8 releaseValue; // 0x26
+ u8 panCmd;
+ u8 panValue; // 0x28
+ u8 tieCmd; // 0x29
+ u8 tieKeyValue; // 0x2A
+ u8 tieVelocityValue; // 0x2B
+ u8 unkCmd0C[2]; // 0x2C
+ u16 unkCmd0CParam; // 0x2E
+ u8 end[2]; // 0x30
+};
+
+#define MPT_FLG_VOLSET 0x01
+#define MPT_FLG_VOLCHG 0x03
+#define MPT_FLG_PITSET 0x04
+#define MPT_FLG_PITCHG 0x0C
+#define MPT_FLG_START 0x40
+#define MPT_FLG_EXIST 0x80
+
+struct MusicPlayerTrack
+{
+ u8 flags;
+ u8 wait;
+ u8 patternLevel;
+ u8 repN;
+ u8 gateTime;
+ u8 key;
+ u8 velocity;
+ u8 runningStatus;
+ u8 keyM;
+ u8 pitM;
+ s8 keyShift;
+ s8 keyShiftX;
+ s8 tune;
+ u8 pitX;
+ s8 bend;
+ u8 bendRange;
+ u8 volMR;
+ u8 volML;
+ u8 vol;
+ u8 volX;
+ s8 pan;
+ s8 panX;
+ s8 modM;
+ u8 mod;
+ u8 modT;
+ u8 lfoSpeed;
+ u8 lfoSpeedC;
+ u8 lfoDelay;
+ u8 lfoDelayC;
+ u8 priority;
+ u8 echoVolume;
+ u8 echoLength;
+ struct SoundChannel *chan;
+ struct ToneData tone;
+ u8 gap[10];
+ u16 unk_3A;
+ u32 unk_3C;
+ u8 *cmdPtr;
+ u8 *patternStack[3];
+};
+
+#define MUSICPLAYER_STATUS_TRACK 0x0000ffff
+#define MUSICPLAYER_STATUS_PAUSE 0x80000000
+
+#define MAX_MUSICPLAYER_TRACKS 16
+
+#define TEMPORARY_FADE 0x0001
+#define FADE_IN 0x0002
+#define FADE_VOL_MAX 64
+#define FADE_VOL_SHIFT 2
+
+struct MusicPlayerInfo
+{
+ struct SongHeader *songHeader;
+ u32 status;
+ u8 trackCount;
+ u8 priority;
+ u8 cmd;
+ u8 unk_B;
+ u32 clock;
+ u8 gap[8];
+ u8 *memAccArea;
+ u16 tempoD;
+ u16 tempoU;
+ u16 tempoI;
+ u16 tempoC;
+ u16 fadeOI;
+ u16 fadeOC;
+ u16 fadeOV;
+ struct MusicPlayerTrack *tracks;
+ struct ToneData *tone;
+ u32 ident;
+ u32 func;
+ u32 intp;
+};
+
+struct MusicPlayer
+{
+ struct MusicPlayerInfo *info;
+ struct MusicPlayerTrack *track;
+ u8 unk_8;
+ u16 unk_A;
+};
+
+struct Song
+{
+ struct SongHeader *header;
+ u16 ms;
+ u16 me;
+};
+
+extern const struct MusicPlayer gMPlayTable[];
+extern const struct Song gSongTable[];
+
+
+
+extern u8 gMPlayMemAccArea[];
+
+//u8 gPokemonCrySong[52];
+//u8 gPokemonCrySongs[52 * MAX_POKEMON_CRIES];
+
+#define MAX_POKEMON_CRIES 2
+
+extern struct PokemonCrySong gPokemonCrySong;
+extern struct PokemonCrySong gPokemonCrySongs[];
+
+extern struct MusicPlayerInfo gPokemonCryMusicPlayers[];
+extern struct MusicPlayerTrack gPokemonCryTracks[];
+
+extern char SoundMainRAM[];
+
+extern void *gMPlayJumpTable[];
+
+typedef void (*XcmdFunc)(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+extern const XcmdFunc gXcmdTable[];
+
+extern struct CgbChannel gCgbChans[];
+
+extern const u8 gScaleTable[];
+extern const u32 gFreqTable[];
+extern const u16 gPcmSamplesPerVBlankTable[];
+
+extern const u8 gCgbScaleTable[];
+extern const s16 gCgbFreqTable[];
+extern const u8 gNoiseTable[];
+
+extern const struct PokemonCrySong gPokemonCrySongTemplate;
+
+extern const struct ToneData voicegroup000;
+
+extern char gNumMusicPlayers[];
+extern char gMaxLines[];
+
+#define NUM_MUSIC_PLAYERS ((u16)gNumMusicPlayers)
+#define MAX_LINES ((u32)gMaxLines)
+
+u32 umul3232H32(u32 multiplier, u32 multiplicand);
+void SoundMain(void);
+void SoundMainBTM(void);
+void TrackStop(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track);
+void MPlayMain(void);
+void RealClearChain(void *x);
+
+void MPlayContinue(struct MusicPlayerInfo *mplayInfo);
+void MPlayStart(struct MusicPlayerInfo *mplayInfo, struct SongHeader *songHeader);
+void m4aMPlayStop(struct MusicPlayerInfo *mplayInfo);
+void FadeOutBody(struct MusicPlayerInfo *mplayInfo);
+void TrkVolPitSet(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track);
+void MPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed);
+void ClearChain(void *x);
+void Clear64byte(void *addr);
+void SoundInit(struct SoundInfo *soundInfo);
+void MPlayExtender(struct CgbChannel *cgbChans);
+void m4aSoundMode(u32 mode);
+void MPlayOpen(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track, u8 a3);
+void CgbSound(void);
+void CgbOscOff(u8);
+u32 MidiKeyToCgbFreq(u8, u8, u8);
+void DummyFunc(void);
+void MPlayJumpTableCopy(void **mplayJumpTable);
+void SampleFreqSet(u32 freq);
+void m4aSoundVSyncOn(void);
+void m4aSoundVSyncOff(void);
+
+void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo);
+void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume);
+void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch);
+void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan);
+void ClearModM(struct MusicPlayerTrack *track);
+void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth);
+void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed);
+
+struct MusicPlayerInfo *SetPokemonCryTone(struct ToneData *tone);
+void SetPokemonCryVolume(u8 val);
+void SetPokemonCryPanpot(s8 val);
+void SetPokemonCryPitch(s16 val);
+void SetPokemonCryLength(u16 val);
+void SetPokemonCryRelease(u8 val);
+void SetPokemonCryProgress(u32 val);
+int IsPokemonCryPlaying(struct MusicPlayerInfo *mplayInfo);
+void SetPokemonCryChorus(s8 val);
+void SetPokemonCryStereo(u32 val);
+void SetPokemonCryPriority(u8 val);
+
+// sound command handler functions
+void ply_fine(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_goto(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_patt(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_pend(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_rept(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_memacc(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_prio(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_tempo(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_keysh(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_voice(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_vol(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_pan(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_bend(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_bendr(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_lfos(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_lfodl(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_mod(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_modt(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_tune(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_port(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xcmd(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_endtie(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_note(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+
+// extended sound command handler functions
+void ply_xxx(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xwave(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xtype(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xatta(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xdeca(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xsust(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xrele(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xiecv(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xiecl(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xleng(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xswee(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xcmd_0C(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+void ply_xcmd_0D(struct MusicPlayerInfo *, struct MusicPlayerTrack *);
+
+#endif // GUARD_GBA_M4A_INTERNAL_H
diff --git a/berry_fix/payload/include/gba/macro.h b/berry_fix/payload/include/gba/macro.h
new file mode 100644
index 000000000..6f9c55f2e
--- /dev/null
+++ b/berry_fix/payload/include/gba/macro.h
@@ -0,0 +1,247 @@
+#ifndef GUARD_GBA_MACRO_H
+#define GUARD_GBA_MACRO_H
+
+#define CPU_FILL(value, dest, size, bit) \
+{ \
+ vu##bit tmp = (vu##bit)(value); \
+ CpuSet((void *)&tmp, \
+ dest, \
+ CPU_SET_##bit##BIT | CPU_SET_SRC_FIXED | ((size)/(bit/8) & 0x1FFFFF)); \
+}
+
+#define CpuFill16(value, dest, size) CPU_FILL(value, dest, size, 16)
+#define CpuFill32(value, dest, size) CPU_FILL(value, dest, size, 32)
+
+#define CPU_COPY(src, dest, size, bit) CpuSet(src, dest, CPU_SET_##bit##BIT | ((size)/(bit/8) & 0x1FFFFF))
+
+#define CpuCopy16(src, dest, size) CPU_COPY(src, dest, size, 16)
+#define CpuCopy32(src, dest, size) CPU_COPY(src, dest, size, 32)
+
+#define CpuFastFill(value, dest, size) \
+{ \
+ vu32 tmp = (vu32)(value); \
+ CpuFastSet((void *)&tmp, \
+ dest, \
+ CPU_FAST_SET_SRC_FIXED | ((size)/(32/8) & 0x1FFFFF)); \
+}
+
+#define CpuFastFill16(value, dest, size) CpuFastFill(((value) << 16) | (value), (dest), (size))
+
+#define CpuFastFill8(value, dest, size) CpuFastFill(((value) << 24) | ((value) << 16) | ((value) << 8) | (value), (dest), (size))
+
+#define CpuFastCopy(src, dest, size) CpuFastSet(src, dest, ((size)/(32/8) & 0x1FFFFF))
+
+#define DmaSet(dmaNum, src, dest, control) \
+{ \
+ vu32 *dmaRegs = (vu32 *)REG_ADDR_DMA##dmaNum; \
+ dmaRegs[0] = (vu32)(src); \
+ dmaRegs[1] = (vu32)(dest); \
+ dmaRegs[2] = (vu32)(control); \
+ dmaRegs[2]; \
+}
+
+#define DMA_FILL(dmaNum, value, dest, size, bit) \
+{ \
+ vu##bit tmp = (vu##bit)(value); \
+ DmaSet(dmaNum, \
+ &tmp, \
+ dest, \
+ (DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_FIXED | DMA_DEST_INC) << 16 \
+ | ((size)/(bit/8))); \
+}
+
+#define DmaFill16(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 16)
+#define DmaFill32(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 32)
+
+// Note that the DMA clear macros cause the DMA control value to be calculated
+// at runtime rather than compile time. The size is divided by the DMA transfer
+// unit size (2 or 4 bytes) and then combined with the DMA control flags using a
+// bitwise OR operation.
+
+#define DMA_CLEAR(dmaNum, dest, size, bit) \
+{ \
+ vu##bit *_dest = (vu##bit *)(dest); \
+ u32 _size = size; \
+ DmaFill##bit(dmaNum, 0, _dest, _size); \
+}
+
+#define DmaClear16(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 16)
+#define DmaClear32(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 32)
+
+#define DMA_COPY(dmaNum, src, dest, size, bit) \
+ DmaSet(dmaNum, \
+ src, \
+ dest, \
+ (DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_INC | DMA_DEST_INC) << 16 \
+ | ((size)/(bit/8)))
+
+#define DmaCopy16(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 16)
+#define DmaCopy32(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 32)
+
+#define DmaCopyLarge(dmaNum, src, dest, size, block, bit) \
+{ \
+ const void *_src = src; \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ DmaCopy##bit(dmaNum, _src, _dest, (block)); \
+ _src += (block); \
+ _dest += (block); \
+ _size -= (block); \
+ if (_size <= (block)) \
+ { \
+ DmaCopy##bit(dmaNum, _src, _dest, _size); \
+ break; \
+ } \
+ } \
+}
+
+#define DmaCopyLarge16(dmaNum, src, dest, size, block) DmaCopyLarge(dmaNum, src, dest, size, block, 16)
+
+#define DmaCopyLarge32(dmaNum, src, dest, size, block) DmaCopyLarge(dmaNum, src, dest, size, block, 32)
+
+#define DmaFillLarge(dmaNum, value, dest, size, block, bit) \
+{ \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ DmaFill##bit(dmaNum, value, _dest, (block)); \
+ _dest += (block); \
+ _size -= (block); \
+ if (_size <= (block)) \
+ { \
+ DmaFill##bit(dmaNum, value, _dest, _size); \
+ break; \
+ } \
+ } \
+}
+
+#define DmaFillLarge16(dmaNum, value, dest, size, block) DmaFillLarge(dmaNum, value, dest, size, block, 16)
+
+#define DmaFillLarge32(dmaNum, value, dest, size, block) DmaFillLarge(dmaNum, value, dest, size, block, 32)
+
+#define DmaClearLarge(dmaNum, dest, size, block, bit) \
+{ \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ DmaFill##bit(dmaNum, 0, _dest, (block)); \
+ _dest += (block); \
+ _size -= (block); \
+ if (_size <= (block)) \
+ { \
+ DmaFill##bit(dmaNum, 0, _dest, _size); \
+ break; \
+ } \
+ } \
+}
+
+#define DmaClearLarge16(dmaNum, dest, size, block) DmaClearLarge(dmaNum, dest, size, block, 16)
+
+#define DmaClearLarge32(dmaNum, dest, size, block) DmaClearLarge(dmaNum, dest, size, block, 32)
+
+#define DmaCopyDefvars(dmaNum, src, dest, size, bit) \
+{ \
+ const void *_src = src; \
+ void *_dest = (void *)(dest); \
+ u32 _size = size; \
+ DmaCopy##bit(dmaNum, _src, _dest, _size); \
+}
+
+#define DmaCopy16Defvars(dmaNum, src, dest, size) DmaCopyDefvars(dmaNum, src, dest, size, 16)
+#define DmaCopy32Defvars(dmaNum, src, dest, size) DmaCopyDefvars(dmaNum, src, dest, size, 32)
+
+#define DmaFillDefvars(dmaNum, value, dest, size, bit) \
+{ \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ DmaFill##bit(dmaNum, value, _dest, _size); \
+}
+
+#define DmaFill16Defvars(dmaNum, value, dest, size) DmaFillDefvars(dmaNum, value, dest, size, 16)
+#define DmaFill32Defvars(dmaNum, value, dest, size) DmaFillDefvars(dmaNum, value, dest, size, 32)
+
+#define DmaClearDefvars(dmaNum, dest, size, bit) \
+{ \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ DmaClear##bit(dmaNum, _dest, _size); \
+}
+
+#define DmaClear16Defvars(dmaNum, dest, size) DmaClearDefvars(dmaNum, dest, size, 16)
+#define DmaClear32Defvars(dmaNum, dest, size) DmaClearDefvars(dmaNum, dest, size, 32)
+
+#define DmaStop(dmaNum) \
+{ \
+ vu16 *dmaRegs = (vu16 *)REG_ADDR_DMA##dmaNum; \
+ dmaRegs[5] &= ~(DMA_START_MASK | DMA_DREQ_ON | DMA_REPEAT); \
+ dmaRegs[5] &= ~DMA_ENABLE; \
+ dmaRegs[5]; \
+}
+
+#define IntrEnable(flags) \
+{ \
+ u16 imeTemp; \
+ \
+ imeTemp = REG_IME; \
+ REG_IME = 0; \
+ REG_IE |= flags; \
+ REG_IME = imeTemp; \
+} \
+// from pokeemerald
+// Maximum amount of data we will transfer in one operation
+#define MAX_DMA_BLOCK_SIZE 0x1000
+
+#define MAX_DMA_REQUESTS 128
+
+#define DMA_REQUEST_COPY32 1
+#define DMA_REQUEST_FILL32 2
+#define DMA_REQUEST_COPY16 3
+#define DMA_REQUEST_FILL16 4
+
+#define Dma3CopyLarge_(src, dest, size, bit) \
+{ \
+ const void *_src = src; \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ if (_size <= MAX_DMA_BLOCK_SIZE) \
+ { \
+ DmaCopy##bit(3, _src, _dest, _size); \
+ break; \
+ } \
+ DmaCopy##bit(3, _src, _dest, MAX_DMA_BLOCK_SIZE); \
+ _src += MAX_DMA_BLOCK_SIZE; \
+ _dest += MAX_DMA_BLOCK_SIZE; \
+ _size -= MAX_DMA_BLOCK_SIZE; \
+ } \
+}
+
+#define Dma3CopyLarge16_(src, dest, size) Dma3CopyLarge_(src, dest, size, 16)
+#define Dma3CopyLarge32_(src, dest, size) Dma3CopyLarge_(src, dest, size, 32)
+
+#define Dma3FillLarge_(value, dest, size, bit) \
+{ \
+ void *_dest = (void *)dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ if (_size <= MAX_DMA_BLOCK_SIZE) \
+ { \
+ DmaFill##bit(3, value, _dest, _size); \
+ break; \
+ } \
+ DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
+ _dest += MAX_DMA_BLOCK_SIZE; \
+ _size -= MAX_DMA_BLOCK_SIZE; \
+ } \
+}
+
+#define Dma3FillLarge16_(value, dest, size) Dma3FillLarge_(value, dest, size, 16)
+#define Dma3FillLarge32_(value, dest, size) Dma3FillLarge_(value, dest, size, 32)
+
+#endif // GUARD_GBA_MACRO_H
diff --git a/berry_fix/payload/include/gba/multiboot.h b/berry_fix/payload/include/gba/multiboot.h
new file mode 100644
index 000000000..14b6594b2
--- /dev/null
+++ b/berry_fix/payload/include/gba/multiboot.h
@@ -0,0 +1,55 @@
+#ifndef GUARD_GBA_MULTIBOOT_H
+#define GUARD_GBA_MULTIBOOT_H
+
+#define MULTIBOOT_NCHILD 3 // Maximum number of slaves
+#define MULTIBOOT_HEADER_SIZE 0xc0 // Header size
+#define MULTIBOOT_SEND_SIZE_MIN 0x100 // Minimum transmission size
+#define MULTIBOOT_SEND_SIZE_MAX 0x40000 // Maximum transmission size
+
+struct MultiBootParam
+{
+ u32 system_work[5]; // 00
+ u8 handshake_data; // 14
+ u8 padding; // 15
+ u16 handshake_timeout; // 16
+ u8 probe_count; // 18
+ u8 client_data[MULTIBOOT_NCHILD]; // 19
+ u8 palette_data; // 1c
+ u8 response_bit; // 1d
+ u8 client_bit; // 1e
+ u8 reserved1; // 1f
+ const u8 *boot_srcp; // 20
+ const u8 *boot_endp; // 24
+ const u8 *masterp;
+ u8 *reserved2[MULTIBOOT_NCHILD];
+ u32 system_work2[4];
+ u8 sendflag;
+ u8 probe_target_bit;
+ u8 check_wait;
+ u8 server_type;
+};
+
+#define MULTIBOOT_ERROR_04 0x04
+#define MULTIBOOT_ERROR_08 0x08
+#define MULTIBOOT_ERROR_0c 0x0c
+#define MULTIBOOT_ERROR_40 0x40
+#define MULTIBOOT_ERROR_44 0x44
+#define MULTIBOOT_ERROR_48 0x48
+#define MULTIBOOT_ERROR_4c 0x4c
+#define MULTIBOOT_ERROR_80 0x80
+#define MULTIBOOT_ERROR_84 0x84
+#define MULTIBOOT_ERROR_88 0x88
+#define MULTIBOOT_ERROR_8c 0x8c
+#define MULTIBOOT_ERROR_NO_PROBE_TARGET 0x50
+#define MULTIBOOT_ERROR_NO_DLREADY 0x60
+#define MULTIBOOT_ERROR_BOOT_FAILURE 0x70
+#define MULTIBOOT_ERROR_HANDSHAKE_FAILURE 0x71
+
+#define MULTIBOOT_CONNECTION_CHECK_WAIT 15
+
+#define MULTIBOOT_SERVER_TYPE_NORMAL 0
+#define MULTIBOOT_SERVER_TYPE_QUICK 1
+
+#define MULTIBOOT_HANDSHAKE_TIMEOUT 400
+
+#endif // GUARD_GBA_MULTIBOOT_H
diff --git a/berry_fix/payload/include/gba/syscall.h b/berry_fix/payload/include/gba/syscall.h
new file mode 100644
index 000000000..eb1bd4e20
--- /dev/null
+++ b/berry_fix/payload/include/gba/syscall.h
@@ -0,0 +1,57 @@
+#ifndef GUARD_GBA_SYSCALL_H
+#define GUARD_GBA_SYSCALL_H
+
+#include "gba/types.h"
+
+#define RESET_EWRAM 0x01
+#define RESET_IWRAM 0x02
+#define RESET_PALETTE 0x04
+#define RESET_VRAM 0x08
+#define RESET_OAM 0x10
+#define RESET_SIO_REGS 0x20
+#define RESET_SOUND_REGS 0x40
+#define RESET_REGS 0x80
+#define RESET_ALL 0xFF
+
+void SoftReset(u32 resetFlags);
+
+void RegisterRamReset(u32 resetFlags);
+
+void VBlankIntrWait(void);
+
+u16 Sqrt(u32 num);
+
+u16 ArcTan2(s16 x, s16 y);
+
+#define CPU_SET_SRC_FIXED 0x01000000
+#define CPU_SET_16BIT 0x00000000
+#define CPU_SET_32BIT 0x04000000
+
+void CpuSet(const void *src, void *dest, u32 control);
+
+#define CPU_FAST_SET_SRC_FIXED 0x01000000
+
+void CpuFastSet(const void *src, void *dest, u32 control);
+
+void BgAffineSet(struct BgAffineSrcData *src, struct BgAffineDstData *dest, s32 count);
+
+void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset);
+
+void LZ77UnCompWram(const void *src, void *dest);
+
+void LZ77UnCompVram(const void *src, void *dest);
+
+void RLUnCompWram(const void *src, void *dest);
+
+void RLUnCompVram(const void *src, void *dest);
+
+int MultiBoot(struct MultiBootParam *mp);
+
+void SoundBiasReset(void);
+
+void SoundBiasSet(void);
+
+u32 Div(u32 divisor, u32 dividend);
+u32 Mod(u32 divisor, u32 dividend);
+
+#endif // GUARD_GBA_SYSCALL_H
diff --git a/berry_fix/payload/include/gba/types.h b/berry_fix/payload/include/gba/types.h
new file mode 100644
index 000000000..e919abc22
--- /dev/null
+++ b/berry_fix/payload/include/gba/types.h
@@ -0,0 +1,146 @@
+#ifndef GUARD_GBA_TYPES_H
+#define GUARD_GBA_TYPES_H
+
+#include <stdint.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+typedef volatile u8 vu8;
+typedef volatile u16 vu16;
+typedef volatile u32 vu32;
+typedef volatile u64 vu64;
+typedef volatile s8 vs8;
+typedef volatile s16 vs16;
+typedef volatile s32 vs32;
+typedef volatile s64 vs64;
+
+typedef float f32;
+typedef double f64;
+
+typedef u8 bool8;
+typedef u16 bool16;
+typedef u32 bool32;
+
+struct BgCnt
+{
+ u16 priority:2;
+ u16 charBaseBlock:2;
+ u16 dummy:2;
+ u16 mosaic:1;
+ u16 palettes:1;
+ u16 screenBaseBlock:5;
+ u16 areaOverflowMode:1;
+ u16 screenSize:2;
+};
+typedef volatile struct BgCnt vBgCnt;
+
+struct PlttData
+{
+ u16 r:5; // red
+ u16 g:5; // green
+ u16 b:5; // blue
+ u16 unused_15:1;
+};
+
+struct OamData
+{
+ /*0x00*/ u32 y:8;
+ /*0x01*/ u32 affineMode:2; // 0x1, 0x2 -> 0x4
+ u32 objMode:2; // 0x4, 0x8 -> 0xC
+ u32 mosaic:1; // 0x10
+ u32 bpp:1; // 0x20
+ u32 shape:2; // 0x40, 0x80 -> 0xC0
+
+ /*0x02*/ u32 x:9;
+ u32 matrixNum:5; // bits 3/4 are h-flip/v-flip if not in affine mode
+ u32 size:2;
+
+ /*0x04*/ u16 tileNum:10; // 0x3FF
+ u16 priority:2; // 0x400, 0x800 -> 0xC00
+ u16 paletteNum:4;
+ /*0x06*/ u16 affineParam;
+};
+
+#define ST_OAM_OBJ_NORMAL 0
+#define ST_OAM_OBJ_BLEND 1
+#define ST_OAM_OBJ_WINDOW 2
+
+#define ST_OAM_AFFINE_OFF 0
+#define ST_OAM_AFFINE_NORMAL 1
+#define ST_OAM_AFFINE_ERASE 2
+#define ST_OAM_AFFINE_DOUBLE 3
+
+#define ST_OAM_AFFINE_ON_MASK 1
+#define ST_OAM_AFFINE_DOUBLE_MASK 2
+
+#define ST_OAM_4BPP 0
+#define ST_OAM_8BPP 1
+
+#define ST_OAM_SQUARE 0
+#define ST_OAM_H_RECTANGLE 1
+#define ST_OAM_V_RECTANGLE 2
+
+struct BgAffineSrcData
+{
+ s32 texX;
+ s32 texY;
+ s16 scrX;
+ s16 scrY;
+ s16 sx;
+ s16 sy;
+ u16 alpha;
+};
+
+struct BgAffineDstData
+{
+ s16 pa;
+ s16 pb;
+ s16 pc;
+ s16 pd;
+ s32 dx;
+ s32 dy;
+};
+
+struct ObjAffineSrcData
+{
+ s16 xScale;
+ s16 yScale;
+ u16 rotation;
+};
+
+// Multi-player SIO Control Structure
+struct SioMultiCnt
+{
+ u16 baudRate:2; // baud rate
+ u16 si:1; // SI terminal
+ u16 sd:1; // SD terminal
+ u16 id:2; // ID
+ u16 error:1; // error flag
+ u16 enable:1; // SIO enable
+ u16 unused_11_8:4;
+ u16 mode:2; // communication mode (should equal 2)
+ u16 intrEnable:1; // IRQ enable
+ u16 unused_15:1;
+ u16 data; // data
+};
+
+#define ST_SIO_MULTI_MODE 2 // Multi-player communication mode
+
+// baud rate
+#define ST_SIO_9600_BPS 0 // 9600 bps
+#define ST_SIO_38400_BPS 1 // 38400 bps
+#define ST_SIO_57600_BPS 2 // 57600 bps
+#define ST_SIO_115200_BPS 3 // 115200 bps
+
+typedef void (*MainCallback)(void);
+typedef void (*IntrCallback)(void);
+typedef void (*IntrFunc)(void);
+
+#endif // GUARD_GBA_TYPES_H
diff --git a/berry_fix/payload/include/global.berry.h b/berry_fix/payload/include/global.berry.h
new file mode 100644
index 000000000..8f185c8f9
--- /dev/null
+++ b/berry_fix/payload/include/global.berry.h
@@ -0,0 +1,62 @@
+#ifndef GUARD_GLOBAL_BERRY_H
+#define GUARD_GLOBAL_BERRY_H
+
+struct Berry
+{
+ /*0x00*/ u8 name[7];
+ /*0x07*/ u8 firmness;
+ /*0x08*/ u16 size;
+ /*0x0A*/ u8 maxYield;
+ /*0x0B*/ u8 minYield;
+ /*0x0C*/ const u8 *description1;
+ /*0x10*/ const u8 *description2;
+ /*0x14*/ u8 stageDuration;
+ /*0x15*/ u8 spicy;
+ /*0x16*/ u8 dry;
+ /*0x17*/ u8 sweet;
+ /*0x18*/ u8 bitter;
+ /*0x19*/ u8 sour;
+ /*0x1A*/ u8 smoothness;
+};
+
+struct EnigmaBerry
+{
+ /*0x000*/ struct Berry berry;
+ /*0x01B*/ u8 pic[(6 * 6) * TILE_SIZE_4BPP];
+ /*0x49C*/ u16 palette[16];
+ /*0x4BC*/ u8 description1[45];
+ /*0x4E9*/ u8 description2[45];
+ /*0x516*/ u8 itemEffect[18];
+ /*0x528*/ u8 holdEffect;
+ /*0x529*/ u8 holdEffectParam;
+ /*0x52C*/ u32 checksum;
+};
+
+struct BattleEnigmaBerry
+{
+ /*0x00*/ u8 name[7];
+ /*0x07*/ u8 holdEffect;
+ /*0x08*/ u8 itemEffect[18];
+ /*0x1A*/ u8 holdEffectParam;
+};
+
+struct BerryTree
+{
+ /*0x00*/ u8 berry;
+ /*0x01*/ u8 stage:7;
+ /*
+ A berry sparkle is a state that a berry tree
+ can be in after growing within the player's
+ viewport.
+ */
+ /*0x01*/ bool8 growthSparkle:1;
+ /*0x02*/ u16 minutesUntilNextStage;
+ /*0x04*/ u8 berryYield;
+ /*0x05*/ u8 regrowthCount:4;
+ /*0x05*/ u8 watered1:1;
+ /*0x05*/ u8 watered2:1;
+ /*0x05*/ u8 watered3:1;
+ /*0x05*/ u8 watered4:1;
+};
+
+#endif // GUARD_GLOBAL_BERRY_H
diff --git a/berry_fix/payload/include/global.fieldmap.h b/berry_fix/payload/include/global.fieldmap.h
new file mode 100644
index 000000000..f876e5a56
--- /dev/null
+++ b/berry_fix/payload/include/global.fieldmap.h
@@ -0,0 +1,317 @@
+#ifndef GUARD_GLOBAL_FIELDMAP_H
+#define GUARD_GLOBAL_FIELDMAP_H
+
+enum
+{
+ CONNECTION_SOUTH = 1,
+ CONNECTION_NORTH,
+ CONNECTION_WEST,
+ CONNECTION_EAST,
+ CONNECTION_DIVE,
+ CONNECTION_EMERGE
+};
+
+typedef void (*TilesetCB)(void);
+
+struct Tileset
+{
+ /*0x00*/ bool8 isCompressed;
+ /*0x01*/ bool8 isSecondary;
+ /*0x04*/ void *tiles;
+ /*0x08*/ void *palettes;
+ /*0x0c*/ void *metatiles;
+ /*0x10*/ void *metatileAttributes;
+ /*0x14*/ TilesetCB callback;
+};
+
+struct MapLayout
+{
+ /*0x00*/ s32 width;
+ /*0x04*/ s32 height;
+ /*0x08*/ u16 *border;
+ /*0x0c*/ u16 *map;
+ /*0x10*/ struct Tileset *primaryTileset;
+ /*0x14*/ struct Tileset *secondaryTileset;
+};
+
+struct BackupMapLayout
+{
+ s32 width;
+ s32 height;
+ u16 *map;
+};
+
+struct EventObjectTemplate
+{
+ /*0x00*/ u8 localId;
+ /*0x01*/ u8 graphicsId;
+ /*0x02*/ u8 unk2;
+ /*0x04*/ s16 x;
+ /*0x06*/ s16 y;
+ /*0x08*/ u8 elevation;
+ /*0x09*/ u8 movementType;
+ /*0x0A*/ u8 movementRangeX:4;
+ u8 movementRangeY:4;
+ /*0x0C*/ u16 trainerType;
+ /*0x0E*/ u16 trainerRange_berryTreeId;
+ /*0x10*/ u8 *script;
+ /*0x14*/ u16 flagId;
+};
+
+struct WarpEvent
+{
+ s16 x, y;
+ u8 elevation;
+ u8 warpId;
+ u8 mapNum;
+ u8 mapGroup;
+};
+
+struct CoordEvent
+{
+ s16 x, y;
+ u8 elevation;
+ u16 trigger;
+ u16 index;
+ u8 filler_A[0x2];
+ u8 *script;
+};
+
+struct BgEvent
+{
+ /*0x00*/u16 x;
+ /*0x02*/u16 y;
+ /*0x04*/u8 elevation;
+ /*0x05*/u8 kind;
+ /*0x08*/union { // carried over from diego's FR/LG work, seems to be the same struct
+ // in gen 3, "kind" (0x3 in BgEvent struct) determines the method to read the union.
+ u8 *script;
+
+ // hidden item type
+ struct {
+ u16 item;
+ u16 hiddenItemId; // flag offset to determine flag lookup
+ } hiddenItem;
+
+ // secret base type
+ u32 secretBaseId;
+
+ } bgUnion;
+};
+
+struct MapEvents
+{
+ u8 eventObjectCount;
+ u8 warpCount;
+ u8 coordEventCount;
+ u8 bgEventCount;
+
+ struct EventObjectTemplate *eventObjects;
+ struct WarpEvent *warps;
+ struct CoordEvent *coordEvents;
+ struct BgEvent *bgEvents;
+};
+
+struct MapConnection
+{
+ /*0x00*/ u8 direction;
+ /*0x01*/ u32 offset;
+ /*0x05*/ u8 mapGroup;
+ /*0x06*/ u8 mapNum;
+};
+
+struct MapConnections
+{
+ s32 count;
+ struct MapConnection *connections;
+};
+
+struct MapHeader
+{
+ /* 0x00 */ struct MapLayout *mapLayout;
+ /* 0x04 */ struct MapEvents *events;
+ /* 0x08 */ u8 *mapScripts;
+ /* 0x0C */ struct MapConnections *connections;
+ /* 0x10 */ u16 music;
+ /* 0x12 */ u16 mapLayoutId;
+ /* 0x14 */ u8 regionMapSectionId;
+ /* 0x15 */ u8 cave;
+ /* 0x16 */ u8 weather;
+ /* 0x17 */ u8 mapType;
+ /* 0x18 */ u8 filler_18;
+ /* 0x19 */ u8 escapeRope;
+ /* 0x1A */ u8 flags;
+ /* 0x1B */ u8 battleType;
+};
+
+struct EventObject
+{
+ /*0x00*/ u32 active:1;
+ u32 singleMovementActive:1;
+ u32 triggerGroundEffectsOnMove:1;
+ u32 triggerGroundEffectsOnStop:1;
+ u32 disableCoveringGroundEffects:1; // disables ground effects that cover parts of the object's sprite
+ u32 landingJump:1;
+ u32 heldMovementActive:1;
+ u32 heldMovementFinished:1;
+ /*0x01*/ u32 frozen:1;
+ u32 facingDirectionLocked:1;
+ u32 disableAnim:1; // used to disable forced movement sliding animations (like on ice)
+ u32 enableAnim:1;
+ u32 inanimate:1;
+ u32 invisible:1;
+ u32 offScreen:1;
+ u32 trackedByCamera:1; // only set for the player object
+ /*0x02*/ u32 isPlayer:1;
+ u32 hasReflection:1;
+ u32 inShortGrass:1;
+ u32 inShallowFlowingWater:1;
+ u32 inSandPile:1;
+ u32 inHotSprings:1;
+ u32 hasShadow:1;
+ u32 spriteAnimPausedBackup:1;
+ /*0x03*/ u32 spriteAffineAnimPausedBackup:1;
+ u32 disableJumpLandingGroundEffect:1;
+ u32 fixedPriority:1;
+ /*0x04*/ u8 spriteId;
+ /*0x05*/ u8 graphicsId;
+ /*0x06*/ u8 movementType;
+ /*0x07*/ u8 trainerType;
+ /*0x08*/ u8 localId;
+ /*0x09*/ u8 mapNum;
+ /*0x0A*/ u8 mapGroup;
+ /*0x0B*/ u8 currentElevation:4;
+ u8 previousElevation:4;
+ /*0x0C*/ struct Coords16 initialCoords;
+ /*0x10*/ struct Coords16 currentCoords;
+ /*0x14*/ struct Coords16 previousCoords;
+ /*0x18*/ u8 facingDirection:4;
+ /*0x18*/ u8 movementDirection:4;
+ /*0x19*/ union __attribute__((packed)) {
+ u8 as_byte;
+ struct __attribute__((packed)) {
+ u16 x:4;
+ u16 y:4;
+ } as_nybbles;
+ } range;
+ /*0x1A*/ u8 fieldEffectSpriteId;
+ /*0x1B*/ u8 warpArrowSpriteId;
+ /*0x1C*/ u8 movementActionId;
+ /*0x1D*/ u8 trainerRange_berryTreeId;
+ /*0x1E*/ u8 currentMetatileBehavior;
+ /*0x1F*/ u8 previousMetatileBehavior;
+ /*0x20*/ u8 previousMovementDirection;
+ /*0x21*/ u8 directionSequenceIndex;
+ /*0x22*/ u8 playerCopyableMovement; // used as an index to gCopyPlayerMovementFuncs for the "copy player" movement types
+ /*size = 0x24*/
+};
+
+struct EventObjectGraphicsInfo
+{
+ /*0x00*/ u16 tileTag;
+ /*0x02*/ u16 paletteTag;
+ /*0x04*/ u16 bridgeReflectionPaletteTag;
+ /*0x06*/ u16 size;
+ /*0x08*/ s16 width;
+ /*0x0A*/ s16 height;
+ /*0x0C*/ u8 paletteSlot:4;
+ u8 shadowSize:2;
+ u8 inanimate:1;
+ u8 disableReflectionPaletteLoad:1;
+ /*0x0D*/ u8 tracks;
+ /*0x10*/ const struct OamData *oam;
+ /*0x14*/ const struct SubspriteTable *subspriteTables;
+ /*0x18*/ const union AnimCmd *const *anims;
+ /*0x1C*/ const struct SpriteFrameImage *images;
+ /*0x20*/ const union AffineAnimCmd *const *affineAnims;
+};
+
+#define PLAYER_AVATAR_FLAG_ON_FOOT (1 << 0)
+#define PLAYER_AVATAR_FLAG_MACH_BIKE (1 << 1)
+#define PLAYER_AVATAR_FLAG_ACRO_BIKE (1 << 2)
+#define PLAYER_AVATAR_FLAG_SURFING (1 << 3)
+#define PLAYER_AVATAR_FLAG_UNDERWATER (1 << 4)
+#define PLAYER_AVATAR_FLAG_5 (1 << 5)
+#define PLAYER_AVATAR_FLAG_6 (1 << 6)
+#define PLAYER_AVATAR_FLAG_DASH (1 << 7)
+
+enum
+{
+ ACRO_BIKE_NORMAL,
+ ACRO_BIKE_TURNING,
+ ACRO_BIKE_WHEELIE_STANDING,
+ ACRO_BIKE_BUNNY_HOP,
+ ACRO_BIKE_WHEELIE_MOVING,
+ ACRO_BIKE_STATE5,
+ ACRO_BIKE_STATE6,
+};
+
+enum
+{
+ DIR_NONE,
+ DIR_SOUTH,
+ DIR_NORTH,
+ DIR_WEST,
+ DIR_EAST,
+ DIR_SOUTHWEST,
+ DIR_SOUTHEAST,
+ DIR_NORTHWEST,
+ DIR_NORTHEAST,
+};
+
+enum
+{
+ COLLISION_LEDGE_JUMP = 6
+};
+
+// player running states
+enum
+{
+ NOT_MOVING,
+ TURN_DIRECTION, // not the same as turning! turns your avatar without moving. also known as a turn frame in some circles
+ MOVING,
+};
+
+// player tile transition states
+enum
+{
+ T_NOT_MOVING,
+ T_TILE_TRANSITION,
+ T_TILE_CENTER, // player is on a frame in which they are centered on a tile during which the player either stops or keeps their momentum and keeps going, changing direction if necessary.
+};
+
+struct PlayerAvatar /* 0x202E858 */
+{
+ /*0x00*/ u8 flags;
+ /*0x01*/ u8 unk1; // used to be named bike, but its definitely not that. seems to be some transition flags
+ /*0x02*/ u8 runningState; // this is a static running state. 00 is not moving, 01 is turn direction, 02 is moving.
+ /*0x03*/ u8 tileTransitionState; // this is a transition running state: 00 is not moving, 01 is transition between tiles, 02 means you are on the frame in which you have centered on a tile but are about to keep moving, even if changing directions. 2 is also used for a ledge hop, since you are transitioning.
+ /*0x04*/ u8 spriteId;
+ /*0x05*/ u8 eventObjectId;
+ /*0x06*/ bool8 preventStep;
+ /*0x07*/ u8 gender;
+ /*0x08*/ u8 acroBikeState; // 00 is normal, 01 is turning, 02 is standing wheelie, 03 is hopping wheelie
+ /*0x09*/ u8 newDirBackup; // during bike movement, the new direction as opposed to player's direction is backed up here.
+ /*0x0A*/ u8 bikeFrameCounter; // on the mach bike, when this value is 1, the bike is moving but not accelerating yet for 1 tile. on the acro bike, this acts as a timer for acro bike.
+ /*0x0B*/ u8 bikeSpeed;
+ // acro bike only
+ /*0x0C*/ u32 directionHistory; // up/down/left/right history is stored in each nybble, but using the field directions and not the io inputs.
+ /*0x10*/ u32 abStartSelectHistory; // same as above but for A + B + start + select only
+ // these two are timer history arrays which [0] is the active timer for acro bike. every element is backed up to the next element upon update.
+ /*0x14*/ u8 dirTimerHistory[8];
+ /*0x1C*/ u8 abStartSelectTimerHistory[8];
+};
+
+struct Camera
+{
+ bool8 active:1;
+ s32 x;
+ s32 y;
+};
+
+extern struct EventObject gMapObjects[];
+extern u8 gSelectedEventObject;
+extern struct MapHeader gMapHeader;
+extern struct PlayerAvatar gPlayerAvatar;
+
+#endif // GUARD_GLOBAL_FIELDMAP_H
diff --git a/berry_fix/payload/include/global.h b/berry_fix/payload/include/global.h
new file mode 100644
index 000000000..c218b5f4e
--- /dev/null
+++ b/berry_fix/payload/include/global.h
@@ -0,0 +1,875 @@
+#ifndef GUARD_GLOBAL_H
+#define GUARD_GLOBAL_H
+
+#include "gba/gba.h"
+
+// global.h from pokemon ruby
+
+// IDE support
+#if defined(__APPLE__) || defined(__CYGWIN__)
+#define _(x) x
+#define __(x) x
+#define INCBIN(x) {0}
+#define INCBIN_U8 INCBIN
+#define INCBIN_U16 INCBIN
+#define INCBIN_U32 INCBIN
+#define INCBIN_S8 INCBIN
+#define INCBIN_S16 INCBIN
+#define INCBIN_S32 INCBIN
+#endif
+
+// Prevent cross-jump optimization.
+#define BLOCK_CROSS_JUMP asm("");
+
+// to help in decompiling
+#define asm_comment(x) asm volatile("@ -- " x " -- ")
+
+#define asm_unified(x) asm(".syntax unified\n" x "\n.syntax divided\n")
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof((array)[0]))
+
+
+#define POKEMON_SLOTS_NUMBER 412
+#define POKEMON_NAME_LENGTH 10
+#define OT_NAME_LENGTH 7
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+
+// why does GF hate 2d arrays
+#define MULTI_DIM_ARR(x, dim, y) ((x) * dim + (y))
+
+// dim access enums
+enum
+{
+ B_8 = 1,
+ B_16 = 2,
+ B_32 = 4
+};
+
+// There are many quirks in the source code which have overarching behavioral differences from
+// a number of other files. For example, diploma.c seems to declare rodata before each use while
+// other files declare out of order and must be at the beginning. There are also a number of
+// macros which differ from one file to the next due to the method of obtaining the result, such
+// as these below. Because of this, there is a theory (Two Team Theory) that states that these
+// programming projects had more than 1 "programming team" which utilized different macros for
+// each of the files that were worked on.
+#define T1_READ_8(ptr) ((ptr)[0])
+#define T1_READ_16(ptr) ((ptr)[0] | ((ptr)[1] << 8))
+#define T1_READ_32(ptr) ((ptr)[0] | ((ptr)[1] << 8) | ((ptr)[2] << 16) | ((ptr)[3] << 24))
+#define T1_READ_PTR(ptr) (u8*) T1_READ_32(ptr)
+
+// T2_READ_8 is a duplicate to remain consistent with each group.
+#define T2_READ_8(ptr) ((ptr)[0])
+#define T2_READ_16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
+#define T2_READ_32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
+#define T2_READ_PTR(ptr) (void*) T2_READ_32(ptr)
+
+// Credits to Made (dolphin emoji)
+#define S16TOPOSFLOAT(val) \
+({ \
+ s16 v = (val); \
+ float f = (float)v; \
+ if(v < 0) f += 65536.0f; \
+ f; \
+})
+
+enum
+{
+ VERSION_SAPPHIRE = 1,
+ VERSION_RUBY = 2,
+ VERSION_EMERALD = 3,
+};
+
+enum LanguageId
+{
+ LANGUAGE_JAPANESE = 1,
+ LANGUAGE_ENGLISH = 2,
+ LANGUAGE_GERMAN = 5,
+};
+
+// capacities of various saveblock objects
+#define DAYCARE_MON_COUNT 2
+#define POKEBLOCKS_COUNT 40
+#define PARTY_SIZE 6
+#define EVENT_OBJECTS_COUNT 16
+#define BERRY_TREES_COUNT 128
+#define FLAGS_COUNT 288
+#define VARS_COUNT 256
+#define MAIL_COUNT 16
+#define SECRET_BASES_COUNT 20
+#define TV_SHOWS_COUNT 25
+#define POKE_NEWS_COUNT 16
+#define PC_ITEMS_COUNT 50
+#define BAG_ITEMS_COUNT 20
+#define BAG_KEYITEMS_COUNT 20
+#define BAG_POKEBALLS_COUNT 16
+#define BAG_TMHM_COUNT 64
+#define BAG_BERRIES_COUNT 46
+
+enum
+{
+ MALE,
+ FEMALE
+};
+
+enum
+{
+ OPTIONS_BUTTON_MODE_NORMAL,
+ OPTIONS_BUTTON_MODE_LR,
+ OPTIONS_BUTTON_MODE_L_EQUALS_A
+};
+
+enum
+{
+ OPTIONS_TEXT_SPEED_SLOW,
+ OPTIONS_TEXT_SPEED_MID,
+ OPTIONS_TEXT_SPEED_FAST
+};
+
+enum
+{
+ OPTIONS_SOUND_MONO,
+ OPTIONS_SOUND_STEREO
+};
+
+enum
+{
+ OPTIONS_BATTLE_STYLE_SHIFT,
+ OPTIONS_BATTLE_STYLE_SET
+};
+
+enum
+{
+ BAG_ITEMS = 1,
+ BAG_POKEBALLS,
+ BAG_TMsHMs,
+ BAG_BERRIES,
+ BAG_KEYITEMS
+};
+
+struct Coords16
+{
+ s16 x;
+ s16 y;
+};
+
+struct UCoords16
+{
+ u16 x;
+ u16 y;
+};
+
+struct SecretBaseRecord
+{
+ /*0x1A08*/ u8 secretBaseId;
+ /*0x1A09*/ u8 sbr_field_1_0:4;
+ /*0x1A09*/ u8 gender:1;
+ /*0x1A09*/ u8 sbr_field_1_5:1;
+ /*0x1A09*/ u8 sbr_field_1_6:2;
+ /*0x1A0A*/ u8 playerName[OT_NAME_LENGTH];
+ /*0x1A11*/ u8 trainerId[4]; // byte 0 is used for determining trainer class
+ /*0x1A16*/ u16 sbr_field_e;
+ /*0x1A18*/ u8 sbr_field_10;
+ /*0x1A19*/ u8 sbr_field_11;
+ /*0x1A1A*/ u8 decorations[16];
+ /*0x1A2A*/ u8 decorationPos[16];
+ /*0x1A3C*/ u32 partyPersonality[6];
+ /*0x1A54*/ u16 partyMoves[6 * 4];
+ /*0x1A84*/ u16 partySpecies[6];
+ /*0x1A90*/ u16 partyHeldItems[6];
+ /*0x1A9C*/ u8 partyLevels[6];
+ /*0x1AA2*/ u8 partyEVs[6];
+};
+
+#include "constants/game_stat.h"
+#include "global.fieldmap.h"
+#include "global.berry.h"
+#include "pokemon.h"
+
+struct WarpData
+{
+ s8 mapGroup;
+ s8 mapNum;
+ s8 warpId;
+ s16 x, y;
+};
+
+struct ItemSlot
+{
+ u16 itemId;
+ u16 quantity;
+};
+
+struct Pokeblock
+{
+ u8 color;
+ u8 spicy;
+ u8 dry;
+ u8 sweet;
+ u8 bitter;
+ u8 sour;
+ u8 feel;
+};
+
+struct Roamer
+{
+ /*0x00*/ u32 ivs;
+ /*0x04*/ u32 personality;
+ /*0x08*/ u16 species;
+ /*0x0A*/ u16 hp;
+ /*0x0C*/ u8 level;
+ /*0x0D*/ u8 status;
+ /*0x0E*/ u8 cool;
+ /*0x0F*/ u8 beauty;
+ /*0x10*/ u8 cute;
+ /*0x11*/ u8 smart;
+ /*0x12*/ u8 tough;
+ /*0x13*/ bool8 active;
+ /*0x14*/ u8 filler[0x8];
+};
+
+struct RamScriptData
+{
+ u8 magic;
+ u8 mapGroup;
+ u8 mapNum;
+ u8 objectId;
+ u8 script[995];
+};
+
+struct RamScript
+{
+ u32 checksum;
+ struct RamScriptData data;
+};
+
+struct EasyChatPair
+{
+ u16 unk0_0:7;
+ u16 unk0_7:7;
+ u16 unk1_6:1;
+ u16 unk2;
+ u16 words[2];
+}; /*size = 0x8*/
+
+struct TVShowCommon
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 pad02[20];
+ /*0x16*/ u16 var16[3];
+ /*0x1C*/ u8 srcTrainerId3Lo;
+ /*0x1D*/ u8 srcTrainerId3Hi;
+ /*0x1E*/ u8 srcTrainerId2Lo;
+ /*0x1F*/ u8 srcTrainerId2Hi;
+ /*0x20*/ u8 srcTrainerIdLo;
+ /*0x21*/ u8 srcTrainerIdHi;
+ /*0x22*/ u8 trainerIdLo;
+ /*0x23*/ u8 trainerIdHi;
+};
+
+struct TVShowFanClubLetter
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 species;
+ /*0x04*/ u16 pad04[6];
+ /*0x10*/ u8 playerName[8];
+ /*0x18*/ u8 language;
+};
+
+struct TVShowRecentHappenings
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 var02;
+ /*0x04*/ u16 var04[6];
+ /*0x10*/ u8 playerName[8];
+ /*0x18*/ u8 language;
+ /*0x19*/ u8 pad19[10];
+};
+
+struct TVShowFanclubOpinions
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 var02;
+ /*0x04*/ u8 var04A:4;
+ /*0x04*/ u8 var04B:4;
+ /*0x05*/ u8 playerName[8];
+ /*0x0D*/ u8 language;
+ /*0x0E*/ u8 var0E;
+ /*0x0F*/ u8 var0F;
+ /*0x10*/ u8 var10[8];
+ /*0x18*/ u16 var18[2];
+ /*0x1C*/ u16 var1C[4];
+};
+
+struct TVShowUnknownType04
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 pad02[4];
+ /*0x06*/ u16 var06;
+};
+
+struct TVShowNameRaterShow
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 species;
+ /*0x04*/ u8 pokemonName[11];
+ /*0x0F*/ u8 trainerName[11];
+ /*0x1A*/ u8 random;
+ /*0x1B*/ u8 random2;
+ /*0x1C*/ u16 var1C;
+ /*0x1E*/ u8 language;
+ /*0x1F*/ u8 pokemonNameLanguage;
+};
+
+struct TVShowBravoTrainerPokemonProfiles
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 species;
+ /*0x04*/ u16 var04[2];
+ /*0x08*/ u8 pokemonNickname[11];
+ /*0x13*/ u8 contestCategory:3;
+ /*0x13*/ u8 contestRank:2;
+ /*0x13*/ u8 contestResult:2;
+ /*0x13*/ u8 var13_7:1;
+ /*0x14*/ u16 var14;
+ /*0x16*/ u8 playerName[8];
+ /*0x1E*/ u8 language;
+ /*0x1F*/ u8 var1f;
+};
+
+struct TVShowBravoTrainerBattleTowerSpotlight
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 trainerName[8];
+ /*0x0A*/ u16 species;
+ /*0x0C*/ u8 enemyTrainerName[8];
+ /*0x14*/ u16 defeatedSpecies;
+ /*0x16*/ u16 var16;
+ /*0x18*/ u16 var18[1];
+ /*0x1A*/ u8 btLevel;
+ /*0x1B*/ u8 var1b;
+ /*0x1C*/ u8 var1c;
+ /*0x1D*/ u8 language;
+};
+
+struct TVShowPokemonToday
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 language;
+ /*0x03*/ u8 language2;
+ /*0x04*/ u8 nickname[11];
+ /*0x0F*/ u8 ball;
+ /*0x10*/ u16 species;
+ /*0x12*/ u8 var12;
+ /*0x13*/ u8 playerName[8];
+};
+
+struct TVShowSmartShopper
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 priceReduced;
+ /*0x03*/ u8 language;
+ /*0x04*/ u8 pad04[2];
+ /*0x06*/ u16 itemIds[3];
+ /*0x0C*/ u16 itemAmounts[3];
+ /*0x12*/ u8 shopLocation;
+ /*0x13*/ u8 playerName[8];
+};
+
+struct TVShowPokemonTodayFailed
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 language;
+ /*0x03*/ u8 pad03[9];
+ /*0x0c*/ u16 species;
+ /*0x0e*/ u16 species2;
+ /*0x10*/ u8 var10;
+ /*0x11*/ u8 var11;
+ /*0x12*/ u8 var12;
+ /*0x13*/ u8 playerName[8];
+};
+
+struct TVShowPokemonAngler
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 var02;
+ /*0x03*/ u8 var03;
+ /*0x04*/ u16 var04;
+ /*0x06*/ u8 language;
+ u8 pad07[12];
+ /*0x13*/ u8 playerName[8];
+};
+
+struct TVShowWorldOfMasters
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u16 var02;
+ /*0x04*/ u16 var04;
+ /*0x06*/ u16 var06;
+ /*0x08*/ u16 var08;
+ /*0x0a*/ u8 var0a;
+ /*0x0b*/ u8 language;
+ u8 pad0c[7];
+ /*0x13*/ u8 playerName[8];
+};
+
+struct TVShowMassOutbreak
+{
+ /*0x00*/ u8 kind;
+ /*0x01*/ bool8 active;
+ /*0x02*/ u8 var02;
+ /*0x03*/ u8 var03;
+ /*0x04*/ u16 moves[4];
+ /*0x0C*/ u16 species;
+ /*0x0E*/ u16 var0E;
+ /*0x10*/ u8 locationMapNum;
+ /*0x11*/ u8 locationMapGroup;
+ /*0x12*/ u8 var12;
+ /*0x13*/ u8 probability;
+ /*0x14*/ u8 level;
+ /*0x15*/ u8 var15;
+ /*0x16*/ u16 daysLeft;
+ /*0x18*/ u8 language;
+ u8 pad19[11];
+};
+
+typedef union TVShow
+{
+ struct TVShowCommon common;
+ struct TVShowFanClubLetter fanclubLetter;
+ struct TVShowRecentHappenings recentHappenings;
+ struct TVShowFanclubOpinions fanclubOpinions;
+ struct TVShowUnknownType04 unkShow04;
+ struct TVShowNameRaterShow nameRaterShow;
+ struct TVShowBravoTrainerPokemonProfiles bravoTrainer;
+ struct TVShowBravoTrainerBattleTowerSpotlight bravoTrainerTower;
+ struct TVShowPokemonToday pokemonToday;
+ struct TVShowSmartShopper smartshopperShow;
+ struct TVShowPokemonTodayFailed pokemonTodayFailed;
+ struct TVShowPokemonAngler pokemonAngler;
+ struct TVShowWorldOfMasters worldOfMasters;
+ struct TVShowMassOutbreak massOutbreak;
+} TVShow;
+
+struct MailStruct
+{
+ /*0x00*/ u16 words[9];
+ /*0x12*/ u8 playerName[8];
+ /*0x1A*/ u8 trainerId[4];
+ /*0x1E*/ u16 species;
+ /*0x20*/ u16 itemId;
+};
+
+
+// Mauville Pokemon Center men
+
+struct MauvilleManCommon
+{
+ u8 id;
+};
+
+struct MauvilleManBard
+{
+ /*0x00*/ u8 id;
+ /*0x02*/ u16 songLyrics[6];
+ /*0x0E*/ u16 temporaryLyrics[6];
+ /*0x1A*/ u8 playerName[8];
+ /*0x22*/ u8 filler_2DB6[0x3];
+ /*0x25*/ u8 playerTrainerId[4];
+ /*0x29*/ bool8 hasChangedSong;
+}; /*size = 0x2C*/
+
+struct MauvilleManHipster
+{
+ u8 id;
+ bool8 alreadySpoken;
+};
+
+struct MauvilleManTrader
+{
+ u8 id;
+ u8 unk1[4];
+ u8 unk5[4][11];
+ bool8 alreadyTraded;
+};
+
+struct MauvilleManStoryteller
+{
+ u8 id;
+ bool8 alreadyRecorded;
+ u8 filler2[2];
+ u8 gameStatIDs[4];
+ u8 trainerNames[4][7];
+ u8 statValues[4][4];
+};
+
+struct MauvilleManGiddy
+{
+ /*0x00*/ u8 id;
+ /*0x01*/ u8 taleCounter;
+ /*0x02*/ u8 questionNum;
+ /*0x04*/ u16 randomWords[10];
+ /*0x18*/ u8 questionList[12];
+}; /*size = 0x2C*/
+
+
+union MauvilleMan
+{
+ struct MauvilleManCommon common;
+ struct MauvilleManBard bard;
+ struct MauvilleManHipster hipster;
+ struct MauvilleManTrader trader;
+ struct MauvilleManStoryteller storyteller;
+ struct MauvilleManGiddy giddy;
+ u8 filler[0x40]; // needed to pad out the struct
+};
+
+struct PokeNews
+{
+ u8 kind;
+ u8 state;
+ u16 days;
+};
+
+struct GabbyAndTyData
+{
+ /*2b10*/ u16 mon1;
+ /*2b12*/ u16 mon2;
+ /*2b14*/ u16 lastMove;
+ /*2b16*/ u16 quote;
+ /*2b18*/ u8 mapnum;
+ /*2b19*/ u8 battleNum;
+ /*2b1a*/ u8 valA_0:1;
+ /*2b1a*/ u8 valA_1:1;
+ /*2b1a*/ u8 valA_2:1;
+ /*2b1a*/ u8 valA_3:1;
+ /*2b1a*/ u8 valA_4:1;
+ /*2b1a*/ u8 valA_5:3;
+ /*2b1b*/ u8 valB_0:1;
+ /*2b1b*/ u8 valB_1:1;
+ /*2b1b*/ u8 valB_2:1;
+ /*2b1b*/ u8 valB_3:1;
+ /*2b1b*/ u8 valB_4:1;
+ /*2b1b*/ u8 valB_5:3;
+};
+
+struct DayCareMail
+{
+ /*0x00*/ struct MailStruct message;
+ /*0x24*/ u8 names[19];
+};
+
+struct DayCareStepCountersEtc {
+ u32 steps[DAYCARE_MON_COUNT];
+ u16 pendingEggPersonality;
+ u8 eggCycleStepsRemaining;
+};
+
+struct RecordMixingDayCareMail
+{
+ struct DayCareMail mail[DAYCARE_MON_COUNT];
+ u32 numDaycareMons;
+ u16 itemsHeld[DAYCARE_MON_COUNT]; // marks whether or not each daycare mon is currently holding an item.
+};
+
+struct DayCareMisc
+{
+ struct DayCareMail mail[DAYCARE_MON_COUNT];
+ struct DayCareStepCountersEtc countersEtc;
+};
+
+struct DayCare {
+ struct BoxPokemon mons[DAYCARE_MON_COUNT];
+ struct DayCareMisc misc;
+};
+
+struct LinkBattleRecord
+{
+ u8 name[8];
+ u16 trainerId;
+ u16 wins;
+ u16 losses;
+ u16 draws;
+};
+
+struct RecordMixingGiftData
+{
+ u8 unk0;
+ u8 quantity;
+ u16 itemId;
+ u8 filler4[8];
+};
+
+struct RecordMixingGift
+{
+ int checksum;
+ struct RecordMixingGiftData data;
+};
+
+struct ContestWinner
+{
+ /*0x00*/ u32 personality; // personality
+ /*0x04*/ u32 otId; // otId
+ /*0x08*/ u16 species; // species
+ /*0x0A*/ u8 contestCategory;
+ /*0x0B*/ u8 nickname[11];
+ /*0x16*/ u8 trainerName[8];
+};
+
+// there should be enough flags for all 412 slots
+// each slot takes up 8 flags
+// if the value is not divisible by 8, we need to account for the reminder as well
+#define DEX_FLAGS_NO ((POKEMON_SLOTS_NUMBER / 8) + ((POKEMON_SLOTS_NUMBER % 8) ? 1 : 0))
+
+struct SaveBlock1 /* 0x02025734 */
+{
+ /*0x00*/ struct Coords16 pos;
+ /*0x04*/ struct WarpData location;
+ /*0x0C*/ struct WarpData warp1;
+ /*0x14*/ struct WarpData warp2;
+ /*0x1C*/ struct WarpData lastHealLocation;
+ /*0x24*/ struct WarpData warp4;
+ /*0x2C*/ u16 savedMusic;
+ /*0x2E*/ u8 weather;
+ /*0x2F*/ u8 weatherCycleStage;
+ /*0x30*/ u8 flashLevel; // flash level on current map, 0 being normal and 4 being the darkest
+ /*0x32*/ u16 mapLayoutId;
+ /*0x34*/ u16 mapView[0x100];
+ /*0x234*/ u8 playerPartyCount;
+ /*0x238*/ struct Pokemon playerParty[6];
+ /*0x490*/ u32 money;
+ /*0x494*/ u16 coins;
+ /*0x496*/ u16 registeredItem; // registered for use with SELECT button
+ /*0x498*/ struct ItemSlot pcItems[PC_ITEMS_COUNT];
+ /*0x560*/ struct ItemSlot bagPocket_Items[BAG_ITEMS_COUNT];
+ /*0x5B0*/ struct ItemSlot bagPocket_KeyItems[BAG_KEYITEMS_COUNT];
+ /*0x600*/ struct ItemSlot bagPocket_PokeBalls[BAG_POKEBALLS_COUNT];
+ /*0x640*/ struct ItemSlot bagPocket_TMHM[BAG_TMHM_COUNT];
+ /*0x740*/ struct ItemSlot bagPocket_Berries[BAG_BERRIES_COUNT];
+ /*0x7F8*/ struct Pokeblock pokeblocks[POKEBLOCKS_COUNT];
+ /*0x938*/ u8 dexSeen2[DEX_FLAGS_NO];
+ /*0x96C*/ u16 berryBlenderRecords[3];
+ /*0x972*/ u8 filler_972[0x6];
+ /*0x978*/ u16 trainerRematchStepCounter;
+ /*0x97A*/ u8 trainerRematches[100];
+ /*0x9E0*/ struct EventObject eventObjects[EVENT_OBJECTS_COUNT];
+ /*0xC20*/ struct EventObjectTemplate eventObjectTemplates[64];
+ /*0x1220*/ u8 flags[FLAGS_COUNT];
+ /*0x1340*/ u16 vars[VARS_COUNT];
+ /*0x1540*/ u32 gameStats[NUM_GAME_STATS];
+ /*0x1608*/ struct BerryTree berryTrees[BERRY_TREES_COUNT];
+ /*0x1A08*/ struct SecretBaseRecord secretBases[SECRET_BASES_COUNT];
+ /*0x2688*/ u8 playerRoomDecor[12];
+ /*0x2694*/ u8 playerRoomDecorPos[12];
+ /*0x26A0*/ u8 decorDesk[10];
+ /*0x26AA*/ u8 decorChair[10];
+ /*0x26B4*/ u8 decorPlant[10];
+ /*0x26BE*/ u8 decorOrnament[30];
+ /*0x26DC*/ u8 decorMat[30];
+ /*0x26FA*/ u8 decorPoster[10];
+ /*0x2704*/ u8 decorDoll[40];
+ /*0x272C*/ u8 decorCushion[10];
+ /*0x2736*/ u8 padding_2736[2];
+ /*0x2738*/ TVShow tvShows[TV_SHOWS_COUNT];
+ /*0x2ABC*/ struct PokeNews pokeNews[POKE_NEWS_COUNT];
+ /*0x2AFC*/ u16 outbreakPokemonSpecies;
+ /*0x2AFE*/ u8 outbreakLocationMapNum;
+ /*0x2AFF*/ u8 outbreakLocationMapGroup;
+ /*0x2B00*/ u8 outbreakPokemonLevel;
+ /*0x2B01*/ u8 outbreakUnk1;
+ /*0x2B02*/ u16 outbreakUnk2;
+ /*0x2B04*/ u16 outbreakPokemonMoves[4];
+ /*0x2B0C*/ u8 outbreakUnk4;
+ /*0x2B0D*/ u8 outbreakPokemonProbability;
+ /*0x2B0E*/ u16 outbreakUnk5;
+ /*0x2B10*/ struct GabbyAndTyData gabbyAndTyData;
+ /*0x2B1C*/ struct {
+ /*0x2B1C*/ u16 unk2B1C[6];
+ /*0x2B28*/ u16 unk2B28[6];
+ /*0x2B34*/ u16 unk2B34[6];
+ /*0x2B40*/ u16 unk2B40[6];
+ } easyChats;
+ /*0x2B4C*/ struct MailStruct mail[MAIL_COUNT];
+ /*0x2D8C*/ u8 unk2D8C[4]; // What is this? Apparently it's supposed to be 64 bytes in size.
+ /*0x2D90*/ u8 filler_2D90[0x4];
+ /*0x2D94*/ union MauvilleMan mauvilleMan;
+ /*0x2DD4*/ struct EasyChatPair easyChatPairs[5]; //Dewford trend [0] and some other stuff
+ /*0x2DFC*/ struct ContestWinner contestWinners[8];
+ /*0x2EFC*/ struct ContestWinner museumPortraits[5];
+ /*0x2F9C*/ struct DayCare daycare;
+ /*0x30B8*/ struct LinkBattleRecord linkBattleRecords[5];
+ struct {
+ /*0x3108*/ u8 unknown1[8];
+ /*0x3110*/ u8 giftRibbons[11];
+ /*0x311B*/ u8 unknown2[8];
+ /*0x3123*/ u32 currentPokeCoupons;
+ /*0x3127*/ u32 totalEarnedPokeCoupons;
+ /*0x312B*/ u8 unknown3[6];
+ /*0x3131*/ u8 receivedWishmakerJirachi;
+ /*0x3132*/ u8 unknown4[18];
+ } __attribute__((packed)) externalReservedData;
+ /*0x3144*/ struct Roamer roamer;
+ /*0x3160*/ struct EnigmaBerry enigmaBerry;
+ /*0x3690*/ struct RamScript ramScript;
+ /*0x3A7C*/ struct RecordMixingGift recordMixingGift;
+ /*0x3A8C*/ u8 dexSeen3[DEX_FLAGS_NO];
+};
+
+extern struct SaveBlock1 gSaveBlock1;
+
+struct Time
+{
+ /*0x00*/ s16 days;
+ /*0x02*/ s8 hours;
+ /*0x03*/ s8 minutes;
+ /*0x04*/ s8 seconds;
+};
+
+struct Pokedex
+{
+ /*0x00*/ u8 order;
+ /*0x01*/ u8 unknown1;
+ /*0x02*/ u8 nationalMagic; // must equal 0xDA in order to have National mode
+ /*0x03*/ u8 unknown2;
+ /*0x04*/ u32 unownPersonality; // set when you first see Unown
+ /*0x08*/ u32 spindaPersonality; // set when you first see Spinda
+ /*0x0C*/ u32 unknown3;
+ /*0x10*/ u8 owned[DEX_FLAGS_NO];
+ /*0x44*/ u8 seen[DEX_FLAGS_NO];
+};
+
+struct BattleTowerTrainer
+{
+ /*0x00*/ u8 trainerClass;
+ /*0x01*/ u8 name[8];
+ /*0x09*/ u8 teamFlags;
+ u8 filler0A[2];
+ /*0x0C*/ u16 greeting[6];
+};
+
+struct BattleTowerRecord // record mixing
+{
+ /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100
+ /*0x01*/ u8 trainerClass;
+ /*0x02*/ u16 winStreak;
+ /*0x04*/ u8 name[8];
+ /*0x0C*/ u8 trainerId[4];
+ /*0x10*/ u16 greeting[6];
+ /*0x1C*/ struct BattleTowerPokemon party[3];
+ /*0xA0*/ u32 checksum;
+};
+
+struct BattleTowerEReaderTrainer
+{
+ /*0x00*/ u8 unk0;
+ /*0x01*/ u8 trainerClass;
+ /*0x02*/ u16 winStreak;
+ /*0x04*/ u8 name[8];
+ /*0x0C*/ u8 trainerId[4];
+ /*0x10*/ u16 greeting[6];
+ /*0x1C*/ u16 farewellPlayerLost[6];
+ /*0x28*/ u16 farewellPlayerWon[6];
+ /*0x34*/ struct BattleTowerPokemon party[3];
+ /*0xB8*/ u32 checksum;
+};
+
+struct BattleTowerData
+{
+ /*0x0000, 0x00A8*/ struct BattleTowerRecord playerRecord;
+ /*0x00A4, 0x014C*/ struct BattleTowerRecord records[5]; // from record mixing
+ /*0x03D8, 0x0480*/ u16 firstMonSpecies; // species of the first pokemon in the player's battle tower party
+ /*0x03DA, 0x0482*/ u16 defeatedBySpecies; // species of the pokemon that defated the player
+ /*0x03DC, 0x0484*/ u8 defeatedByTrainerName[8];
+ /*0x03E4, 0x048C*/ u8 firstMonNickname[POKEMON_NAME_LENGTH]; // nickname of the first pokemon in the player's battle tower party
+ /*0x03F0, 0x0498*/ struct BattleTowerEReaderTrainer ereaderTrainer;
+ /*0x04AC, 0x0554*/ u8 battleTowerLevelType:1; // 0 = level 50; 1 = level 100
+ /*0x04AC, 0x0554*/ u8 unk_554:1;
+ /*0x04AD, 0x0555*/ u8 battleOutcome;
+ /*0x04AE, 0x0556*/ u8 var_4AE[2];
+ /*0x04B0, 0x0558*/ u16 curChallengeBattleNum[2]; // 1-based index of battle in the current challenge. (challenges consist of 7 battles)
+ /*0x04B4, 0x055C*/ u16 curStreakChallengesNum[2]; // 1-based index of the current challenge in the current streak.
+ /*0x04B8, 0x0560*/ u16 recordWinStreaks[2];
+ /*0x04BC, 0x0564*/ u8 battleTowerTrainerId; // index for gBattleTowerTrainers table
+ /*0x04BD, 0x0565*/ u8 selectedPartyMons[0x3]; // indices of the 3 selected player party mons.
+ /*0x04C0, 0x0568*/ u16 prizeItem;
+ /*0x04C2, 0x056A*/ u8 battledTrainerIds[6];
+ /*0x04C8, 0x0570*/ u16 totalBattleTowerWins;
+ /*0x04CA, 0x0572*/ u16 bestBattleTowerWinStreak;
+ /*0x04CC, 0x0574*/ u16 currentWinStreaks[2];
+ /*0x04D0, 0x0578*/ u8 lastStreakLevelType; // 0 = level 50, 1 = level 100. level type of the last streak. Used by tv to report the level mode.
+ /*0x04D1, 0x0579*/ u8 filler_4D1[0x317];
+};
+
+struct SaveBlock2 /* 0x02024EA4 */
+{
+ /*0x00*/ u8 playerName[8];
+ /*0x08*/ u8 playerGender; // MALE, FEMALE
+ /*0x09*/ u8 specialSaveWarp;
+ /*0x0A*/ u8 playerTrainerId[4];
+ /*0x0E*/ u16 playTimeHours;
+ /*0x10*/ u8 playTimeMinutes;
+ /*0x11*/ u8 playTimeSeconds;
+ /*0x12*/ u8 playTimeVBlanks;
+ /*0x13*/ u8 optionsButtonMode; // OPTIONS_BUTTON_MODE_[NORMAL/LR/L_EQUALS_A]
+ /*0x14*/ u16 optionsTextSpeed:3; // OPTIONS_TEXT_SPEED_[SLOW/MID/FAST]
+ u16 optionsWindowFrameType:5; // Specifies one of the 20 decorative borders for text boxes
+ u16 optionsSound:1; // OPTIONS_SOUND_[MONO/STEREO]
+ u16 optionsBattleStyle:1; // OPTIONS_BATTLE_STYLE_[SHIFT/SET]
+ u16 optionsBattleSceneOff:1; // whether battle animations are disabled
+ u16 regionMapZoom:1; // whether the map is zoomed in
+ /*0x18*/ struct Pokedex pokedex;
+ /*0x90*/ u8 filler_90[0x8];
+ /*0x98*/ struct Time localTimeOffset;
+ /*0xA0*/ struct Time lastBerryTreeUpdate;
+ /*0xA8*/ struct BattleTowerData battleTower;
+};
+
+struct MapPosition
+{
+ s16 x;
+ s16 y;
+ s8 height;
+};
+
+struct UnkStruct_8054FF8
+{
+ u8 a;
+ u8 b;
+ u8 c;
+ u8 d;
+ struct MapPosition sub;
+ u16 field_C;
+};
+
+// wasnt defined so I had to define it
+struct HallOfFame
+{
+ u8 filler[0x1F00];
+};
+
+extern struct SaveBlock2 gSaveBlock2;
+
+#define RomHeaderGameTitle ((const char *)0x080000A0)
+#define RomHeaderGameCode ((const char *)0x080000AC)
+#define RomHeaderMakerCode ((const char *)0x080000B0)
+#define RomHeaderMagic ((const u8 *) 0x080000B2)
+#define RomHeaderSoftwareVersion ((const u8 *) 0x080000BC)
+
+#define LocalTimeOffset ((struct Time *)0x02028098)
+#define LastBerryTreeUpdate ((struct Time *)0x020280A0)
+
+#endif //GUARD_GLOBAL_H
diff --git a/berry_fix/payload/include/main.h b/berry_fix/payload/include/main.h
new file mode 100644
index 000000000..cb58d5982
--- /dev/null
+++ b/berry_fix/payload/include/main.h
@@ -0,0 +1,45 @@
+#ifndef GUARD_MAIN_H
+#define GUARD_MAIN_H
+
+#include "gba/gba.h"
+
+enum RomHeaderValidationResult
+{
+ SAPPHIRE_UPDATABLE = 2,
+ RUBY_UPDATABLE,
+ SAPPHIRE_NONEED,
+ RUBY_NONEED,
+ INVALID
+};
+
+enum MainCallbackState
+{
+ MAINCB_INIT = 0,
+ MAINCB_CHECK_RTC,
+ MAINCB_CHECK_FLASH,
+ MAINCB_READ_SAVE,
+ MAINCB_CHECK_TIME,
+ MAINCB_FIX_DATE,
+ MAINCB_NO_NEED_TO_FIX,
+ MAINCB_YEAR_MAKES_NO_SENSE,
+ MAINCB_FINISHED,
+ MAINCB_CHECK_PACIFIDLOG_TM,
+ MAINCB_FIX_PACIFIDLOG_TM,
+ MAINCB_ERROR
+};
+
+extern IntrFunc gIntrTable[];
+extern u16 gHeldKeys;
+extern u16 gNewKeys;
+extern u8 gIntrVector[];
+extern u32 gUpdateSuccessful;
+extern u32 gUnknown_3001194;
+extern u32 gUnknown_30011A0[];
+extern u32 gMainCallbackState;
+extern u32 gGameVersion;
+
+extern u8 gSharedMem[0x8000];
+
+extern const IntrFunc gIntrFuncPointers[];
+
+#endif //GUARD_MAIN_H
diff --git a/berry_fix/payload/include/pokemon.h b/berry_fix/payload/include/pokemon.h
new file mode 100644
index 000000000..d3a14ffff
--- /dev/null
+++ b/berry_fix/payload/include/pokemon.h
@@ -0,0 +1,154 @@
+#ifndef GUARD_POKEMON_H
+#define GUARD_POKEMON_H
+
+struct PokemonSubstruct0
+{
+ u16 species;
+ u16 heldItem;
+ u32 experience;
+ u8 ppBonuses;
+ u8 friendship;
+};
+
+struct PokemonSubstruct1
+{
+ u16 moves[4];
+ u8 pp[4];
+};
+
+struct PokemonSubstruct2
+{
+ u8 hpEV;
+ u8 attackEV;
+ u8 defenseEV;
+ u8 speedEV;
+ u8 spAttackEV;
+ u8 spDefenseEV;
+ u8 cool;
+ u8 beauty;
+ u8 cute;
+ u8 smart;
+ u8 tough;
+ u8 sheen;
+};
+
+struct PokemonSubstruct3
+{
+ /*0x00*/ u8 pokerus;
+ /*0x01*/ u8 metLocation;
+
+ /*0x02*/ u16 metLevel:7;
+ /*0x02*/ u16 metGame:4;
+ /*0x03*/ u16 pokeball:4;
+ /*0x03*/ u16 otGender:1;
+
+ /*0x04*/ u32 hpIV:5;
+ /*0x04*/ u32 attackIV:5;
+ /*0x05*/ u32 defenseIV:5;
+ /*0x05*/ u32 speedIV:5;
+ /*0x05*/ u32 spAttackIV:5;
+ /*0x06*/ u32 spDefenseIV:5;
+ /*0x07*/ u32 isEgg:1;
+ /*0x07*/ u32 altAbility:1;
+
+ /*0x08*/ u32 coolRibbon:3;
+ /*0x08*/ u32 beautyRibbon:3;
+ /*0x08*/ u32 cuteRibbon:3;
+ /*0x09*/ u32 smartRibbon:3;
+ /*0x09*/ u32 toughRibbon:3;
+ /*0x09*/ u32 championRibbon:1;
+ /*0x0A*/ u32 winningRibbon:1;
+ /*0x0A*/ u32 victoryRibbon:1;
+ /*0x0A*/ u32 artistRibbon:1;
+ /*0x0A*/ u32 effortRibbon:1;
+ /*0x0A*/ u32 giftRibbon1:1;
+ /*0x0A*/ u32 giftRibbon2:1;
+ /*0x0A*/ u32 giftRibbon3:1;
+ /*0x0A*/ u32 giftRibbon4:1;
+ /*0x0B*/ u32 giftRibbon5:1;
+ /*0x0B*/ u32 giftRibbon6:1;
+ /*0x0B*/ u32 giftRibbon7:1;
+ /*0x0B*/ u32 fatefulEncounter:5; // unused in Ruby/Sapphire, but the high bit must be set for Mew/Deoxys to obey in FR/LG/Emerald
+};
+
+union PokemonSubstruct
+{
+ struct PokemonSubstruct0 type0;
+ struct PokemonSubstruct1 type1;
+ struct PokemonSubstruct2 type2;
+ struct PokemonSubstruct3 type3;
+ u16 raw[6];
+};
+
+struct BoxPokemon
+{
+ /*0x00*/ u32 personality;
+ /*0x04*/ u32 otId;
+ /*0x08*/ u8 nickname[POKEMON_NAME_LENGTH];
+ /*0x12*/ u8 language;
+ /*0x13*/ u8 isBadEgg:1;
+ u8 hasSpecies:1;
+ u8 isEgg:1;
+ /*0x14*/ u8 otName[OT_NAME_LENGTH];
+ /*0x1B*/ u8 markings;
+ /*0x1C*/ u16 checksum;
+ /*0x1E*/ u16 unknown;
+
+ union
+ {
+ u32 raw[12];
+ union PokemonSubstruct substructs[4];
+ } secure;
+}; /*size = 0x50*/
+
+struct Pokemon
+{
+ /*0x00*/ struct BoxPokemon box;
+ /*0x50*/ u32 status;
+ /*0x54*/ u8 level;
+ /*0x55*/ u8 mail;
+ /*0x56*/ u16 hp;
+ /*0x58*/ u16 maxHP;
+ /*0x5A*/ u16 attack;
+ /*0x5C*/ u16 defense;
+ /*0x5E*/ u16 speed;
+ /*0x60*/ u16 spAttack;
+ /*0x62*/ u16 spDefense;
+};
+
+struct BattleTowerPokemon
+{
+ /*0x00*/u16 species;
+ /*0x02*/u16 heldItem;
+ /*0x04*/u16 moves[4];
+ /*0x0C*/u8 level;
+ /*0x0D*/u8 ppBonuses;
+ /*0x0E*/u8 hpEV;
+ /*0x0F*/u8 attackEV;
+ /*0x10*/u8 defenseEV;
+ /*0x11*/u8 speedEV;
+ /*0x12*/u8 spAttackEV;
+ /*0x13*/u8 spDefenseEV;
+ /*0x14*/u32 otId;
+ /*0x18*/u32 hpIV:5;
+ /*0x18*/u32 attackIV:5;
+ /*0x19*/u32 defenseIV:5;
+ /*0x19*/u32 speedIV:5;
+ /*0x1A*/u32 spAttackIV:5;
+ /*0x1A*/u32 spDefenseIV:5;
+ /*0x1B*/u32 gap:1;
+ /*0x1B*/u32 altAbility:1;
+ /*0x1C*/u32 personality;
+ /*0x20*/u8 nickname[POKEMON_NAME_LENGTH + 1];
+ /*0x2B*/u8 friendship;
+};
+
+struct PokemonStorage
+{
+ /*0x0000*/ u8 currentBox;
+ /*0x0004*/ struct BoxPokemon boxes[14][30];
+ /*0x8344*/ u8 boxNames[14][9];
+ /*0x83c2*/ u8 wallpaper[14];
+};
+
+#endif // GUARD_POKEMON_H
diff --git a/berry_fix/payload/include/rtc.h b/berry_fix/payload/include/rtc.h
new file mode 100644
index 000000000..35654d866
--- /dev/null
+++ b/berry_fix/payload/include/rtc.h
@@ -0,0 +1,15 @@
+#ifndef GUARD_RTC_H
+#define GUARD_RTC_H
+
+#include "gba/gba.h"
+#include "siirtc.h"
+#include "global.h"
+
+extern struct Time gTimeSinceBerryUpdate;
+extern struct Time gRtcUTCTime;
+
+bool32 rtc_maincb_is_rtc_working(void);
+bool32 rtc_maincb_is_time_since_last_berry_update_positive(u8 *);
+void rtc_maincb_fix_date(void);
+
+#endif //GUARD_RTC_H
diff --git a/berry_fix/payload/include/siirtc.h b/berry_fix/payload/include/siirtc.h
new file mode 100644
index 000000000..de4fd634d
--- /dev/null
+++ b/berry_fix/payload/include/siirtc.h
@@ -0,0 +1,54 @@
+#ifndef GUARD_RTC_H
+#define GUARD_RTC_H
+
+#include "gba/gba.h"
+
+#define SIIRTCINFO_INTFE 0x01 // frequency interrupt enable
+#define SIIRTCINFO_INTME 0x02 // per-minute interrupt enable
+#define SIIRTCINFO_INTAE 0x04 // alarm interrupt enable
+#define SIIRTCINFO_24HOUR 0x40 // 0: 12-hour mode, 1: 24-hour mode
+#define SIIRTCINFO_POWER 0x80 // power on or power failure occurred
+
+enum
+{
+ MONTH_JAN = 1,
+ MONTH_FEB,
+ MONTH_MAR,
+ MONTH_APR,
+ MONTH_MAY,
+ MONTH_JUN,
+ MONTH_JUL,
+ MONTH_AUG,
+ MONTH_SEP,
+ MONTH_OCT,
+ MONTH_NOV,
+ MONTH_DEC
+};
+
+struct SiiRtcInfo
+{
+ u8 year;
+ u8 month;
+ u8 day;
+ u8 dayOfWeek;
+ u8 hour;
+ u8 minute;
+ u8 second;
+ u8 status;
+ u8 alarmHour;
+ u8 alarmMinute;
+};
+
+void SiiRtcUnprotect(void);
+void SiiRtcProtect(void);
+u8 SiiRtcProbe(void);
+bool8 SiiRtcReset(void);
+bool8 SiiRtcGetStatus(struct SiiRtcInfo *rtc);
+bool8 SiiRtcSetStatus(struct SiiRtcInfo *rtc);
+bool8 SiiRtcGetDateTime(struct SiiRtcInfo *rtc);
+bool8 SiiRtcSetDateTime(struct SiiRtcInfo *rtc);
+bool8 SiiRtcGetTime(struct SiiRtcInfo *rtc);
+bool8 SiiRtcSetTime(struct SiiRtcInfo *rtc);
+bool8 SiiRtcSetAlarm(struct SiiRtcInfo *rtc);
+
+#endif // GUARD_RTC_H