View difference between Paste ID: 2s3PnCDQ and cAJSJ0np
SHOW: | | - or go back to the newest paste.
1
; ==============================================================================
2
; ------------------------------------------------------------------------------
3
; Nemesis decompression routine
4
; ------------------------------------------------------------------------------
5
; Optimized by vladikcomper
6
; Modified for Sonic 2 by MainMemory
7
; ------------------------------------------------------------------------------
8-
NemDec_RAM:
8+
9
NemDecToRAM:
10-
	lea	NemDec_WriteRowToRAM(pc),a3
10+
11
	lea	NemDec_WriteAndAdvance(pc),a3
12
	bra.s	NemDec_Main
13
14
; ------------------------------------------------------------------------------
15
NemDec:
16-
	lea	$C00000,a4		; load VDP Data Port     
16+
17-
	lea	NemDec_WriteRowToVDP(pc),a3
17+
	lea	(VDP_data_port).l,a4		; load VDP Data Port     
18
	lea	NemDec_WriteAndStay(pc),a3
19
20-
	lea	$FFFFAA00,a1		; load Nemesis decompression buffer
20+
21
	lea	(Decomp_Buffer).w,a1		; load Nemesis decompression buffer
22-
	bpl.s	@0			; are we in Mode 0?
22+
23
	bpl.s	+			; are we in Mode 0?
24-
@0	lsl.w	#3,d2
24+
25
+
26
	lsl.w	#3,d2
27
	movea.w	d2,a5
28
	moveq	#7,d3
29-
	bsr.w	NemDec4
29+
30
	moveq	#0,d4
31
	bsr.w	NemDecPrepare
32
	move.b	(a0)+,d5		; get first byte of compressed data
33
	asl.w	#8,d5			; shift up by a byte
34
	move.b	(a0)+,d5		; get second byte of compressed data
35
	move.w	#$10,d6			; set initial shift value
36
	bsr.s	NemDec2
37
	movem.l	(sp)+,d0-a1/a3-a6
38
	rts
39
40
; ---------------------------------------------------------------------------
41
; Part of the Nemesis decompressor, processes the actual compressed data
42
; ---------------------------------------------------------------------------
43
44
NemDec2:
45
	move.w	d6,d7
46
	subq.w	#8,d7			; get shift value
47
	move.w	d5,d1
48
	lsr.w	d7,d1			; shift so that high bit of the code is in bit position 7
49
	cmpi.b	#%11111100,d1		; are the high 6 bits set?
50
	bcc.s	NemDec_InlineData	; if they are, it signifies inline data
51
	andi.w	#$FF,d1
52
	add.w	d1,d1
53-
	bcc.s	@0			; if not, branch
53+
54
	cmpi.w	#9,d6			; does a new byte need to be read?
55
	bcc.s	+			; if not, branch
56
	addq.w	#8,d6
57-
@0	move.b	1(a1,d1.w),d1
57+
58
	move.b	(a0)+,d5		; read next byte
59
+
60
	move.b	1(a1,d1.w),d1
61
	move.w	d1,d0
62
	andi.w	#$F,d1			; get palette index for pixel
63
	andi.w	#$F0,d0
64
65
NemDec_GetRepeatCount:
66
	lsr.w	#4,d0			; get repeat count
67
68
NemDec_WritePixel:
69
	lsl.l	#4,d4			; shift up by a nybble
70
	or.b	d1,d4			; write pixel
71
	dbf	d3,NemDec_WritePixelLoop; ~~
72-
NemDec3:
72+
73
; ---------------------------------------------------------------------------
74
75
NemDec_WriteIter:
76
	moveq	#0,d4			; reset row
77
	moveq	#7,d3			; reset nybble counter
78
79
NemDec_WritePixelLoop:
80
	dbf	d0,NemDec_WritePixel
81
	bra.s	NemDec2
82
; ---------------------------------------------------------------------------
83
84-
	bcc.s	@0
84+
85
	subq.w	#6,d6			; 6 bits needed to signal inline data
86
	cmpi.w	#9,d6
87
	bcc.s	+
88-
@0	subq.w	#7,d6			; and 7 bits needed for the inline data itself
88+
89
	asl.w	#8,d5
90
	move.b	(a0)+,d5
91
+
92
	subq.w	#7,d6			; and 7 bits needed for the inline data itself
93
	move.w	d5,d1
94
	lsr.w	d6,d1			; shift so that low bit of the code is in bit position 0
95
	move.w	d1,d0
96
	andi.w	#$F,d1			; get palette index for pixel
97
	andi.w	#$70,d0			; high nybble is repeat count for pixel
