- -- --- Mr. Fusion by bananaboy A bare metal demonstration for the Leapster Explorer presented at Syntax 2025 in the Wild Demo category, taking 6th place. All code, graphics, and music by bananaboy. :: Quick Start To run the demo on your Leapster Explorer: 1. Plug your device into your PC with a USB cable. 2. Boot your device into recovery mode by holding down the left and right shoulder buttons and the ? button, and turn on the power. You should see a picture of the Leapster Explorer and a PC connected by a cable. 3. Ensure that Python is in your path. 4. Run `upload.bat` in this package as administrator. 5. The demo should start! Note: this will NOT overwrite anything in your Leapster! This simply loads the demo into RAM and executes it from there. If you run into any troubles feel free to contact me (see the end of this document). :: Hardware The Leapster Explorer is a kids handheld console toy with an ARM9-based CPU running at 393 Mhz, with 64 MB SDRAM, a simple audio output device, and a 320x240 screen. There is no FPU. There is also OpenGL ES 1.1 level 3D acceleration, but Mr. Fusion doesn't use this; it only uses a framebuffer. The Leapster Explorer runs Linux, but I didn't think it was particularly interesting to just build an elf for Linux, so instead I wrote a bare metal demo. :: Running If you have a Leapster Explorer and wish to run this demo, you can boot your device into recovery mode and use the included batch file `upload.bat` to transfer the demo to the device and launch it. In recovery mode, the device expects to receive a Linux kernel, but we can send it whatever binary we want. It will load the binary into RAM and jump to it, as though it is starting a Linux kernel. When in recovery mode the device appears to a connected PC as a USB mass storage device, and waits for SCSI commands to send it data. We can automate this using the `sg3_utils` package and some simple Python and batch scripting to find the attached device and upload our code. This zip includes the required executables and scripts (except for Python). :: Software The recovery mode boot loader does the bare minimum to initialise the device. When it jumps to our entry point, we are running bare metal, so we have to do everything - there is no elf loader, the MMU hasn't been configured, and most of the hardware that we want to use hasn't been initialised. We first need to do some housekeeping. When we start executing we are still running in the ARM IRQ processor mode with whatever stack the boot loader set up. But ideally we would be running in supervisor mode with our own stack memory configured, and our own interrupt handlers. The first thing we do is set up a new stack under our control for each of the processor modes, and leave the processor in supervisor mode. Because the boot loader runs from ROM, the initial interrupt vector table is unmodifiable so we can't just patch in our own interrupt handlers. But the ARM9 has an MMU and the ability to relocate the interrupt vector table to 0xFFFF0000. So we can enable the MMU, map some physical pages to 0xFFFF0000, and then set up our interrupt vector table in there. We also enable the I- and D-caches. Then we jump to main. Now we can do what we like! Because we're running bare metal, we have no executable loader that started us, and I also build without any runtime library which means we have to zero the bss section ourselves. We have to also be careful to not use any constructs that require relocations, since they will never be patched (because no loader!). So when compiling we can enable position-independent code with `-fPIC` which will tell the compiler to use PC-relative addressing where possible. In a future iteration of the code base I plan on writing a loader that handles this and allows me to have relocatable code. :: Contact For any further questions about the tech and hacking the Leapster Explorer, feel free to contact me at sam@humbug.net or ping me on Discord on the LFHacks server. EOF