diff options
author | ElectroDeoxys <ElectroDeoxys@gmail.com> | 2021-02-17 10:55:58 +0000 |
---|---|---|
committer | ElectroDeoxys <ElectroDeoxys@gmail.com> | 2021-02-17 10:55:58 +0000 |
commit | 4155ce971b75265261b473dff137d37fa11d9409 (patch) | |
tree | 63ada85eb8635e27609247c6e6c71579f2adc131 /src | |
parent | 046d7d3901a4907910c83e4542d9dc11496a1795 (diff) |
Improve decompression documentation
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/bank03.asm | 2 | ||||
-rw-r--r-- | src/engine/bank1c.asm | 4 | ||||
-rw-r--r-- | src/engine/bank20.asm | 2 | ||||
-rw-r--r-- | src/engine/home.asm | 119 | ||||
-rw-r--r-- | src/wram.asm | 50 |
5 files changed, 110 insertions, 67 deletions
diff --git a/src/engine/bank03.asm b/src/engine/bank03.asm index 1b4207b..42cc0a0 100644 --- a/src/engine/bank03.asm +++ b/src/engine/bank03.asm @@ -496,7 +496,7 @@ Func_c38f: ; c38f (3:438f) jr z, .skip push hl - ld b, HIGH(wc000) + ld b, HIGH(wDecompressionSecondaryBuffer) call InitDataDecompression ld a, [wd23d] ld [wTempPointerBank], a diff --git a/src/engine/bank1c.asm b/src/engine/bank1c.asm index 1408f18..d657ba1 100644 --- a/src/engine/bank1c.asm +++ b/src/engine/bank1c.asm @@ -260,7 +260,7 @@ Func_701e9: ; 701e9 (1c:41e9) push bc ld e, l ld d, h - ld b, HIGH(wc000) + ld b, HIGH(wDecompressionSecondaryBuffer) call InitDataDecompression pop bc pop de @@ -429,7 +429,7 @@ DecompressSGBPalette: ; 70403 (1c:4403) push bc ld e, l ld d, h - ld b, HIGH(wc000) + ld b, HIGH(wDecompressionSecondaryBuffer) call InitDataDecompression pop bc ld de, wDecompressionBuffer diff --git a/src/engine/bank20.asm b/src/engine/bank20.asm index 18f4d59..feae9f4 100644 --- a/src/engine/bank20.asm +++ b/src/engine/bank20.asm @@ -109,7 +109,7 @@ Func_800bd: ; 800bd (20:40bd) ld a, [wTempPointer + 1] adc $00 ld d, a - ld b, HIGH(wc000) + ld b, HIGH(wDecompressionSecondaryBuffer) call InitDataDecompression ld a, [wVRAMPointer] ld e, a diff --git a/src/engine/home.asm b/src/engine/home.asm index f12f24d..b0971cf 100644 --- a/src/engine/home.asm +++ b/src/engine/home.asm @@ -1519,33 +1519,31 @@ UpdateRNGSources: ; 089b (0:089b) pop hl ret -; initilizes variables used to decompress -; data in DecompressData -; de points to the source of compressed data -; b is used as the HIGH byte of the -; WRAM address to write to ($100 bytes of buffer space) +; initilizes variables used to decompress data in DecompressData +; de = source of compressed data +; b = HIGH byte of secondary buffer ($100 bytes of buffer space) ; also clears this $100 byte space InitDataDecompression: ; 08bf (0:08bf) - ld hl, wcad6 + ld hl, wDecompSourcePosPtr ld [hl], e inc hl ld [hl], d - ld hl, wcad8 - ld [hl], $1 + ld hl, wDecompNumCommandBitsLeft + ld [hl], 1 inc hl xor a - ld [hli], a ; wcad9 - ld [hli], a ; wcada - ld [hli], a ; wcadb - ld [hli], a ; wcadc - ld [hl], b ; wcadd + ld [hli], a ; wDecompCommandByte + ld [hli], a ; wDecompRepeatModeToggle + ld [hli], a ; wDecompRepeatLengths + ld [hli], a ; wDecompNumBytesToRepeat + ld [hl], b ; wDecompSecondaryBufferPtrHigh inc hl - ld [hli], a ; wcade - ld [hl], $ef ; wcadf + ld [hli], a ; wDecompRepeatSeqOffset + ld [hl], LOW(wDecompressionSecondaryBufferStart) ; wDecompSecondaryBufferPtrLow ; clear buffer ld h, b - ld l, LOW(wc000) + ld l, LOW(wDecompressionSecondaryBuffer) xor a .loop ld [hl], a @@ -1555,7 +1553,7 @@ InitDataDecompression: ; 08bf (0:08bf) ; decompresses data ; uses values initialized by InitDataDecompression -; wcad6 holds the pointer for compressed source +; wDecompSourcePosPtr holds the pointer for compressed source ; input: ; bc = row width ; de = buffer to place decompressed data @@ -1576,99 +1574,110 @@ DecompressData: ; 08de (0:08de) pop hl ret -; instructions start with a byte stored in wcad9 -; its bits are read from higher to lower bit -; wcad8 stores the current bit being read -; bit set: -; - 1 byte read and copied literally -; bit not set: -; - 2 bytes read WW XY ZZ, byte in pos WW -; copied (X + 1) times, then in pos ZZ -; copied (Y + 1) times +; decompression works as follows: +; first a command byte is read that will dictate how the +; following bytes will be copied +; the position will then move to the next byte (0xXY), and +; the command byte's bits are read from higher to lower bit +; - if command bit is set, then copy 0xXY to buffer; +; - if command bit is not set, then decompression enters "repeat mode," +; which means it stores 0xXY in memory as number of bytes to repeat +; from a given offset. This offset is in the next byte in the data, +; 0xZZ, which tells the offset to start repeating. A toggle is switched +; each time the algorithm hits "repeat mode": +; - if off -> on it reads 0xXY and stores it, +; then repeats (0x0X + 2) bytes from the offset starting at 0xZZ; +; - if on -> off, then the data only provides the offset, +; and the previous byte read for number of bytes to repeat, 0xXY, is reused +; in which case (0x0Y + 2) bytes are repeated starting from the offset. .Decompress: ; 08ef (0:08ef) - ld hl, wcadc + ld hl, wDecompNumBytesToRepeat ld a, [hl] or a - jr z, .read_instruction + jr z, .read_command -; still repeating byte +; still repeating sequence dec [hl] inc hl .repeat_byte - ld b, [hl] ; wcadd + ld b, [hl] ; wDecompSecondaryBufferPtrHigh inc hl - ld c, [hl] ; wcade + ld c, [hl] ; wDecompRepeatSeqOffset inc [hl] inc hl ld a, [bc] - ld c, [hl] ; wcadf + ld c, [hl] ; wDecompSecondaryBufferPtrLow inc [hl] ld [bc], a ret -.read_instruction - ld hl, wcad6 +.read_command + ld hl, wDecompSourcePosPtr ld c, [hl] inc hl ld b, [hl] - inc hl ; wcad8 + inc hl ; wDecompNumCommandBitsLeft dec [hl] - inc hl ; wcad9 - jr nz, .asm_914 - dec hl ; wcad8 + inc hl ; wDecompCommandByte + jr nz, .read_command_bit + dec hl ; wDecompNumCommandBitsLeft ld [hl], $8 ; number of bits - inc hl ; wcad9 + inc hl ; wDecompCommandByte ld a, [bc] inc bc ld [hl], a -.asm_914 +.read_command_bit rl [hl] ld a, [bc] inc bc - jr nc, .asm_92a + jr nc, .repeat_command ; copy 1 byte literally - ld hl, wcad6 + ld hl, wDecompSourcePosPtr ld [hl], c inc hl ld [hl], b - ld hl, wcadd + ld hl, wDecompSecondaryBufferPtrHigh ld b, [hl] inc hl inc hl - ld c, [hl] ; wcadf + ld c, [hl] ; wDecompSecondaryBufferPtrLow inc [hl] ld [bc], a ret -.asm_92a - ld [wcade], a - ld hl, wcada +.repeat_command + ld [wDecompRepeatSeqOffset], a ; save the offset to repeat from + ld hl, wDecompRepeatModeToggle bit 0, [hl] - jr nz, .asm_94a + jr nz, .repeat_mode_toggle_on set 0, [hl] inc hl +; read byte for num of bytes to read +; and use its higher nybble ld a, [bc] inc bc - ld [hli], a ; wcadb + ld [hli], a ; wDecompRepeatLengths swap a -.asm_93c +.get_sequence_len and $f inc a ; number of times to repeat - ld [hli], a ; wcadc + ld [hli], a ; wDecompNumBytesToRepeat push hl - ld hl, wcad6 + ld hl, wDecompSourcePosPtr ld [hl], c inc hl ld [hl], b pop hl jr .repeat_byte -.asm_94a +.repeat_mode_toggle_on +; get the previous byte (num of bytes to repeat) +; and use its lower nybble res 0, [hl] inc hl - ld a, [hli] ; wcadb - jr .asm_93c + ld a, [hli] ; wDecompRepeatLengths + jr .get_sequence_len ; set attributes for [hl] sprites starting from wOAM + [wOAMOffset] / 4 ; return carry if reached end of wOAM before finishing diff --git a/src/wram.asm b/src/wram.asm index 85c839b..e5f8b9c 100644 --- a/src/wram.asm +++ b/src/wram.asm @@ -15,6 +15,22 @@ NEXTU wc000:: ; c000 ds $100 +NEXTU + +; aside from wDecompressionBuffer, which stores the +; de facto final decompressed data after decompression, +; this buffer stores a secondary buffer that is used +; for "lookbacks" when repeating byte sequences. +; actually starts in the middle of the buffer, +; at wDecompressionSecondaryBufferStart, then wraps back up +; to wDecompressionSecondaryBuffer. +; this is used so that $00 can be "looked back", since anything +; before $ef is initialized to 0 when starting decompression. +wDecompressionSecondaryBuffer:: ; c000 + ds $ef +wDecompressionSecondaryBufferStart:: ; ; c0ef + ds $11 + ENDU ds $100 @@ -543,30 +559,48 @@ wDoFrameFunction:: ; cad3 wcad5:: ; cad5 ds $1 -wcad6:: ; cad6 +; pointer to keep track of where +; in the source data we are while +; running the decompression algorithm +wDecompSourcePosPtr:: ; cad6 ds $2 -wcad8:: ; cad8 +; number of bits that are still left +; to read from the current command byte +wDecompNumCommandBitsLeft:: ; cad8 ds $1 -wcad9:: ; cad9 +; command byte from which to read the bits +; to decompress source data +wDecompCommandByte:: ; cad9 ds $1 -wcada:: ; cada +; if bit 7 is changed from off to on, then +; decompression routine will read next two bytes +; for repeating previous sequence (num of bytes, offset) +; if changes from off to on, then the routine +; will only read one byte, and reuse previous num of bytes +wDecompRepeatModeToggle:: ; cada ds $1 -wcadb:: ; cadb +; stores in both nybbles the length of the +; sequences to copy in decompression +; the high nybble is used first, then the low nybble +; for a subsequent sequence repition +wDecompRepeatLengths:: ; cadb ds $1 -wcadc:: ; cadc +wDecompNumBytesToRepeat:: ; cadc ds $1 -wcadd:: ; cadd +wDecompSecondaryBufferPtrHigh:: ; cadd ds $1 -wcade:: ; cade +; offset to repeat byte from decompressed data +wDecompRepeatSeqOffset:: ; cade ds $1 +wDecompSecondaryBufferPtrLow:: ; cadf ds $1 wTempSGBPacket:: ; cae0 |