Technical appendix · Home · Français
Used by .HUF streams and by G3.CON record
0x27 subs 9 and 10. Those two are the only
.CON payloads that pass try_decompress. All of
this is implemented by maup_parse.py.
| Routine | EA | Role |
|---|---|---|
Lz_DecompressFar |
0x19D92 |
entry: AX = length low, DX = length high; clears state, sets limit |
Lz_Decompress |
0x19C6A |
main loop, owns the ring window |
Lz_ReadToken |
0x19BD6 |
tree walk to a symbol |
Lz_ReadDistance |
0x19C14 |
distance decode |
Lz_ReadByte / Lz_ReadBit |
0x19855 / 0x197F8 |
input |
Lz_BitInit |
0x198AF |
tree and bit-reader init |
Lz_UpdateTree / Lz_RebuildTree |
0x19ACE / 0x19958 |
adaptive update |
A stream starts with a u32 output length, skipped at
0x19C70. The tree is built at runtime, so there is no
static table to find. Decoding stops when the produced count reaches the
length.
MSB-first through a 16-bit register (DS:303E, count at
DS:3040).
tree: 314 symbols; token < 0x100 is a literal
match length = token - 0xFD (add ax,0FF03h at 0x19CF6)
c = ReadByte()
high = LzDist_ExtraBits[c] << 6 ; DS:2E3E
n = LzDist_BaseBits[c] - 2 ; DS:2F3E
acc = c; repeat n times: acc = acc*2 + ReadBit()
distance = high | (acc & 0x3F)
A 4096-byte ring at DS:6754, with its first
0xFC4 bytes filled with spaces and writing starting at
0xFC4. Match source =
(pos - distance - 1) & 0xFFF.
0x400
counter is not a chunk format0x19D4F-0x19D69 only raises
wLzProgressLimit by 0x400 when the output
passes it. Nothing reads that for decoding: it doesn't change input
position, bit state, tree or window. maup_parse.py
decodes every stream correctly without chunk handling.
selftest decodes all 29 MUS and 28
SND streams; header lengths agree and tail padding is at
most 7 bits.
Previous: File formats, scenes and palettes · Next: Video · Technical appendix · Home