Advertisement
Prof9

MMBNLC GBAState struct

Nov 12th, 2023 (edited)
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.62 KB | None | 0 0
  1. Generally lives at address 0x80200040. Every GBA ASM function takes a GBAState reference as its first and only parameter, and is expected to return the original value of r15.
  2.  
  3. When you hook a GBA ASM function, you'll generally always find a reference to this struct in one of the registers. Which register it is can vary, though.
  4.  
  5. The way memory is accessed is slightly different between GBA and LC. In GBA, a memory pointer can be dereferenced directly to get the data. In LC, memory pointers are actually offsets in the GBA memory map. This means you have to add the base memory map address ("memory" field in GBAState.env) to the offset to get the actual virtual memory location of the data. While the GBA memory map used in LC is generally the same as the one on a real GBA, there is a difference in how variables and constants are loaded. On GBA variables are stored in WRAM (0x02000000 or sometimes 0x03000000) while constants are stored in the ROM (0x08000000). In LC these are both linked to memory range memory+0x00004000, which is initialized with labels.bin from the exe.dat file. It starts with zero-initialized data (hence why labels.bin is all zeros at the start) followed by constants.
  6.  
  7. #include <stdbool.h>
  8. #include <stdint.h>
  9.  
  10. typedef enum : uint32_t {
  11.     CPU_FLAG_NONE = 0x0,
  12.     // The following 4 flags are used in the flags field
  13.     CPU_FLAG_N = 0x1,  // signed flag
  14.     CPU_FLAG_C = 0x2,  // carry flag
  15.     CPU_FLAG_Z = 0x4,  // zero flag
  16.     CPU_FLAG_V = 0x8,  // overflow flag
  17.     // The following 4 flags are used in the flagsImplicitUpdate field
  18.     CPU_FLAG_UPDATE_N = 0x10,
  19.     CPU_FLAG_UPDATE_C = 0x20,
  20.     CPU_FLAG_UPDATE_Z = 0x40,
  21.     CPU_FLAG_UPDATE_V = 0x80,
  22. } CPUFlags;
  23.  
  24. class nbExe;
  25.  
  26. typedef struct {
  27.     struct {
  28.         /* offset 0x00, size 0x4 */ uint32_t r0;
  29.         /* offset 0x04, size 0x4 */ uint32_t r1;
  30.         /* offset 0x08, size 0x4 */ uint32_t r2;
  31.         /* offset 0x0C, size 0x4 */ uint32_t r3;
  32.         /* offset 0x10, size 0x4 */ uint32_t r4;
  33.         /* offset 0x14, size 0x4 */ uint32_t r5;
  34.         /* offset 0x18, size 0x4 */ uint32_t r6;
  35.         /* offset 0x1C, size 0x4 */ uint32_t r7;
  36.         /* offset 0x20, size 0x4 */ uint32_t r8;
  37.         /* offset 0x24, size 0x4 */ uint32_t r9;
  38.         /* offset 0x28, size 0x4 */ uint32_t r10;
  39.         /* offset 0x2C, size 0x4 */ uint32_t r11;
  40.         /* offset 0x30, size 0x4 */ uint32_t r12;
  41.         /* offset 0x34, size 0x4 */ union { uint32_t sp; uint32_t r13; };
  42.         /* offset 0x38, size 0x4 */ union { uint32_t lr; uint32_t r14; };
  43.         /* offset 0x3C, size 0x4 */ union { uint32_t pc; uint32_t r15; };
  44.     } regs;
  45.     struct {
  46.        /// Original GBA ARM CPU flags
  47.         /* offset 0x40, size 0x4 */ CPUFlags flags;
  48.        /// CMP/TST instructions explicitly update all flags, but some instructions (e.g. ADD, SUB) can implicitly update flags.
  49.        /// This field indicates which flags will be implicitly updated for such instructions. The other flags are preserved.
  50.         /* offset 0x44, size 0x4 */ CPUFlags flagsImplicitUpdate;
  51.         /// Points to GBA memory map, see below
  52.         /* offset 0x48, size 0x8 */ void *memory;
  53.         /// Direct virtual memory pointer to the bottom of the stack - maybe actually used for something else?
  54.         /* offset 0x50, size 0x8 */ void *stackBottom;
  55.         /// Pointer to nbExe class instance which owns the GBA instance
  56.         /* offset 0x58, size 0x8 */ nbExe *owner;
  57.         /// While a LDMIA/STMIA instruction is being run, the transient memory address is stored and incremented here
  58.         /* offset 0x60, size 0x4 */ uint32_t addrLdmiaStmia;
  59.         /// Number of registers on the stack
  60.         /* offset 0x64, size 0x4 */ uint32_t stackCount;
  61.         /// Incremented by 1 when lr (r14) is pushed onto the stack
  62.         /// Decremented by 1 when pc (r15) is popped from the stack
  63.         /* offset 0x68, size 0x4 */ uint32_t callDepth;
  64.         /// Always set to 1? Purpose unknown
  65.         /* offset 0x6C, size 0x4 */ uint32_t always1;
  66.         /// Set to true when entering a function from an alternate entry point
  67.         /// Reset to false after alternate entry point is checked
  68.         /* offset 0x70, size 0x1 */ bool isAltEntry;
  69.         /// Unknown pointer related to overlays
  70.         /* offset 0x78, size 0x8 */ void *overlayUnk;
  71.         /// Overlay picture on background
  72.         /* offset 0x80, size 0x8 */ void *overlayBG;
  73.         /// Overlay picture on sprite objects
  74.         /* offset 0x88, size 0x8 */ void *overlayOBJ;
  75.         /// Unknown pointer which is written (only?) in objtrans::ObjCharInit but doesn't seem to be used
  76.         /* offset 0x90, size 0x8 */ void *objUnk;
  77.     } env;
  78. } GBAState __attribute__((aligned(0x40)));
  79.  
  80. Full memory size = 0x14800000
  81. memory+0x00004000 = Initialized R+W data (labels.bin)
  82. memory+0x02000000 = GBA Working RAM (equivalent to 0x2000000 on GBA)
  83.     Most game variables are in labels, but WRAM is still used for e.g. graphics data buffers
  84. memory+0x04000000 = GBA I/O Registers (equivalent to 0x4000000 on GBA)
  85. memory+0x05000000 = GBA Palette RAM (equivalent to 0x5000000 on GBA)
  86. memory+0x06000000 = GBA Video RAM (equivalent to 0x6000000 on GBA)
  87. memory+0x07000000 = GBA Object RAM (equivalent to 0x7000000 on GBA)
  88. memory+0x08000000 = GBA ROM Original (equivalent to 0x80000000 on GBA)
  89.     Japanese ROM is loaded here (even if playing in English)
  90. memory+0x10000000 = mpak
  91.     mpak for current language is loaded here
  92. memory+0x12000000 = GBA Working RAM (equivalent to 0x2000000)
  93.     Text archive which would normally be loaded to 0x20xxxxx is loaded to 0x120xxxxx instead
  94.     See game function moji::sub::MojiPrintVramSet
  95.     Presumably done to allow loading text archives which exceed the size of the original buffer
  96.     (This does happen with some English text archives)
  97. memory+0x13FFFDB0 = ???
  98. memory+0x13FFFF60 = GBA ROM Localized (equivalent to 0x8000000 on GBA)
  99.     English ROM is loaded here
  100.  
  101. On alternate entry points: some functions have two entry points, for instance:
  102.  
  103. entryPointA:
  104.     mov     r0,0x0
  105.     b       @@startOfFunction
  106. entryPointB:
  107.     mov     r0,0x4
  108. @@startOfFunction:
  109.     push    r4-r7,r15
  110.     // ...
  111.  
  112. In LC, the way this is handled is entryPointA sets isAltEntry to true and then jumps to entryPointB. entryPointB checks isAltEntry and if it's set to true, it will skip doing its own initialization before @@startOfFunction, and set isAltEntry back to false.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement