News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_roudoudou

Shrinkler Z80 decrunch routine

Started by roudoudou, 10:42, 31 January 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

roudoudou

Hi there, i made a decrunch routine for the Amiga Shrinkler cruncher
This statistic cruncher is a LZMA stripdown algo so it is very efficiently but also very slow and need 2.5k of memory to store probabilities
To compare with exomizer and the wellknown Boubler Dash executable, you gain 10% over exomizer
The decrunch speed is not dependant of the target size but of the crunched size -> expect more than 15s for a 4K intro

From 350 bytes, Thanks to Hicks, Antonio Villena & Urusergi the routine were quickly sized down to 245 bytes

Madram joined the game and sent me his version, reoptimised and simplified (D4 in 8 bits) 209 bytes for a recall version!


Parameters to use with the version:
IX=source
DE=destination


NOTICE: The source is supposed to be used with an assembler dealing with a correct operator priority. This need adaptations for old assemblers (remove parenthesis, use division instead of shifting, ...)




Shrinkler Amiga/Linux/Windows executables here: http://crinkler.net/shrinkler45.zip
Official topic here: http://ada.untergrund.net/?p=boardthread&id=264


With the cruncher use the options -d -p -9
-d in order to crunch without header in output
-p to avoid shit with windows (don't care with Linux)
-9 to crunch better, the default parameter is not enough to have good results on small files


sample test with a crunched screen (rasm source)



buildsna
bankset 0
org #100
run #100
di
ld sp,#100
ld ix,#4000
ld de,#C000
breakpoint
call shrinkler_decrunch
breakpoint
jr $


include 'shrinkler.asm'


org #4000
incbin 'defaultscr.shr'
My pronouns are RASM and ACE

Targhan

Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

roudoudou

thanks: updated 1st post with official cruncher executables and official Amiga topic
My pronouns are RASM and ACE


roudoudou

Quote from: krusty_benediction on 11:28, 31 January 18
I'll look at it as soon as possible.
However with 1min to fill the banks, I doubt I'll use it


In fact i misled.


The decrunch speed is not dependant of the target size but of the crunched size  ;D  roughly 5000 nops per crunched bytes


My test was 2748 bytes crunched so 13.7s for 16k. Once the bits are decoded, that's just ldi or ldir


My pronouns are RASM and ACE

Urusergi

Quote from: roudoudou on 10:42, 31 January 18
I may send a commented version if people want to try to optimize the code

Yes, please, please  :)

roudoudou

Yeah! I gain 2 bytes more with an optim!


Updated the first post with new source and commented version
My pronouns are RASM and ACE

Ast


Quote from: roudoudou on 10:42, 31 January 18
Hi there, i made a decrunch routine for the Amiga Shrinkler cruncher
This statistic cruncher is a LZMA stripdown algo so it is very efficiently but also very slow and need memory to store probabilities
To compare with exomizer and the wellknown Boubler Dash executable, you gain 10% over exomizer
But...
But the decrunch routine is 180 bytes bigger and the buffer needs 3Kb anywhere in the memory
Speed decrunch performance is roughly 1kb/s
The decrunch speed is not dependant of the target size but of the crunched size -> 5000 nops per crunched byte
Do not hesitate to report me bugs
I may send a commented version if people want to try to optimize the code
The version here is supposed to be compliant with all assemblers


Shrinkler Amiga/Linux/Windows executables here: http://crinkler.net/shrinkler45.zip
Official topic here: http://ada.untergrund.net/?p=boardthread&id=264
Well done !
_____________________

Ast/iMP4CT. "By the power of Grayskull, i've the power"

http://amstradplus.forumforever.com/index.php
http://impdos.wikidot.com/
http://impdraw.wikidot.com/

All friends are welcome !

roudoudou

New file in the first post shrinkler_z80_330.asm



I re-wrote the variables initialization
I modified the spread of flags
I factored some call parameters
Finally, I re-wrote the many calls to the virtual registry D6


The result is that the binary is now 330 bytes  8)
My pronouns are RASM and ACE

roudoudou

With Hicks advices, some size optimisations at the end -> now 326 bytes  ;D


First post updated with source
My pronouns are RASM and ACE

