Run-Length Encoding WB
- 1 Description
- 2 Encoder format
- 3 Software to compress in RLEWB
- 4 C decoders
- 5 Assembler decoders
- 6 MSX BASIC
- 7 Visual Basic dotnet
- 8 Acknowledgments
- 9 References
RLEWB is a compressor of the RLE type (Run-Length Encoding), with the advantage that it improves the results in data sequences where there are not many series of repeated values. This is because it does not penalize for the simple values.
It is designed for graphical data where repeating values are often found, although positive results are obtained on other types of data as well.
This repository collects resources to use this compression algorithm. It includes the encoder for Visual Basic .net and the decoder for C, Assembler and MSX BASIC.
This project is an Open Source library.
In the source code you can find applications for testing and learning purposes.
Note: |
---|
RLEWB encoder is inspired in Wonder Boy RLE compression algorithm, published on SMS POWER! WEBSITE. |
CD = Control Digit = $80
CD + $0 --> When the value to be written to the output is equal to the Control Digit
CD + $FF --> End - Decompressed until it finds this value.
CD + nn + dd --> Repeat nn+1 ($2 to $FE) value equivalent to 3 up to 255 repetitions.
In dd is the value to repeat.
dd (!= CD) --> Raw data. Values without repetition.
---------- HELLO WORLD________4444
34 Bytes
80,09,2D,20,48,45,4C,4C,4F,20,57,4F,52,4C,44,80,07,5F,80,03,34,80,FF
23 Bytes
CD + 9 + "-"
+ " HELLO WORLD"
+ CD + 7 + "_"
+ CD + 3 + "4"
+ CD + $FF
- RLE-WB compressor for MSX Fusion-C by Eric Boez.
MacOS
Windows 64bits
Linux 64bits
- ByteniZ3R devtool Another generator of data tables in Bytes.
.net 4
For direct decompression to VRAM, two libraries (.rel) are available, depending on the execution environment (MSX-DOS or BIOS ROM/BASIC).
unRLEWBtoRAM | ||
---|---|---|
Decompress RLEWB data to RAM | ||
Function | void unRLEWBtoRAM (unsigned int sourceADDR, unsigned int targetADDR) | |
Input | unsigned int | source data address |
unsigned int | target VRAM address |
Example
// RLE WB compressed - Original size=2048 - Compress size=33
const char DATA_COL[]={
0x80,0xFE,0xFC,0x80,0xFE,0xFC,0xFC,0xFC,0x80,0x3F,0xF2,0x80,
0x0F,0x51,0x80,0x0F,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80,
0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80,
0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80,
0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80,
0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80,
0x07,0x51,0x80,0xB7,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80,
0x0F,0x51,0x80,0x0F,0xF2,0x80,0x17,0x51,0x80,0x67,0xF2,0x80,
0xFE,0xF3,0x80,0xFE,0xF3,0xF3,0xF3,0x80,0xFF};
void main()
{
unRLEWBtoRAM ((unsigned int) DATA_COL, 0xD000);
}
unRLEWBRAM | ||
---|---|---|
Decompress RLEWB data to RAM | ||
Input | HL | source data address |
DE | target RAM address |
Example
void SetDATA() __naked
{
__asm
;decompress to RAM
ld HL,#DATA_COL
ld DE,#0xD000 ;RAM addr
call unRLEWBRAM
;copy to VRAM
ld HL,#0xD000 ;RAM addr
ld DE,#0x2000 ;VRAM addr
ld BC,#0x800 ;length
call 0x005C ;LDIRVM
ret
DATA_COL:
.db 0x80,0xFE,0xFC,0x80,0xFE,0xFC,0xFC,0xFC,0x80,0x3F,0xF2,0x80
.db 0x0F,0x51,0x80,0x0F,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80
.db 0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80
.db 0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80
.db 0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80
.db 0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80
.db 0x07,0x51,0x80,0xB7,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80
.db 0x0F,0x51,0x80,0x0F,0xF2,0x80,0x17,0x51,0x80,0x67,0xF2,0x80
.db 0xFE,0xF3,0x80,0xFE,0xF3,0xF3,0xF3,0x80,0xFF
__endasm;
}
- MSX with BIOS (ROM or MSX BASIC)
unRLEWBtoVRAM.rel
- MSX-DOS
unRLEWBtoVRAM_MSXDOS.rel
unRLEWBtoVRAM.h
unRLEWBtoVRAM | ||
---|---|---|
Decompress RLEWB data to VRAM | ||
Function | void unRLEWBtoVRAM (unsigned int sourceADDR, unsigned int targetADDR) | |
Input | unsigned int | source data address |
unsigned int | target VRAM address |
Example
// RLE WB compressed - Original size=2048 - Compress size=33
const char DATA_COL[]={
0x80,0xFE,0xFC,0x80,0xFE,0xFC,0xFC,0xFC,0x80,0x3F,0xF2,0x80,
0x0F,0x51,0x80,0x0F,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80,
0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80,
0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80,
0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80,
0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80,
0x07,0x51,0x80,0xB7,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80,
0x0F,0x51,0x80,0x0F,0xF2,0x80,0x17,0x51,0x80,0x67,0xF2,0x80,
0xFE,0xF3,0x80,0xFE,0xF3,0xF3,0xF3,0x80,0xFF};
void main()
{
unRLEWBtoVRAM ((unsigned int) DATA_COL, 0x2000);
}
unRLEWBVRAM | ||
---|---|---|
Decompress RLEWB data to VRAM | ||
Input | HL | source data address |
DE | target VRAM address |
Example
void SetGFX() __naked
{
__asm
ld HL,#DATA_COL
ld DE,#0x2000 ;BASE11 Color Table
call unRLEWBVRAM
ret
; RLE WB compressed - Original size=2048 - Compress size=105
DATA_COL:
.db 0x80,0xFE,0xFC,0x80,0xFE,0xFC,0xFC,0xFC,0x80,0x3F,0xF2,0x80
.db 0x0F,0x51,0x80,0x0F,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80
.db 0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80
.db 0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80
.db 0x07,0x51,0x80,0xAF,0xF2,0x80,0x07,0x51,0x80,0x17,0xF2,0x80
.db 0x07,0x51,0x80,0x0F,0xF2,0x80,0x07,0x51,0x80,0x07,0xF2,0x80
.db 0x07,0x51,0x80,0xB7,0xF2,0x80,0x0F,0x51,0x80,0x0F,0xF2,0x80
.db 0x0F,0x51,0x80,0x0F,0xF2,0x80,0x17,0x51,0x80,0x67,0xF2,0x80
.db 0xFE,0xF3,0x80,0xFE,0xF3,0xF3,0xF3,0x80,0xFF
__endasm;
}
It is available with support for cross-development assemblers: asMSX, Sjasm and tniASM.
An adapted source is available for all three assemblers but it doesn't work with the current version of asMSX v.1.0.1, as there is a pending Bug related to Conditional Assembly [#90](https://github.com/Fubukimaru/asMSX/issues/90)
.
Therefore you will find asMSX-specific sources for BIOS-based environments (ROM and BASIC) and MSX-DOS.
You can add the following Labels to your main code, to configure the decompressor for different environments:
Note: For Sjasm assembler, use DEFINE + Label
- Identify the assembler (
ASMSX
,SJASM
orTNIASM
) Default: ASMSX/SJASM - Runtime (
MSXROM
,MSXDOS
orMSXBASIC
) Default: MSXROM/MSXBASIC DIRECTRANGE
if you have a compressor that generated a range from 3 to 254 repetitions.
A cross assembler:
- For Sjasm and tniASM
unRLEWBtoRAM.asm
- For asMSX
unRLEWBtoRAM_ASMSX.asm
unRLEWBtoRAM | ||
---|---|---|
Decompress RLEWB data to RAM | ||
Input | HL | source data address |
DE | target RAM address |
Example
;decompress to RAM
ld HL,DATA_COL
ld DE,0xD000
call unRLEWBtoRAM
;copy to VRAM
ld HL,#0xD000 ;RAM addr
ld DE,#0x2000 ;VRAM addr
ld BC,#800 ;length
call 0x005C ;LDIRVM
ret
; RLE WB compressed - Original size=2048 - Compress size=105
DATA_COL:
db $80,$FE,$FC,$80,$FE,$FC,$FC,$FC,$80,$3F,$F2,$80,$0F,$51,$80,$0F
db $F2,$80,$0F,$51,$80,$0F,$F2,$80,$07,$51,$80,$AF,$F2,$80,$07,$51
db $80,$17,$F2,$80,$07,$51,$80,$0F,$F2,$80,$07,$51,$80,$07,$F2,$80
db $07,$51,$80,$AF,$F2,$80,$07,$51,$80,$17,$F2,$80,$07,$51,$80,$0F
db $F2,$80,$07,$51,$80,$07,$F2,$80,$07,$51,$80,$B7,$F2,$80,$0F,$51
db $80,$0F,$F2,$80,$0F,$51,$80,$0F,$F2,$80,$17,$51,$80,$67,$F2,$80
db $FE,$F3,$80,$FE,$F3,$F3,$F3,$80,$FF
- For Sjasm and tniASM
unRLEWBtoVRAM.asm
- For asMSX on MSX BIOS (ROM or BASIC)
unRLEWBtoVRAM_MSXROM_ASMSX.asm
- For asMSX on MSX-DOS
unRLEWBtoVRAM_MSXDOS_ASMSX.asm
unRLEWBtoVRAM | ||
---|---|---|
Decompress RLEWB data to VRAM | ||
Input | HL | source data address |
DE | target VRAM address |
Example
ld HL,DATA_COL
ld DE,$2000 ;BASE11 Color Table
call unRLEWBtoVRAM
ret
; RLE WB compressed - Original size=2048 - Compress size=105
DATA_COL:
db $80,$FE,$FC,$80,$FE,$FC,$FC,$FC,$80,$3F,$F2,$80,$0F,$51,$80,$0F
db $F2,$80,$0F,$51,$80,$0F,$F2,$80,$07,$51,$80,$AF,$F2,$80,$07,$51
db $80,$17,$F2,$80,$07,$51,$80,$0F,$F2,$80,$07,$51,$80,$07,$F2,$80
db $07,$51,$80,$AF,$F2,$80,$07,$51,$80,$17,$F2,$80,$07,$51,$80,$0F
db $F2,$80,$07,$51,$80,$07,$F2,$80,$07,$51,$80,$B7,$F2,$80,$0F,$51
db $80,$0F,$F2,$80,$0F,$51,$80,$0F,$F2,$80,$17,$51,$80,$67,$F2,$80
db $FE,$F3,$80,$FE,$F3,$F3,$F3,$80,$FF
The RLEWB decoder is so simple that it can be easily programmed in MSX BASIC.
Although it may not seem like it, it can be faster than directly reading the data and dumping it to memory, since repeated data is written faster. However, the main advantage is still that you can reduce the size of your program.
Remember that when writing the DATA in BASIC it is not necessary to include the zeros.
The best option would be to include the decompression routine in the binary that includes the data and execute it on load, but it would be a task that you would have to do yourself since there is no tool that makes it easy for you.
To use it, you will have to do a RESTORE
with the line number where the data starts,
provide the value of the RAM address to the DE
variable and do a GOSUB 9100
.
Example
100 REM Test unRLEWB to RAM
110 DEFINT A-Z
120 SCREEN 1
122 WIDTH 32
130 PRINT "Decompress data to RAM"
140 RESTORE 1020
150 DE=&HE000
160 GOSUB 9100
170 PRINT "Copy RAM to VRAM"
180 DE=BASE(5)+(32*2)
190 FOR BC=&HE000 TO &HE160
200 A=PEEK(BC)
210 VPOKE DE,A
220 DE=DE+1
230 NEXT
240 IF INKEY$="" THEN 240
250 LOCATE 0,14
260 END
1000 REM map size width:32 height:11
1010 REM RLE WB compressed - Original size=352 - Compress size=103
1020 DATA 24,128,29,23,25,22,128,29,32,22,22,128,29,32,22,22
1030 DATA 128,29,32,22,22,128,8,32,72,101,108,108,111,32,87,111
1040 DATA 114,108,100,33,128,8,32,22,22,128,29,32,22,22,128,29
1050 DATA 32,22,22,128,29,32,22,26,128,4,23,18,128,17,23,18
1060 DATA 128,4,23,27,128,5,32,22,32,80,114,101,115,115,32,97
1070 DATA 110,121,32,107,101,121,128,3,32,22,128,11,32,26,128,17
1080 DATA 23,27,128,5,32,128,255
9000 '=================================
9010 ' unRLEWB to RAM for MSX BASIC
9020 ' Decompress RLEWB data to RAM
9030 ' Input:
9040 ' RESTORE [line] <-- DATAs
9050 ' DE <-- RAM address
9060 '=================================
9100 READ A
9110 IF A=128 THEN 9130
9120 POKE DE,A:DE=DE+1:GOTO 9100
9130 READ B
9140 IF B=255 THEN RETURN
9150 IF B=0 THEN 9120
9160 READ A
9170 FOR DE=DE TO DE+B:POKE DE,A:NEXT
9180 GOTO 9100
Run it on MSXPen
You can find another example here.
To use it, you will have to do a RESTORE
with the line number where the data starts,
provide the value of the VRAM address to the DE
variable and do a GOSUB 9100
.
Example
100 REM Test unRLEWB to VRAM
101 DEFINT A-Z
110 COLOR 15,4,5
120 SCREEN 1
122 WIDTH 32
130 RESTORE 1020
140 DE=BASE(5)
150 GOSUB 9100
160 LOCATE 22,9
170 IF INKEY$="" THEN 170
190 END
1000 REM map size width:32 height:11
1010 REM RLE WB compressed - Original size=352 - Compress size=103
1020 DATA 24,128,29,23,25,22,128,29,32,22,22,128,29,32,22,22
1030 DATA 128,29,32,22,22,128,8,32,72,101,108,108,111,32,87,111
1040 DATA 114,108,100,33,128,8,32,22,22,128,29,32,22,22,128,29
1050 DATA 32,22,22,128,29,32,22,26,128,4,23,18,128,17,23,18
1060 DATA 128,4,23,27,128,5,32,22,32,80,114,101,115,115,32,97
1070 DATA 110,121,32,107,101,121,128,3,32,22,128,11,32,26,128,17
1080 DATA 23,27,128,5,32,128,255
9000 '=================================
9010 ' unRLEWB to VRAM for MSX BASIC
9020 ' Decompress RLEWB data to VRAM
9030 ' Input:
9040 ' RESTORE [line] <-- DATAs
9050 ' DE <-- VRAM address
9060 '=================================
9100 READ A
9110 IF A=128 THEN 9130
9120 VPOKE DE,A:DE=DE+1:GOTO 9100
9130 READ B
9140 IF B=255 THEN RETURN
9150 IF B=0 THEN 9120
9160 READ A
9170 FOR DE=DE TO DE+B:VPOKE DE,A:NEXT
9180 GOTO 9100
Run it on MSXPen
You can find another example here.
Compress | ||
---|---|---|
Function | Compress(ByVal data() As Byte) As Byte() | |
Compress the input Byte Array | ||
Input | Byte() | Raw data |
Output | Byte() | Compress data |
Decompress | ||
---|---|---|
Function | Decompress(ByVal data() As Byte) As Byte() | |
Decompress the input Byte Array. | ||
Input | Byte() | Compress data |
Output | Byte() | Raw data |
I want to give a special thanks to all those who freely share their knowledge with the Retrocomputing developer community.
- SMS Power >
WEB
- SDsnatcher >
WEB
- Eric Boez >
gitHub
- MSX Assembly Page >
WEB
- Portar MSX Tech Doc >
WEB
- MSX Resource Center >
WEB
- Karoshi MSX Community >
WEB
- BlueMSX emulator >>
WEB
- OpenMSX emulator >>
WEB
WebMSX
emulator by Paulo A. Peccin >>gitHub
MSXPen
by Rafael Jannone- fMSX emulator by Marat Fayzullin
WEB
- Meisei emulator by Hap >>
?
- Run-Length Encoding
- Wonder Boy RLE compression algorithm.