eliminate texrels (wip)
[picodrive.git] / pico / draw_arm.S
CommitLineData
cff531af 1/*\r
2 * assembly optimized versions of most funtions from draw.c\r
ea38612f 3 * (C) notaz, 2006-2010,2017\r
cff531af 4 *\r
5 * This work is licensed under the terms of MAME license.\r
6 * See COPYING file in the top-level directory.\r
7 *\r
8 * this is highly specialized, be careful if changing related C code!\r
9 */\r
cc68a136 10\r
ea38612f 11#include "pico_int_o32.h"\r
12\r
cc68a136 13.extern PicoOpt\r
14.extern HighCol\r
cc68a136 15.extern HighSprZ\r
283fec1b 16.extern HighPreSpr\r
cc68a136 17.extern DrawLineDest\r
cc68a136 18.extern DrawStripInterlace\r
07abbab1 19.extern HighCacheS_ptr\r
cc68a136 20\r
5a681086 21.equiv OVERRIDE_HIGHCOL, 1\r
22\r
283fec1b 23.equ PDRAW_SPRITES_MOVED, (1<<0)\r
24.equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
25.equ PDRAW_ACC_SPRITES, (1<<2)\r
26.equ PDRAW_DIRTY_SPRITES, (1<<4)\r
27.equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
28.equ PDRAW_SHHI_DONE, (1<<7)\r
cc68a136 29\r
30@ helper\r
31.macro TilePixel pat lsrr offs\r
32.if !\lsrr\r
33 ands r4, \pat, r2\r
34.else\r
35 ands r4, \pat, r2, lsr #\lsrr\r
36.endif\r
37 orrne r4, r3, r4\r
38 strneb r4, [r1,#\offs]\r
39.endm\r
40\r
41@ TileNorm (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
42.macro TileNorm pat\r
43 TilePixel \pat, 12, 0 @ #0x0000f000\r
44 TilePixel \pat, 8, 1 @ #0x00000f00\r
45 TilePixel \pat, 4, 2 @ #0x000000f0\r
46 TilePixel \pat, 0, 3 @ #0x0000000f\r
47 TilePixel \pat, 28, 4 @ #0xf0000000\r
48 TilePixel \pat, 24, 5 @ #0x0f000000\r
49 TilePixel \pat, 20, 6 @ #0x00f00000\r
50 TilePixel \pat, 16, 7 @ #0x000f0000\r
51.endm\r
52\r
53@ TileFlip (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
54.macro TileFlip pat\r
55 TilePixel \pat, 16, 0 @ #0x000f0000\r
56 TilePixel \pat, 20, 1 @ #0x00f00000\r
57 TilePixel \pat, 24, 2 @ #0x0f000000\r
58 TilePixel \pat, 28, 3 @ #0xf0000000\r
59 TilePixel \pat, 0, 4 @ #0x0000000f\r
60 TilePixel \pat, 4, 5 @ #0x000000f0\r
61 TilePixel \pat, 8, 6 @ #0x00000f00\r
62 TilePixel \pat, 12, 7 @ #0x0000f000\r
63.endm\r
64\r
65@ shadow/hilight mode\r
66\r
67@ this one is for hi priority layer\r
68.macro TilePixelShHP lsrr offs\r
69.if !\lsrr\r
70 ands r4, r12, r2\r
71.else\r
72 ands r4, r12, r2, lsr #\lsrr\r
73.endif\r
74 ldreqb r4, [r1,#\offs]\r
75 orrne r4, r3, r4\r
bfa12428 76 andeq r4, r4, #0xbf\r
07abbab1 77 strb r4, [r1,#\offs]\r
cc68a136 78.endm\r
79\r
7a7c6476 80@ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits\r
cc68a136 81.macro TileNormShHP\r
82 TilePixelShHP 12, 0 @ #0x0000f000\r
83 TilePixelShHP 8, 1 @ #0x00000f00\r
84 TilePixelShHP 4, 2 @ #0x000000f0\r
85 TilePixelShHP 0, 3 @ #0x0000000f\r
86 TilePixelShHP 28, 4 @ #0xf0000000\r
87 TilePixelShHP 24, 5 @ #0x0f000000\r
88 TilePixelShHP 20, 6 @ #0x00f00000\r
89 TilePixelShHP 16, 7 @ #0x000f0000\r
90.endm\r
91\r
7a7c6476 92@ TileFlipShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
cc68a136 93.macro TileFlipShHP\r
94 TilePixelShHP 16, 0 @ #0x000f0000\r
95 TilePixelShHP 20, 1 @ #0x00f00000\r
96 TilePixelShHP 24, 2 @ #0x0f000000\r
97 TilePixelShHP 28, 3 @ #0xf0000000\r
98 TilePixelShHP 0, 4 @ #0x0000000f\r
99 TilePixelShHP 4, 5 @ #0x000000f0\r
100 TilePixelShHP 8, 6 @ #0x00000f00\r
101 TilePixelShHP 12, 7 @ #0x0000f000\r
102.endm\r
103\r
104\r
105@ TileSingleSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx; r12: helper pattern 0xf\r
106.macro TileSingleSh\r
107 tst r0, #1 @ not aligned?\r
108 mov r7, #0x00c000\r
109 orr r7, r7, #0xc0\r
110 ldrneb r4, [r1]\r
111 ldreqh r4, [r1]\r
112 orr r4, r4, r7\r
113 strneb r4, [r1], #1\r
114 streqh r4, [r1], #2\r
115 ldrh r4, [r1]\r
116 orr r4, r4, r7\r
117 strh r4, [r1], #2\r
118 ldrh r4, [r1]\r
119 orr r4, r4, r7\r
120 strh r4, [r1], #2\r
121 ldrh r4, [r1]\r
122 orr r4, r4, r7\r
123 strh r4, [r1], #2\r
124 ldrneb r4, [r1]\r
125 orr r4, r4, r7\r
126 strneb r4, [r1], #1\r
127.endm\r
128\r
129@ TileSingleHi (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
130.macro TileSingleHi\r
131 tst r1, #1 @ not aligned?\r
132 mov r7, #0x008000\r
133 orr r7, r7, #0x80\r
134 ldrneb r4, [r1], #1\r
135 ldreqh r4, [r1], #2 @ 1ci\r
136 ldrh r12, [r1], #2\r
137 bic r4, r4, r7, lsr #1\r
138 orr r4, r4, r7\r
139 strneb r4, [r1, #-3]\r
140 streqh r4, [r1, #-4]\r
141 ldrh r4, [r1], #2\r
142 bic r12, r12, r7, lsr #1\r
143 orr r12, r12, r7\r
144 strh r12, [r1, #-4]\r
145 ldrh r12, [r1], #2\r
146 bic r4, r4, r7, lsr #1\r
147 orr r4, r4, r7\r
148 strh r4, [r1, #-4]\r
149 ldrneb r4, [r1]\r
150 bic r12, r12, r7, lsr #1\r
151 orr r12, r12, r7\r
152 strh r12, [r1, #-2]\r
153 bicne r4, r4, r7, lsr #1\r
154 orrne r4, r4, r7\r
155 strneb r4, [r1], #1\r
156 mov r12, #0xf\r
157.endm\r
158\r
159.macro TileDoShGenPixel shift ofs\r
160.if \shift\r
161 ands r4, r12, r2, lsr #\shift\r
162.else\r
163 ands r4, r12, r2\r
164.endif\r
07abbab1 165 beq 0f\r
cc68a136 166 cmp r4, #0xe\r
bfa12428 167 ldrgeb r7, [r1,#\ofs]\r
168 orrlt r7, r3, r4 @ normal\r
07abbab1 169\r
bfa12428 170 bicge r7, r7, #0xc0\r
171 orrge r7, r7, r4, lsl #6\r
172 strb r7, [r1,#\ofs]\r
07abbab1 1730:\r
cc68a136 174.endm\r
175\r
176@ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
177.macro TileFlipSh\r
178 TileDoShGenPixel 16, 0 @ #0x000f0000\r
179 TileDoShGenPixel 20, 1 @ #0x00f00000\r
180 TileDoShGenPixel 24, 2 @ #0x0f000000\r
181 TileDoShGenPixel 28, 3 @ #0xf0000000\r
182 TileDoShGenPixel 0, 4 @ #0x0000000f\r
183 TileDoShGenPixel 4, 5 @ #0x000000f0\r
184 TileDoShGenPixel 8, 6 @ #0x00000f00\r
185 TileDoShGenPixel 12, 7 @ #0x0000f000\r
186.endm\r
187\r
188@ TileNormSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
189.macro TileNormSh\r
190 TileDoShGenPixel 12, 0 @ #0x0000f000\r
191 TileDoShGenPixel 8, 1 @ #0x00000f00\r
192 TileDoShGenPixel 4, 2 @ #0x000000f0\r
193 TileDoShGenPixel 0, 3 @ #0x0000000f\r
194 TileDoShGenPixel 28, 4 @ #0xf0000000\r
195 TileDoShGenPixel 24, 5 @ #0x0f000000\r
196 TileDoShGenPixel 20, 6 @ #0x00f00000\r
197 TileDoShGenPixel 16, 7 @ #0x000f0000\r
198.endm\r
199\r
bfa12428 200.macro TileDoShGenPixel_markop shift ofs\r
07abbab1 201.if \shift\r
bfa12428 202 ands r4, r12, r2, lsr #\shift\r
07abbab1 203.else\r
bfa12428 204 ands r4, r12, r2\r
07abbab1 205.endif\r
bfa12428 206 beq 0f\r
207 cmp r4, #0xe\r
208 ldrgeb r4, [r1,#\ofs]\r
209 orrlt r4, r3, r4\r
e54507e8 210 orrge r4, r4, #0x80\r
bfa12428 211 strb r4, [r1,#\ofs]\r
2120:\r
07abbab1 213.endm\r
214\r
e54507e8 215.macro TileFlipSh_markop\r
bfa12428 216 TileDoShGenPixel_markop 16, 0 @ #0x000f0000\r
217 TileDoShGenPixel_markop 20, 1 @ #0x00f00000\r
218 TileDoShGenPixel_markop 24, 2 @ #0x0f000000\r
219 TileDoShGenPixel_markop 28, 3 @ #0xf0000000\r
220 TileDoShGenPixel_markop 0, 4 @ #0x0000000f\r
221 TileDoShGenPixel_markop 4, 5 @ #0x000000f0\r
222 TileDoShGenPixel_markop 8, 6 @ #0x00000f00\r
223 TileDoShGenPixel_markop 12, 7 @ #0x0000f000\r
07abbab1 224.endm\r
225\r
e54507e8 226.macro TileNormSh_markop\r
bfa12428 227 TileDoShGenPixel_markop 12, 0 @ #0x0000f000\r
228 TileDoShGenPixel_markop 8, 1 @ #0x00000f00\r
229 TileDoShGenPixel_markop 4, 2 @ #0x000000f0\r
230 TileDoShGenPixel_markop 0, 3 @ #0x0000000f\r
231 TileDoShGenPixel_markop 28, 4 @ #0xf0000000\r
232 TileDoShGenPixel_markop 24, 5 @ #0x0f000000\r
233 TileDoShGenPixel_markop 20, 6 @ #0x00f00000\r
234 TileDoShGenPixel_markop 16, 7 @ #0x000f0000\r
07abbab1 235.endm\r
236\r
237.macro TileDoShGenPixel_onlyop_lp shift ofs\r
238.if \shift\r
239 ands r7, r12, r2, lsr #\shift\r
240.else\r
241 ands r7, r12, r2\r
242.endif\r
243 ldrneb r4, [r1,#\ofs]\r
07abbab1 244 cmp r7, #0xe\r
bfa12428 245 blt 0f\r
246\r
247 tst r4, #0xc0\r
248 bicne r4, r4, #0xc0\r
249 orrne r4, r4, r7, lsl #6\r
250 strneb r4, [r1,#\ofs]\r
07abbab1 2510:\r
252.endm\r
253\r
254.macro TileFlipSh_onlyop_lp\r
255 TileDoShGenPixel_onlyop_lp 16, 0 @ #0x000f0000\r
256 TileDoShGenPixel_onlyop_lp 20, 1 @ #0x00f00000\r
257 TileDoShGenPixel_onlyop_lp 24, 2 @ #0x0f000000\r
258 TileDoShGenPixel_onlyop_lp 28, 3 @ #0xf0000000\r
259 TileDoShGenPixel_onlyop_lp 0, 4 @ #0x0000000f\r
260 TileDoShGenPixel_onlyop_lp 4, 5 @ #0x000000f0\r
261 TileDoShGenPixel_onlyop_lp 8, 6 @ #0x00000f00\r
262 TileDoShGenPixel_onlyop_lp 12, 7 @ #0x0000f000\r
263.endm\r
264\r
265.macro TileNormSh_onlyop_lp\r
266 TileDoShGenPixel_onlyop_lp 12, 0 @ #0x0000f000\r
267 TileDoShGenPixel_onlyop_lp 8, 1 @ #0x00000f00\r
268 TileDoShGenPixel_onlyop_lp 4, 2 @ #0x000000f0\r
269 TileDoShGenPixel_onlyop_lp 0, 3 @ #0x0000000f\r
270 TileDoShGenPixel_onlyop_lp 28, 4 @ #0xf0000000\r
271 TileDoShGenPixel_onlyop_lp 24, 5 @ #0x0f000000\r
272 TileDoShGenPixel_onlyop_lp 20, 6 @ #0x00f00000\r
273 TileDoShGenPixel_onlyop_lp 16, 7 @ #0x000f0000\r
274.endm\r
275\r
cc68a136 276\r
277@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
278\r
279@ struct TileStrip\r
280@ {\r
281@ int nametab; // 0x00\r
282@ int line; // 0x04\r
283@ int hscroll; // 0x08\r
284@ int xmask; // 0x0C\r
285@ int *hc; // 0x10 (pointer to cache buffer)\r
286@ int cells; // 0x14\r
287@ };\r
288\r
ea38612f 289@ void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells,\r
290@ struct PicoEState *est)\r
cc68a136 291\r
83c093a4 292.global DrawLayer\r
cc68a136 293\r
294DrawLayer:\r
ea38612f 295 ldr r12, [sp] @ est\r
cc68a136 296 stmfd sp!, {r4-r11,lr}\r
297\r
ea38612f 298 ldr r11, [r12, #OFS_Pico_video]\r
cc68a136 299 mov r8, #1\r
300\r
83c093a4 301 ldrb r7, [r11, #16] @ ??vv??hh\r
cc68a136 302\r
303 mov r6, r1 @ hcache\r
83c093a4 304 orr r9, r3, r0, lsl #30\r
305 orr r9, r9, r2, lsl #8 @ r9=sh[31]|cellskip[15:8]|maxcells[7:0] (tmp)\r
cc68a136 306\r
307 mov r1, r7, lsl #4\r
308 orr r1, r1, #0x00ff\r
309\r
310 and r10, r7, #3\r
311 cmp r10, #1\r
312 biclt r1, r1, #0xfc00\r
313 biceq r1, r1, #0xfe00\r
314 bicgt r1, r1, #0xff00 @ r1=ymask=(height<<8)|0xff; ...; // Y Mask in pixels\r
315\r
316 add r10, r10, #5\r
317 cmp r10, #7\r
318 subge r10, r10, #1 @ r10=shift[width] (5,6,6,7)\r
319\r
ea38612f 320 ldr r2, [r12, #OFS_DrawScanline]\r
321 ldr lr, [r12, #OFS_Pico_vram]\r
cc68a136 322\r
323 @ Find name table:\r
83c093a4 324 ands r0, r0, #1\r
cc68a136 325 ldreqb r12, [r11, #2]\r
326 ldrneb r12, [r11, #4]\r
327\r
ea38612f 328 @ calculate xmask:\r
329 mov r5, r8, lsl r10\r
330 sub r5, r5, #1 @ r5=xmask\r
cc68a136 331\r
332 moveq r12, r12, lsl #10\r
333 movne r12, r12, lsl #13\r
334 and r12, r12, #(7<<13) @ r12=(ts->nametab<<1) (halfword compliant)\r
335\r
336 ldrh r8, [r11, #12]\r
337 ldrb r7, [r11, #11]\r
cc68a136 338\r
339 mov r4, r8, lsr #8 @ pvid->reg[13]\r
340 mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)\r
341 tst r7, #2\r
b6d7ac70 342 addne r4, r4, r2, lsl #2 @ htab+=DrawScanline<<1; // Offset by line\r
cc68a136 343 tst r7, #1\r
344 biceq r4, r4, #0x1f @ htab&=~0xf; // Offset by tile\r
345 add r4, r4, r0, lsl #1 @ htab+=plane\r
346 bic r4, r4, #0x00ff0000 @ just in case\r
347 ldrh r3, [lr, r4] @ r3=hscroll\r
348\r
349 tst r7, #4\r
350 bne .DrawStrip_vsscroll\r
351\r
352 @ Get vertical scroll value:\r
353 add r7, lr, #0x012000\r
354 add r7, r7, #0x000180 @ r7=Pico.vsram (Pico+0x22180)\r
355 ldr r7, [r7]\r
356\r
357 tst r8, #2\r
358 tstne r8, #4\r
359 bne .DrawStrip_interlace\r
360\r
361 tst r0, r0\r
362 movne r7, r7, lsr #16\r
363\r
364 @ Find the line in the name table\r
365 add r2, r2, r7\r
366 and r2, r2, r1\r
367 mov r4, r2, lsr #3\r
368 add r10, r10, #1 @ shift[width]++\r
369 add r12, r12, r4, lsl r10 @ nametab+=(ts.line>>3)<<shift[width];\r
370\r
371 @ ldmia r0, {r1,r2,r3,r5,r6,r9} @ r2=line, r3=ts->hscroll, r5=ts->xmask, r6=ts->hc, r9=ts->cells\r
cc68a136 372\r
373 and r10,r2, #7\r
374 mov r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1;\r
375 orr r10,r10, r9, lsl #24\r
376\r
377 rsb r8, r3, #0\r
378 mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3\r
379\r
380 sub r1, r3, #1\r
381 and r1, r1, #7\r
382 add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1\r
383\r
384 tst r9, #1<<31\r
385 mov r3, #0\r
740da8c6 386 orrne r10,r10, #1<<23 @ r10=(cells<<24|sh<<23|hi_not_empty<<22|had_output<<21|ty)\r
cc68a136 387 movne r3, #0x40 @ default to shadowed pal on sh mode\r
388\r
cc68a136 389 cmp r7, #8\r
390 addne r10,r10, #0x01000000 @ we will loop cells+1 times if there is scroll\r
391\r
83c093a4 392 and r9, r9, #0xff00\r
393 add r8, r8, r9, lsr #8 @ tilex+=cellskip\r
394 add r7, r7, r9, lsr #5 @ dx+=cellskip<<3;\r
395 sub r10,r10,r9, lsl #16 @ cells-=cellskip\r
83c093a4 396\r
cc68a136 397 @ cache some stuff to avoid mem access\r
ea8c405f 398.if OVERRIDE_HIGHCOL\r
399 ldr r11,=HighCol\r
400 mov r0, #0xf\r
401 ldr r11,[r11]\r
402.else\r
cc68a136 403 ldr r11,=HighCol\r
404 mov r0, #0xf\r
ea8c405f 405.endif\r
406\r
407 mvn r9, #0 @ r9=prevcode=-1\r
cc68a136 408 add r1, r11, r7 @ r1=pdest\r
409\r
410\r
411 @ r4 & r7 are scratch in this loop\r
412.dsloop_subr1:\r
413 sub r1, r1, #8\r
414.dsloop: @ 40-41 times\r
415 subs r10,r10, #0x01000000\r
416 bmi .dsloop_exit\r
417\r
418.dsloop_enter:\r
419 and r7, r5, r8\r
420 add r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)\r
421 ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend)\r
422\r
423 add r1, r1, #8\r
424 add r8, r8, #1\r
425\r
426 tst r7, #0x8000\r
427 bne .DrawStrip_hiprio\r
428\r
429 cmp r7, r9\r
430 beq .DrawStrip_samecode @ we know stuff about this tile already\r
431\r
432 mov r9, r7 @ remember code\r
740da8c6 433 orr r10, r10, #1<<21 @ seen non hi-prio tile\r
cc68a136 434\r
435 movs r2, r9, lsl #20 @ if (code&0x1000)\r
436 mov r2, r2, lsl #1\r
437 add r2, r2, r10, lsl #17\r
438 mov r2, r2, lsr #17\r
439 eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;\r
440\r
441 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
442\r
443 bic r7, r3, #0x3f\r
444 and r3, r9, #0x6000\r
445 add r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
446\r
447.DrawStrip_samecode:\r
448 tst r2, r2\r
449 beq .dsloop @ tileline blank\r
450\r
451 cmp r2, r2, ror #4\r
452 beq .DrawStrip_SingleColor @ tileline singlecolor \r
453\r
454 tst r9, #0x0800\r
7a7c6476 455 bne .DrawStrip_TileFlip\r
cc68a136 456\r
457 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
cc68a136 458.DrawStrip_TileNorm:\r
459 TileNorm r0\r
460 b .dsloop\r
461\r
7a7c6476 462.DrawStrip_TileFlip:\r
463 TileFlip r0\r
464 b .dsloop\r
465\r
cc68a136 466.DrawStrip_SingleColor:\r
467 and r4, r2, #0xf\r
468 orr r4, r3, r4\r
469 orr r4, r4, r4, lsl #8\r
470 tst r1, #1 @ not aligned?\r
471 strneb r4, [r1], #1\r
472 streqh r4, [r1], #2\r
473 strh r4, [r1], #2\r
474 strh r4, [r1], #2\r
475 strh r4, [r1], #2\r
476 strneb r4, [r1], #1 @ have a remaining unaligned pixel?\r
477 b .dsloop_subr1\r
478\r
cc68a136 479.DrawStrip_hiprio_maybempt:\r
480 cmp r7, r9\r
481 beq .dsloop @ must've been empty, otherwise we wouldn't get here\r
482 movs r2, r7, lsl #20 @ if (code&0x1000)\r
483 mov r2, r2, lsl #1\r
484 add r2, r2, r10, lsl #17\r
485 mov r2, r2, lsr #17\r
486 eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;\r
487 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
488 mov r9, r7 @ remember code\r
489 tst r2, r2\r
740da8c6 490 beq .dsloop\r
491 orr r10, r10, #1<<22\r
492\r
493.DrawStrip_hiprio:\r
494 tst r10, #0x00c00000\r
495 beq .DrawStrip_hiprio_maybempt\r
496 sub r0, r1, r11\r
497 orr r7, r7, r0, lsl #16\r
498 orr r7, r7, r10, lsl #25 @ (ty<<25)\r
499 tst r7, #0x1000\r
500 eorne r7, r7, #7<<26 @ if(code&0x1000) cval^=7<<26;\r
501 str r7, [r6], #4 @ cache hi priority tile\r
502 mov r0, #0xf\r
cc68a136 503 b .dsloop\r
504\r
505.dsloop_exit:\r
740da8c6 506 tst r10, #1<<21 @ seen non hi-prio tile\r
ea38612f 507 ldr r1, [sp, #9*4] @ est\r
cc68a136 508 mov r0, #0\r
ea38612f 509 ldreq r2, [r1, #OFS_rendstatus]\r
cc68a136 510 str r0, [r6] @ terminate the cache list\r
283fec1b 511 orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
ea38612f 512 streq r2, [r1, #OFS_rendstatus]\r
cc68a136 513\r
514 ldmfd sp!, {r4-r11,lr}\r
515 bx lr\r
516\r
6d7acf9e 517@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
cc68a136 518\r
519.DrawStrip_vsscroll:\r
6d7acf9e 520 rsb r8, r3, #0\r
521 mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3\r
7b802576 522 bic r8, r8, #0x3fc00000\r
523 orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|had_output[24]|tilex[21:0])\r
cc68a136 524\r
ea38612f 525 ldr r11, [sp, #9*4] @ est\r
6d7acf9e 526 orr r5, r1, r10, lsl #24\r
ea38612f 527 ldr r4, [r11, #OFS_DrawScanline]\r
6d7acf9e 528 sub r1, r3, #1\r
529 orr r5, r5, r4, lsl #16 @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0])\r
530 and r1, r1, #7\r
531 add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1\r
cc68a136 532\r
6d7acf9e 533 mov r10,r9, lsl #16\r
83c093a4 534 tst r0, #1\r
6d7acf9e 535 orrne r10,r10, #0x8000\r
536 tst r9, #1<<31\r
537 mov r3, #0\r
538 orr r10,r10, #0xff000000 @ will be adjusted on entering loop\r
83c093a4 539 orrne r10,r10, #1<<23 @ r10=(cell[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0])\r
6d7acf9e 540 movne r3, #0x40 @ default to shadowed pal on sh mode\r
cc68a136 541\r
83c093a4 542 cmp r7, #8\r
543 subne r10,r10, #0x01000000 @ have hscroll, start with negative cell\r
544\r
545 and r9, r9, #0xff00\r
546 add r8, r8, r9, lsr #8 @ tilex+=cellskip\r
547 add r7, r7, r9, lsr #5 @ dx+=cellskip<<3;\r
548 add r10,r10,r9, lsl #16 @ cell+=cellskip\r
cc68a136 549\r
6d7acf9e 550 @ cache some stuff to avoid mem access\r
ea8c405f 551.if OVERRIDE_HIGHCOL\r
6d7acf9e 552 ldr r11,=HighCol\r
553 mov r0, #0xf\r
ea8c405f 554 ldr r11,[r11]\r
555.else\r
556 ldr r11,=HighCol\r
557 mov r0, #0xf\r
558.endif\r
6d7acf9e 559\r
ea8c405f 560 mvn r9, #0 @ r9=prevcode=-1\r
561 add r1, r11, r7 @ r1=pdest\r
6d7acf9e 562\r
563 @ r4 & r7 are scratch in this loop\r
564.dsloop_vs_subr1:\r
565 sub r1, r1, #8\r
566.dsloop_vs: @ 40-41 times\r
567 add r10,r10, #0x01000000\r
568 and r4, r10, #0x003f0000\r
569 cmp r4, r10, asr #8\r
740da8c6 570 ble .dsloop_vs_exit\r
6d7acf9e 571\r
572 @ calc offset and read tileline code to r7, also calc ty\r
573 add r7, lr, #0x012000\r
574 add r7, r7, #0x000180 @ r7=Pico.vsram (Pico+0x22180)\r
575 add r7, r7, r10,asr #23 @ vsram + ((cell&~1)<<1)\r
576 bic r7, r7, #3\r
577 tst r10,#0x8000 @ plane1?\r
578 addne r7, r7, #2\r
579 ldrh r7, [r7] @ r7=vscroll\r
580\r
581 bic r10,r10,#0xff @ clear old ty\r
7b802576 582 and r4, r5, #0xff0000 @ scanline\r
583 add r4, r4, r7, lsl #16 @ ... += vscroll\r
584 and r4, r4, r5, lsl #16 @ ... &= ymask\r
6d7acf9e 585 and r7, r4, #0x70000\r
586 orr r10,r10,r7, lsr #15 @ new ty\r
587\r
588 mov r4, r4, lsr #19\r
589 mov r7, r5, lsr #24\r
590 mov r4, r4, lsl r7 @ nametabadd\r
591\r
592 and r7, r8, r8, lsr #25\r
593 add r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)\r
594 add r7, r7, r4, lsl #1\r
595 ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend)\r
596\r
597 add r1, r1, #8\r
598 add r8, r8, #1\r
599\r
600 tst r7, #0x8000\r
601 bne .DrawStrip_vs_hiprio\r
602\r
603 cmp r7, r9\r
604 beq .DrawStrip_vs_samecode @ we know stuff about this tile already\r
605\r
606 mov r9, r7 @ remember code\r
7b802576 607 orr r8, r8, #(1<<24)@ seen non hi-prio tile\r
6d7acf9e 608\r
609 movs r2, r9, lsl #20 @ if (code&0x1000)\r
610 mov r2, r2, lsl #1\r
611 add r2, r2, r10, lsl #17\r
612 mov r2, r2, lsr #17\r
613 eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;\r
614\r
615 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
616\r
617 bic r7, r3, #0x3f\r
618 and r3, r9, #0x6000\r
619 add r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
620\r
621.DrawStrip_vs_samecode:\r
622 tst r2, r2\r
623 beq .dsloop_vs @ tileline blank\r
624\r
625 cmp r2, r2, ror #4\r
626 beq .DrawStrip_vs_SingleColor @ tileline singlecolor \r
627\r
628 tst r9, #0x0800\r
7a7c6476 629 bne .DrawStrip_vs_TileFlip\r
6d7acf9e 630\r
631 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
6d7acf9e 632.DrawStrip_vs_TileNorm:\r
633 TileNorm r0\r
634 b .dsloop_vs\r
635\r
7a7c6476 636.DrawStrip_vs_TileFlip:\r
637 TileFlip r0\r
638 b .dsloop_vs\r
639\r
6d7acf9e 640.DrawStrip_vs_SingleColor:\r
641 and r4, r2, #0xf\r
642 orr r4, r3, r4\r
643 orr r4, r4, r4, lsl #8\r
644 tst r1, #1 @ not aligned?\r
645 strneb r4, [r1], #1\r
646 streqh r4, [r1], #2\r
647 strh r4, [r1], #2\r
648 strh r4, [r1], #2\r
649 strh r4, [r1], #2\r
650 strneb r4, [r1], #1 @ have a remaining unaligned pixel?\r
651 b .dsloop_vs_subr1\r
652\r
653.DrawStrip_vs_hiprio:\r
654 tst r10, #0x00c00000\r
655 beq .DrawStrip_vs_hiprio_maybempt\r
656 sub r0, r1, r11\r
657 orr r7, r7, r0, lsl #16\r
658 orr r7, r7, r10, lsl #25 @ (ty<<25)\r
659 tst r7, #0x1000\r
660 eorne r7, r7, #7<<26 @ if(code&0x1000) cval^=7<<26;\r
661 str r7, [r6], #4 @ cache hi priority tile\r
662 mov r0, #0xf\r
663 b .dsloop_vs\r
664\r
665.DrawStrip_vs_hiprio_maybempt:\r
666 cmp r7, r9\r
667 beq .dsloop_vs @ must've been empty, otherwise we wouldn't get here\r
668 movs r2, r7, lsl #20 @ if (code&0x1000)\r
669 mov r2, r2, lsl #1\r
670 add r2, r2, r10, lsl #17\r
671 mov r2, r2, lsr #17\r
672 eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;\r
673 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
674 mov r9, r7 @ remember code\r
675 tst r2, r2\r
676 orrne r10, r10, #1<<22\r
677 bne .DrawStrip_vs_hiprio\r
678 b .dsloop_vs\r
679\r
740da8c6 680.dsloop_vs_exit:\r
7b802576 681 tst r8, #(1<<24) @ seen non hi-prio tile\r
ea38612f 682 ldr r1, [sp, #9*4] @ est\r
740da8c6 683 mov r0, #0\r
ea38612f 684 ldreq r2, [r1, #OFS_rendstatus]\r
740da8c6 685 str r0, [r6] @ terminate the cache list\r
283fec1b 686 orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
ea38612f 687 streq r2, [r1, #OFS_rendstatus]\r
740da8c6 688\r
689 ldmfd sp!, {r4-r11,lr}\r
690 bx lr\r
691\r
6d7acf9e 692\r
693@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
cc68a136 694\r
695@ interlace mode 2? Sonic 2?\r
696.DrawStrip_interlace:\r
697 tst r0, r0\r
698 moveq r7, r7, lsl #21\r
699 movne r7, r7, lsl #5\r
700\r
701 @ Find the line in the name table\r
b6d7ac70 702 add r2, r7, r2, lsl #22 @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);\r
cc68a136 703 orr r1, r1, #0x80000000\r
704 and r2, r2, r1, ror #10 @ &((ymask<<1)|1)<<21;\r
705 mov r2, r2, lsr #21\r
706 mov r4, r2, lsr #4\r
707 mov r12, r12, lsr #1 @ halfwords\r
708 add r0, r12, r4, lsl r10 @ nametab+=(ts.line>>4)<<shift[width];\r
709 and r9, r9, #0xff\r
710\r
711 sub sp, sp, #6*4\r
712 stmia sp, {r0,r2,r3,r5,r6,r9}\r
713\r
714 mov r0, sp\r
715 bl DrawStripInterlace @ struct TileStrip *ts\r
716\r
717 add sp, sp, #6*4\r
718 ldmfd sp!, {r4-r11,lr}\r
719 bx lr\r
720\r
721.pool\r
722\r
723@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
724\r
725\r
726.global BackFill @ int reg7, int sh\r
727\r
728BackFill:\r
729 stmfd sp!, {r4-r9,lr}\r
730\r
ea8c405f 731.if OVERRIDE_HIGHCOL\r
732 ldr lr, =HighCol\r
733 mov r0, r0, lsl #26\r
734 ldr lr, [lr]\r
735 mov r0, r0, lsr #26\r
736 add lr, lr, #8\r
737.else\r
cc68a136 738 ldr lr, =(HighCol+8)\r
cc68a136 739 mov r0, r0, lsl #26\r
740 mov r0, r0, lsr #26\r
ea8c405f 741.endif\r
742\r
cc68a136 743 orr r0, r0, r1, lsl #6\r
744 orr r0, r0, r0, lsl #8\r
745 orr r0, r0, r0, lsl #16\r
746\r
747 mov r1, r0\r
748 mov r2, r0\r
749 mov r3, r0\r
750 mov r4, r0\r
751 mov r5, r0\r
752 mov r6, r0\r
753 mov r7, r0\r
754\r
755 @ go go go!\r
756 stmia lr!, {r0-r7} @ 10*8*4\r
757 stmia lr!, {r0-r7}\r
758 stmia lr!, {r0-r7}\r
759 stmia lr!, {r0-r7}\r
760 stmia lr!, {r0-r7}\r
761 stmia lr!, {r0-r7}\r
762 stmia lr!, {r0-r7}\r
763 stmia lr!, {r0-r7}\r
764 stmia lr!, {r0-r7}\r
765 stmia lr!, {r0-r7}\r
766\r
767 ldmfd sp!, {r4-r9,r12}\r
768 bx r12\r
769\r
770\r
771@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
772\r
ea38612f 773@ void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est)\r
cc68a136 774\r
ea38612f 775.global DrawTilesFromCache\r
cc68a136 776\r
777DrawTilesFromCache:\r
ea38612f 778 stmfd sp!, {r4-r9,r11,lr}\r
cc68a136 779\r
cc68a136 780 @ cache some stuff to avoid mem access\r
ea8c405f 781.if OVERRIDE_HIGHCOL\r
cc68a136 782 ldr r11,=HighCol\r
cc68a136 783 mov r12,#0xf\r
ea8c405f 784 ldr r11,[r11]\r
785.else\r
786 ldr r11,=HighCol\r
787 mov r12,#0xf\r
788.endif\r
ea38612f 789 ldr lr, [r3, #OFS_Pico_vram]\r
790 mov r9, r3 @ est\r
cc68a136 791\r
740da8c6 792 mvn r5, #0 @ r5=prevcode=-1\r
7a7c6476 793 ands r8, r1, #1\r
794 orr r8, r8, r2, lsl #1\r
740da8c6 795 bne .dtfc_check_rendflags\r
796\r
cc68a136 797 @ scratch: r4, r7\r
798.dtfc_loop:\r
799 ldr r6, [r0], #4 @ read code\r
800 movs r1, r6, lsr #16 @ r1=dx;\r
ea38612f 801 ldmeqfd sp!, {r4-r9,r11,pc} @ dx is never zero, this must be a terminator, return\r
7a7c6476 802 bic r4, r1, #0xfe00\r
803 add r1, r11, r4 @ r1=pdest\r
cc68a136 804\r
805 mov r7, r6, lsl #16\r
806 cmp r5, r7, lsr #16\r
807 beq .dtfc_samecode @ if (code==prevcode)\r
808\r
809 mov r5, r7, lsr #16\r
810\r
811 mov r2, r5, lsl #21\r
812 mov r2, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4;\r
813 add r2, r2, r6, lsr #25 @ addr+=ty\r
814\r
815 and r3, r5, #0x6000\r
816 mov r3, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
817\r
818 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
819\r
820.dtfc_samecode:\r
7a7c6476 821 rsbs r4, r4, r8, lsr #1\r
822 bmi .dtfc_cut_tile\r
823\r
824 tst r8, #1\r
cc68a136 825 bne .dtfc_shadow\r
826\r
827 tst r2, r2\r
828 beq .dtfc_loop\r
829\r
830 cmp r2, r2, ror #4\r
831 beq .dtfc_SingleColor @ tileline singlecolor \r
832\r
833 tst r5, #0x0800\r
7a7c6476 834 bne .dtfc_TileFlip\r
cc68a136 835\r
836 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
cc68a136 837.dtfc_TileNorm:\r
838 TileNorm r12\r
839 b .dtfc_loop\r
840\r
7a7c6476 841.dtfc_TileFlip:\r
842 TileFlip r12\r
843 b .dtfc_loop\r
844\r
cc68a136 845.dtfc_SingleColor:\r
846 and r4, r2, #0xf\r
847 orr r4, r3, r4\r
848 orr r4, r4, r4, lsl #8\r
849 tst r1, #1 @ not aligned?\r
850 strneb r4, [r1], #1\r
851 streqh r4, [r1], #2\r
852 strh r4, [r1], #2\r
853 strh r4, [r1], #2\r
854 strh r4, [r1], #2\r
855 strneb r4, [r1], #1 @ have a remaining unaligned pixel?\r
856 b .dtfc_loop\r
857\r
858.dtfc_shadow:\r
859 tst r2, r2\r
860 beq .dtfc_shadow_blank\r
861\r
862 cmp r2, r2, ror #4\r
863 beq .dtfc_SingleColor @ tileline singlecolor \r
864\r
865 tst r5, #0x0800\r
7a7c6476 866 bne .dtfc_TileFlipShHP\r
cc68a136 867\r
868 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
cc68a136 869.dtfc_TileNormShHP:\r
870 TileNormShHP\r
871 b .dtfc_loop\r
872\r
7a7c6476 873.dtfc_TileFlipShHP:\r
874 TileFlipShHP\r
875 b .dtfc_loop\r
876\r
cc68a136 877.dtfc_shadow_blank:\r
07abbab1 878 tst r1, #1\r
879 ldrneb r4, [r1]\r
bfa12428 880 mov r6, #0xbf\r
881 and r4, r4, #0xbf\r
07abbab1 882 strneb r4, [r1], #1\r
883 ldrh r4, [r1]\r
884 orr r6, r6, r6, lsl #8\r
885 and r4, r4, r6\r
886 strh r4, [r1], #2\r
887 ldrh r4, [r1]\r
888 and r4, r4, r6\r
889 strh r4, [r1], #2\r
890 ldrh r4, [r1]\r
891 and r4, r4, r6\r
892 strh r4, [r1], #2\r
893 ldrh r4, [r1]\r
894 and r4, r4, r6\r
895 streqh r4, [r1]\r
896 strneb r4, [r1]\r
cc68a136 897 b .dtfc_loop\r
898\r
7a7c6476 899.dtfc_cut_tile:\r
900 add r4, r4, #7 @ 0-6\r
901 mov r4, r4, lsl #2\r
902 mov r12,#0xf<<28\r
903 mov r12,r12,asr r4\r
904 mov r2, r2, ror #16\r
905 tst r5, #0x0800 @ flipped?\r
906 mvnne r12,r12\r
907 and r2, r2, r12\r
908 mov r2, r2, ror #16\r
909 mov r12,#0xf\r
910 tst r8, #1\r
911 bne .dtfc_shadow\r
912 tst r2, r2\r
913 beq .dtfc_loop\r
914 tst r5, #0x0800\r
915 beq .dtfc_TileNorm\r
916 b .dtfc_TileFlip\r
917\r
740da8c6 918@ check if we have detected layer covered with hi-prio tiles:\r
919.dtfc_check_rendflags:\r
ea38612f 920 ldr r2, [r9, #OFS_rendstatus]\r
283fec1b 921 tst r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE)\r
740da8c6 922 beq .dtfc_loop\r
7a7c6476 923 bic r8, r8, #1 @ sh/hi mode off\r
283fec1b 924 tst r2, #PDRAW_SHHI_DONE\r
740da8c6 925 bne .dtfc_loop @ already processed\r
283fec1b 926 orr r2, r2, #PDRAW_SHHI_DONE\r
ea38612f 927 str r2, [r9, #OFS_rendstatus]\r
740da8c6 928\r
929 add r1, r11,#8\r
07abbab1 930 mov r3, #320/4/4\r
bfa12428 931 mov r6, #0xbf\r
740da8c6 932 orr r6, r6, r6, lsl #8\r
933 orr r6, r6, r6, lsl #16\r
934.dtfc_loop_shprep:\r
07abbab1 935 ldmia r1, {r2,r4,r5,r7}\r
740da8c6 936 subs r3, r3, #1\r
07abbab1 937 and r2, r2, r6\r
938 and r4, r4, r6\r
939 and r5, r5, r6\r
940 and r7, r7, r6\r
941 stmia r1!,{r2,r4,r5,r7}\r
942 bne .dtfc_loop_shprep\r
943\r
944 mvn r5, #0 @ r5=prevcode=-1\r
945 b .dtfc_loop\r
740da8c6 946\r
cc68a136 947.pool\r
948\r
949@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
950\r
951\r
ea38612f 952@ void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est)\r
953\r
954.global DrawSpritesSHi\r
e352c3af 955\r
956DrawSpritesSHi:\r
fbc65db7 957 ldr r3, [r0]\r
958 mov r12,#0xff\r
e352c3af 959 ands r3, r3, #0x7f\r
960 bxeq lr\r
cc68a136 961\r
ea38612f 962 stmfd sp!, {r1,r4-r11,lr} @ +est\r
fbc65db7 963 strb r12,[r0,#2] @ set end marker\r
964 add r10,r0, #3 @ r10=HighLnSpr end\r
e352c3af 965 add r10,r10,r3 @ r10=HighLnSpr end\r
966\r
ea8c405f 967.if OVERRIDE_HIGHCOL\r
cc68a136 968 ldr r11,=HighCol\r
ea8c405f 969 mov r12,#0xf\r
970 ldr r11,[r11]\r
971.else\r
972 ldr r11,=HighCol\r
973 mov r12,#0xf\r
974.endif\r
ea38612f 975 ldr lr, [r1, #OFS_Pico_vram]\r
cc68a136 976\r
cc68a136 977\r
e352c3af 978DrawSpriteSHi:\r
979 @ draw next sprite\r
980 ldrb r0, [r10,#-1]!\r
ea38612f 981 ldr r7, [sp] @ est\r
e352c3af 982 ldr r1, =HighPreSpr\r
e352c3af 983 cmp r0, #0xff\r
ea38612f 984 ldmeqfd sp!, {r1,r4-r11,pc} @ end of list\r
e352c3af 985 and r0, r0, #0x7f\r
986 add r0, r1, r0, lsl #3\r
987\r
988 ldr r9, [r0, #4] @ sprite[1]\r
989 mov r2, r9, asr #16 @ r2=sx\r
cc68a136 990\r
e352c3af 991 mov r9, r9, lsl #16\r
992 mov r3, r9, lsr #31 @ priority\r
993 mov r9, r9, lsr #16\r
fbc65db7 994@ orr r9, r9, r8, lsl #31 @ r9=code|sh[31] @@ sh is always on here now\r
e352c3af 995 and r4, r9, #0x6000\r
996 orr r9, r9, r4, lsl #16\r
fbc65db7 997 orr r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
e352c3af 998 cmp r12,r9, lsr #28 @ sh/hi with pal3?\r
e54507e8 999 cmpne r3, #1 @ if not, is it hi prio?\r
e352c3af 1000 bne DrawSpriteSHi @ non-operator low sprite, already drawn\r
cc68a136 1001\r
e352c3af 1002 ldr r3, [r0] @ sprite[0]\r
e352c3af 1003 mov r6, r3, lsr #28\r
1004 sub r6, r6, #1 @ r6=width-1 (inc later)\r
1005 mov r5, r3, lsr #24\r
1006 and r5, r5, #7 @ r5=height\r
cc68a136 1007\r
ea38612f 1008 ldr r7, [r7, #OFS_DrawScanline]\r
e352c3af 1009 mov r0, r3, lsl #16 @ r4=sy<<16 (tmp)\r
cc68a136 1010\r
e352c3af 1011 sub r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy\r
cc68a136 1012\r
e352c3af 1013 tst r9, #0x1000\r
1014 movne r0, r5, lsl #3\r
1015 subne r0, r0, #1\r
1016 subne r7, r0, r7 @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
cc68a136 1017\r
e352c3af 1018 add r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1019 tst r9, #0x0800\r
1020 mlane r8, r5, r6, r8 @ if (code&0x0800) { tile+=delta*(width-1);\r
1021 rsbne r5, r5, #0 @ delta=-delta; } // r5=delta now\r
cc68a136 1022\r
e352c3af 1023 mov r8, r8, lsl #21\r
1024 mov r8, r8, lsr #17\r
1025 and r7, r7, #7\r
1026 add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1027\r
1028 mov r5, r5, lsl #4 @ delta<<=4; // Delta of address\r
e352c3af 1029 mov r3, r4, lsr #9 @ r3=pal=((code>>9)&0x30);\r
1030\r
1031 add r6, r6, #1 @ inc now\r
1032 adds r0, r2, #0 @ mov sx to r0 and set ZV flags\r
1033 b .dsprShi_loop_enter\r
1034\r
1035.dsprShi_loop:\r
1036 subs r6, r6, #1 @ width--\r
1037 beq DrawSpriteSHi\r
1038 adds r0, r0, #8 @ sx+=8\r
1039 add r8, r8, r5 @ tile+=delta\r
1040\r
1041.dsprShi_loop_enter:\r
1042 ble .dsprShi_loop @ sx <= 0\r
cc68a136 1043 cmp r0, #328\r
e352c3af 1044 bge DrawSpriteSHi\r
cc68a136 1045\r
1046 mov r8, r8, lsl #17\r
e352c3af 1047 mov r8, r8, lsr #17 @ tile&=0x7fff; // Clip tile address\r
cc68a136 1048\r
e352c3af 1049 ldr r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1050 add r1, r11, r0 @ r1=pdest\r
cc68a136 1051 tst r2, r2\r
e352c3af 1052 beq .dsprShi_loop\r
cc68a136 1053\r
e352c3af 1054 cmp r12, r9, lsr #28\r
1055 beq .dsprShi_shadow\r
cc68a136 1056\r
1057 cmp r2, r2, ror #4\r
e352c3af 1058 beq .dsprShi_SingleColor @ tileline singlecolor \r
cc68a136 1059\r
e352c3af 1060 tst r9, #0x0800\r
1061 bne .dsprShi_TileFlip\r
cc68a136 1062\r
e352c3af 1063 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1064@ scratch: r4, r7\r
1065.dsprShi_TileNorm:\r
cc68a136 1066 TileNorm r12\r
e352c3af 1067 b .dsprShi_loop\r
cc68a136 1068\r
e352c3af 1069.dsprShi_TileFlip:\r
7a7c6476 1070 TileFlip r12\r
e352c3af 1071 b .dsprShi_loop\r
7a7c6476 1072\r
e352c3af 1073.dsprShi_SingleColor:\r
cc68a136 1074 and r4, r2, #0xf\r
1075 orr r4, r3, r4\r
1076 orr r4, r4, r4, lsl #8\r
e352c3af 1077 tst r0, #1 @ not aligned?\r
cc68a136 1078 strneb r4, [r1], #1\r
1079 streqh r4, [r1], #2\r
1080 strh r4, [r1], #2\r
1081 strh r4, [r1], #2\r
1082 strh r4, [r1], #2\r
1083 strneb r4, [r1], #1\r
e352c3af 1084 b .dsprShi_loop\r
cc68a136 1085\r
e352c3af 1086.dsprShi_shadow:\r
1087 tst r9, #0x8000\r
1088 beq .dsprShi_shadow_lowpri\r
07abbab1 1089\r
cc68a136 1090 cmp r2, r2, ror #4\r
e352c3af 1091 beq .dsprShi_singlec_sh\r
cc68a136 1092\r
e352c3af 1093 tst r9, #0x0800\r
1094 bne .dsprShi_TileFlip_sh\r
cc68a136 1095\r
e54507e8 1096 @ (r1=pdest, r2=pixels8, r3=pal) r4, r7: scratch, r12: helper pattern\r
e352c3af 1097.dsprShi_TileNorm_sh:\r
cc68a136 1098 TileNormSh\r
e352c3af 1099 b .dsprShi_loop\r
cc68a136 1100\r
e352c3af 1101.dsprShi_TileFlip_sh:\r
7a7c6476 1102 TileFlipSh\r
e352c3af 1103 b .dsprShi_loop\r
7a7c6476 1104\r
e352c3af 1105.dsprShi_singlec_sh:\r
cc68a136 1106 cmp r2, #0xe0000000\r
e352c3af 1107 bcc .dsprShi_SingleColor @ normal singlecolor tileline (carry inverted in ARM)\r
cc68a136 1108 tst r2, #0x10000000\r
e352c3af 1109 bne .dsprShi_sh_sh\r
cc68a136 1110 TileSingleHi\r
e352c3af 1111 b .dsprShi_loop\r
cc68a136 1112\r
e352c3af 1113.dsprShi_sh_sh:\r
cc68a136 1114 TileSingleSh\r
e352c3af 1115 b .dsprShi_loop\r
cc68a136 1116\r
e352c3af 1117.dsprShi_shadow_lowpri:\r
1118 tst r9, #0x800\r
1119 bne .dsprShi_TileFlip_sh_lp\r
07abbab1 1120\r
e352c3af 1121.dsprShi_TileNorm_sh_lp:\r
07abbab1 1122 TileNormSh_onlyop_lp\r
e352c3af 1123 b .dsprShi_loop\r
07abbab1 1124\r
e352c3af 1125.dsprShi_TileFlip_sh_lp:\r
07abbab1 1126 TileFlipSh_onlyop_lp\r
e352c3af 1127 b .dsprShi_loop\r
07abbab1 1128\r
cc68a136 1129.pool\r
1130\r
1131@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1132\r
ea38612f 1133@ void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
1134@ struct PicoEState *est)\r
1135\r
1136.global DrawAllSprites\r
283fec1b 1137\r
1138DrawAllSprites:\r
fbc65db7 1139 orr r1, r2, r1, lsl #1\r
ea38612f 1140 ldr r12,[r3, #OFS_rendstatus]\r
0fc0e241 1141 tst r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED)\r
283fec1b 1142 beq das_no_prep\r
ea38612f 1143 stmfd sp!, {r0,r1,r3,lr}\r
283fec1b 1144 and r0, r12,#PDRAW_DIRTY_SPRITES\r
0fc0e241 1145 bic r12,r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED)\r
ea38612f 1146 str r12,[r3, #OFS_rendstatus]\r
283fec1b 1147 bl PrepareSprites\r
ea38612f 1148 ldmfd sp!, {r0,r1,r3,lr}\r
283fec1b 1149\r
1150das_no_prep:\r
ea38612f 1151 ldr r2, [r0]\r
1152 ands r2, r2, #0x7f\r
283fec1b 1153 bxeq lr\r
1154\r
1155 @ time to do some real work\r
ea38612f 1156 stmfd sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est\r
283fec1b 1157 mov r12,#0xff\r
fbc65db7 1158 strb r12,[r0,#2] @ set end marker\r
1159 add r10,r0, #3\r
ea38612f 1160 add r10,r10,r2 @ r10=HighLnSpr end\r
283fec1b 1161\r
1162.if OVERRIDE_HIGHCOL\r
1163 ldr r11,=HighCol\r
1164 mov r12,#0xf\r
1165 ldr r11,[r11]\r
1166.else\r
1167 ldr r11,=HighCol\r
1168 mov r12,#0xf\r
1169.endif\r
ea38612f 1170 ldr lr, [r3, #OFS_Pico_vram]\r
283fec1b 1171\r
1172@ + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size\r
cc68a136 1173@ + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
1174\r
ea38612f 1175DrawSprite:\r
283fec1b 1176 @ draw next sprite\r
1177 ldrb r0, [r10,#-1]!\r
ea38612f 1178 ldr r8, [sp] @ sh|prio<<1\r
1179 ldr r7, [sp, #4] @ est\r
e352c3af 1180 mov r2, r0, lsr #7\r
1181 cmp r0, #0xff\r
ea38612f 1182 ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
97a7f774 1183 cmp r2, r8, lsr #1\r
e352c3af 1184 bne DrawSprite @ wrong priority\r
ea38612f 1185 ldr r1, =HighPreSpr\r
283fec1b 1186 and r0, r0, #0x7f\r
1187 add r0, r1, r0, lsl #3\r
cc68a136 1188\r
cc68a136 1189 ldr r3, [r0] @ sprite[0]\r
ea38612f 1190 ldr r7, [r7, #OFS_DrawScanline]\r
cc68a136 1191 mov r6, r3, lsr #28\r
1192 sub r6, r6, #1 @ r6=width-1 (inc later)\r
1193 mov r5, r3, lsr #24\r
1194 and r5, r5, #7 @ r5=height\r
1195\r
1196 mov r4, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1197\r
cc68a136 1198 ldr r9, [r0, #4]\r
b6d7ac70 1199 sub r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy\r
cc68a136 1200\r
cc68a136 1201 mov r2, r9, asr #16 @ r2=sx\r
e5fa9817 1202 mov r9, r9, lsl #16\r
1203 mov r9, r9, lsr #16\r
97a7f774 1204 orr r9, r9, r8, lsl #31 @ r9=code|sh[31]\r
cc68a136 1205\r
1206 tst r9, #0x1000\r
1207 movne r4, r5, lsl #3\r
1208 subne r4, r4, #1\r
1209 subne r7, r4, r7 @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1210\r
07abbab1 1211 add r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
cc68a136 1212 tst r9, #0x0800\r
1213 mlane r8, r5, r6, r8 @ if (code&0x0800) { tile+=delta*(width-1);\r
1214 rsbne r5, r5, #0 @ delta=-delta; } // r5=delta now\r
1215\r
07abbab1 1216 mov r8, r8, lsl #21\r
1217 mov r8, r8, lsr #17\r
cc68a136 1218 and r7, r7, #7\r
1219 add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1220\r
e5fa9817 1221.dspr_continue:\r
cc68a136 1222 @ cache some stuff to avoid mem access\r
cc68a136 1223 mov r5, r5, lsl #4 @ delta<<=4; // Delta of address\r
1224 and r4, r9, #0x6000\r
1225 orr r9, r9, r4, lsl #16\r
97a7f774 1226 orrs r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
cc68a136 1227\r
cc68a136 1228 mov r3, r4, lsr #9 @ r3=pal=((code>>9)&0x30);\r
97a7f774 1229 orrmi r3, r3, #0x40 @ for sh/hi\r
cc68a136 1230\r
1231 add r6, r6, #1 @ inc now\r
1232 adds r0, r2, #0 @ mov sx to r0 and set ZV flags\r
1233 b .dspr_loop_enter\r
1234\r
1235.dspr_loop:\r
1236 subs r6, r6, #1 @ width--\r
283fec1b 1237 beq DrawSprite\r
cc68a136 1238 adds r0, r0, #8 @ sx+=8\r
1239 add r8, r8, r5 @ tile+=delta\r
1240\r
1241.dspr_loop_enter:\r
1242 ble .dspr_loop @ sx <= 0\r
1243 cmp r0, #328\r
283fec1b 1244 bge DrawSprite\r
cc68a136 1245\r
1246 mov r8, r8, lsl #17\r
1247 mov r8, r8, lsr #17 @ tile&=0x7fff; // Clip tile address\r
1248\r
1249 ldr r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1250 add r1, r11, r0 @ r1=pdest\r
1251 tst r2, r2\r
1252 beq .dspr_loop\r
1253\r
1254 cmp r12, r9, lsr #28\r
1255 beq .dspr_shadow\r
1256\r
1257 cmp r2, r2, ror #4\r
1258 beq .dspr_SingleColor @ tileline singlecolor \r
1259\r
1260 tst r9, #0x0800\r
7a7c6476 1261 bne .dspr_TileFlip\r
cc68a136 1262\r
1263 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
cc68a136 1264@ scratch: r4, r7\r
1265.dspr_TileNorm:\r
1266 TileNorm r12\r
1267 b .dspr_loop\r
1268\r
7a7c6476 1269.dspr_TileFlip:\r
1270 TileFlip r12\r
1271 b .dspr_loop\r
1272\r
07abbab1 1273.dspr_singlec_sh:\r
1274 cmp r2, #0xe0000000\r
e54507e8 1275 bcs .dspr_TileNorm_sh @ op. tileline, markop. XXX: maybe add a spec. handler?\r
07abbab1 1276\r
cc68a136 1277.dspr_SingleColor:\r
1278 and r4, r2, #0xf\r
1279 orr r4, r3, r4\r
1280 orr r4, r4, r4, lsl #8\r
1281 tst r0, #1 @ not aligned?\r
1282 strneb r4, [r1], #1\r
1283 streqh r4, [r1], #2\r
1284 strh r4, [r1], #2\r
1285 strh r4, [r1], #2\r
1286 strh r4, [r1], #2\r
1287 strneb r4, [r1], #1\r
1288 b .dspr_loop\r
1289\r
1290.dspr_shadow:\r
1291 cmp r2, r2, ror #4\r
1292 beq .dspr_singlec_sh\r
1293\r
1294 tst r9, #0x0800\r
7a7c6476 1295 bne .dspr_TileFlip_sh\r
cc68a136 1296\r
1297 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
cc68a136 1298.dspr_TileNorm_sh:\r
e54507e8 1299 TileNormSh_markop\r
cc68a136 1300 b .dspr_loop\r
1301\r
7a7c6476 1302.dspr_TileFlip_sh:\r
e54507e8 1303 TileFlipSh_markop\r
cc68a136 1304 b .dspr_loop\r
1305\r
1306\r
cc68a136 1307@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1308\r
ea38612f 1309@ void DrawWindow(int tstart, int tend, int prio, int sh\r
1310@ struct PicoEState *est)\r
1311\r
1312.global DrawWindow\r
cc68a136 1313\r
1314DrawWindow:\r
ea38612f 1315 ldr r12, [sp] @ est\r
cc68a136 1316 stmfd sp!, {r4-r11,lr}\r
1317\r
ea38612f 1318 ldr r6, [r12, #OFS_Pico_video]\r
1319 ldr r10, [r12, #OFS_DrawScanline]\r
1320 mov r11, r12 @ est\r
1321 ldrb r12, [r6, #3] @ pvid->reg[3]\r
cc68a136 1322\r
ea38612f 1323 ldr r4, [r6, #12]\r
cc68a136 1324 mov r5, r10, lsr #3\r
1325 and r10, r10, #7\r
1326 mov r10, r10, lsl #1 @ r10=ty\r
1327\r
1328 mov r12, r12, lsl #10\r
1329\r
1330 tst r4, #1 @ 40 cell mode?\r
1331 andne r12, r12, #0xf000 @ 0x3c<<10\r
1332 andeq r12, r12, #0xf800\r
1333 addne r12, r12, r5, lsl #7\r
1334 addeq r12, r12, r5, lsl #6 @ nametab\r
1335 add r12, r12, r0, lsl #2 @ +starttile\r
1336\r
ea38612f 1337 ldr lr, [r11, #OFS_Pico_vram]\r
1338 ldr r6, [r11, #OFS_rendstatus]\r
cc68a136 1339\r
1340 @ fetch the first code now\r
1341 ldrh r7, [lr, r12]\r
1342\r
283fec1b 1343 ands r6, r6, #PDRAW_WND_DIFF_PRIO\r
cc68a136 1344 orr r6, r6, r2\r
cc68a136 1345\r
7292c709 1346 eoreq r8, r2, r7, lsr #15 @ do prio bits differ?\r
1347 cmpeq r8, #1\r
1348 ldmeqfd sp!, {r4-r11,pc} @ yes, assume that whole window uses same priority\r
cc68a136 1349\r
cc68a136 1350 orr r6, r6, r3, lsl #8 @ shadow mode\r
1351\r
1352 sub r8, r1, r0\r
cc68a136 1353\r
1354 @ cache some stuff to avoid mem access\r
ea8c405f 1355.if OVERRIDE_HIGHCOL\r
1356 ldr r11,=HighCol\r
1357 mov r8, r8, lsl #1 @ cells\r
1358 ldr r11,[r11]\r
1359 mvn r9, #0 @ r9=prevcode=-1\r
1360 add r11,r11,#8\r
1361.else\r
cc68a136 1362 ldr r11,=(HighCol+8)\r
ea8c405f 1363 mov r8, r8, lsl #1 @ cells\r
1364 mvn r9, #0 @ r9=prevcode=-1\r
1365.endif\r
07abbab1 1366 add r1, r11, r0, lsl #4 @ r1=pdest\r
cc68a136 1367 mov r0, #0xf\r
1368 b .dwloop_enter\r
1369\r
07abbab1 1370 @ r4,r5 are scratch in this loop\r
cc68a136 1371.dwloop:\r
1372 add r1, r1, #8\r
1373.dwloop_nor1:\r
1374 add r12, r12, #2 @ halfwords\r
1375 ldrh r7, [lr, r12] @ r7=code (int, but from unsigned, no sign extend)\r
1376 subs r8, r8, #1\r
1377 beq .dwloop_end @ done\r
1378\r
1379 eor r5, r6, r7, lsr #15\r
1380 tst r5, #1\r
1381 orrne r6, r6, #2 @ wrong pri\r
1382 bne .dwloop\r
1383\r
1384 cmp r7, r9\r
1385 beq .dw_samecode @ we know stuff about this tile already\r
1386\r
1387.dwloop_enter:\r
1388 mov r9, r7 @ remember code\r
1389\r
1390 movs r2, r9, lsl #20 @ if (code&0x1000)\r
1391 mov r2, r2, lsl #1\r
1392 add r2, r10, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4; addr+=ty\r
1393 eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe;\r
1394\r
1395 and r3, r9, #0x6000\r
1396 mov r3, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
1397\r
1398 ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1399\r
1400.dw_samecode:\r
1401 tst r6, #0x100\r
1402 bne .dw_shadow\r
1403.dw_shadow_done:\r
1404 tst r2, r2\r
1405 beq .dwloop @ tileline blank\r
1406\r
1407 cmp r2, r2, ror #4\r
1408 beq .dw_SingleColor @ tileline singlecolor \r
1409\r
1410 tst r9, #0x0800\r
7a7c6476 1411 bne .dw_TileFlip\r
cc68a136 1412\r
1413 @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
cc68a136 1414.dw_TileNorm:\r
1415 TileNorm r0\r
1416 b .dwloop\r
1417\r
7a7c6476 1418.dw_TileFlip:\r
1419 TileFlip r0\r
1420 b .dwloop\r
1421\r
cc68a136 1422.dw_SingleColor:\r
1423 and r4, r0, r2 @ #0x0000000f\r
1424 orr r4, r3, r4\r
1425 orr r4, r4, r4, lsl #8\r
1426 orr r4, r4, r4, lsl #16\r
1427 mov r5, r4\r
1428 stmia r1!, {r4,r5}\r
1429 b .dwloop_nor1 @ we incremeted r1 ourselves\r
1430\r
1431.dw_shadow:\r
1432 tst r6, #1 @ hi pri?\r
1433 orreq r3, r3, #0x40\r
1434 beq .dw_shadow_done\r
1435 ldr r4, [r1]\r
07abbab1 1436 mov r5, #0x3f\r
1437 orr r5, r5, r5, lsl #8\r
1438 orr r5, r5, r5, lsl #16\r
1439 and r4, r4, r5\r
cc68a136 1440 str r4, [r1]\r
1441 ldr r4, [r1,#4]\r
07abbab1 1442 and r4, r4, r5\r
cc68a136 1443 str r4, [r1,#4]\r
1444 b .dw_shadow_done\r
1445\r
1446.dwloop_end:\r
ea38612f 1447 and r2, r6, #PDRAW_WND_DIFF_PRIO\r
1448 ldmfd sp!, {r4-r11,lr}\r
1449 ldr r0, [sp]\r
1450 ldr r1, [r0, #OFS_rendstatus]\r
1451 orr r1, r1, r2\r
1452 str r1, [r0, #OFS_rendstatus]\r
cc68a136 1453\r
ea38612f 1454 bx lr\r
cc68a136 1455\r
1456\r
1457@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1458\r
1459\r
1460@ hilights 2 pixels in RGB444/BGR444 format\r
1461.macro TileDoShHi2Pixels444 reg\r
1462 mov \reg, \reg, ror #12\r
1463 adds \reg, \reg, #0x40000000\r
1464 orrcs \reg, \reg, #0xf0000000\r
1465 mov \reg, \reg, ror #28\r
1466 adds \reg, \reg, #0x40000000\r
1467 orrcs \reg, \reg, #0xf0000000\r
1468 mov \reg, \reg, ror #28\r
1469 adds \reg, \reg, #0x40000000\r
1470 orrcs \reg, \reg, #0xf0000000\r
1471 mov \reg, \reg, ror #24\r
1472 adds \reg, \reg, #0x40000000\r
1473 orrcs \reg, \reg, #0xf0000000\r
1474 mov \reg, \reg, ror #28\r
1475 adds \reg, \reg, #0x40000000\r
1476 orrcs \reg, \reg, #0xf0000000\r
1477 mov \reg, \reg, ror #28\r
1478 adds \reg, \reg, #0x40000000\r
1479 orrcs \reg, \reg, #0xf0000000\r
1480 mov \reg, \reg, ror #12\r
1481.endm\r
1482\r
1483\r
cc68a136 1484@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1485\r
1486\r
cc68a136 1487@ Convert 0000bbb0 ggg0rrr0\r
1488@ to rrrrrggg gggbbbbb\r
1489\r
a39d8ba5 1490@ r2,r3 - scratch, lr = 0x001c001c, r8 = 0x08610861\r
cc68a136 1491.macro convRGB565 reg\r
a39d8ba5 1492 and r2, lr, \reg,lsr #7 @ b\r
1493 and r3, lr, \reg,lsr #3 @ g\r
1494 and \reg, lr, \reg,lsl #1 @ r\r
1495 orr r2, r2, r3, lsl #6\r
1496 orr \reg, r2, \reg,lsl #11\r
1497\r
1498 and r2, r8, \reg,lsr #4\r
1499 orr \reg, \reg, r2\r
cc68a136 1500.endm\r
1501\r
a39d8ba5 1502@ trashes: r2-r8,r12,lr; r8 = 0x08610861; r0,r1 are advanced\r
b2305d08 1503.macro vidConvCpyRGB565_local\r
2ec14aec 1504 mov r12, r2, lsr #3 @ repeats\r
cc68a136 1505 mov lr, #0x001c0000\r
1506 orr lr, lr, #0x01c @ lr == pattern 0x001c001c\r
cc68a136 1507\r
b2305d08 15080:\r
cc68a136 1509 ldmia r1!, {r4-r7}\r
1510 subs r12, r12, #1\r
1511 convRGB565 r4\r
1512 str r4, [r0], #4\r
1513 convRGB565 r5\r
1514 str r5, [r0], #4\r
1515 convRGB565 r6\r
1516 str r6, [r0], #4\r
1517 convRGB565 r7\r
1518 str r7, [r0], #4\r
1519\r
b2305d08 1520 bgt 0b\r
1521.endm\r
1522\r
1523\r
1524.global vidConvCpyRGB565\r
cc68a136 1525\r
b2305d08 1526vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1527 stmfd sp!, {r4-r9,lr}\r
a39d8ba5 1528 mov r8, #0x0061\r
1529 orr r8, r8, #0x0800\r
f4750ee0 1530 orr r8, r8, r8, lsl #16\r
b2305d08 1531 vidConvCpyRGB565_local\r
cc68a136 1532 ldmfd sp!, {r4-r9,lr}\r
1533 bx lr\r
1534\r
1535\r
ea38612f 1536@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
1537\r
1538.global PicoDoHighPal555\r
cc68a136 1539\r
b2305d08 1540PicoDoHighPal555:\r
ea38612f 1541 stmfd sp!, {r4-r10,lr}\r
1542 mov r10,r2 @ est\r
b2305d08 1543 mov r1, #0\r
ea38612f 1544 ldr r8, [r10, #OFS_Pico_video]\r
cc68a136 1545\r
b2305d08 1546PicoDoHighPal555_nopush:\r
a39d8ba5 1547 orr r9, r1, r0, lsl #31 @ 0:called from FinalizeLine555, 31: s/h\r
b2305d08 1548\r
b2305d08 1549 ldr r0, =HighPal\r
1550\r
cc68a136 1551 mov r1, #0\r
b2305d08 1552 strb r1, [r8, #-0x1a] @ 0x2220e ~ dirtyPal\r
1553\r
3d48f143 1554 sub r1, r8, #0x128 @ r1=Pico.cram\r
cc68a136 1555 mov r2, #0x40\r
a39d8ba5 1556 mov r8, #0x0061\r
1557 orr r8, r8, #0x0800\r
f4750ee0 1558 orr r8, r8, r8, lsl #16\r
a39d8ba5 1559\r
b2305d08 1560 vidConvCpyRGB565_local\r
cc68a136 1561\r
a39d8ba5 1562 tst r9, #(1<<31)\r
b2305d08 1563 beq PicoDoHighPal555_end\r
1564\r
1565 ldr r3, =HighPal\r
cc68a136 1566\r
1567 @ shadowed pixels:\r
1568 mov r12, #0x008e\r
cc68a136 1569 add r4, r3, #0x40*2\r
b2305d08 1570 orr r12,r12,#0x7300\r
cc68a136 1571 add r5, r3, #0xc0*2\r
b2305d08 1572 orr r12,r12,r12,lsl #16\r
cc68a136 1573 mov lr, #0x40/4\r
1574.fl_loopcpRGB555_sh:\r
1575 ldmia r3!, {r1,r6}\r
1576 subs lr, lr, #1\r
1577 and r1, r12, r1, lsr #1\r
1578 and r6, r12, r6, lsr #1\r
1579 stmia r4!, {r1,r6}\r
1580 stmia r5!, {r1,r6}\r
1581 bne .fl_loopcpRGB555_sh\r
1582\r
1583 @ hilighted pixels:\r
a39d8ba5 1584 @ t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;\r
1585 @ t |= (t >> 4) & 0x08610861;\r
1586 @ r8=0x08610861\r
cc68a136 1587 sub r3, r3, #0x40*2\r
a39d8ba5 1588 mov lr, #0x40/4\r
cc68a136 1589.fl_loopcpRGB555_hi:\r
a39d8ba5 1590 ldmia r3!, {r1,r6}\r
1591 and r1, r12, r1, lsr #1\r
1592 and r6, r12, r6, lsr #1\r
1593 add r1, r12, r1\r
1594 add r6, r12, r6\r
1595 and r5, r8, r1, lsr #4\r
1596 and r7, r8, r6, lsr #4\r
1597 orr r1, r1, r5\r
1598 orr r6, r6, r7\r
1599 stmia r4!, {r1,r6}\r
cc68a136 1600 subs lr, lr, #1\r
1601 bne .fl_loopcpRGB555_hi\r
b2305d08 1602 mov r0, #1\r
cc68a136 1603\r
b2305d08 1604PicoDoHighPal555_end:\r
a39d8ba5 1605 tst r9, #1\r
ea38612f 1606 ldmeqfd sp!, {r4-r10,pc}\r
b2305d08 1607\r
ea38612f 1608 ldr r8, [r10, #OFS_Pico_video]\r
b2305d08 1609 b FinalizeLineRGB555_pal_done\r
1610\r
1611\r
ea38612f 1612@ void FinalizeLine555(int sh, int line, struct PicoEState *est)\r
1613\r
1614.global FinalizeLine555\r
b2305d08 1615\r
5a681086 1616FinalizeLine555:\r
ea38612f 1617 stmfd sp!, {r4-r10,lr}\r
1618 mov r10,r2 @ est\r
1619 ldr r8, [r10, #OFS_Pico_video]\r
b2305d08 1620\r
1621 ldrb r2, [r8, #-0x1a] @ 0x2220e ~ dirtyPal\r
1622 mov r1, #1\r
1623 tst r2, r2\r
1624 bne PicoDoHighPal555_nopush\r
1625\r
1626FinalizeLineRGB555_pal_done:\r
1627 ldr r3, =HighPal\r
cc68a136 1628\r
ea38612f 1629 ldr r12, [r10, #OFS_rendstatus]\r
b2305d08 1630 eors r0, r0, #1 @ sh is 0\r
e5fa9817 1631 mov lr, #0xff\r
283fec1b 1632 tstne r12,#PDRAW_ACC_SPRITES\r
e5fa9817 1633 movne lr, #0x3f\r
1634\r
ea8c405f 1635.if OVERRIDE_HIGHCOL\r
1636 ldr r1, =HighCol\r
1637 ldr r0, =DrawLineDest\r
1638 ldr r1, [r1]\r
1639 ldr r0, [r0]\r
1640 add r1, r1, #8\r
1641.else\r
3d48f143 1642 ldr r0, =DrawLineDest\r
cc68a136 1643 ldr r1, =(HighCol+8)\r
3d48f143 1644 ldr r0, [r0]\r
ea8c405f 1645.endif\r
3d48f143 1646\r
1647 ldrb r12, [r8, #12]\r
cc68a136 1648 mov lr, lr, lsl #1\r
1649\r
3d48f143 1650 tst r12, #1\r
1651 movne r2, #320/8 @ len\r
1652 bne .fl_no32colRGB555\r
1653 ldr r4, =PicoOpt\r
1654 mov r2, #256/8\r
1655 ldr r4, [r4]\r
1656 tst r4, #0x4000\r
1657 bne .fl_32scale_RGB555\r
1658 tst r4, #0x0100\r
1659 addeq r0, r0, #32*2\r
1660\r
1661.fl_no32colRGB555:\r
cc68a136 1662\r
f62850ba 1663#ifdef UNALIGNED_DRAWLINEDEST\r
499a0be3 1664 @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1665 tst r0, #2\r
1666 bne .fl_RGB555u\r
f62850ba 1667#endif\r
499a0be3 1668\r
1669.fl_loopRGB555:\r
cc68a136 1670 ldr r12, [r1], #4\r
1671 ldr r7, [r1], #4\r
1672\r
1673 and r4, lr, r12, lsl #1\r
1674 ldrh r4, [r3, r4]\r
1675 and r5, lr, r12, lsr #7\r
1676 ldrh r5, [r3, r5]\r
1677 and r6, lr, r12, lsr #15\r
1678 ldrh r6, [r3, r6]\r
1679 orr r4, r4, r5, lsl #16\r
1680\r
1681 and r5, lr, r12, lsr #23\r
1682 ldrh r5, [r3, r5]\r
1683 and r8, lr, r7, lsl #1\r
1684 ldrh r8, [r3, r8]\r
1685 orr r5, r6, r5, lsl #16\r
1686\r
1687 and r6, lr, r7, lsr #7\r
1688 ldrh r6, [r3, r6]\r
1689 and r12,lr, r7, lsr #15\r
1690 ldrh r12,[r3, r12]\r
499a0be3 1691 and r7, lr, r7, lsr #23\r
1692 ldrh r7, [r3, r7]\r
cc68a136 1693 orr r8, r8, r6, lsl #16\r
1694\r
cc68a136 1695 subs r2, r2, #1\r
499a0be3 1696 orr r12,r12, r7, lsl #16\r
cc68a136 1697\r
1698 stmia r0!, {r4,r5,r8,r12}\r
1699 bne .fl_loopRGB555\r
1700\r
ea38612f 1701 ldmfd sp!, {r4-r10,lr}\r
3d48f143 1702 bx lr\r
1703\r
1704\r
1705.fl_32scale_RGB555:\r
3d48f143 1706 mov r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1707 orr r9, r9, #0x00e7\r
1708\r
f62850ba 1709#ifdef UNALIGNED_DRAWLINEDEST\r
499a0be3 1710 tst r0, #2\r
1711 bne .fl_32scale_RGB555u\r
f62850ba 1712#endif\r
499a0be3 1713\r
3d48f143 1714.fl_loop32scale_RGB555:\r
1715 ldr r12, [r1], #4\r
1716 ldr r7, [r1], #4\r
cc68a136 1717\r
3d48f143 1718 and r4, lr, r12,lsl #1\r
1719 ldrh r4, [r3, r4]\r
1720 and r5, lr, r12,lsr #7\r
1721 ldrh r5, [r3, r5]\r
1722 and r4, r4, r9, lsl #2\r
1723 orr r4, r4, r4, lsl #14 @ r4[31:16] = 1/4 pix_s 0\r
1724 and r5, r5, r9, lsl #2\r
1725 sub r6, r5, r5, lsr #2 @ r6 = 3/4 pix_s 1\r
1726 add r4, r4, r6, lsl #16 @ pix_d 0, 1\r
1727 and r6, lr, r12,lsr #15\r
1728 ldrh r6, [r3, r6]\r
1729 and r12,lr, r12,lsr #23\r
1730 ldrh r12,[r3, r12]\r
1731 and r6, r6, r9, lsl #2\r
1732 add r5, r5, r6\r
1733 mov r5, r5, lsr #1\r
1734 sub r6, r6, r6, lsr #2 @ r6 = 3/4 pix_s 2\r
1735 orr r5, r5, r6, lsl #16\r
1736\r
1737 and r6, lr, r7, lsl #1\r
1738 ldrh r6, [r3, r6]\r
1739 and r12,r12,r9, lsl #2\r
1740 add r5, r5, r12,lsl #14 @ pix_d 2, 3\r
1741 and r6, r6, r9, lsl #2\r
1742 orr r6, r12,r6, lsl #16 @ pix_d 4, 5\r
1743\r
1744 and r12,lr, r7, lsr #7\r
1745 ldrh r12,[r3, r12]\r
1746 and r10,lr, r7, lsr #15\r
1747 ldrh r10,[r3, r10]\r
1748 and r12,r12,r9, lsl #2\r
1749 sub r8, r12,r12,lsr #2 @ r8 = 3/4 pix_s 1\r
1750 add r8, r8, r6, lsr #18\r
1751 and r7, lr, r7, lsr #23\r
1752 ldrh r7, [r3, r7]\r
1753 and r10,r10,r9, lsl #2\r
1754 orr r8, r8, r10,lsl #15\r
1755 add r8, r8, r12,lsl #15 @ pix_d 6, 7\r
1756 sub r10,r10,r10,lsr #2 @ r10= 3/4 pix_s 2\r
1757 and r7, r7, r9, lsl #2\r
1758 add r10,r10,r7, lsr #2 @ += 1/4 pix_s 3\r
1759 orr r10,r10,r7, lsl #16 @ pix_d 8, 9\r
1760\r
1761 subs r2, r2, #1\r
1762\r
1763 stmia r0!, {r4,r5,r6,r8,r10}\r
1764 bne .fl_loop32scale_RGB555\r
1765\r
ea38612f 1766 ldmfd sp!, {r4-r10,lr}\r
3d48f143 1767 bx lr\r
1768\r
f62850ba 1769#ifdef UNALIGNED_DRAWLINEDEST\r
499a0be3 1770 @ unaligned versions of loops\r
9839d126 1771 @ warning: starts drawing 2bytes before dst\r
499a0be3 1772\r
1773.fl_RGB555u:\r
9839d126 1774 sub r0, r0, #2 @ initial adjustment\r
1775 mov r8, #0\r
499a0be3 1776\r
1777.fl_loopRGB555u:\r
1778 ldr r12, [r1], #4\r
1779 ldr r7, [r1], #4\r
1780\r
9839d126 1781 and r6, lr, r12,lsl #1\r
1782 ldrh r6, [r3, r6]\r
1783 and r5, lr, r12,lsr #7\r
499a0be3 1784 ldrh r5, [r3, r5]\r
9839d126 1785 orr r4, r8, r6, lsl #16\r
499a0be3 1786\r
9839d126 1787 and r6, lr, r12,lsr #15\r
499a0be3 1788 ldrh r6, [r3, r6]\r
9839d126 1789 and r8, lr, r12,lsr #23\r
499a0be3 1790 ldrh r8, [r3, r8]\r
9839d126 1791 orr r5, r5, r6, lsl #16\r
499a0be3 1792\r
9839d126 1793 and r6, lr, r7, lsl #1\r
499a0be3 1794 ldrh r6, [r3, r6]\r
9839d126 1795 and r12,lr, r7, lsr #7\r
499a0be3 1796 ldrh r12,[r3, r12]\r
9839d126 1797 orr r6, r8, r6, lsl #16\r
1798\r
1799 and r8, lr, r7, lsr #15\r
499a0be3 1800 ldrh r8, [r3, r8]\r
9839d126 1801 and r7, lr, r7, lsr #23\r
499a0be3 1802\r
1803 subs r2, r2, #1\r
9839d126 1804 orr r12,r12,r8, lsl #16\r
1805 ldrh r8, [r3, r7]\r
1806\r
1807 stmia r0!, {r4,r5,r6,r12}\r
499a0be3 1808 bne .fl_loopRGB555u\r
1809\r
1810 strh r8, [r0], #2\r
1811\r
ea38612f 1812 ldmfd sp!, {r4-r10,lr}\r
499a0be3 1813 bx lr\r
1814\r
1815\r
1816.fl_32scale_RGB555u:\r
9839d126 1817 sub r0, r0, #2 @ initial adjustment\r
1818 mov r4, #0\r
499a0be3 1819\r
1820 @ r9 f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1821.fl_loop32scale_RGB555u:\r
1822 ldr r12, [r1], #4\r
1823 ldr r7, [r1], #4\r
1824\r
9839d126 1825 and r6, lr, r12,lsl #1\r
1826 ldrh r6, [r3, r6]\r
499a0be3 1827 and r5, lr, r12,lsr #7\r
1828 ldrh r5, [r3, r5]\r
9839d126 1829 and r6, r6, r9, lsl #2\r
1830 orr r4, r4, r6, lsl #16 @ r4 = pix_d -1, 0\r
499a0be3 1831\r
1832 and r5, r5, r9, lsl #2\r
9839d126 1833 sub r8, r5, r5, lsr #2 @ r8 = 3/4 pix_s 1\r
1834 add r6, r8, r6, lsr #2 @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
1835 orr r5, r6, r5, lsl #15\r
499a0be3 1836\r
1837 and r6, lr, r12,lsr #15\r
1838 ldrh r6, [r3, r6]\r
1839 and r12,lr, r12,lsr #23\r
1840 ldrh r12,[r3, r12]\r
1841 and r6, r6, r9, lsl #2\r
9839d126 1842 add r5, r5, r6, lsl #15 @ r5 = pix_d 1, 2\r
499a0be3 1843\r
9839d126 1844 and r8, lr, r7, lsl #1\r
1845 ldrh r8, [r3, r8]\r
1846 and r10,lr, r7, lsr #7\r
1847 ldrh r10,[r3, r10]\r
499a0be3 1848 and r12,r12,r9, lsl #2\r
9839d126 1849 sub r6, r6, r6, lsr #2 @ r6 = 3/4 pix_s 2\r
1850 add r6, r6, r12,lsr #2\r
1851 orr r6, r6, r12,lsl #16 @ r6 = pix_d 3, 4\r
499a0be3 1852\r
9839d126 1853 and r8, r8, r9, lsl #2\r
1854 and r10,r10,r9, lsl #2\r
1855 sub r12,r10,r10,lsr #2 @ r12 = 3/4 pix_s 5\r
1856 orr r8, r8, r8, lsl #14\r
1857 add r8, r8, r12,lsl #16 @ r8 = pix_d 5, 6\r
1858 and r12,lr, r7, lsr #15\r
499a0be3 1859 ldrh r12,[r3, r12]\r
499a0be3 1860 and r7, lr, r7, lsr #23\r
1861 ldrh r7, [r3, r7]\r
9839d126 1862 and r12,r12,r9, lsl #2\r
1863 add r10,r10,r12\r
1864 mov r10,r10, lsr #1\r
1865 sub r12,r12,r12,lsr #2 @ r12 = 3/4 pix_s 6\r
1866 orr r10,r10,r12,lsl #16\r
499a0be3 1867 and r7, r7, r9, lsl #2\r
9839d126 1868 add r10,r10,r7, lsl #14 @ r10 = pix_d 7, 8\r
499a0be3 1869\r
1870 subs r2, r2, #1\r
1871\r
1872 stmia r0!, {r4,r5,r6,r8,r10}\r
9839d126 1873 mov r4, r7\r
499a0be3 1874 bne .fl_loop32scale_RGB555u\r
1875\r
9839d126 1876 strh r4, [r0], #2\r
1877\r
ea38612f 1878 ldmfd sp!, {r4-r10,lr}\r
499a0be3 1879 bx lr\r
1880\r
f62850ba 1881#endif /* UNALIGNED_DRAWLINEDEST */\r
499a0be3 1882\r
cc68a136 1883\r
1884@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1885\r
1886@ utility\r
1887.global blockcpy @ void *dst, void *src, size_t n\r
1888\r
1889blockcpy:\r
1890 stmfd sp!, {r4,r5}\r
1891 mov r2, r2, lsr #4\r
1892blockcpy_loop:\r
1893 ldmia r1!, {r3-r5,r12}\r
1894 subs r2, r2, #1\r
1895 stmia r0!, {r3-r5,r12}\r
1896 bne blockcpy_loop\r
1897 ldmfd sp!, {r4,r5}\r
1898 bx lr\r
1899\r
1900\r
1901.global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
1902\r
1903blockcpy_or:\r
1904 stmfd sp!, {r4-r6}\r
1905 orr r3, r3, r3, lsl #8\r
1906 orr r3, r3, r3, lsl #16\r
1907 mov r2, r2, lsr #4\r
1908blockcpy_loop_or:\r
1909 ldmia r1!, {r4-r6,r12}\r
1910 subs r2, r2, #1\r
1911 orr r4, r4, r3\r
1912 orr r5, r5, r3\r
1913 orr r6, r6, r3\r
1914 orr r12,r12,r3\r
1915 stmia r0!, {r4-r6,r12}\r
1916 bne blockcpy_loop_or\r
1917 ldmfd sp!, {r4-r6}\r
1918 bx lr\r
1919\r
cff531af 1920@ vim:filetype=armasm\r