-
Notifications
You must be signed in to change notification settings - Fork 2
/
deshrinkler_np.asm
210 lines (196 loc) · 2.61 KB
/
deshrinkler_np.asm
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
; Shrinkler z80 decompressor Madram/OVL version v8
;
; Modified by Ivan Gorodetsky (2019-10-06)
; 1. Support of R800 with hardware multiplication added
; 2. Self-modifying code removed
; 3. Initialisation of d2 for reuse of decompressor added
; 4. Minor optimisations
; 5. No parity context
;
; 206 bytes - z80 version
; 193 bytes - R800 version
; Compile with The Telemark Assembler (TASM) 3.2
;
; input IX=source
; input DE=destination - it has to be even!
; call shrinkler_decrunch
; you may change probs to point to any 256-byte aligned free buffer (size 2.0 Kilobytes)
probs = 01000h
probs_ref = probs+400h
probs_length = probs_ref
probs_offset = probs_length+200h
;#DEFINE R800
shrinkler_decrunch
exx
ld hl,8*256+probs
ld bc,8*256+80h
xor a
init
dec h
iniloop
ld (hl),a
inc l
jr nz,iniloop
xor c
djnz init
ld d,b
ld e,b
push de
pop iy ; d2=0
inc e
ld a,c
ex af,af'
literal
scf
getlit
call nc,getbit
rl l
jr nc,getlit
ld a,l
exx
ld (de),a
inc de
call getkind
jr nc,literal
ld h,probs_ref/256
call getbit
jr nc,readoffset
readlength
ld h,probs_length/256
call getnumber
push hl
add hl,de
ldir
pop hl
call getkind
jr nc,literal
readoffset
ld h,probs_offset/256
call getnumber
ld hl,2
sbc hl,bc
exx
jr nz,readlength
ret
getnumber
_numberloop
inc l
inc l
call getbit
jr c,_numberloop
exx
ld bc,1
exx
_bitsloop
dec l
call getbit
exx
rl c
rl b
exx
dec l
jr nz,_bitsloop
exx
ret
readbit
ex de,hl
add hl,hl
ex de,hl
ex af,af'
add a,a
jr nz,_rbok
ld a,(ix)
inc ix
adc a,a
_rbok
ex af,af'
add iy,iy
ex af,af'
jr nc,$+4
.db 0FDh,2Ch ; inc yl
ex af,af'
jr getbit
getkind
exx
ld hl,probs
getbit
ld a,d
add a,a
jr nc,readbit
ld b,(hl)
inc h
ld c,(hl)
push hl
ld l,c
ld h,b
push bc
ld a,11100001b
shift4
srl b
rr c
add a,a
jr c,shift4
sbc hl,bc
pop bc
push hl
IFDEF R800
push de
ex de,hl
.db 0EDh,0C3h ; muluw hl,bc
.db 0FDh,7Dh ; ld a,yl
sub e
ld l,a
.db 0FDh,7Ch ; ld a,yh
sbc a,d
jr nc,zero
one
pop bc
ELSE
sbc hl,hl
muluw
add hl,hl
rl c
rl b
jr nc,_mulcont
add hl,de
jr nc,_mulcont
inc bc
_mulcont
dec a
jr nz,muluw
.db 0FDh,7Dh ; ld a,yl
sub c
ld l,a
.db 0FDh,7Ch ; ld a,yh
sbc a,b
jr nc,zero
one
ld e,c
ld d,b
ENDIF
pop bc
ld a,b
sub 0F0h
ld b,a
dec bc
jr _probret
zero
.db 0FDh,67h ; ld yh,a
ld a,l
.db 0FDh,6Fh ; ld yl,a
IFDEF R800
pop hl
sbc hl,de
ELSE
ex de,hl
sbc hl,bc
ENDIF
ex de,hl
pop bc
_probret
pop hl
ld (hl),c
dec h
ld (hl),b
ret
;.end