View difference between Paste ID: g1dX0VZm and GrFDdHFE
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-
	move.l	#0,(a0)+				; and mark the last slot as free
110+
111-
	move.w	#0,(a0)+
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.
192
	clr.w	d3						; Low word is zero.
193
	bra.s	.FetchNewCode
194
; ---------------------------------------------------------------------------
195
.FetchCodeLoop:
196
	; Code 1 (Uncompressed byte).
197
	_Kos_RunBitStream
198
	move.b	(a0)+,(a1)+
199
200
.FetchNewCode:
201
	_Kos_ReadBit
202
	bcs.s	.FetchCodeLoop			; If code = 1, branch.
203
204
	; Codes 00 and 01.
205
	moveq	#-1,d5
206
	lea	(a1),a5
207
	_Kos_RunBitStream
208
	if _Kos_ExtremeUnrolling==1
209
	_Kos_ReadBit
210
	bcs.w	.Code_01
211
212
	; Code 00 (Dictionary ref. short).
213
	_Kos_RunBitStream
214
	_Kos_ReadBit
215
	bcs.s	.Copy45
216
	_Kos_RunBitStream
217
	_Kos_ReadBit
218
	bcs.s	.Copy3
219
	_Kos_RunBitStream
220
	move.b	(a0)+,d5				; d5 = displacement.
221
	adda.w	d5,a5
222
	move.b	(a5)+,(a1)+
223
	move.b	(a5)+,(a1)+
224
	bra.s	.FetchNewCode
225
; ---------------------------------------------------------------------------
226
.Copy3:
227
	_Kos_RunBitStream
228
	move.b	(a0)+,d5				; d5 = displacement.
229
	adda.w	d5,a5
230
	move.b	(a5)+,(a1)+
231
	move.b	(a5)+,(a1)+
232
	move.b	(a5)+,(a1)+
233
	bra.w	.FetchNewCode
234
; ---------------------------------------------------------------------------
235
.Copy45:
236
	_Kos_RunBitStream
237
	_Kos_ReadBit
238
	bcs.s	.Copy5
239
	_Kos_RunBitStream
240
	move.b	(a0)+,d5				; d5 = displacement.
241
	adda.w	d5,a5
242
	move.b	(a5)+,(a1)+
243
	move.b	(a5)+,(a1)+
244
	move.b	(a5)+,(a1)+
245
	move.b	(a5)+,(a1)+
246
	bra.w	.FetchNewCode
247
; ---------------------------------------------------------------------------
248
.Copy5:
249
	_Kos_RunBitStream
250
	move.b	(a0)+,d5				; d5 = displacement.
251
	adda.w	d5,a5
252
	move.b	(a5)+,(a1)+
253
	move.b	(a5)+,(a1)+
254
	move.b	(a5)+,(a1)+
255
	move.b	(a5)+,(a1)+
256
	move.b	(a5)+,(a1)+
257
	bra.w	.FetchNewCode
258
; ---------------------------------------------------------------------------
259
	else
260
	moveq	#0,d4					; d4 will contain copy count.
261
	_Kos_ReadBit
262
	bcs.s	.Code_01
263
264
	; Code 00 (Dictionary ref. short).
265
	_Kos_RunBitStream
266
	_Kos_ReadBit
267
	addx.w	d4,d4
268
	_Kos_RunBitStream
269
	_Kos_ReadBit
270
	addx.w	d4,d4
271
	_Kos_RunBitStream
272
	move.b	(a0)+,d5				; d5 = displacement.
273
274
.StreamCopy:
275
	adda.w	d5,a5
276
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
277
278
.copy:
279
	move.b	(a5)+,(a1)+
280
	dbra	d4,.copy
281
	bra.w	.FetchNewCode
282
	endif
283
; ---------------------------------------------------------------------------
284
.Code_01:
285
	moveq	#0,d4					; d4 will contain copy count.
286
	; Code 01 (Dictionary ref. long / special).
