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
|
; -----------------------------------------------------------------------------
; ZX0 decoder by Einar Saukas
; "Standard" version (69 bytes only) - BACKWARDS VARIANT
; -----------------------------------------------------------------------------
; Parameters:
; HL: last source address (compressed data)
; DE: last destination address (decompressing)
; -----------------------------------------------------------------------------
Macro dzx0_standard_back
ld bc, 1 ; preserve default offset 1
push bc
ld a, $80
@dzx0sb_literals:
call @dzx0sb_elias ; obtain length
lddr ; copy literals
inc c
add a, a ; copy from last offset or new offset?
jr c, @dzx0sb_new_offset
call @dzx0sb_elias ; obtain length
@dzx0sb_copy:
ex (sp), hl ; preserve source, restore offset
push hl ; preserve offset
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
pop hl ; restore offset
ex (sp), hl ; preserve offset, restore source
add a, a ; copy from literals or new offset?
jr nc, @dzx0sb_literals
@dzx0sb_new_offset:
inc sp ; discard last offset
inc sp
call @dzx0sb_elias ; obtain offset MSB
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
push bc ; preserve new offset
ld bc, 1 ; obtain length
call c, @dzx0sb_elias_backtrack
inc bc
jr @dzx0sb_copy
@dzx0sb_elias_backtrack:
add a, a
rl c
rl b
@dzx0sb_elias:
add a, a ; inverted interlaced Elias gamma coding
jr nz, @dzx0sb_elias_skip
ld a, (hl) ; load another group of 8 bits
dec hl
rla
@dzx0sb_elias_skip:
jr c, @dzx0sb_elias_backtrack
ret
mend
; -----------------------------------------------------------------------------
|