Skip to content

mvac7/Z80_RLEWB

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RLEWB

Run-Length Encoding WB


Index



1 Description

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.

Index


2 Encoder format

 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.

Example:

Source:

---------- HELLO WORLD________4444 34 Bytes

Result:

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


Index


3 Software to compress in RLEWB



4 C decoders

For direct decompression to VRAM, two libraries (.rel) are available, depending on the execution environment (MSX-DOS or BIOS ROM/BASIC).

4.1 Requirements

4.2 Decompress RLEWB to RAM

unRLEWBtoRAM

unRLEWBtoRAM
Decompress RLEWB data to RAM
Functionvoid unRLEWBtoRAM (unsigned int sourceADDR, unsigned int targetADDR)
Inputunsigned intsource data address
unsigned inttarget 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 (for Assembler inline)

unRLEWBRAM
Decompress RLEWB data to RAM
InputHLsource data address
DEtarget 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;
}

Index

4.3 Decompress RLEWB to VRAM

unRLEWBtoVRAM

unRLEWBtoVRAM
Decompress RLEWB data to VRAM
Functionvoid unRLEWBtoVRAM (unsigned int sourceADDR, unsigned int targetADDR)
Inputunsigned intsource data address
unsigned inttarget 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 (for Assembler inline)

unRLEWBVRAM
Decompress RLEWB data to VRAM
InputHLsource data address
DEtarget 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;
}

Index


5 Assembler decoders

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 or TNIASM) Default: ASMSX/SJASM
  • Runtime (MSXROM , MSXDOS or MSXBASIC) Default: MSXROM/MSXBASIC
  • DIRECTRANGE if you have a compressor that generated a range from 3 to 254 repetitions.

5.1 Requirements

A cross assembler:

5.2 Decompress RLEWB to RAM

unRLEWBtoRAM
Decompress RLEWB data to RAM
InputHLsource data address
DEtarget 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

Index

5.3 unRLEWBtoVRAM

unRLEWBtoVRAM
Decompress RLEWB data to VRAM
InputHLsource data address
DEtarget 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 

Index


6 MSX BASIC

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.

6.1 Decompress RLEWB to RAM

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.


Index

6.2 Decompress RLEWB to VRAM

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.


Index


7 Visual Basic dotnet

VisualBasic_dotnet/RLEWB.vb

7.1 RLEWB encoder

Compress
FunctionCompress(ByVal data() As Byte) As Byte()
Compress the input Byte Array
InputByte()Raw data
OutputByte()Compress data

7.2 RLEWB decoder

Decompress
FunctionDecompress(ByVal data() As Byte) As Byte()
Decompress the input Byte Array.
InputByte()Compress data
OutputByte()Raw data

Index


8 Acknowledgments

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 >> ?


9 References


Index