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