roudoudou

#10
323  ;D  319


My pronouns are RASM and ACE

roudoudou

The current version is now 304 bytes  :D
My pronouns are RASM and ACE

antoniovillena

Quote from: roudoudou on 21:21, 02 February 18
The current version is now 304 bytes  :D


-2 bytes




shrinkler_decrunch:
        ld      (shrinkler_a5+1), hl


        ; Init range decoder state
        ld      hl, shrinkler_dr+1536*2+8
        ld      bc, 1536*2
        ld      (hl), c
        inc     hl
        ld      (hl), $80
        ld      de, shrinkler_dr+1536*2+7
        lddr
        ld      c, $08
        dec     hl
        lddr
        inc     (hl)


shrinkler_lit:

antoniovillena

Another -2 bytes




shrinkler_lit:
        ; Literal
        scf
shrinkler_getlit:
        call    nc, shrinkler_getbit
        ld      hl, shrinkler_d6
        rl      (hl)
        jr      nc, shrinkler_getlit
shrinkler_a5:
        ld      de,  $1234
        ldi

antoniovillena

Easy -1 byte



        jr      nc, shrinkler_lit


        ; Reference
        sbc     hl, hl
        call    shrinkler_altgetbit

ervin

@roudoudo - have the optimisations found so far resulted in any speed increases?

Hicks

#16
I submitted to Roudoudou a lot of optimisations by PM, but I will write here now if other people work on it too (hi antonio!).


shrinkler_nonewword   
    ld (shrinkler_d4),de : ld (shrinkler_d4+2),hl ; written in little endian
    ex af,af' ; retrieve previous carry
    ld hl,(shrinkler_d2) : adc hl,hl : ld (shrinkler_d2),hl
    ld hl,(shrinkler_d3) : add hl,hl : ld (shrinkler_d3),hl ; 0x22


Becomes (for -1) :


shrinkler_nonewword   
    ld (shrinkler_d4),de : ld (shrinkler_d4+2),hl ; written in little endian
    ex af,af'
    ld hl,shrinkler_d2+1
    rl (hl) : dec hl : rl (hl) : dec hl
    sla (hl) : dec hl : rl (hl)


But you must modify the order of the labels : d3 - d6 - d2 becomes d3 - d2 - d6.

roudoudou

Quote from: ervin on 08:34, 03 February 18
@roudoudo - have the optimisations found so far resulted in any speed increases?

The speed gain/loss is not significant. Thanks Antonio for the optims!
My pronouns are RASM and ACE

roudoudou

Hicks, the registers order of d3 (first) & d6 (last) can't be changed without changing the init


I updated first post with 299 bytes version
My pronouns are RASM and ACE

Hicks

#19
I modified my post: the same tricks works with d3 - d2 - d6 order...
First must be d3 and last d4 (no d6), so we can reverse d2 / d6.

roudoudou

#20
... (2s)
My pronouns are RASM and ACE

roudoudou

ok, i succeed to make the rl optim


(updated the first post)






        ld hl,shrinkler_d3
        sla (hl) : inc hl : rl (hl) : inc hl
        ex af,af' ; retrieve previous carry
        rl (hl) : inc hl : rl (hl)
My pronouns are RASM and ACE

Hicks

#22
This part:


shrinkler_readoffset:
    ld a,3
    call shrinkler_getnumber
    ; retour systématique avec carry et HL=BC
    ld hl,2
    xor a
    sbc hl,bc


Since Carry is always=1, then:


shrinkler_readoffset:
    ld a,3
    call shrinkler_getnumber
    ; retour systématique avec carry et HL=BC
    ld hl,2+1    ; +1 in order to compensate Carry
    sbc hl,bc


Then -1 byte

Hicks

Another -1 byte:


shrinkler_d5:    ld de,#0101
    ld hl,(shrinkler_a5+1)
    push hl
    add hl,de
    pop de   


Becomes:


shrinkler_d5: ld hl,#0101
    ld de,(shrinkler_a5+1)
    add hl,de


A lot of CPU saved too!

roudoudou

I like where this tread is going  :)


296!
My pronouns are RASM and ACE

Powered by SMFPacks Menu Editor Mod