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
|
; C convention
.globl _ap_uncompress
; register call
;
; hl = source
; de = dest
.globl ap_uncompress
; The original Z80 decompressors for ApLib were written by Dan Weiss (Dwedit).
;
; aPPack decompressor
; original source by dwedit
; very slightly adapted by utopian
; optimized by Metalbrain
; this is to enable undocumented Z80 opcodes in SDCC assembler
.ez80
_ap_uncompress::
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
inc hl
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
ap_uncompress::
ld ixl, #128
apbranch1:
ldi
aploop0:
ld ixh, #1 ;LWM = 0
aploop:
call ap_getbit
jr nc, apbranch1
call ap_getbit
jr nc, apbranch2
ld b, #0
call ap_getbit
jr nc, apbranch3
ld c, #16 ;get an offset
apget4bits:
call ap_getbit
rl c
jr nc, apget4bits
jr nz, apbranch4
ld a, b
apwritebyte:
ld (de), a ;write a 0
inc de
jr aploop0
apbranch4:
and a
ex de, hl ;write a previous byte (1-15 away from dest)
sbc hl, bc
ld a, (hl)
add hl, bc
ex de, hl
jr apwritebyte
apbranch3:
ld c, (hl) ;use 7 bit offset, length = 2 or 3
inc hl
rr c
ret z ;if a zero is encountered here, it is EOF
ld a, #2
adc a,b
push hl
ld iyh, b
ld iyl, c
ld h, d
ld l, e
sbc hl, bc
ld c, a
jr ap_finishup2
apbranch2:
call ap_getgamma ;use a gamma code * 256 for offset, another gamma code for length
dec c
ld a, c
sub ixh
jr z, ap_r0_gamma ;if gamma code is 2, use old r0 offset,
dec a
;do I even need this code?
;bc=bc*256+(hl), lazy 16bit way
ld b, a
ld c, (hl)
inc hl
ld iyh, b
ld iyl, c
push bc
call ap_getgamma
ex (sp), hl ;bc = len, hl=offs
push de
ex de, hl
ld a, #4
cp d
jr nc, apskip2
inc bc
or a
apskip2:
ld hl, #127
sbc hl, de
jr c, apskip3
inc bc
inc bc
apskip3:
pop hl ;bc = len, de = offs, hl=junk
push hl
or a
ap_finishup:
sbc hl, de
pop de ;hl=dest-offs, bc=len, de = dest
ap_finishup2:
ldir
pop hl
ld ixh, b
jr aploop
ap_r0_gamma:
call ap_getgamma ;and a new gamma code for length
push hl
push de
ex de, hl
ld d, iyh
ld e, iyl
jr ap_finishup
ap_getbit:
ld a, ixl
add a, a
ld ixl, a
ret nz
ld a, (hl)
inc hl
rla
ld ixl, a
ret
ap_getgamma:
ld bc, #1
ap_getgammaloop:
call ap_getbit
rl c
rl b
call ap_getbit
jr c, ap_getgammaloop
ret
|