Tactics Ogre:Tutorials

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Decompression at \$81/F7CC

In Tactics Ogre V 1.0, you can find a subroutine at \$81/F7CC that decompresses data. Here is how it works.

When this subroutine is called, X and A contain the address of compressed data (X the address and A the bank, of course), while the address in [\$23] contains the commands for decompression.

```[\$23] COMMANDS
Pos.    ArgB
#\$00 - \$F81C - 4
#\$01 - \$F8AA - 3
#\$02 -(\$F7EF)-
#\$03 - \$F7FE -
#\$04 - \$F88D - 2
> 04 -(\$F7FB)-
```

[\$23] = #\$01

The first argument byte is a number between 1 and 6 or 7 (I think). Some bytes of Compressed Data actually contains two values, and the first argument byte tells how many digits belong to the first number. The first number is the number of bytes to do (with some alternations), the second number is the offset from the current \$23-position as source address for the then-upcoming MVN command. The second and third argument byte (Little Endian) are a Limit value for a loop counter. The Limit value is the size of the decompressed data. The rest is decided upon the Compressed Data Bytes, until the limit value of the loop counter is reached, then the subroutine gets ended.

Structure of the corresponding Compressed Data

The data of the compressed data begins with a Command Flag Byte. These are worked of from the MSB to the LSB; If a bit/flag is set, the next byte in the Compressed Data gets transfered to the store address as it is. If it is clear, the following two bytes of data are the number of bytes to do and the offset for MVN. This is where the AND-Mask from [\$23]-Byte-1 comes into play. This tells you which digit belongs to what. The offset is Big Endian, BTW.

[\$23] = #\$04

Difference to #\$01: The Loop Counter value is in the Compressed Data

The first argument byte is a number between 1 and 6 or 7 (I think). Some bytes of Compressed Data actually contains two values, and the first argument byte tells how many digits belong to the first number. The first number is the number of bytes to do (with some alternations), the second number is the offset from the current \$23-position as source address for the then-upcoming MVN command. The second argument byte is never used, so it generally should be #\$00. The rest is decided upon the Compressed Data Bytes, until the limit value of the loop counter is reached, then the subroutine gets ended.

Structure of the corresponding Compressed Data

The data of the compressed data begins with a doublebyte that is used as a Limit value for a Loop Counter. The value is the size of the decompressed data. The next byte a Command Flag Byte. These are worked of from the MSB to the LSB; If a bit/flag is set, the next byte in the Compressed Data gets transfered to the store address as it is. If it is clear, the following two bytes of data are the number of bytes to do and the offset for MVN. This is where the AND-Mask from [\$23]-Byte-1 comes into play. This tells you which digit belongs to what. The offset is Big Endian, BTW.

Decompression at \$81/F9E5

In Tactics Ogre V 1.0, you can find a subroutine at \$81/F9E5 that decompresses data. Here is how it works.

When this subroutine is called, X and A contain the address of compressed data (X the address and A the bank, of course).

The first two bytes of the compressed data give the size of the decompressed data. After that, the next byte contains flags and commands for the decompression subroutines:

#%1xxx.xxxx Repeat Bytes

If the MSB is set, this means that already decompressed stuff has to be repeated. The second byte also belongs to this command and gets loaded after it is clear this decompression function is meant. The corresponding command double byte is structured like this:

```#%1aaa.abbb.bbbb.bbbb
```
```1 = The set MSB is the signal for this command
a = these four bit are the number of bytes to repeat minus three
b = these bits are the number of bytes to go backwards from the current position minus one
```

#%0000.0000 Go Read the Next Bank

I think this part of the subroutine is never used and was only built in for savety reasons: This subroutine increments the bank number of the Compressed Data's read address and sets the address back to \$8000 - the start of a new bank. This was built in if the compressed data overleaps into a new bank.

#%01xx.xxxx Copy directly from compressed data

```#%01aa.aaaa

a = These bits form the number of Bytes minus two
```

This transfers the next (a+1) bytes after this command unchanged into the decompressed data.

#%001x.xxxx Write \$00 Bytes

```#%001a.aaaa

a = These bits form the number of Bytes minus two
```

This writes \$00 bytes into the decompressed data. There will be at least two and thirty-three at most (a is the number of bytes minus two)

#%000x.xxxx Repeat lots of Bytes from far back

This function of the decompression uses three bytes for commands. It is the same as the first repeat function, but it can move further back and can transfer more bytes than the other one. The downside of this subroutine is that it takes more time and two more bytes in compressed data.

```FIRST BYTE

#%000a.bbbb

a = Actually not always obligatory bit to be set for this function
b = Part of the number of bytes to transfer

THIRD AND SECOND BYTE (set together in this order as one 16 bit value)

#%ccdd.dddd.dddd.dddd

c = Part of the number of bytes to transfer
d = Number of bytes to move backwards
```

Note that this subroutine does not work with the first byte being completely empty. So, if you want to set the whole "b" part to zero, you should set the "a" bit.

The number of bytes to transfer is a bit tricky. Here is how it is calculated:

```cc * #\$10 + bbbb + #\$04

Number of Bytes to transfer = #%00cc.bbbb + #\$04
```

Three is added, and the fourth additional byte comes from the structure of the MVN command.

Internal Data for Tactics Ogre

One Byte Hacks

As always, this is only checked for Tactics Ogre 1.0

```         Original Value
Position |  Effect
======== |  ======
\$9C/8B57 49 GAME INTRO: Remove the Hermit Logo entirely (replace value by 66)
\$9C/8E50 9E GAME INTRO: Timer for the Quest Logo (02 - Fastest, E3 - Slowest)
```