View difference between Paste ID: gXrJRZNd and VZbyHDaC
SHOW: | | - or go back to the newest paste.
1
; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
2
; ---------------------------------------------------------------------------
3
; KOSINSKI DECOMPRESSION PROCEDURE
4
; (sometimes called KOZINSKI decompression)
5
;
6
; ARGUMENTS:
7
; a0 = source address
8
; a1 = destination address
9
;
10
; For format explanation see http://info.sonicretro.org/Kosinski_compression
11
; New faster version by written by vladikcomper, with additional improvements by
12
; MarkeyJester and Flamewing
13
; ---------------------------------------------------------------------------
14
_Kos_UseLUT := 1
15
_Kos_LoopUnroll := 3
16
_Kos_ExtremeUnrolling := 1
17
18
_Kos_RunBitStream macro
19
	dbra	d2,.skip
20
	moveq	#7,d2					; Set repeat count to 8.
21
	move.b	d1,d0					; Use the remaining 8 bits.
22-
	swap	d3						; Have all 16 bits been used up?
22+
	not.w	d3						; Have all 16 bits been used up?
23-
	bpl.s	.skip					; Branch if not.
23+
	bne.s	.skip					; Branch if not.
24
	move.b	(a0)+,d0				; Get desc field low-byte.
25
	move.b	(a0)+,d1				; Get desc field hi-byte.
26
	if _Kos_UseLUT==1
27
	move.b	(a4,d0.w),d0			; Invert bit order...
28
	move.b	(a4,d1.w),d1			; ... for both bytes.
29
	endif
30
.skip
31
	endm
32
33
_Kos_ReadBit macro
34
	if _Kos_UseLUT==1
35
	add.b	d0,d0					; Get a bit from the bitstream.
36
	else
37
	lsr.b	#1,d0					; Get a bit from the bitstream.
38
	endif
39
	endm
40
; ===========================================================================
41
; KozDec_193A:
42
KosDec:
43
	moveq	#(1<<_Kos_LoopUnroll)-1,d7
44
	if _Kos_UseLUT==1
45
	moveq	#0,d0
46
	moveq	#0,d1
47
	lea	KosDec_ByteMap(pc),a4		; Load LUT pointer.
48
	endif
49
	move.b	(a0)+,d0				; Get desc field low-byte.
50
	move.b	(a0)+,d1				; Get desc field hi-byte.
51
	if _Kos_UseLUT==1
52
	move.b	(a4,d0.w),d0			; Invert bit order...
53
	move.b	(a4,d1.w),d1			; ... for both bytes.
54
	endif
55
	moveq	#7,d2					; Set repeat count to 8.
56-
	moveq	#-1,d3					; d3 will be desc field switcher.
56+
	moveq	#0,d3					; d3 will be desc field switcher.
57-
	clr.w	d3						; Low word is zero.
57+
58
; ---------------------------------------------------------------------------
59
.FetchCodeLoop:
60
	; Code 1 (Uncompressed byte).
61
	_Kos_RunBitStream
62
	move.b	(a0)+,(a1)+
63
64
.FetchNewCode:
65
	_Kos_ReadBit
66
	bcs.s	.FetchCodeLoop			; If code = 1, branch.
67
68
	; Codes 00 and 01.
69
	moveq	#-1,d5
70
	lea	(a1),a5
71
	_Kos_RunBitStream
72
	if _Kos_ExtremeUnrolling==1
73
	_Kos_ReadBit
74
	bcs.w	.Code_01
75
76
	; Code 00 (Dictionary ref. short).
77
	_Kos_RunBitStream
78
	_Kos_ReadBit
79
	bcs.s	.Copy45
80
	_Kos_RunBitStream
81
	_Kos_ReadBit
82
	bcs.s	.Copy3
83
	_Kos_RunBitStream
84
	move.b	(a0)+,d5				; d5 = displacement.
85
	adda.w	d5,a5
86
	move.b	(a5)+,(a1)+
87
	move.b	(a5)+,(a1)+
88
	bra.s	.FetchNewCode
89
; ---------------------------------------------------------------------------
90
.Copy3:
91
	_Kos_RunBitStream
92
	move.b	(a0)+,d5				; d5 = displacement.
93
	adda.w	d5,a5
94
	move.b	(a5)+,(a1)+
95
	move.b	(a5)+,(a1)+
96
	move.b	(a5)+,(a1)+
97
	bra.w	.FetchNewCode
98
; ---------------------------------------------------------------------------
99
.Copy45:
100
	_Kos_RunBitStream
101
	_Kos_ReadBit
102
	bcs.s	.Copy5
103
	_Kos_RunBitStream
104
	move.b	(a0)+,d5				; d5 = displacement.
105
	adda.w	d5,a5
106
	move.b	(a5)+,(a1)+
107
	move.b	(a5)+,(a1)+
108
	move.b	(a5)+,(a1)+
109
	move.b	(a5)+,(a1)+
110
	bra.w	.FetchNewCode
111
; ---------------------------------------------------------------------------
112
.Copy5:
113
	_Kos_RunBitStream
114
	move.b	(a0)+,d5				; d5 = displacement.
115
	adda.w	d5,a5
116
	move.b	(a5)+,(a1)+
117
	move.b	(a5)+,(a1)+
118
	move.b	(a5)+,(a1)+
119
	move.b	(a5)+,(a1)+
120
	move.b	(a5)+,(a1)+
121
	bra.w	.FetchNewCode
122
; ---------------------------------------------------------------------------
123
	else
124
	moveq	#0,d4					; d4 will contain copy count.
125
	_Kos_ReadBit
126
	bcs.s	.Code_01
127
128
	; Code 00 (Dictionary ref. short).
129
	_Kos_RunBitStream
130
	_Kos_ReadBit
