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 | ; =========================================================================== |