- 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
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, because it does not penalize for the simple values.
This repository collects resources to use this compression algorithm definition. It includes the encoder for Visual Basic .net and the decoder for C, Assembler and MSX BASIC.
This project is an Open Source library.
It is primarily designed for graphical data from the TMS9918A, where repetitions of values are often found, especially in the color table.
In the source code you can find applications for testing and learning purposes.
It is inspired by the Wonder Boy RLE compression algorithm, published on the 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.
- 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 decompression directly 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.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
unRLEWBtoRAM.asm
- For asMSX on MSX BIOS (ROM or BASIC)
unRLEWBtoRAM.asm
- For asMSX on MSX-DOS
unRLEWBtoRAM.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 encoder 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, although the main advantage is 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 itself 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.
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=&H80 THEN 9150
9120 POKE DE,A
9130 DE=DE+1
9140 GOTO 9100
9150 READ A
9160 IF A=&HFF THEN RETURN
9170 IF A=0 THEN A=&H80:GOTO 9120
9180 READ B
9190 FOR DE=DE TO DE+A
9200 POKE DE,B
9210 NEXT
9220 GOTO 9100
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 RESTORE 1020
120 DE=&HE000
130 GOSUB 9100
140 END
1000 REM Tileset Pattern data All BANKs
1010 REM RLE WB compressed - Original size= 6144 - Compress size= 1368
1020 DATA 128,254,,128,10,,1,3,7,15,31,63,15,127,128,213
1030 DATA 255,240,254,128,5,255,,,128,,192,224,240,248,252,128
1040 DATA 15,,63,128,2,127,128,3,255,248,224,192,128,,128,
1050 DATA 128,210,,31,7,3,1,1,128,2,,252,128,2,254,128
...
1870 DATA 128,254,,128,205,,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=&H80 THEN 9150
9120 VPOKE DE,A
9130 DE=DE+1
9140 GOTO 9100
9150 READ A
9160 IF A=&HFF THEN RETURN
9170 IF A=0 THEN A=&H80:GOTO 9120
9180 READ B
9190 FOR DE=DE TO DE+A
9200 VPOKE DE,B
9210 NEXT
9220 GOTO 9100
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
You can find the complete example in here.
100 REM Test unRLEWB to VRAM
110 DEFINT A-Z
120 COLOR 15,4,4
130 SCREEN 2
140 RESTORE 1020
150 DE=BASE(12)
160 GOSUB 9100
170 IF INKEY$="" THEN 170
180 END
1000 REM Tileset Pattern data All BANKs
1010 REM RLE WB compressed - Original size= 6144 - Compress size= 1368
1020 DATA 128,254,,128,10,,1,3,7,15,31,63,15,127,128,213
1030 DATA 255,240,254,128,5,255,,,128,,192,224,240,248,252,128
1040 DATA 15,,63,128,2,127,128,3,255,248,224,192,128,,128,
1050 DATA 128,210,,31,7,3,1,1,128,2,,252,128,2,254,128
...
1870 DATA 128,254,,128,205,,128,255
GetRLEWB | ||
---|---|---|
Function | GetRLEWB(ByVal data() As Byte) As Byte() | |
Compress input Byte Array | ||
Input | Byte() | Raw data |
Output | Byte() | Compress 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
- Avelino Herrera >
WEB
- Nerlaska >
Blog
- MSXKun/Paxanga soft >
WEB
- Fubukimaru
gitHub
- Marq >
Marq
- Sapphire/Z80ST >
WEB
- Andrear >
Blog
- Konamiman
gitHub
WEB
- 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
- fMSX emulator by Marat Fayzullin
WEB
- Meisei emulator by Hap >>
?