View difference between Paste ID: mueQp41A and g1dX0VZm
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
; ===========================================================================