Journeys in the GBA BIOS

Note: This is a write-up from my old dev blog site. External web links have been updated, yet the message is otherwise reposted verbatim.

So, that tweet went a little viral. Its the classic Game Kid Advancement boot-up display, with the message altered to the oh-so-relatable Im Gay . I could have produced this as an animation, however rather Id invested a couple of days poring over documentation and disassembly to actually modify the sprites in the systems BIOS data. I thought it may be interesting to share the technical information about that.by link gba bios files website

For all of my screening I was utilizing the VisualBoyAdvance emulator. Its got some extremely good debug sights to think of the state of the VRAM, a memory customer, and really helpfully the disassembly of the energetic program code, together with the ability to step guidelines one-by-one.

My first presumption was that the graphics information would certainly exist in a noticeable format in the biographies, and that Id be able to find it simply by dumping out the biography as a picture, mapping each byte to a pixel. Ive utilized this method on various other reverse-engineering jobs and its typically very valuable. In this instance, nevertheless, I showed up only worsening – no apparent formed information at all.

I attempted zeroing out numerous parts of the BIOS information, seeing if I might reason the place of the sprite information. This didnt job extremely well – I handled to damage the audio chime and later handled to collapse the BIOS completely, so I scrapped that idea quite quickly.

I reached the final thought that the information must be pressed in some type, and started browsing for sources regarding GBA data compression techniques. I came across a task called dsdecmp which consisted of code for compression and decompression with numerous formulas utilized by the GBA and DS systems, and believed it could be valuable.

I attempted running dsdecmps LZ77 decompressor on the BIOS, starting at each point in the biographies that could feasibly match the LZ77 data header, in the hopes that I can discover the compressed sprite information by sheer strength, yet this likewise shown up a stumbling block.

Ultimately I understood I was going to need to obtain my hands dirty, and by stepping via the BIOS code one direction at a time utilizing VBAs disassembler, I had the ability to identify the following information flow:

  • Copy $ 370 bytes from $ 0000332C to $ 03000564
  • Unwind $ 370 bytes from $ 03000564 right into $ 3C0 bytes at $ 03001564
  • Decompress $ 3C0 bytes from $ 03001564 into $ 800 bytes at $ 03000564
  • Expand $ 800 bytes of 2bit graphics data from $ 03000564 into $ 2000 bytes of 8bit graphics information at $ 06000040

A fast note concerning the GBA memory layout. The BIOS is mapped at address array $ 00000000-$ 00003FFF, theres some general-purpose RAM beginning at $ 03000000, and VRAM starts at $ 06000000. There are various other parts of addressable memory however theyre not pertinent right here. ( source: GBATEK)

So its copying some compressed information from the BIOS right into IRAM, decompressing it two times in IRAM, and afterwards increasing it while copying right into VRAM. After a bit checking out the GBATEK paperwork and contrasting versus the compressed data, I had the ability to determine from the header bytes that the initial compression pass is Huffman and the second pass is LZ77. So I think the BIOS is in fact doing the following actions using the BIOS decompression features:

MemCopy($ 0000332C, $03000564, $370);// most likely utilizing CpuSet or CpuFastSet
HuffUnCompReadNormal($ 03000564, $03001564);.
LZ77UnCompReadNormalWrite8bit($ 03001564, $03000564);.
BitUnPack($ 03000564, $06000040, 
sourceLength: $800,.
sourceWidth: 2,.
destWidth: 8,.
dataOffset: 0.
);.

I had the ability to bodge together some C# code to extract the sprite data and unload it out to a photo data. I after that bodged together some even more code to review the image file, cut it to 2 bits per pixel, and compress the information in the fashion the BIOS expects. I could then just customize the photo data, run the code, and Id get a customized BIOS documents with the brand-new sprites.

This does not work all the time though. If the sprites have excessive entropy, the compression wont be able to keep the data under $ 370 bytes, and I think the halfway-stage compressed information has a top size restriction also. The good news is I procured the information I desired under the size limit, however I did have a number of fallen short attempts while exploring.

While Im certain plenty of you desire my tooling for this, I wont be releasing it. Its a hacky and buggy mess Im not specifically pleased with, and I don’t really seem like tidying it up or fielding assistance demands. This need to have given you enough detail to construct a comparable tool on your own if youre truly figured out though;-RRB- Oh, and there was a reward GDPR joke tweet that exploded a little bit too, made with the exact same strategies.