287
	_Kos_RunBitStream
288
	move.b	(a0)+,d6				; d6 = %LLLLLLLL.
289
	move.b	(a0)+,d4				; d4 = %HHHHHCCC.
290
	move.b	d4,d5					; d5 = %11111111 HHHHHCCC.
291
	lsl.w	#5,d5					; d5 = %111HHHHH CCC00000.
292
	move.b	d6,d5					; d5 = %111HHHHH LLLLLLLL.
293
	if _Kos_LoopUnroll==3
294
	and.w	d7,d4					; d4 = %00000CCC.
295
	else
296
	andi.w	#7,d4
297
	endif
298
	bne.s	.StreamCopy				; if CCC=0, branch.
299
300
	; special mode (extended counter)
301
	move.b	(a0)+,d4				; Read cnt
302
	beq.s	.Quit					; If cnt=0, quit decompression.
303
	subq.b	#1,d4
304
	beq.w	.FetchNewCode			; If cnt=1, fetch a new code.
305
306
	adda.w	d5,a5
307
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
308
	move.w	d4,d6
309
	not.w	d6
310
	and.w	d7,d6
311
	add.w	d6,d6
312
	lsr.w	#_Kos_LoopUnroll,d4
313
	jmp	.largecopy(pc,d6.w)
314
; ---------------------------------------------------------------------------
315
.largecopy:
316
	rept (1<<_Kos_LoopUnroll)
317
	move.b	(a5)+,(a1)+
318
	endm
319
	dbra	d4,.largecopy
320
	bra.w	.FetchNewCode
321
; ---------------------------------------------------------------------------
322
	if _Kos_ExtremeUnrolling==1
323
.StreamCopy:
324
	adda.w	d5,a5
325
	move.b	(a5)+,(a1)+				; Do 1 extra copy (to compensate +1 to copy counter).
326
	if _Kos_LoopUnroll==3
327
	eor.w	d7,d4
328
	else
329
	eori.w	#7,d4
330
	endif
331
	add.w	d4,d4
332
	jmp	.mediumcopy(pc,d4.w)
333
; ---------------------------------------------------------------------------
334
.mediumcopy:
335
	rept 8
336
	move.b	(a5)+,(a1)+
337
	endm
338
	bra.w	.FetchNewCode
339
	endif
340
; ---------------------------------------------------------------------------
341
.Quit:
342
	move.l	a0,(Kos_decomp_queue).w
343
	move.l	a1,(Kos_decomp_destination).w
344
	andi.w	#$7FFF,(Kos_decomp_queue_count).w	; clear decompression in progress bit
345
	subq.w	#1,(Kos_decomp_queue_count).w
346
	beq.s	.Done								; branch if there aren't any entries remaining in the queue
347
	lea	(Kos_decomp_queue).w,a0
348
	lea	(Kos_decomp_queue+8).w,a1				; otherwise, shift all entries up
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
	move.l	(a1)+,(a0)+
355
356
.Done:
357
	rts
358
; ---------------------------------------------------------------------------
359
Restore_Kos_Bookmark:
360
	movem.w	(Kos_decomp_stored_registers).w,d0-d6
361
	movem.l	(Kos_decomp_stored_registers+2*7).w,a0-a1/a5
362
	move.l	(Kos_decomp_bookmark).w,-(sp)
363
	move.w	(Kos_decomp_stored_SR).w,-(sp)
364
	moveq	#(1<<_Kos_LoopUnroll)-1,d7
365
	lea	KosDec_ByteMap(pc),a4		; Load LUT pointer.
366
	rte
367
; End of function Process_Kos_Queue
368
; ===========================================================================
369
Backup_Kos_Registers:
370
	move	sr,(Kos_decomp_stored_SR).w
371
	movem.w	d0-d6,(Kos_decomp_stored_registers).w
372
	movem.l	a0-a1/a5,(Kos_decomp_stored_registers+2*7).w
373
	rts
374
; ===========================================================================