gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Fast ASM decompressor - use it if you need it

#63896 - Querdopleen - Sat Dec 17, 2005 11:09 am

.GLOBL ASM_DecompressRLData

.ARM
.SECTION .iwram
.ALIGN
.TEXT

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ R0 = Source, R1 = Destination, R2 = Byte counter
@
@ R3 = St?tuszbyte, R4 = Adatbyte, R5 = Ugr?s c?m?hez haszn?lt regiszter
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.macro PUTCOMPRESSEDBYTE byteszam, index
STRB R4,[R1,#\index]
.if \byteszam-1
PUTCOMPRESSEDBYTE "(\byteszam-1)","(\index-1)"
.endif
.endm

.macro PUTUNCOMPRESSEDBYTE byteszam, index
LDRSB R4,[R0,#\index]
STRB R4,[R1,#\index]
.if \byteszam-1
PUTUNCOMPRESSEDBYTE "(\byteszam-1)","(\index-1)"
.endif
.endm

ASM_DecompressRLData:
STMFD SP!,{R4-R5}

DRLDCIKLUS:
LDRSB R3,[R0],#1
AND R3,R3,#0xff @ előjel kiterjesztett ?s ?gy a felső 3 byte-ot t?r?lni kell, hogy j? sz?ml?l? legyen
TST R3,#0x80
BEQ UNCOMPRESSED
@ Compressed
LDRSB R4,[R0],#1 @ Sokszorozand? byte
SUB R3,R3,#0x7d @ Bytesz?m
RSB R5,R3,#130 @ 130-Bytesz?m
MOV R5,R5,LSL#2 @ (130-Bytesz?m)*4 - Ez m?r a c?mz?shez j?
ADD R15,R15,R5

MOV R2,R2 @ Dummy, kell a j? c?mz?shez
PUTCOMPRESSEDBYTE 65,129
PUTCOMPRESSEDBYTE 65,64

ADD R1,R1,R3
SUBS R2,R2,R3
BNE DRLDCIKLUS
BAL END

UNCOMPRESSED:
ADD R3,R3,#1 @ Bytesz?m
RSB R5,R3,#128 @ 128-Bytesz?m
MOV R5,R5,LSL#3 @ (128-Bytesz?m)*8 - Ez m?r a c?mz?shez j?
ADD R15,R15,R5

MOV R2,R2 @ Dummy, kell a j? c?mz?shez
PUTUNCOMPRESSEDBYTE 64,127
PUTUNCOMPRESSEDBYTE 64,63

ADD R0,R0,R3
ADD R1,R1,R3
SUBS R2,R2,R3
BNE DRLDCIKLUS
@ BAL END @ R?csorog a v?g?re

END:
LDMFD SP!,{R4-R5}
BX LR

#63934 - DiscoStew - Sat Dec 17, 2005 7:09 pm

We're greatful for this, but what are R3-R5? I only know English and a slight Japanese. And am I to assume that this also can COMPRESS run-length data? Just a little documentation on it would really help a bunch of us out.
_________________
DS - It's all about DiscoStew

#63943 - poslundc - Sat Dec 17, 2005 8:57 pm

It looks like a modified RLE scheme designed to support both encoded and unencoded bytestreams.

Like most decompression routines, it's pretty useless without an encoder (or at least the encoding scheme). For this, the scheme appears to be (N[D+])* (forgive my half-assed attempt at something like a regular expression).

N is the control byte. If N is less than zero, it indicates a run of N bytes to copy straight out. If N is greater than zero it indicates a single byte to be repeated N times.

D is a data byte. If N is less than zero, then there are N data bytes. If N is greater than zero, there is only 1 data byte.

It's not a bad decompression algorithm, but could be further optimized. And, moreover, it won't decompress to VRAM (which requires 16-bit alignment).

Dan.

#63991 - Querdopleen - Sun Dec 18, 2005 9:53 am

It's able to decompress the standard RLE GBA compression. Use it instead of the standard GBA ROM procedure because it's faster (it doesn't contain loops for every single bytes so the overhead is minimal).
I found this RLE comression very useful; for example my simple background (240*160 pixel) is 17.780 bytes instead of 38.400 bytes. Sometimes it can compress better, sometimes worse.
(If you need more info about the compression technology/efficiency on GBA, please read http://members.iinet.net.au/~freeaxs/gbacomp/; very useful.)

You can use different compressors; I use gbacrusherCL in my make script (you can download it from gbadev.org)

R3,R4,R5 - work registers;
R3 - status byte (N in the previous letter)
R4 - data byte (D)
R5 - address shift; used to jump into the appropriate part of the decompression procedure; it is used instead of the loop and the loop counter.
The 2 (recursive) macros are used to prevent a lot of typing; otherwise it will create LDRSB, STRB 130 times.

#63994 - Ultima2876 - Sun Dec 18, 2005 11:33 am

Is there something similar for VRAM-safe or non-VRAM safe LZ77?