Fubukimaru / Z80_RLEWB

Resources for Run-Length Encoding WB

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RLEWB

Sorry! This text is pending correction of the English translation



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, 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.



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.


3 Software to compress in RLEWB



4 C decoders

For decompression directly 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;
}

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;
}


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 unRLEWBtoRAM

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

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 


6 MSX BASIC

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.

6.1 Decompress RLEWB to RAM

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

6.2 Decompress RLEWB to VRAM

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


7 Visual Basic dotnet

7.1 RLEWB encoder

VisualBasic_dotnet/RLEWB.vb

GetRLEWB
FunctionGetRLEWB(ByVal data() As Byte) As Byte()
Compress input Byte Array
InputByte()Raw data
OutputByte()Compress data


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

About

Resources for Run-Length Encoding WB


Languages

Language:C 52.5%Language:Assembly 23.9%Language:BASIC 11.1%Language:Roff 9.4%Language:Batchfile 2.2%Language:Visual Basic .NET 0.9%