If you are still using the old URL (datacrystal.romhacking.net), please update your bookmarks! The old URL may stop working soon.
The current URL is datacrystal.tcrf.net.
The current URL is datacrystal.tcrf.net.
Final Fantasy VI/Compression Format: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
m (clarified "800 byte" to "800h byte", as the former could be misinterpreted as decimal.) |
||
Line 6: | Line 6: | ||
* 2 bytes at the start specify the size of the compressed data (self-inclusive) | * 2 bytes at the start specify the size of the compressed data (self-inclusive) | ||
* The next byte is used as 8 bitflags, read lowest bit first: 0th bit is the first bit checked, 7th bit is the last bit checked. | * The next byte is used as 8 bitflags, read lowest bit first: 0th bit is the first bit checked, 7th bit is the last bit checked. | ||
* If the next bit is set, then it puts the next byte into the destination address and in | * If the next bit is set, then it puts the next byte into the destination address and in a 2048-byte (800h) buffer. | ||
* If the next bit is clear, then it uses the next 2 bytes to copy from the buffer: | * If the next bit is clear, then it uses the next 2 bytes to copy from the buffer: | ||
** The 11 low bits are an absolute pointer into the | ** The 11 low bits are an absolute pointer into the 800h byte buffer (11 bits = xxx xxxx xxxx = max of 7FF) | ||
** The 5 high bits specify how many bytes to copy from that buffer to the destination address, plus 3 (it will copy between 3 and 66 bytes, in decimal). | ** The 5 high bits specify how many bytes to copy from that buffer to the destination address, plus 3 (it will copy between 3 and 66 bytes, in decimal). | ||
** The game copies the given bytes to the destination address AND back into the buffer. | ** The game copies the given bytes to the destination address AND back into the buffer. | ||
Line 18: | Line 18: | ||
* Destination address is in $F6 (3 bytes) | * Destination address is in $F6 (3 bytes) | ||
* Size to decompress is in $FC (2 bytes) | * Size to decompress is in $FC (2 bytes) | ||
* The | * The 800h byte buffer is located at 7F:F800 - 7F:FFFF | ||
* The game starts writing to the buffer at offset 7DE (7F:FFDE) and goes up. It goes back to 000 after 7FF. | * The game starts writing to the buffer at offset 7DE (7F:FFDE) and goes up. It goes back to 000 after 7FF. | ||
* Y holds the relative offset of the byte it's currently decompressing: ($F3) + Y = pointer to current byte | * Y holds the relative offset of the byte it's currently decompressing: ($F3) + Y = pointer to current byte | ||
* X holds the buffer offset; 7F:F800,X | * X holds the buffer offset; 7F:F800,X | ||
* When processing 'clear' bits, Y is backed up in $F9 and used as the read position in the buffer. | * When processing 'clear' bits, Y is backed up in $F9 and used as the read position in the buffer. |
Revision as of 13:53, 13 June 2013
The game has a very basic compression for some of it's data, such as the intro credits as Terra, Vicks, and Wedge are marching towards Narshe.
The compression is called by first placing the starting address of the compressed data in $F3, and the destination address in RAM in $F6, then a JSL to $C2FF6D.
The compressed data has a very simple format
- 2 bytes at the start specify the size of the compressed data (self-inclusive)
- The next byte is used as 8 bitflags, read lowest bit first: 0th bit is the first bit checked, 7th bit is the last bit checked.
- If the next bit is set, then it puts the next byte into the destination address and in a 2048-byte (800h) buffer.
- If the next bit is clear, then it uses the next 2 bytes to copy from the buffer:
- The 11 low bits are an absolute pointer into the 800h byte buffer (11 bits = xxx xxxx xxxx = max of 7FF)
- The 5 high bits specify how many bytes to copy from that buffer to the destination address, plus 3 (it will copy between 3 and 66 bytes, in decimal).
- The game copies the given bytes to the destination address AND back into the buffer.
When all 8 bits from the current bit-flag byte have been checked, the game uses the next byte as another bitflag. This loop is repeated until the game has decompressed the amount of bytes in ROM specified at the start of the compressed data.
Some notes on the actual code:
- Source address is in $F3 (3 bytes)
- Destination address is in $F6 (3 bytes)
- Size to decompress is in $FC (2 bytes)
- The 800h byte buffer is located at 7F:F800 - 7F:FFFF
- The game starts writing to the buffer at offset 7DE (7F:FFDE) and goes up. It goes back to 000 after 7FF.
- Y holds the relative offset of the byte it's currently decompressing: ($F3) + Y = pointer to current byte
- X holds the buffer offset; 7F:F800,X
- When processing 'clear' bits, Y is backed up in $F9 and used as the read position in the buffer.