Most homebrew multiboot programs support both cartridge and multiboot use by copying the code from ROM to RAM when run as a cartridge. But if the copy routine loads a constant source address of 0x08000000 (start of cartridge), it'll get tripped up and read open bus. The GBA version of Magic Floor by nocash is an example of a program that fails on GBA Movie Player and in the mGBA emulator.
I discovered a fix that allows a program that works on cart and multiboot to also work on GBAMP. I patched the copy routine to calculate the source address based on the program counter (r15), so that if it gets loaded into RAM and run with the cart entry point, it copies from 0x02000000 to 0x02000000, essentially a no-op.
The source address is loaded at start+0xC8:
mov r0, #0x08000000
The fix makes the copy source PC relative:
sub r0, pc, #0xD0
This can be applied to the source or to the binary. If you have no$gba installed, open MAGICFLR.A22 and make this change around line 185 of MAGICFLR.A22 near rom_start:, then reassemble.
Code: Select all
; Replace this mov r0,8000000h ;src/rom ;\ ; with this sub r0,pc,0D0h ;src/rom ;\
The GBA init code in devkitARM handles it a different way. Because the init code is assembled once and linked into both cartridge and multiboot programs, it cannot conditionally assemble the copying code because that would cause "not constant" errors. Instead, it uses 12 bytes of Thumb code to compare __text_start (beginning of the main code section) and PC to decide whether to copy. (I've attached a copy of devkitARM's init code for the benefit of users whose operating system lacks a TLS 1.2 client.)