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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
; ******************************************************
; ** Librer�a de rutinas SDCC para Amstrad CPC **
; ** Ra�l Simarro (Artaburu) - 2009, 2012 **
; ******************************************************
;*************************************
; UNEXO
;*************************************
; Exomizer 2 Z80 decoder
; by Metalbrain
;
; optimized by Antonio Villena
;
; compression algorithm by Magnus Lind
;input: hl=compressed data start
; de=uncompressed destination start
;
; you may change exo_mapbasebits to point to any free buffer
.globl _cpc_UnExo
_cpc_UnExo::
; POP AF
; POP HL ;DESTINATION ADDRESS
; POP DE ;SPRITE DATA
; PUSH AF
LD IX,#2
ADD IX,SP
LD e,2 (IX)
LD d,3 (IX) ;DESTINO
LD l,0 (IX)
LD h,1 (IX) ;TEXTO ORIGEN
di
call deexo
ei
ret
deexo:
ld iy, #exo_mapbasebits
ld a,#128
ld b,#52
push de
exo_initbits:
ex af,af'
ld a,b
sub #4
and #15
jr nz,exo_node1
ld de,#1 ;DE=b2
exo_node1:
ld c,#16
ex af, af'
exo_get4bits:
call exo_getbit
rl c
jr nc,exo_get4bits
ld (iy),c ;bits[i]=b1
push hl
ld hl,#1
.db #210 ;3 bytes nop (JP NC)
exo_setbit:
add hl,hl
dec c
jr nz,exo_setbit
ld 52 (iy),e
ld 104 (iy),d ;base[i]=b2
add hl,de
ex de,hl
inc iy
pop hl
djnz exo_initbits
inc c
exo_literalseq:
pop de
exo_literalcopy:
ldir ;copy literal(s)
exo_mainloop:
ld c,#1
call exo_getbit ;literal?
jr c,exo_literalcopy
ld c,#255
exo_getindex:
inc c
call exo_getbit
jr nc,exo_getindex
bit 4,c
jr z,exo_continue
bit 0, c
ret z
push de
ld d,#16
call exo_getbits
jr exo_literalseq
exo_continue:
push de
call exo_getpair
push bc
pop ix
ld de,#560 ;512+48 ;1?
inc b
djnz exo_dontgo
dec c
jr z, exo_goforit
dec c ;2?
exo_dontgo:
ld de,#1056 ;1024+32
jr z,exo_goforit
ld e,#16
exo_goforit:
call exo_getbits
ex af, af'
ld a,e
add a,c
ld c,a
ex af, af'
call exo_getpair ;bc=offset
pop de ;de=destination
push hl
ld h,d
ld l,e
sbc hl,bc ;hl=origin
push ix
pop bc ;bc=lenght
ldir
pop hl ;Keep HL, DE is updated
jr exo_mainloop ;Next!
exo_getpair:
ld iy,#exo_mapbasebits
ld b,#0
add iy,bc
ld d,(iy)
call exo_getbits
push hl
ld l, 52 (iy)
ld h, 104 (iy)
add hl, bc ;Always clear C flag
ld b, h
ld c, l
pop hl
ret
exo_getbits:
ld bc,#0 ;get D bits in BC
exo_gettingbits:
dec d
ret m
call exo_getbit
rl c
rl b
jr exo_gettingbits
exo_getbit:
add a, a ;get one bit
ret nz
ld a, (hl)
inc hl
adc a, a
ret
exo_mapbasebits:
;defs 156 ;tables for bits, baseL, baseH
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
.db #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
|