98
	cmpi.w	#9,d6
99
	bcc.s	NemDec_GetRepeatCount
100
	addq.w	#8,d6
101
	asl.w	#8,d5
102
	move.b	(a0)+,d5
103
	bra.s	NemDec_GetRepeatCount
104
105
; ---------------------------------------------------------------------------
106-
NemDec_WriteRowToVDP:
106+
107
; Selected depending on current decompression mode
108
; ---------------------------------------------------------------------------
109
110
NemDec_WriteAndStay:
111-
	bne.s	NemDec3			; if not, branch
111+
112
	move.l	d4,(a4)			; write 8-pixel row
113
	subq.w	#1,a5
114
	move.w	a5,d4			; have all the 8-pixel rows been written?
115-
NemDec_WriteRowToVDP_XOR:
115+
	bne.s	NemDec_WriteIter			; if not, branch
116
	rts
117
; ---------------------------------------------------------------------------
118
119
NemDec_WriteAndStay_XOR:
120-
	bne.s	NemDec3
120+
121
	move.l	d2,(a4)			; and write the result
122
	subq.w	#1,a5
123
	move.w	a5,d4
124-
NemDec_WriteRowToRAM:
124+
	bne.s	NemDec_WriteIter
125
	rts
126
; ---------------------------------------------------------------------------
127
128-
	bne.s	NemDec3			; if not, branch
128+
NemDec_WriteAndAdvance:
129
	move.l	d4,(a4)+		; write 8-pixel row
130
	subq.w	#1,a5
131
	move.w	a5,d4			; have all the 8-pixel rows been written?
132-
NemDec_WriteRowToRAM_XOR:
132+
	bne.s	NemDec_WriteIter			; if not, branch
133
	rts
134
; ---------------------------------------------------------------------------
135
136
NemDec_WriteAndAdvance_XOR:
137-
	bne.s	NemDec3
137+
138
	move.l	d2,(a4)+		; and write the result
139
	subq.w	#1,a5
140
	move.w	a5,d4
141
	bne.s	NemDec_WriteIter
142
	rts
143
144-
NemDec4:
144+
145
; Part of the Nemesis decompressor, builds the code table (in RAM)
146
; ---------------------------------------------------------------------------
147-
@ChkEnd:
147+
148
NemDecPrepare:
149-
	bne.s	@NewPalIndex		; if not, branch
149+
150
151
.ChkEnd:
152
	cmpi.b	#$FF,d0			; has the end of the code table description been reached?
153-
@NewPalIndex:
153+
	bne.s	.NewPalIndex		; if not, branch
154
	rts
155
; ---------------------------------------------------------------------------
156-
@ItemLoop:
156+
157
.NewPalIndex:
158-
	bmi.s	@ChkEnd			; ~~
158+
159
160
.ItemLoop:
161
	move.b	(a0)+,d0		; read next byte
162
	bmi.s	.ChkEnd			; ~~
163
	move.b	d0,d1
164
	andi.w	#$F,d7			; get palette index
165
	andi.w	#$70,d1			; get repeat count for palette index
166
	or.w	d1,d7			; combine the two
167
	andi.w	#$F,d0			; get the length of the code in bits
168
	move.b	d0,d1
169-
	bne.s	@ItemShortCode		; if not, a bit of extra processing is needed
169+
170
	or.w	d1,d7			; combine with palette index and repeat count to form code table entry
171
	moveq	#8,d1
172
	sub.w	d0,d1			; is the code 8 bits long?
173-
	bra.s	@ItemLoop		; repeat
173+
	bne.s	.ItemShortCode		; if not, a bit of extra processing is needed
174
	move.b	(a0)+,d0		; get code
175
	add.w	d0,d0			; each code gets a word-sized entry in the table
176-
@ItemShortCode:
176+
177
	bra.s	.ItemLoop		; repeat
178
; ---------------------------------------------------------------------------
179
180
.ItemShortCode:
181
	move.b	(a0)+,d0		; get code
182
	lsl.w	d1,d0			; shift so that high bit is in bit position 7
183
	add.w	d0,d0			; get index into code table
184
	moveq	#1,d5
185-
@ItemShortCodeLoop:
185+
186
	subq.w	#1,d5			; d5 = 2^d1 - 1
187-
	dbf	d5,@ItemShortCodeLoop	; repeat for required number of entries
187+
188-
	bra.s	@ItemLoop
188+
189
.ItemShortCodeLoop:
190
	move.w	d7,(a6)+		; ~~ store entry
191
	dbf	d5,.ItemShortCodeLoop	; repeat for required number of entries
192
	bra.s	.ItemLoop