I'm trying to write a tool for the 1994 SNES game Super Metroid that creates "out of bound" maps for each the game's rooms. To do so, first I need to extract the tile-by-tile data of each room. For example, the screen below shows 16 x 16 tiles, though of course the room itself is much bigger.
There's this incredible guide that details the ROM. Using it, I've found some example room data:
* Actually, it goes beyond the highlighted area. I just don't know yet how many bytes are room data.
This room data is compressed though. The guide doesn't go into the details of decompression, and the only resource I can find about how to decompress that data is a .txt file uploaded in 2011 to romhacking.net. Here are its contents:
+--------------------------------------------------------------------------------------------------------------+
|=Decompression=Routine=[$80:B0FF-$80:B270]====================================================================|
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
|=Command=Name=|=Hex=|=Binary====|=Syntax==================|=Range======|=Notes================================|
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $00 | %00000000 | | | Copies the next (# + 1) bytes from |
| Direct Copy | .. | CMD..... | [%000xxxxx : xxxxx = #] | 1-32 bytes | Compressed Data (CD) to RAM. |
| | $1F | %00011111 | | | |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $20 | %00100000 | | | Writes the next byte (# + 1) bytes |
| Byte Fill | .. | CMD..... | [%001xxxxx : xxxxx = #] | 1-32 bytes | deep to RAM. |
| | $3F | %00111111 | | | |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $40 | %01000000 | | | Writes the next word (# + 1) bytes |
| Word Fill | .. | CMD..... | [%010xxxxx : xxxxx = #] | 1-32 bytes | deep to RAM. |
| | $5F | %01011111 | | | |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $60 | %01100000 | | | Writes the next byte to RAM. Then |
| Sigma Fill | .. | CMD..... | [%011xxxxx : xxxxx = #] | 1-32 bytes | adds 1 to that byte and writes it |
| | $7F | %01100000 | | | again...etc. Writes (# + 1) times. |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $80 | %10000000 | | | Copies (# + 1) bytes from the RAM |
| Library Copy | .. | CMD..... | [%100xxxxx : xxxxx = #] | 1-32 bytes | address provided in the next two |
| | $9F | %10011111 | | | bytes. |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $A0 | %10100000 | | 1-32 bytes | Much like the Library Copy. The only |
| EORed Copy | .. | CMD..... | [%101xxxxx : xxxxx = #] | $7F:0000 - | difference is that all data copied |
| | $BF | %10111111 | | $7F:FFFF | is EORed with %11111111. |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $C0 | %11000000 | | 1-32 bytes | Subtracts next byte from Y, the RAM |
| Minus Copy | .. | CMD..... | [%110xxxxx : xxxxx = #] | 0-255 from | offset, and copies (# + 1) bytes to |
| | $DF | %11011111 | | current Y | current Y. Can copy last tile. |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | $E0 | %111 000 00-->Bits 8 9 of X (aka #) | 1-1024 | Extends the range of previous CMDs |
| | | ||| --------------------- | bytes | from 1-32, to 1-1024 bytes deep. |
| | | CMD----->Command Code. Any one | | |
| Extended CMD | .. | of the previous 7 CMD | $7F:0000 - | Specifically, Bits 7-5 flag the ECMD,|
| | | patterns can go here. | $7F:FFFF | & Bits 4-2 are interpreted as a CMD. |
| | | --------------------- | RAM | Bits 1-0 & the next byte are treated |
| | $FE | %111 111 11 | | as a 10-bit value for X, aka #. |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
| | | | | | |
| Terminate SR | $FF | %11111111 | [%11111111] | ---- | Terminates Sub Routine |
| | | | | | |
+--------------+-----+-----------+-------------------------+------------+--------------------------------------+
** Full credit to um... UnicornPoop.
I understand each of these rows to be sequential instructions. What am I missing though to translate this into pseudocode that a non-"old school" programmer like myself can understand? For example, take this:
Copies the next (# + 1) bytes from Compressed Data (CD) to RAM.
What is #
? What exactly am I supposed to do to the room data, 01 00 0a e9 ...
? Or what knowledge am I missing to understand what's going on here.
Thanks in advance.