gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/sm83/zx0_decompress.s
1 ; -----------------------------------------------------------------------------
2 ; ZX0 decoder by Einar Saukas & Urusergi
3 ; GBZ80 version by Tony Pavlov
4 ; -----------------------------------------------------------------------------
5
6 .title "ZX0 Decompress"
7 .module ZX0Decompress
8
9 .area _HRAM
10
11 dzx0_temp::
12 .ds 0x01
13
14 .area _CODE
15
16 .macro EX_SP_HL
17 push de
18 ld a, l
19 ld d, h
20 ldhl sp, #2
21 ld e, (hl)
22 ld (hl+), a
23 ld a, (hl)
24 ld (hl), d
25 ld h, a
26 ld l, e
27 pop de
28 .endm
29
30 ; -----------------------------------------------------------------------------
31 ; Parameters for the SDCC UNZX0() function:
32 ; DE: source address (compressed data)
33 ; BC: destination address (decompressing)
34 ; -----------------------------------------------------------------------------
35 _zx0_decompress::
36 ld h, d
37 ld l, e
38 ld d, b
39 ld e, c
40
41 ; -----------------------------------------------------------------------------
42 ; Parameters:
43 ; HL: source address (compressed data)
44 ; DE: destination address (decompressing)
45 ; -----------------------------------------------------------------------------
46 dzx0_standard::
47 ld bc, #0xffff ; preserve default offset 1
48 push bc
49 inc bc
50 ld a, #0x80
51 dzx0s_literals:
52 call dzx0s_elias ; obtain length
53 ldh (dzx0_temp), a
54 call dzx0_ldir ; copy literals
55 ldh a, (dzx0_temp)
56 add a, a ; copy from last offset or new offset?
57 jr c, dzx0s_new_offset
58 call dzx0s_elias ; obtain length
59 dzx0s_copy:
60 ldh (dzx0_temp), a
61 EX_SP_HL ; preserve source, restore offset
62 push hl ; preserve offset
63 add hl, de ; calculate destination - offset
64 call dzx0_ldir ; copy from offset
65 pop hl ; restore offset
66 EX_SP_HL ; preserve offset, restore source
67 ldh a, (dzx0_temp)
68 add a, a ; copy from literals or new offset?
69 jr nc, dzx0s_literals
70 dzx0s_new_offset:
71 pop bc ; discard last offset
72 ld c, #0xfe ; prepare negative offset
73 call dzx0s_elias_loop ; obtain offset MSB
74 inc c
75 ret z ; check end marker
76 ld b, c
77 ld c, (hl) ; obtain offset LSB
78 inc hl
79 rr b ; last offset bit becomes first length bit
80 rr c
81 push bc ; preserve new offset
82 ld bc, #1 ; obtain length
83 call nc, dzx0s_elias_backtrack
84 inc bc
85 jr dzx0s_copy
86 dzx0s_elias:
87 inc c ; interlaced Elias gamma coding
88 dzx0s_elias_loop:
89 add a, a
90 jr nz, dzx0s_elias_skip
91 ld a, (hl+) ; load another group of 8 bits
92 rla
93 dzx0s_elias_skip:
94 ret c
95 dzx0s_elias_backtrack:
96 add a, a
97 rl c
98 rl b
99 jr dzx0s_elias_loop
100 dzx0_ldir:
101 srl b
102 rr c
103 inc b
104 inc c
105 jr c, 0$
106 jr 1$
107 2$:
108 ld a, (hl+)
109 ld (de), a
110 inc de
111 0$:
112 ld a, (hl+)
113 ld (de), a
114 inc de
115 1$:
116 dec c
117 jr nz, 2$
118 dec b
119 jr nz, 2$
120 ret
121 ; -----------------------------------------------------------------------------
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.