SHOW:
|
|
- or go back to the newest paste.
1 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
2 | ; --------------------------------------------------------------------------- | |
3 | ; Adds a Kosinski Moduled archive to the module queue | |
4 | ; Inputs: | |
5 | ; a1 = address of the archive | |
6 | ; d2 = destination in VRAM | |
7 | ; --------------------------------------------------------------------------- | |
8 | Queue_Kos_Module: | |
9 | lea (Kos_module_queue).w,a2 | |
10 | tst.l (a2) ; is the first slot free? | |
11 | beq.s Process_Kos_Module_Queue_Init ; if it is, branch | |
12 | ||
13 | .findFreeSlot: | |
14 | addq.w #6,a2 ; otherwise, check next slot | |
15 | tst.l (a2) | |
16 | bne.s .findFreeSlot | |
17 | ||
18 | move.l a1,(a2)+ ; store source address | |
19 | move.w d2,(a2)+ ; store destination VRAM address | |
20 | rts | |
21 | ; End of function Queue_Kos_Module | |
22 | ; =========================================================================== | |
23 | ||
24 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
25 | ; --------------------------------------------------------------------------- | |
26 | ; Initializes processing of the first module on the queue | |
27 | ; --------------------------------------------------------------------------- | |
28 | Process_Kos_Module_Queue_Init: | |
29 | move.w (a1)+,d3 ; get uncompressed size | |
30 | cmpi.w #$A000,d3 | |
31 | bne.s .gotsize | |
32 | move.w #$8000,d3 ; $A000 means $8000 for some reason | |
33 | ||
34 | .gotsize: | |
35 | lsr.w #1,d3 | |
36 | move.w d3,d0 | |
37 | rol.w #5,d0 | |
38 | andi.w #$1F,d0 ; get number of complete modules | |
39 | move.b d0,(Kos_modules_left).w | |
40 | andi.w #$7FF,d3 ; get size of last module in words | |
41 | bne.s .gotleftover ; branch if it's non-zero | |
42 | subq.b #1,(Kos_modules_left).w ; otherwise decrement the number of modules | |
43 | move.w #$800,d3 ; and take the size of the last module to be $800 words | |
44 | ||
45 | .gotleftover: | |
46 | move.w d3,(Kos_last_module_size).w | |
47 | move.w d2,(Kos_module_destination).w | |
48 | move.l a1,(Kos_module_queue).w | |
49 | addq.b #1,(Kos_modules_left).w ; store total number of modules | |
50 | rts | |
51 | ; End of function Process_Kos_Module_Queue_Init | |
52 | ; =========================================================================== | |
53 | ||
54 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
55 | ; --------------------------------------------------------------------------- | |
56 | ; Processes the first module on the queue | |
57 | ; --------------------------------------------------------------------------- | |
58 | Process_Kos_Module_Queue: | |
59 | tst.b (Kos_modules_left).w | |
60 | bne.s .modulesLeft | |
61 | ||
62 | .done: | |
63 | rts | |
64 | ; --------------------------------------------------------------------------- | |
65 | .modulesLeft: | |
66 | bmi.s .decompressionStarted | |
67 | cmpi.w #4,(Kos_decomp_queue_count).w | |
68 | bcc.s .done ; branch if the Kosinski decompression queue is full | |
69 | movea.l (Kos_module_queue).w,a1 | |
70 | lea (Kos_decomp_buffer).w,a2 | |
71 | bsr.w Queue_Kos ; add current module to decompression queue | |
72 | ori.b #$80,(Kos_modules_left).w ; and set bit to signify decompression in progress | |
73 | rts | |
74 | ; --------------------------------------------------------------------------- | |
75 | .decompressionStarted: | |
76 | tst.w (Kos_decomp_queue_count).w | |
77 | bne.s .done ; branch if the decompression isn't complete | |
78 | ||
79 | ; otherwise, DMA the decompressed data to VRAM | |
80 | andi.b #$7F,(Kos_modules_left).w | |
81 | move.w #$800,d3 | |
82 | subq.b #1,(Kos_modules_left).w | |
83 | bne.s .skip ; branch if it isn't the last module | |
84 | move.w (Kos_last_module_size).w,d3 | |
85 | ||
86 | .skip: | |
87 | move.w (Kos_module_destination).w,d2 | |
88 | move.w d2,d0 | |
89 | add.w d3,d0 | |
90 | add.w d3,d0 | |
91 | move.w d0,(Kos_module_destination).w ; set new destination | |
92 | move.l (Kos_module_queue).w,d0 | |
93 | move.l (Kos_decomp_queue).w,d1 | |
94 | sub.l d1,d0 | |
95 | andi.l #$F,d0 | |
96 | add.l d0,d1 ; round to the nearest $10 boundary | |
97 | move.l d1,(Kos_module_queue).w ; and set new source | |
98 | move.l #Kos_decomp_buffer,d1 | |
99 | jsr (QueueDMATransfer).w | |
100 | tst.b (Kos_modules_left).w | |
101 | bne.s .exit ; return if this wasn't the last module | |
102 | lea (Kos_module_queue).w,a0 | |
103 | lea (Kos_module_queue+6).w,a1 | |
104 | move.l (a1)+,(a0)+ ; otherwise, shift all entries up | |
105 | move.w (a1)+,(a0)+ | |
106 | move.l (a1)+,(a0)+ | |
107 | move.w (a1)+,(a0)+ | |
108 | move.l (a1)+,(a0)+ | |
109 | move.w (a1)+,(a0)+ | |
110 | moveq #0,d0 | |
111 | move.l d0,(a0)+ ; and mark the last slot as free | |
112 | move.w d0,(a0)+ | |
113 | move.l (Kos_module_queue).w,d0 | |
114 | beq.s .exit ; return if the queue is now empty | |
115 | movea.l d0,a1 | |
116 | move.w (Kos_module_destination).w,d2 | |
117 | bra.w Process_Kos_Module_Queue_Init | |
118 | ||
119 | .exit: | |
120 | rts | |
121 | ; End of function Process_Kos_Module_Queue | |
122 | ; =========================================================================== | |
123 | ||
124 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
125 | ; --------------------------------------------------------------------------- | |
126 | ; Adds Kosinski-compressed data to the decompression queue | |
127 | ; Inputs: | |
128 | ; a1 = compressed data address | |
129 | ; a2 = decompression destination in RAM | |
130 | ; --------------------------------------------------------------------------- | |
131 | Queue_Kos: | |
132 | move.w (Kos_decomp_queue_count).w,d0 | |
133 | lsl.w #3,d0 | |
134 | lea (Kos_decomp_queue).w,a3 | |
135 | move.l a1,(a3,d0.w) ; store source | |
136 | move.l a2,4(a3,d0.w) ; store destination | |
137 | addq.w #1,(Kos_decomp_queue_count).w | |
138 | rts | |
139 | ; End of function Queue_Kos | |
140 | ; =========================================================================== | |
141 | ||
142 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
143 | ; --------------------------------------------------------------------------- | |
144 | ; Checks if V-int occured in the middle of Kosinski queue processing | |
145 | ; and stores the location from which processing is to resume if it did | |
146 | ; --------------------------------------------------------------------------- | |
147 | Set_Kos_Bookmark: | |
148 | tst.w (Kos_decomp_queue_count).w | |
149 | bpl.s .done ; branch if a decompression wasn't in progress | |
150 | move.l $42(sp),d0 ; check address V-int is supposed to rte to | |
151 | cmpi.l #Process_Kos_Queue.Main,d0 | |
152 | bcs.s .done | |
153 | cmpi.l #Process_Kos_Queue.Done,d0 | |
154 | bcc.s .done | |
155 | move.l $42(sp),(Kos_decomp_bookmark).w | |
156 | move.l #Backup_Kos_Registers,$42(sp) ; force V-int to rte here instead if needed | |
157 | ||
158 | .done: | |
159 | rts | |
160 | ; End of function Set_Kos_Bookmark | |
161 | ; =========================================================================== | |
162 | ||
163 | ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| | |
164 | ; --------------------------------------------------------------------------- | |
165 | ; Processes the first entry in the Kosinski decompression queue | |
166 | ; --------------------------------------------------------------------------- | |
167 | Process_Kos_Queue: | |
168 | tst.w (Kos_decomp_queue_count).w | |
169 | beq.w .Done | |
170 | bmi.w Restore_Kos_Bookmark ; branch if a decompression was interrupted by V-int | |
171 | ||
172 | .Main: | |
173 | ori.w #$8000,(Kos_decomp_queue_count).w ; set sign bit to signify decompression in progress | |
174 | movea.l (Kos_decomp_queue).w,a0 | |
175 | movea.l (Kos_decomp_destination).w,a1 | |
176 | ||
177 | ; what follows is identical to the normal Kosinski decompressor | |
178 | moveq #(1<<_Kos_LoopUnroll)-1,d7 | |
179 | if _Kos_UseLUT==1 | |
180 | moveq #0,d0 | |
181 | moveq #0,d1 | |
182 | lea KosDec_ByteMap(pc),a4 ; Load LUT pointer. | |
183 | endif | |
184 | move.b (a0)+,d0 ; Get desc field low-byte. | |
185 | move.b (a0)+,d1 ; Get desc field hi-byte. | |
186 | if _Kos_UseLUT==1 | |
187 | move.b (a4,d0.w),d0 ; Invert bit order... | |
188 | move.b (a4,d1.w),d1 ; ... for both bytes. | |
189 | endif | |
190 | moveq #7,d2 ; Set repeat count to 8. | |
191 | - | moveq #-1,d3 ; d3 will be desc field switcher. |
191 | + | moveq #0,d3 ; d3 will be desc field switcher. |
192 | - | clr.w d3 ; Low word is zero. |
192 | + | |
193 | ; --------------------------------------------------------------------------- | |
194 | .FetchCodeLoop: | |
195 | ; Code 1 (Uncompressed byte). | |
196 | _Kos_RunBitStream | |
197 | move.b (a0)+,(a1)+ | |
198 | ||
199 | .FetchNewCode: | |
200 | _Kos_ReadBit | |
201 | bcs.s .FetchCodeLoop ; If code = 1, branch. | |
202 | ||
203 | ; Codes 00 and 01. | |
204 | moveq #-1,d5 | |
205 | lea (a1),a5 | |
206 | _Kos_RunBitStream | |
207 | if _Kos_ExtremeUnrolling==1 | |
208 | _Kos_ReadBit | |
209 | bcs.w .Code_01 | |
210 | ||
211 | ; Code 00 (Dictionary ref. short). | |
212 | _Kos_RunBitStream | |
213 | _Kos_ReadBit | |
214 | bcs.s .Copy45 | |
215 | _Kos_RunBitStream | |
216 | _Kos_ReadBit | |
217 | bcs.s .Copy3 | |
218 | _Kos_RunBitStream | |
219 | move.b (a0)+,d5 ; d5 = displacement. | |
220 | adda.w d5,a5 | |
221 | move.b (a5)+,(a1)+ | |
222 | move.b (a5)+,(a1)+ | |
223 | bra.s .FetchNewCode | |
224 | ; --------------------------------------------------------------------------- | |
225 | .Copy3: | |
226 | _Kos_RunBitStream | |
227 | move.b (a0)+,d5 ; d5 = displacement. | |
228 | adda.w d5,a5 | |
229 | move.b (a5)+,(a1)+ | |
230 | move.b (a5)+,(a1)+ | |
231 | move.b (a5)+,(a1)+ | |
232 | bra.w .FetchNewCode | |
233 | ; --------------------------------------------------------------------------- | |
234 | .Copy45: | |
235 | _Kos_RunBitStream | |
236 | _Kos_ReadBit | |
237 | bcs.s .Copy5 | |
238 | _Kos_RunBitStream | |
239 | move.b (a0)+,d5 ; d5 = displacement. | |
240 | adda.w d5,a5 | |
241 | move.b (a5)+,(a1)+ | |
242 | move.b (a5)+,(a1)+ | |
243 | move.b (a5)+,(a1)+ | |
244 | move.b (a5)+,(a1)+ | |
245 | bra.w .FetchNewCode | |
246 | ; --------------------------------------------------------------------------- | |
247 | .Copy5: | |
248 | _Kos_RunBitStream | |
249 | move.b (a0)+,d5 ; d5 = displacement. | |
250 | adda.w d5,a5 | |
251 | move.b (a5)+,(a1)+ | |
252 | move.b (a5)+,(a1)+ | |
253 | move.b (a5)+,(a1)+ | |
254 | move.b (a5)+,(a1)+ | |
255 | move.b (a5)+,(a1)+ | |
256 | bra.w .FetchNewCode | |
257 | ; --------------------------------------------------------------------------- | |
258 | else | |
259 | moveq #0,d4 ; d4 will contain copy count. | |
260 | _Kos_ReadBit | |
261 | bcs.s .Code_01 | |
262 | ||
263 | ; Code 00 (Dictionary ref. short). | |
264 | _Kos_RunBitStream | |
265 | _Kos_ReadBit | |
266 | addx.w d4,d4 | |
267 | _Kos_RunBitStream | |
268 | _Kos_ReadBit | |
269 | addx.w d4,d4 | |
270 | _Kos_RunBitStream | |
271 | move.b (a0)+,d5 ; d5 = displacement. | |
272 | ||
273 | .StreamCopy: | |
274 | adda.w d5,a5 | |
275 | move.b (a5)+,(a1)+ ; Do 1 extra copy (to compensate +1 to copy counter). | |
276 | ||
277 | .copy: | |
278 | move.b (a5)+,(a1)+ | |
279 | dbra d4,.copy | |
280 | bra.w .FetchNewCode | |
281 | endif | |
282 | ; --------------------------------------------------------------------------- | |
283 | .Code_01: | |
284 | moveq #0,d4 ; d4 will contain copy count. | |
285 | ; Code 01 (Dictionary ref. long / special). | |
286 | _Kos_RunBitStream | |
287 | move.b (a0)+,d6 ; d6 = %LLLLLLLL. | |
288 | move.b (a0)+,d4 ; d4 = %HHHHHCCC. | |
289 | move.b d4,d5 ; d5 = %11111111 HHHHHCCC. | |
290 | lsl.w #5,d5 ; d5 = %111HHHHH CCC00000. | |
291 | move.b d6,d5 ; d5 = %111HHHHH LLLLLLLL. | |
292 | if _Kos_LoopUnroll==3 | |
293 | and.w d7,d4 ; d4 = %00000CCC. | |
294 | else | |
295 | andi.w #7,d4 | |
296 | endif | |
297 | bne.s .StreamCopy ; if CCC=0, branch. | |
298 | ||
299 | ; special mode (extended counter) | |
300 | move.b (a0)+,d4 ; Read cnt | |
301 | beq.s .Quit ; If cnt=0, quit decompression. | |
302 | subq.b #1,d4 | |
303 | beq.w .FetchNewCode ; If cnt=1, fetch a new code. | |
304 | ||
305 | adda.w d5,a5 | |
306 | move.b (a5)+,(a1)+ ; Do 1 extra copy (to compensate +1 to copy counter). | |
307 | move.w d4,d6 | |
308 | not.w d6 | |
309 | and.w d7,d6 | |
310 | add.w d6,d6 | |
311 | lsr.w #_Kos_LoopUnroll,d4 | |
312 | jmp .largecopy(pc,d6.w) | |
313 | ; --------------------------------------------------------------------------- | |
314 | .largecopy: | |
315 | rept (1<<_Kos_LoopUnroll) | |
316 | move.b (a5)+,(a1)+ | |
317 | endm | |
318 | dbra d4,.largecopy | |
319 | bra.w .FetchNewCode | |
320 | ; --------------------------------------------------------------------------- | |
321 | if _Kos_ExtremeUnrolling==1 | |
322 | .StreamCopy: | |
323 | adda.w d5,a5 | |
324 | move.b (a5)+,(a1)+ ; Do 1 extra copy (to compensate +1 to copy counter). | |
325 | if _Kos_LoopUnroll==3 | |
326 | eor.w d7,d4 | |
327 | else | |
328 | eori.w #7,d4 | |
329 | endif | |
330 | add.w d4,d4 | |
331 | jmp .mediumcopy(pc,d4.w) | |
332 | ; --------------------------------------------------------------------------- | |
333 | .mediumcopy: | |
334 | rept 8 | |
335 | move.b (a5)+,(a1)+ | |
336 | endm | |
337 | bra.w .FetchNewCode | |
338 | endif | |
339 | ; --------------------------------------------------------------------------- | |
340 | .Quit: | |
341 | move.l a0,(Kos_decomp_queue).w | |
342 | move.l a1,(Kos_decomp_destination).w | |
343 | andi.w #$7FFF,(Kos_decomp_queue_count).w ; clear decompression in progress bit | |
344 | subq.w #1,(Kos_decomp_queue_count).w | |
345 | beq.s .Done ; branch if there aren't any entries remaining in the queue | |
346 | lea (Kos_decomp_queue).w,a0 | |
347 | lea (Kos_decomp_queue+8).w,a1 ; otherwise, shift all entries up | |
348 | move.l (a1)+,(a0)+ | |
349 | move.l (a1)+,(a0)+ | |
350 | move.l (a1)+,(a0)+ | |
351 | move.l (a1)+,(a0)+ | |
352 | move.l (a1)+,(a0)+ | |
353 | move.l (a1)+,(a0)+ | |
354 | ||
355 | .Done: | |
356 | rts | |
357 | ; --------------------------------------------------------------------------- | |
358 | Restore_Kos_Bookmark: | |
359 | movem.w (Kos_decomp_stored_registers).w,d0-d6 | |
360 | movem.l (Kos_decomp_stored_registers+2*7).w,a0-a1/a5 | |
361 | move.l (Kos_decomp_bookmark).w,-(sp) | |
362 | move.w (Kos_decomp_stored_SR).w,-(sp) | |
363 | moveq #(1<<_Kos_LoopUnroll)-1,d7 | |
364 | lea KosDec_ByteMap(pc),a4 ; Load LUT pointer. | |
365 | rte | |
366 | ; End of function Process_Kos_Queue | |
367 | ; =========================================================================== | |
368 | Backup_Kos_Registers: | |
369 | move sr,(Kos_decomp_stored_SR).w | |
370 | movem.w d0-d6,(Kos_decomp_stored_registers).w | |
371 | movem.l a0-a1/a5,(Kos_decomp_stored_registers+2*7).w | |
372 | rts | |
373 | ; =========================================================================== |