131
	addx.w	d4,d4
132
	_Kos_RunBitStream
133
	_Kos_ReadBit
134
	addx.w	d4,d4
135
	_Kos_RunBitStream
136
	move.b	(a0)+,d5				; d5 = displacement.
137
138
.StreamCopy:
139
	adda.w	d5,a5
140
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
141
142
.copy:
143
	move.b	(a5)+,(a1)+
144
	dbra	d4,.copy
145
	bra.w	.FetchNewCode
146
	endif
147
; ---------------------------------------------------------------------------
148
.Code_01:
149
	moveq	#0,d4					; d4 will contain copy count.
150
	; Code 01 (Dictionary ref. long / special).
151
	_Kos_RunBitStream
152
	move.b	(a0)+,d6				; d6 = %LLLLLLLL.
153
	move.b	(a0)+,d4				; d4 = %HHHHHCCC.
154
	move.b	d4,d5					; d5 = %11111111 HHHHHCCC.
155
	lsl.w	#5,d5					; d5 = %111HHHHH CCC00000.
156
	move.b	d6,d5					; d5 = %111HHHHH LLLLLLLL.
157
	if _Kos_LoopUnroll==3
158
	and.w	d7,d4					; d4 = %00000CCC.
159
	else
160
	andi.w	#7,d4
161
	endif
162
	bne.s	.StreamCopy				; if CCC=0, branch.
163
164
	; special mode (extended counter)
165
	move.b	(a0)+,d4				; Read cnt
166
	beq.s	.Quit					; If cnt=0, quit decompression.
167
	subq.b	#1,d4
168
	beq.w	.FetchNewCode			; If cnt=1, fetch a new code.
169
170
	adda.w	d5,a5
171
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
172
	move.w	d4,d6
173
	not.w	d6
174
	and.w	d7,d6
175
	add.w	d6,d6
176
	lsr.w	#_Kos_LoopUnroll,d4
177
	jmp	.largecopy(pc,d6.w)
178
; ---------------------------------------------------------------------------
179
.largecopy:
180
	rept (1<<_Kos_LoopUnroll)
181
	move.b	(a5)+,(a1)+
182
	endm
183
	dbra	d4,.largecopy
184
	bra.w	.FetchNewCode
185
; ---------------------------------------------------------------------------
186
	if _Kos_ExtremeUnrolling==1
187
.StreamCopy:
188
	adda.w	d5,a5
189
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
190
	if _Kos_LoopUnroll==3
191
	eor.w	d7,d4
192
	else
193
	eori.w	#7,d4
194
	endif
195
	add.w	d4,d4
196
	jmp	.mediumcopy(pc,d4.w)
197
; ---------------------------------------------------------------------------
198
.mediumcopy:
199
	rept 8
200
	move.b	(a5)+,(a1)+
201
	endm
202
	bra.w	.FetchNewCode
203
	endif
204
; ---------------------------------------------------------------------------
205
.Quit:
206
	rts								; End of function KosDec.
207
; ===========================================================================
208
	if _Kos_UseLUT==1
209
KosDec_ByteMap:
210
	dc.b	$00,$80,$40,$C0,$20,$A0,$60,$E0,$10,$90,$50,$D0,$30,$B0,$70,$F0
211
	dc.b	$08,$88,$48,$C8,$28,$A8,$68,$E8,$18,$98,$58,$D8,$38,$B8,$78,$F8
212
	dc.b	$04,$84,$44,$C4,$24,$A4,$64,$E4,$14,$94,$54,$D4,$34,$B4,$74,$F4
213
	dc.b	$0C,$8C,$4C,$CC,$2C,$AC,$6C,$EC,$1C,$9C,$5C,$DC,$3C,$BC,$7C,$FC
214
	dc.b	$02,$82,$42,$C2,$22,$A2,$62,$E2,$12,$92,$52,$D2,$32,$B2,$72,$F2
215
	dc.b	$0A,$8A,$4A,$CA,$2A,$AA,$6A,$EA,$1A,$9A,$5A,$DA,$3A,$BA,$7A,$FA
216
	dc.b	$06,$86,$46,$C6,$26,$A6,$66,$E6,$16,$96,$56,$D6,$36,$B6,$76,$F6
217
	dc.b	$0E,$8E,$4E,$CE,$2E,$AE,$6E,$EE,$1E,$9E,$5E,$DE,$3E,$BE,$7E,$FE
218
	dc.b	$01,$81,$41,$C1,$21,$A1,$61,$E1,$11,$91,$51,$D1,$31,$B1,$71,$F1
219
	dc.b	$09,$89,$49,$C9,$29,$A9,$69,$E9,$19,$99,$59,$D9,$39,$B9,$79,$F9
220
	dc.b	$05,$85,$45,$C5,$25,$A5,$65,$E5,$15,$95,$55,$D5,$35,$B5,$75,$F5
221
	dc.b	$0D,$8D,$4D,$CD,$2D,$AD,$6D,$ED,$1D,$9D,$5D,$DD,$3D,$BD,$7D,$FD
222
	dc.b	$03,$83,$43,$C3,$23,$A3,$63,$E3,$13,$93,$53,$D3,$33,$B3,$73,$F3
223
	dc.b	$0B,$8B,$4B,$CB,$2B,$AB,$6B,$EB,$1B,$9B,$5B,$DB,$3B,$BB,$7B,$FB
224
	dc.b	$07,$87,$47,$C7,$27,$A7,$67,$E7,$17,$97,$57,$D7,$37,$B7,$77,$F7
225
	dc.b	$0F,$8F,$4F,$CF,$2F,$AF,$6F,$EF,$1F,$9F,$5F,$DF,$3F,$BF,$7F,$FF
226
	endif
227
; ===========================================================================