aboutsummaryrefslogtreecommitdiff
path: root/tools/rasm/decrunch/dzx0_turbo_back.asm
blob: d009e926143a738f15e99201c250e07ff87d7f6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
; -----------------------------------------------------------------------------
; ZX0 decoder by Einar Saukas & introspec
; "Turbo" version (126 bytes, 21% faster) - BACKWARDS VARIANT
; -----------------------------------------------------------------------------
; Parameters:
;   HL: last source address (compressed data)
;   DE: last destination address (decompressing)
; -----------------------------------------------------------------------------

macro dzx0_turbo_back
        ld      bc, 1                   ; preserve default offset 1
        ld      (@dzx0tb_last_offset+1), bc
        ld      a, $80
        jr      @dzx0tb_literals
@dzx0tb_new_offset:
        add     a, a                    ; obtain offset MSB
        call    c, @dzx0tb_elias
        dec     b
        ret     z                       ; check end marker
        dec     c                       ; adjust for positive offset
        ld      b, c
        ld      c, (hl)                 ; obtain offset LSB
        dec     hl
        srl     b                       ; last offset bit becomes first length bit
        rr      c
        inc     bc
        ld      (@dzx0tb_last_offset+1), bc ; preserve new offset
        ld      bc, 1                   ; obtain length
        call    c, @dzx0tb_elias_loop
        inc     bc
@dzx0tb_copy:
        push    hl                      ; preserve source
@dzx0tb_last_offset:
        ld      hl, 0                   ; restore offset
        add     hl, de                  ; calculate destination - offset
        lddr                            ; copy from offset
        inc     c
        pop     hl                      ; restore source
        add     a, a                    ; copy from literals or new offset?
        jr      c, @dzx0tb_new_offset
@dzx0tb_literals:
        add     a, a                    ; obtain length
        call    c, @dzx0tb_elias
        lddr                            ; copy literals
        inc     c
        add     a, a                    ; copy from last offset or new offset?
        jr      c, @dzx0tb_new_offset
        add     a, a                    ; obtain length
        call    c, @dzx0tb_elias
        jp      @dzx0tb_copy
@dzx0tb_elias_loop:
        add     a, a
        rl      c
        add     a, a
        ret     nc
@dzx0tb_elias:
        jp      nz, @dzx0tb_elias_loop   ; inverted interlaced Elias gamma coding
        ld      a, (hl)                 ; load another group of 8 bits
        dec     hl
        rla
        ret     nc
        add     a, a
        rl      c
        add     a, a
        ret     nc
        add     a, a
        rl      c
        add     a, a
        ret     nc
        add     a, a
        rl      c
        add     a, a
        ret     nc
@dzx0tb_elias_reload:
        add     a, a
        rl      c
        rl      b
        add     a, a
        ld      a, (hl)                 ; load another group of 8 bits
        dec     hl
        rla
        ret     nc
        add     a, a
        rl      c
        rl      b
        add     a, a
        ret     nc
        add     a, a
        rl      c
        rl      b
        add     a, a
        ret     nc
        add     a, a
        rl      c
        rl      b
        add     a, a
        jr      c, @dzx0tb_elias_reload
        ret
; -----------------------------------------------------------------------------
mend