get rid of port_config.s
[picodrive.git] / pico / draw_arm.S
1 /*\r
2  * assembly optimized versions of most funtions from draw.c\r
3  * (C) notaz, 2006-2010\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 .extern Pico\r
12 .extern PicoOpt\r
13 .extern HighCol\r
14 .extern DrawScanline\r
15 .extern HighSprZ\r
16 .extern rendstatus\r
17 .extern HighPreSpr\r
18 .extern DrawLineDest\r
19 .extern DrawStripInterlace\r
20 .extern HighCacheS_ptr\r
21 \r
22 .equiv OVERRIDE_HIGHCOL,  1\r
23 \r
24 .equ PDRAW_SPRITES_MOVED, (1<<0)\r
25 .equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
26 .equ PDRAW_ACC_SPRITES,   (1<<2)\r
27 .equ PDRAW_DIRTY_SPRITES, (1<<4)\r
28 .equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
29 .equ PDRAW_SHHI_DONE,     (1<<7)\r
30 \r
31 @ helper\r
32 .macro TilePixel pat lsrr offs\r
33 .if !\lsrr\r
34     ands    r4, \pat, r2\r
35 .else\r
36     ands    r4, \pat, r2, lsr #\lsrr\r
37 .endif\r
38     orrne   r4, r3, r4\r
39     strneb  r4, [r1,#\offs]\r
40 .endm\r
41 \r
42 @ TileNorm (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
43 .macro TileNorm pat\r
44     TilePixel \pat, 12, 0         @ #0x0000f000\r
45     TilePixel \pat,  8, 1         @ #0x00000f00\r
46     TilePixel \pat,  4, 2         @ #0x000000f0\r
47     TilePixel \pat,  0, 3         @ #0x0000000f\r
48     TilePixel \pat, 28, 4         @ #0xf0000000\r
49     TilePixel \pat, 24, 5         @ #0x0f000000\r
50     TilePixel \pat, 20, 6         @ #0x00f00000\r
51     TilePixel \pat, 16, 7         @ #0x000f0000\r
52 .endm\r
53 \r
54 @ TileFlip (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
55 .macro TileFlip pat\r
56     TilePixel \pat, 16, 0         @ #0x000f0000\r
57     TilePixel \pat, 20, 1         @ #0x00f00000\r
58     TilePixel \pat, 24, 2         @ #0x0f000000\r
59     TilePixel \pat, 28, 3         @ #0xf0000000\r
60     TilePixel \pat,  0, 4         @ #0x0000000f\r
61     TilePixel \pat,  4, 5         @ #0x000000f0\r
62     TilePixel \pat,  8, 6         @ #0x00000f00\r
63     TilePixel \pat, 12, 7         @ #0x0000f000\r
64 .endm\r
65 \r
66 @ shadow/hilight mode\r
67 \r
68 @ this one is for hi priority layer\r
69 .macro TilePixelShHP lsrr offs\r
70 .if !\lsrr\r
71     ands    r4, r12, r2\r
72 .else\r
73     ands    r4, r12, r2, lsr #\lsrr\r
74 .endif\r
75     ldreqb  r4, [r1,#\offs]\r
76     orrne   r4, r3, r4\r
77     andeq   r4, r4, #0xbf\r
78     strb    r4, [r1,#\offs]\r
79 .endm\r
80 \r
81 @ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits\r
82 .macro TileNormShHP\r
83     TilePixelShHP 12, 0         @ #0x0000f000\r
84     TilePixelShHP  8, 1         @ #0x00000f00\r
85     TilePixelShHP  4, 2         @ #0x000000f0\r
86     TilePixelShHP  0, 3         @ #0x0000000f\r
87     TilePixelShHP 28, 4         @ #0xf0000000\r
88     TilePixelShHP 24, 5         @ #0x0f000000\r
89     TilePixelShHP 20, 6         @ #0x00f00000\r
90     TilePixelShHP 16, 7         @ #0x000f0000\r
91 .endm\r
92 \r
93 @ TileFlipShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
94 .macro TileFlipShHP\r
95     TilePixelShHP 16, 0         @ #0x000f0000\r
96     TilePixelShHP 20, 1         @ #0x00f00000\r
97     TilePixelShHP 24, 2         @ #0x0f000000\r
98     TilePixelShHP 28, 3         @ #0xf0000000\r
99     TilePixelShHP  0, 4         @ #0x0000000f\r
100     TilePixelShHP  4, 5         @ #0x000000f0\r
101     TilePixelShHP  8, 6         @ #0x00000f00\r
102     TilePixelShHP 12, 7         @ #0x0000f000\r
103 .endm\r
104 \r
105 \r
106 @ TileSingleSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx; r12: helper pattern 0xf\r
107 .macro TileSingleSh\r
108     tst     r0, #1              @ not aligned?\r
109     mov     r7, #0x00c000\r
110     orr     r7, r7, #0xc0\r
111     ldrneb  r4, [r1]\r
112     ldreqh  r4, [r1]\r
113     orr     r4, r4, r7\r
114     strneb  r4, [r1], #1\r
115     streqh  r4, [r1], #2\r
116     ldrh    r4, [r1]\r
117     orr     r4, r4, r7\r
118     strh    r4, [r1], #2\r
119     ldrh    r4, [r1]\r
120     orr     r4, r4, r7\r
121     strh    r4, [r1], #2\r
122     ldrh    r4, [r1]\r
123     orr     r4, r4, r7\r
124     strh    r4, [r1], #2\r
125     ldrneb  r4, [r1]\r
126     orr     r4, r4, r7\r
127     strneb  r4, [r1], #1\r
128 .endm\r
129 \r
130 @ TileSingleHi (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
131 .macro TileSingleHi\r
132     tst     r1,  #1              @ not aligned?\r
133     mov     r7,  #0x008000\r
134     orr     r7,  r7, #0x80\r
135     ldrneb  r4,  [r1], #1\r
136     ldreqh  r4,  [r1], #2        @ 1ci\r
137     ldrh    r12, [r1], #2\r
138     bic     r4,  r4,  r7, lsr #1\r
139     orr     r4,  r4,  r7\r
140     strneb  r4,  [r1, #-3]\r
141     streqh  r4,  [r1, #-4]\r
142     ldrh    r4,  [r1], #2\r
143     bic     r12, r12, r7, lsr #1\r
144     orr     r12, r12, r7\r
145     strh    r12, [r1, #-4]\r
146     ldrh    r12, [r1], #2\r
147     bic     r4,  r4,  r7, lsr #1\r
148     orr     r4,  r4,  r7\r
149     strh    r4,  [r1, #-4]\r
150     ldrneb  r4,  [r1]\r
151     bic     r12, r12, r7, lsr #1\r
152     orr     r12, r12, r7\r
153     strh    r12, [r1, #-2]\r
154     bicne   r4,  r4,  r7, lsr #1\r
155     orrne   r4,  r4,  r7\r
156     strneb  r4,  [r1], #1\r
157     mov     r12, #0xf\r
158 .endm\r
159 \r
160 .macro TileDoShGenPixel shift ofs\r
161 .if \shift\r
162     ands    r4, r12, r2, lsr #\shift\r
163 .else\r
164     ands    r4, r12, r2\r
165 .endif\r
166     beq     0f\r
167     cmp     r4, #0xe\r
168     ldrgeb  r7, [r1,#\ofs]\r
169     orrlt   r7, r3, r4            @ normal\r
170 \r
171     bicge   r7, r7, #0xc0\r
172     orrge   r7, r7, r4, lsl #6\r
173     strb    r7, [r1,#\ofs]\r
174 0:\r
175 .endm\r
176 \r
177 @ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
178 .macro TileFlipSh\r
179     TileDoShGenPixel 16,  0 @ #0x000f0000\r
180     TileDoShGenPixel 20,  1 @ #0x00f00000\r
181     TileDoShGenPixel 24,  2 @ #0x0f000000\r
182     TileDoShGenPixel 28,  3 @ #0xf0000000\r
183     TileDoShGenPixel  0,  4 @ #0x0000000f\r
184     TileDoShGenPixel  4,  5 @ #0x000000f0\r
185     TileDoShGenPixel  8,  6 @ #0x00000f00\r
186     TileDoShGenPixel 12,  7 @ #0x0000f000\r
187 .endm\r
188 \r
189 @ TileNormSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
190 .macro TileNormSh\r
191     TileDoShGenPixel 12,  0 @ #0x0000f000\r
192     TileDoShGenPixel  8,  1 @ #0x00000f00\r
193     TileDoShGenPixel  4,  2 @ #0x000000f0\r
194     TileDoShGenPixel  0,  3 @ #0x0000000f\r
195     TileDoShGenPixel 28,  4 @ #0xf0000000\r
196     TileDoShGenPixel 24,  5 @ #0x0f000000\r
197     TileDoShGenPixel 20,  6 @ #0x00f00000\r
198     TileDoShGenPixel 16,  7 @ #0x000f0000\r
199 .endm\r
200 \r
201 .macro TileDoShGenPixel_markop shift ofs\r
202 .if \shift\r
203     ands    r4, r12, r2, lsr #\shift\r
204 .else\r
205     ands    r4, r12, r2\r
206 .endif\r
207     beq     0f\r
208     cmp     r4, #0xe\r
209     ldrgeb  r4, [r1,#\ofs]\r
210     orrlt   r4, r3, r4\r
211     orrge   r4, r4, #0x80\r
212     strb    r4, [r1,#\ofs]\r
213 0:\r
214 .endm\r
215 \r
216 .macro TileFlipSh_markop\r
217     TileDoShGenPixel_markop 16,  0 @ #0x000f0000\r
218     TileDoShGenPixel_markop 20,  1 @ #0x00f00000\r
219     TileDoShGenPixel_markop 24,  2 @ #0x0f000000\r
220     TileDoShGenPixel_markop 28,  3 @ #0xf0000000\r
221     TileDoShGenPixel_markop  0,  4 @ #0x0000000f\r
222     TileDoShGenPixel_markop  4,  5 @ #0x000000f0\r
223     TileDoShGenPixel_markop  8,  6 @ #0x00000f00\r
224     TileDoShGenPixel_markop 12,  7 @ #0x0000f000\r
225 .endm\r
226 \r
227 .macro TileNormSh_markop\r
228     TileDoShGenPixel_markop 12,  0 @ #0x0000f000\r
229     TileDoShGenPixel_markop  8,  1 @ #0x00000f00\r
230     TileDoShGenPixel_markop  4,  2 @ #0x000000f0\r
231     TileDoShGenPixel_markop  0,  3 @ #0x0000000f\r
232     TileDoShGenPixel_markop 28,  4 @ #0xf0000000\r
233     TileDoShGenPixel_markop 24,  5 @ #0x0f000000\r
234     TileDoShGenPixel_markop 20,  6 @ #0x00f00000\r
235     TileDoShGenPixel_markop 16,  7 @ #0x000f0000\r
236 .endm\r
237 \r
238 .macro TileDoShGenPixel_onlyop_lp shift ofs\r
239 .if \shift\r
240     ands    r7, r12, r2, lsr #\shift\r
241 .else\r
242     ands    r7, r12, r2\r
243 .endif\r
244     ldrneb  r4, [r1,#\ofs]\r
245     cmp     r7, #0xe\r
246     blt     0f\r
247 \r
248     tst     r4, #0xc0\r
249     bicne   r4, r4, #0xc0\r
250     orrne   r4, r4, r7, lsl #6\r
251     strneb  r4, [r1,#\ofs]\r
252 0:\r
253 .endm\r
254 \r
255 .macro TileFlipSh_onlyop_lp\r
256     TileDoShGenPixel_onlyop_lp 16,  0 @ #0x000f0000\r
257     TileDoShGenPixel_onlyop_lp 20,  1 @ #0x00f00000\r
258     TileDoShGenPixel_onlyop_lp 24,  2 @ #0x0f000000\r
259     TileDoShGenPixel_onlyop_lp 28,  3 @ #0xf0000000\r
260     TileDoShGenPixel_onlyop_lp  0,  4 @ #0x0000000f\r
261     TileDoShGenPixel_onlyop_lp  4,  5 @ #0x000000f0\r
262     TileDoShGenPixel_onlyop_lp  8,  6 @ #0x00000f00\r
263     TileDoShGenPixel_onlyop_lp 12,  7 @ #0x0000f000\r
264 .endm\r
265 \r
266 .macro TileNormSh_onlyop_lp\r
267     TileDoShGenPixel_onlyop_lp 12,  0 @ #0x0000f000\r
268     TileDoShGenPixel_onlyop_lp  8,  1 @ #0x00000f00\r
269     TileDoShGenPixel_onlyop_lp  4,  2 @ #0x000000f0\r
270     TileDoShGenPixel_onlyop_lp  0,  3 @ #0x0000000f\r
271     TileDoShGenPixel_onlyop_lp 28,  4 @ #0xf0000000\r
272     TileDoShGenPixel_onlyop_lp 24,  5 @ #0x0f000000\r
273     TileDoShGenPixel_onlyop_lp 20,  6 @ #0x00f00000\r
274     TileDoShGenPixel_onlyop_lp 16,  7 @ #0x000f0000\r
275 .endm\r
276 \r
277 \r
278 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
279 \r
280 @ struct TileStrip\r
281 @ {\r
282 @   int nametab; // 0x00\r
283 @   int line;    // 0x04\r
284 @   int hscroll; // 0x08\r
285 @   int xmask;   // 0x0C\r
286 @   int *hc;     // 0x10 (pointer to cache buffer)\r
287 @   int cells;   // 0x14\r
288 @ };\r
289 \r
290 @ void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells);\r
291 \r
292 .global DrawLayer\r
293 \r
294 DrawLayer:\r
295     stmfd   sp!, {r4-r11,lr}\r
296 \r
297     ldr     r11, =(Pico+0x22228)  @ Pico.video\r
298     mov     r8, #1\r
299 \r
300     ldrb    r7, [r11, #16]        @ ??vv??hh\r
301 \r
302     mov     r6, r1                @ hcache\r
303     orr     r9, r3, r0, lsl #30\r
304     orr     r9, r9, r2, lsl #8    @ r9=sh[31]|cellskip[15:8]|maxcells[7:0]  (tmp)\r
305 \r
306     mov     r1, r7, lsl #4\r
307     orr     r1, r1, #0x00ff\r
308 \r
309     and     r10, r7,  #3\r
310     cmp     r10, #1\r
311     biclt   r1,  r1, #0xfc00\r
312     biceq   r1,  r1, #0xfe00\r
313     bicgt   r1,  r1, #0xff00      @ r1=ymask=(height<<8)|0xff; ...; // Y Mask in pixels\r
314 \r
315     add     r10, r10, #5\r
316     cmp     r10, #7\r
317     subge   r10, r10, #1          @ r10=shift[width] (5,6,6,7)\r
318 \r
319     @ calculate xmask:\r
320     mov     r5, r8, lsl r10\r
321     sub     r5, r5, #1            @ r5=xmask\r
322 \r
323     @ Find name table:\r
324     ands    r0,  r0, #1\r
325     ldreqb  r12, [r11, #2]\r
326     ldrneb  r12, [r11, #4]\r
327 \r
328     ldr     r2, =DrawScanline     @ trying to make good use of pipeline here\r
329     ldr     lr, =(Pico+0x10000)   @ lr=Pico.vram\r
330 \r
331     moveq   r12, r12, lsl #10\r
332     movne   r12, r12, lsl #13\r
333     and     r12, r12, #(7<<13)    @ r12=(ts->nametab<<1) (halfword compliant)\r
334 \r
335     ldrh    r8, [r11, #12]\r
336     ldrb    r7, [r11, #11]\r
337     ldr     r2, [r2]\r
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
342     addne   r4, r4, r2, lsl #2    @ htab+=DrawScanline<<1; // Offset by line\r
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
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
386     orrne   r10,r10, #1<<23 @ r10=(cells<<24|sh<<23|hi_not_empty<<22|had_output<<21|ty)\r
387     movne   r3, #0x40       @ default to shadowed pal on sh mode\r
388 \r
389     cmp     r7, #8\r
390     addne   r10,r10, #0x01000000 @ we will loop cells+1 times if there is scroll\r
391 \r
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
396 \r
397     @ cache some stuff to avoid mem access\r
398 .if OVERRIDE_HIGHCOL\r
399     ldr     r11,=HighCol\r
400     mov     r0, #0xf\r
401     ldr     r11,[r11]\r
402 .else\r
403     ldr     r11,=HighCol\r
404     mov     r0, #0xf\r
405 .endif\r
406 \r
407     mvn     r9, #0               @ r9=prevcode=-1\r
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
433     orr     r10, r10, #1<<21 @ seen non hi-prio tile\r
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
455     bne     .DrawStrip_TileFlip\r
456 \r
457     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
458 .DrawStrip_TileNorm:\r
459     TileNorm r0\r
460     b       .dsloop\r
461 \r
462 .DrawStrip_TileFlip:\r
463     TileFlip r0\r
464     b       .dsloop\r
465 \r
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
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
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
503     b       .dsloop\r
504 \r
505 .dsloop_exit:\r
506     tst     r10, #1<<21 @ seen non hi-prio tile\r
507     ldreq   r1, =rendstatus\r
508     mov     r0, #0\r
509     ldreq   r2, [r1]\r
510     str     r0, [r6]    @ terminate the cache list\r
511     orreq   r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
512     streq   r2, [r1]\r
513 \r
514     ldmfd   sp!, {r4-r11,lr}\r
515     bx      lr\r
516 \r
517 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
518 \r
519 .DrawStrip_vsscroll:\r
520     rsb     r8, r3, #0\r
521     mov     r8, r8, lsr #3        @ r8=tilex=(-ts->hscroll)>>3\r
522     bic     r8, r8, #0x3fc00000\r
523     orr     r8, r8, r5, lsl #25   @ r8=(xmask[31:25]|had_output[24]|tilex[21:0])\r
524 \r
525     ldr     r4, =DrawScanline\r
526     orr     r5, r1, r10, lsl #24\r
527     ldr     r4, [r4]\r
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
532 \r
533     mov     r10,r9, lsl #16\r
534     tst     r0, #1\r
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
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
540     movne   r3, #0x40       @ default to shadowed pal on sh mode\r
541 \r
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
549 \r
550     @ cache some stuff to avoid mem access\r
551 .if OVERRIDE_HIGHCOL\r
552     ldr     r11,=HighCol\r
553     mov     r0, #0xf\r
554     ldr     r11,[r11]\r
555 .else\r
556     ldr     r11,=HighCol\r
557     mov     r0, #0xf\r
558 .endif\r
559 \r
560     mvn     r9, #0               @ r9=prevcode=-1\r
561     add     r1, r11, r7          @ r1=pdest\r
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
570     ble     .dsloop_vs_exit\r
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
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
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
607     orr     r8, r8, #(1<<24)@ seen non hi-prio tile\r
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
629     bne     .DrawStrip_vs_TileFlip\r
630 \r
631     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
632 .DrawStrip_vs_TileNorm:\r
633     TileNorm r0\r
634     b       .dsloop_vs\r
635 \r
636 .DrawStrip_vs_TileFlip:\r
637     TileFlip r0\r
638     b       .dsloop_vs\r
639 \r
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
680 .dsloop_vs_exit:\r
681     tst     r8, #(1<<24) @ seen non hi-prio tile\r
682     ldreq   r1, =rendstatus\r
683     mov     r0, #0\r
684     ldreq   r2, [r1]\r
685     str     r0, [r6]    @ terminate the cache list\r
686     orreq   r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
687     streq   r2, [r1]\r
688 \r
689     ldmfd   sp!, {r4-r11,lr}\r
690     bx      lr\r
691 \r
692 \r
693 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
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
702     add     r2, r7, r2, lsl #22    @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);\r
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
728 BackFill:\r
729     stmfd   sp!, {r4-r9,lr}\r
730 \r
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
738     ldr     lr, =(HighCol+8)\r
739     mov     r0, r0, lsl #26\r
740     mov     r0, r0, lsr #26\r
741 .endif\r
742 \r
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
773 \r
774 .global DrawTilesFromCache @ int *hc, int sh, int rlim\r
775 \r
776 DrawTilesFromCache:\r
777     stmfd   sp!, {r4-r8,r11,lr}\r
778 \r
779     @ cache some stuff to avoid mem access\r
780 .if OVERRIDE_HIGHCOL\r
781     ldr     r11,=HighCol\r
782     mov     r12,#0xf\r
783     ldr     r11,[r11]\r
784 .else\r
785     ldr     r11,=HighCol\r
786     mov     r12,#0xf\r
787 .endif\r
788     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
789 \r
790     mvn     r5, #0         @ r5=prevcode=-1\r
791     ands    r8, r1, #1\r
792     orr     r8, r8, r2, lsl #1\r
793     bne     .dtfc_check_rendflags\r
794 \r
795     @ scratch: r4, r7\r
796 .dtfc_loop:\r
797     ldr     r6, [r0], #4    @ read code\r
798     movs    r1, r6, lsr #16 @ r1=dx;\r
799     ldmeqfd sp!, {r4-r8,r11,pc} @ dx is never zero, this must be a terminator, return\r
800     bic     r4, r1, #0xfe00\r
801     add     r1, r11, r4     @ r1=pdest\r
802 \r
803     mov     r7, r6, lsl #16\r
804     cmp     r5, r7, lsr #16\r
805     beq     .dtfc_samecode  @ if (code==prevcode)\r
806 \r
807     mov     r5, r7, lsr #16\r
808 \r
809     mov     r2, r5, lsl #21\r
810     mov     r2, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4;\r
811     add     r2, r2, r6, lsr #25 @ addr+=ty\r
812 \r
813     and     r3, r5, #0x6000\r
814     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
815 \r
816     ldr     r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
817 \r
818 .dtfc_samecode:\r
819     rsbs    r4, r4, r8, lsr #1\r
820     bmi     .dtfc_cut_tile\r
821 \r
822     tst     r8, #1\r
823     bne     .dtfc_shadow\r
824 \r
825     tst     r2, r2\r
826     beq     .dtfc_loop\r
827 \r
828     cmp     r2, r2, ror #4\r
829     beq     .dtfc_SingleColor @ tileline singlecolor \r
830 \r
831     tst     r5, #0x0800\r
832     bne     .dtfc_TileFlip\r
833 \r
834     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
835 .dtfc_TileNorm:\r
836     TileNorm r12\r
837     b       .dtfc_loop\r
838 \r
839 .dtfc_TileFlip:\r
840     TileFlip r12\r
841     b       .dtfc_loop\r
842 \r
843 .dtfc_SingleColor:\r
844     and     r4, r2, #0xf\r
845     orr     r4, r3, r4\r
846     orr     r4, r4, r4, lsl #8\r
847     tst     r1, #1              @ not aligned?\r
848     strneb  r4, [r1], #1\r
849     streqh  r4, [r1], #2\r
850     strh    r4, [r1], #2\r
851     strh    r4, [r1], #2\r
852     strh    r4, [r1], #2\r
853     strneb  r4, [r1], #1        @ have a remaining unaligned pixel?\r
854     b       .dtfc_loop\r
855 \r
856 .dtfc_shadow:\r
857     tst     r2, r2\r
858     beq     .dtfc_shadow_blank\r
859 \r
860     cmp     r2, r2, ror #4\r
861     beq     .dtfc_SingleColor @ tileline singlecolor \r
862 \r
863     tst     r5, #0x0800\r
864     bne     .dtfc_TileFlipShHP\r
865 \r
866     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
867 .dtfc_TileNormShHP:\r
868     TileNormShHP\r
869     b       .dtfc_loop\r
870 \r
871 .dtfc_TileFlipShHP:\r
872     TileFlipShHP\r
873     b       .dtfc_loop\r
874 \r
875 .dtfc_shadow_blank:\r
876     tst     r1, #1\r
877     ldrneb  r4, [r1]\r
878     mov     r6, #0xbf\r
879     and     r4, r4, #0xbf\r
880     strneb  r4, [r1], #1\r
881     ldrh    r4, [r1]\r
882     orr     r6, r6, r6, lsl #8\r
883     and     r4, r4, r6\r
884     strh    r4, [r1], #2\r
885     ldrh    r4, [r1]\r
886     and     r4, r4, r6\r
887     strh    r4, [r1], #2\r
888     ldrh    r4, [r1]\r
889     and     r4, r4, r6\r
890     strh    r4, [r1], #2\r
891     ldrh    r4, [r1]\r
892     and     r4, r4, r6\r
893     streqh  r4, [r1]\r
894     strneb  r4, [r1]\r
895     b       .dtfc_loop\r
896 \r
897 .dtfc_cut_tile:\r
898     add     r4, r4, #7      @ 0-6\r
899     mov     r4, r4, lsl #2\r
900     mov     r12,#0xf<<28\r
901     mov     r12,r12,asr r4\r
902     mov     r2, r2, ror #16\r
903     tst     r5, #0x0800     @ flipped?\r
904     mvnne   r12,r12\r
905     and     r2, r2, r12\r
906     mov     r2, r2, ror #16\r
907     mov     r12,#0xf\r
908     tst     r8, #1\r
909     bne     .dtfc_shadow\r
910     tst     r2, r2\r
911     beq     .dtfc_loop\r
912     tst     r5, #0x0800\r
913     beq     .dtfc_TileNorm\r
914     b       .dtfc_TileFlip\r
915 \r
916 @ check if we have detected layer covered with hi-prio tiles:\r
917 .dtfc_check_rendflags:\r
918     ldr     r1, =rendstatus\r
919     ldr     r2, [r1]\r
920     tst     r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE)\r
921     beq     .dtfc_loop\r
922     bic     r8, r8, #1      @ sh/hi mode off\r
923     tst     r2, #PDRAW_SHHI_DONE\r
924     bne     .dtfc_loop      @ already processed\r
925     orr     r2, r2, #PDRAW_SHHI_DONE\r
926     str     r2, [r1]\r
927 \r
928     add     r1, r11,#8\r
929     mov     r3, #320/4/4\r
930     mov     r6, #0xbf\r
931     orr     r6, r6, r6, lsl #8\r
932     orr     r6, r6, r6, lsl #16\r
933 .dtfc_loop_shprep:\r
934     ldmia   r1, {r2,r4,r5,r7}\r
935     subs    r3, r3, #1\r
936     and     r2, r2, r6\r
937     and     r4, r4, r6\r
938     and     r5, r5, r6\r
939     and     r7, r7, r6\r
940     stmia   r1!,{r2,r4,r5,r7}\r
941     bne     .dtfc_loop_shprep\r
942 \r
943     mvn     r5, #0         @ r5=prevcode=-1\r
944     b       .dtfc_loop\r
945 \r
946 .pool\r
947 \r
948 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
949 \r
950 \r
951 .global DrawSpritesSHi @ unsigned char *sprited\r
952 \r
953 DrawSpritesSHi:\r
954     ldr     r3, [r0]\r
955     mov     r12,#0xff\r
956     ands    r3, r3, #0x7f\r
957     bxeq    lr\r
958 \r
959     stmfd   sp!, {r4-r11,lr}\r
960     strb    r12,[r0,#2]     @ set end marker\r
961     add     r10,r0, #3      @ r10=HighLnSpr end\r
962     add     r10,r10,r3      @ r10=HighLnSpr end\r
963 \r
964 .if OVERRIDE_HIGHCOL\r
965     ldr     r11,=HighCol\r
966     mov     r12,#0xf\r
967     ldr     r11,[r11]\r
968 .else\r
969     ldr     r11,=HighCol\r
970     mov     r12,#0xf\r
971 .endif\r
972     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
973 \r
974 \r
975 DrawSpriteSHi:\r
976     @ draw next sprite\r
977     ldrb    r0, [r10,#-1]!\r
978     ldr     r1, =HighPreSpr\r
979 @    ldr     r8, [sp, #-4]\r
980     cmp     r0, #0xff\r
981     ldmeqfd sp!, {r4-r11,pc} @ end of list\r
982     and     r0, r0, #0x7f\r
983     add     r0, r1, r0, lsl #3\r
984 \r
985     ldr     r9, [r0, #4]    @ sprite[1]\r
986     mov     r2, r9, asr #16 @ r2=sx\r
987 \r
988     mov     r9, r9, lsl #16\r
989     mov     r3, r9, lsr #31 @ priority\r
990     mov     r9, r9, lsr #16\r
991 @    orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]   @@ sh is always on here now\r
992     and     r4, r9, #0x6000\r
993     orr     r9, r9, r4, lsl #16\r
994     orr     r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
995     cmp     r12,r9, lsr #28 @ sh/hi with pal3?\r
996     cmpne   r3, #1          @ if not, is it hi prio?\r
997     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn\r
998 \r
999     ldr     r3, [r0]        @ sprite[0]\r
1000     ldr     r7, =DrawScanline\r
1001     mov     r6, r3, lsr #28\r
1002     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1003     mov     r5, r3, lsr #24\r
1004     and     r5, r5, #7      @ r5=height\r
1005 \r
1006     mov     r0, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1007 \r
1008     ldr     r7, [r7]\r
1009     sub     r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy\r
1010 \r
1011     tst     r9, #0x1000\r
1012     movne   r0, r5, lsl #3\r
1013     subne   r0, r0, #1\r
1014     subne   r7, r0, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1015 \r
1016     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1017     tst     r9, #0x0800\r
1018     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1019     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1020 \r
1021     mov     r8, r8, lsl #21\r
1022     mov     r8, r8, lsr #17\r
1023     and     r7, r7, #7\r
1024     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1025 \r
1026     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1027     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1028 \r
1029     add     r6, r6, #1         @ inc now\r
1030     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1031     b       .dsprShi_loop_enter\r
1032 \r
1033 .dsprShi_loop:\r
1034     subs    r6, r6, #1         @ width--\r
1035     beq     DrawSpriteSHi\r
1036     adds    r0, r0, #8         @ sx+=8\r
1037     add     r8, r8, r5         @ tile+=delta\r
1038 \r
1039 .dsprShi_loop_enter:\r
1040     ble     .dsprShi_loop     @ sx <= 0\r
1041     cmp     r0, #328\r
1042     bge     DrawSpriteSHi\r
1043 \r
1044     mov     r8, r8, lsl #17\r
1045     mov     r8, r8, lsr #17    @ tile&=0x7fff; // Clip tile address\r
1046 \r
1047     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1048     add     r1, r11, r0        @ r1=pdest\r
1049     tst     r2, r2\r
1050     beq     .dsprShi_loop\r
1051 \r
1052     cmp     r12, r9, lsr #28\r
1053     beq     .dsprShi_shadow\r
1054 \r
1055     cmp     r2, r2, ror #4\r
1056     beq     .dsprShi_SingleColor @ tileline singlecolor \r
1057 \r
1058     tst     r9, #0x0800\r
1059     bne     .dsprShi_TileFlip\r
1060 \r
1061     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1062 @ scratch: r4, r7\r
1063 .dsprShi_TileNorm:\r
1064     TileNorm r12\r
1065     b       .dsprShi_loop\r
1066 \r
1067 .dsprShi_TileFlip:\r
1068     TileFlip r12\r
1069     b       .dsprShi_loop\r
1070 \r
1071 .dsprShi_SingleColor:\r
1072     and     r4, r2, #0xf\r
1073     orr     r4, r3, r4\r
1074     orr     r4, r4, r4, lsl #8\r
1075     tst     r0, #1              @ not aligned?\r
1076     strneb  r4, [r1], #1\r
1077     streqh  r4, [r1], #2\r
1078     strh    r4, [r1], #2\r
1079     strh    r4, [r1], #2\r
1080     strh    r4, [r1], #2\r
1081     strneb  r4, [r1], #1\r
1082     b       .dsprShi_loop\r
1083 \r
1084 .dsprShi_shadow:\r
1085     tst     r9, #0x8000\r
1086     beq     .dsprShi_shadow_lowpri\r
1087 \r
1088     cmp     r2, r2, ror #4\r
1089     beq     .dsprShi_singlec_sh\r
1090 \r
1091     tst     r9, #0x0800\r
1092     bne     .dsprShi_TileFlip_sh\r
1093 \r
1094     @ (r1=pdest, r2=pixels8, r3=pal) r4, r7: scratch, r12: helper pattern\r
1095 .dsprShi_TileNorm_sh:\r
1096     TileNormSh\r
1097     b       .dsprShi_loop\r
1098 \r
1099 .dsprShi_TileFlip_sh:\r
1100     TileFlipSh\r
1101     b       .dsprShi_loop\r
1102 \r
1103 .dsprShi_singlec_sh:\r
1104     cmp     r2, #0xe0000000\r
1105     bcc     .dsprShi_SingleColor   @ normal singlecolor tileline (carry inverted in ARM)\r
1106     tst     r2, #0x10000000\r
1107     bne     .dsprShi_sh_sh\r
1108     TileSingleHi\r
1109     b       .dsprShi_loop\r
1110 \r
1111 .dsprShi_sh_sh:\r
1112     TileSingleSh\r
1113     b       .dsprShi_loop\r
1114 \r
1115 .dsprShi_shadow_lowpri:\r
1116     tst     r9, #0x800\r
1117     bne     .dsprShi_TileFlip_sh_lp\r
1118 \r
1119 .dsprShi_TileNorm_sh_lp:\r
1120     TileNormSh_onlyop_lp\r
1121     b       .dsprShi_loop\r
1122 \r
1123 .dsprShi_TileFlip_sh_lp:\r
1124     TileFlipSh_onlyop_lp\r
1125     b       .dsprShi_loop\r
1126 \r
1127 .pool\r
1128 \r
1129 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1130 \r
1131 .global DrawAllSprites @ unsigned char *sprited, int prio, int sh\r
1132 \r
1133 DrawAllSprites:\r
1134     ldr     r3, =rendstatus\r
1135     orr     r1, r2, r1, lsl #1\r
1136     ldr     r12,[r3]\r
1137     tst     r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED)\r
1138     beq     das_no_prep\r
1139     stmfd   sp!, {r0,r1,lr}\r
1140     and     r0, r12,#PDRAW_DIRTY_SPRITES\r
1141     bic     r12,r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED)\r
1142     str     r12,[r3]\r
1143     bl      PrepareSprites\r
1144     ldmfd   sp!, {r0,r1,lr}\r
1145 \r
1146 das_no_prep:\r
1147     ldr     r3, [r0]\r
1148     ands    r3, r3, #0x7f\r
1149     bxeq    lr\r
1150 \r
1151     @ time to do some real work\r
1152     stmfd   sp!, {r4-r11,lr}\r
1153     mov     r12,#0xff\r
1154     strb    r12,[r0,#2]     @ set end marker\r
1155     add     r10,r0, #3\r
1156     add     r10,r10,r3      @ r10=HighLnSpr end\r
1157 \r
1158     str     r1, [sp, #-4]   @ no calls after this point\r
1159 \r
1160 .if OVERRIDE_HIGHCOL\r
1161     ldr     r11,=HighCol\r
1162     mov     r12,#0xf\r
1163     ldr     r11,[r11]\r
1164 .else\r
1165     ldr     r11,=HighCol\r
1166     mov     r12,#0xf\r
1167 .endif\r
1168     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
1169 \r
1170 @ + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size\r
1171 @ + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
1172 \r
1173 DrawSprite: @ was: unsigned int *sprite, int sh, int acc_sprites\r
1174     @ draw next sprite\r
1175     ldrb    r0, [r10,#-1]!\r
1176     ldr     r1, =HighPreSpr\r
1177     ldr     r8, [sp, #-4]\r
1178     mov     r2, r0, lsr #7\r
1179     cmp     r0, #0xff\r
1180     ldmeqfd sp!, {r4-r11,pc} @ end of list\r
1181     cmp     r2, r8, lsr #1\r
1182     bne     DrawSprite      @ wrong priority\r
1183     and     r0, r0, #0x7f\r
1184     add     r0, r1, r0, lsl #3\r
1185 \r
1186 @    stmfd   sp!, {r4-r9,r11,lr}\r
1187 @    orr     r8, r2, r1, lsl #4\r
1188 \r
1189     ldr     r3, [r0]        @ sprite[0]\r
1190     ldr     r7, =DrawScanline\r
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
1198     ldr     r7, [r7]\r
1199     ldr     r9, [r0, #4]\r
1200     sub     r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy\r
1201 \r
1202     mov     r2, r9, asr #16 @ r2=sx\r
1203     mov     r9, r9, lsl #16\r
1204     mov     r9, r9, lsr #16\r
1205     orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]\r
1206 \r
1207     tst     r9, #0x1000\r
1208     movne   r4, r5, lsl #3\r
1209     subne   r4, r4, #1\r
1210     subne   r7, r4, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1211 \r
1212     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1213     tst     r9, #0x0800\r
1214     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1215     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1216 \r
1217     mov     r8, r8, lsl #21\r
1218     mov     r8, r8, lsr #17\r
1219     and     r7, r7, #7\r
1220     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1221 \r
1222 .dspr_continue:\r
1223     @ cache some stuff to avoid mem access\r
1224     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1225     and     r4, r9, #0x6000\r
1226     orr     r9, r9, r4, lsl #16\r
1227     orrs    r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1228 \r
1229     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1230     orrmi   r3, r3, #0x40      @ for sh/hi\r
1231 \r
1232     add     r6, r6, #1         @ inc now\r
1233     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1234     b       .dspr_loop_enter\r
1235 \r
1236 .dspr_loop:\r
1237     subs    r6, r6, #1         @ width--\r
1238     beq     DrawSprite\r
1239     adds    r0, r0, #8         @ sx+=8\r
1240     add     r8, r8, r5         @ tile+=delta\r
1241 \r
1242 .dspr_loop_enter:\r
1243     ble     .dspr_loop         @ sx <= 0\r
1244     cmp     r0, #328\r
1245     bge     DrawSprite\r
1246 \r
1247     mov     r8, r8, lsl #17\r
1248     mov     r8, r8, lsr #17    @ tile&=0x7fff; // Clip tile address\r
1249 \r
1250     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1251     add     r1, r11, r0        @ r1=pdest\r
1252     tst     r2, r2\r
1253     beq     .dspr_loop\r
1254 \r
1255     cmp     r12, r9, lsr #28\r
1256     beq     .dspr_shadow\r
1257 \r
1258     cmp     r2, r2, ror #4\r
1259     beq     .dspr_SingleColor @ tileline singlecolor \r
1260 \r
1261     tst     r9, #0x0800\r
1262     bne     .dspr_TileFlip\r
1263 \r
1264     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1265 @ scratch: r4, r7\r
1266 .dspr_TileNorm:\r
1267     TileNorm r12\r
1268     b       .dspr_loop\r
1269 \r
1270 .dspr_TileFlip:\r
1271     TileFlip r12\r
1272     b       .dspr_loop\r
1273 \r
1274 .dspr_singlec_sh:\r
1275     cmp     r2, #0xe0000000\r
1276     bcs     .dspr_TileNorm_sh   @ op. tileline, markop. XXX: maybe add a spec. handler?\r
1277 \r
1278 .dspr_SingleColor:\r
1279     and     r4, r2, #0xf\r
1280     orr     r4, r3, r4\r
1281     orr     r4, r4, r4, lsl #8\r
1282     tst     r0, #1              @ not aligned?\r
1283     strneb  r4, [r1], #1\r
1284     streqh  r4, [r1], #2\r
1285     strh    r4, [r1], #2\r
1286     strh    r4, [r1], #2\r
1287     strh    r4, [r1], #2\r
1288     strneb  r4, [r1], #1\r
1289     b       .dspr_loop\r
1290 \r
1291 .dspr_shadow:\r
1292     cmp     r2, r2, ror #4\r
1293     beq     .dspr_singlec_sh\r
1294 \r
1295     tst     r9, #0x0800\r
1296     bne     .dspr_TileFlip_sh\r
1297 \r
1298     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1299 .dspr_TileNorm_sh:\r
1300     TileNormSh_markop\r
1301     b       .dspr_loop\r
1302 \r
1303 .dspr_TileFlip_sh:\r
1304     TileFlipSh_markop\r
1305     b       .dspr_loop\r
1306 \r
1307 \r
1308 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1309 \r
1310 .global DrawWindow @ int tstart, int tend, int prio, int sh // int *hcache\r
1311 \r
1312 DrawWindow:\r
1313     stmfd   sp!, {r4-r11,lr}\r
1314 \r
1315     ldr     r11, =(Pico+0x22228)  @ Pico.video\r
1316     ldr     r10, =DrawScanline\r
1317     ldrb    r12, [r11, #3]        @ pvid->reg[3]\r
1318 \r
1319     ldr     r10, [r10]\r
1320     ldr     r4,  [r11, #12]\r
1321     mov     r5,  r10, lsr #3\r
1322     and     r10, r10, #7\r
1323     mov     r10, r10, lsl #1      @ r10=ty\r
1324 \r
1325     mov     r12, r12, lsl #10\r
1326 \r
1327     tst     r4, #1                @ 40 cell mode?\r
1328     andne   r12, r12, #0xf000     @ 0x3c<<10\r
1329     andeq   r12, r12, #0xf800\r
1330     addne   r12, r12, r5, lsl #7\r
1331     addeq   r12, r12, r5, lsl #6  @ nametab\r
1332     add     r12, r12, r0, lsl #2  @ +starttile\r
1333 \r
1334     ldr     r6, =rendstatus\r
1335     ldr     lr, =(Pico+0x10000)   @ lr=Pico.vram\r
1336     ldr     r6, [r6]\r
1337 \r
1338     @ fetch the first code now\r
1339     ldrh    r7, [lr, r12]\r
1340 \r
1341     ands    r6, r6, #PDRAW_WND_DIFF_PRIO\r
1342     orr     r6, r6, r2\r
1343 \r
1344     eoreq   r8, r2, r7, lsr #15   @ do prio bits differ?\r
1345     cmpeq   r8, #1\r
1346     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
1347 \r
1348     orr     r6, r6, r3, lsl #8    @ shadow mode\r
1349 \r
1350     sub     r8, r1, r0\r
1351 \r
1352     @ cache some stuff to avoid mem access\r
1353 .if OVERRIDE_HIGHCOL\r
1354     ldr     r11,=HighCol\r
1355     mov     r8, r8, lsl #1        @ cells\r
1356     ldr     r11,[r11]\r
1357     mvn     r9, #0                @ r9=prevcode=-1\r
1358     add     r11,r11,#8\r
1359 .else\r
1360     ldr     r11,=(HighCol+8)\r
1361     mov     r8, r8, lsl #1        @ cells\r
1362     mvn     r9, #0                @ r9=prevcode=-1\r
1363 .endif\r
1364     add     r1, r11, r0, lsl #4   @ r1=pdest\r
1365     mov     r0, #0xf\r
1366     b       .dwloop_enter\r
1367 \r
1368     @ r4,r5 are scratch in this loop\r
1369 .dwloop:\r
1370     add     r1, r1, #8\r
1371 .dwloop_nor1:\r
1372     add     r12, r12, #2    @ halfwords\r
1373     ldrh    r7, [lr, r12]   @ r7=code (int, but from unsigned, no sign extend)\r
1374     subs    r8, r8, #1\r
1375     beq     .dwloop_end     @ done\r
1376 \r
1377     eor     r5, r6, r7, lsr #15\r
1378     tst     r5, #1\r
1379     orrne   r6, r6, #2      @ wrong pri\r
1380     bne     .dwloop\r
1381 \r
1382     cmp     r7, r9\r
1383     beq     .dw_samecode    @ we know stuff about this tile already\r
1384 \r
1385 .dwloop_enter:\r
1386     mov     r9, r7          @ remember code\r
1387 \r
1388     movs    r2, r9, lsl #20 @ if (code&0x1000)\r
1389     mov     r2, r2, lsl #1\r
1390     add     r2, r10, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4; addr+=ty\r
1391     eorcs   r2, r2, #0x0e   @ if (code&0x1000) addr^=0xe;\r
1392 \r
1393     and     r3, r9, #0x6000\r
1394     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
1395 \r
1396     ldr     r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1397 \r
1398 .dw_samecode:\r
1399     tst     r6, #0x100\r
1400     bne     .dw_shadow\r
1401 .dw_shadow_done:\r
1402     tst     r2, r2\r
1403     beq     .dwloop              @ tileline blank\r
1404 \r
1405     cmp     r2, r2, ror #4\r
1406     beq     .dw_SingleColor @ tileline singlecolor \r
1407 \r
1408     tst     r9, #0x0800\r
1409     bne     .dw_TileFlip\r
1410 \r
1411     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
1412 .dw_TileNorm:\r
1413     TileNorm r0\r
1414     b       .dwloop\r
1415 \r
1416 .dw_TileFlip:\r
1417     TileFlip r0\r
1418     b       .dwloop\r
1419 \r
1420 .dw_SingleColor:\r
1421     and     r4, r0, r2         @ #0x0000000f\r
1422     orr     r4, r3, r4\r
1423     orr     r4, r4, r4, lsl #8\r
1424     orr     r4, r4, r4, lsl #16\r
1425     mov     r5, r4\r
1426     stmia   r1!, {r4,r5}\r
1427     b       .dwloop_nor1       @ we incremeted r1 ourselves\r
1428 \r
1429 .dw_shadow:\r
1430     tst     r6, #1             @ hi pri?\r
1431     orreq   r3, r3, #0x40\r
1432     beq     .dw_shadow_done\r
1433     ldr     r4, [r1]\r
1434     mov     r5, #0x3f\r
1435     orr     r5, r5, r5, lsl #8\r
1436     orr     r5, r5, r5, lsl #16\r
1437     and     r4, r4, r5\r
1438     str     r4, [r1]\r
1439     ldr     r4, [r1,#4]\r
1440     and     r4, r4, r5\r
1441     str     r4, [r1,#4]\r
1442     b       .dw_shadow_done\r
1443 \r
1444 .dwloop_end:\r
1445     ldr     r0, =rendstatus\r
1446     ldr     r1, [r0]\r
1447     and     r6, r6, #PDRAW_WND_DIFF_PRIO\r
1448     orr     r1, r1, r6\r
1449     str     r1, [r0]\r
1450 \r
1451     ldmfd   sp!, {r4-r11,r12}\r
1452     bx      r12\r
1453 \r
1454 \r
1455 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1456 \r
1457 \r
1458 @ hilights 2 pixels in RGB444/BGR444 format\r
1459 .macro TileDoShHi2Pixels444 reg\r
1460     mov     \reg, \reg, ror #12\r
1461     adds    \reg, \reg, #0x40000000\r
1462     orrcs   \reg, \reg, #0xf0000000\r
1463     mov     \reg, \reg, ror #28\r
1464     adds    \reg, \reg, #0x40000000\r
1465     orrcs   \reg, \reg, #0xf0000000\r
1466     mov     \reg, \reg, ror #28\r
1467     adds    \reg, \reg, #0x40000000\r
1468     orrcs   \reg, \reg, #0xf0000000\r
1469     mov     \reg, \reg, ror #24\r
1470     adds    \reg, \reg, #0x40000000\r
1471     orrcs   \reg, \reg, #0xf0000000\r
1472     mov     \reg, \reg, ror #28\r
1473     adds    \reg, \reg, #0x40000000\r
1474     orrcs   \reg, \reg, #0xf0000000\r
1475     mov     \reg, \reg, ror #28\r
1476     adds    \reg, \reg, #0x40000000\r
1477     orrcs   \reg, \reg, #0xf0000000\r
1478     mov     \reg, \reg, ror #12\r
1479 .endm\r
1480 \r
1481 \r
1482 .global FinalizeLineBGR444 @ int sh\r
1483 \r
1484 FinalizeLineBGR444:\r
1485     stmfd   sp!, {r4-r6,lr}\r
1486     mov     r6, r0\r
1487     ldr     lr, =(Pico+0x22228)  @ Pico.video\r
1488     ldr     r0, =DrawLineDest\r
1489     ldrb    r12, [lr, #12]\r
1490     ldr     r0, [r0]\r
1491     sub     r3, lr, #0x128       @ r3=Pico.cram\r
1492 \r
1493     tst     r12, #1\r
1494     movne   r2, #320/4           @ len\r
1495     bne     .fl_no32colBGR444\r
1496     ldr     r4, =PicoOpt\r
1497     mov     r2, #256/4\r
1498     ldr     r4, [r4]\r
1499     tst     r4, #0x100\r
1500     addeq   r0, r0, #32*2\r
1501 \r
1502 .fl_no32colBGR444:\r
1503     tst     r6, r6\r
1504     beq     .fl_noshBGR444\r
1505 \r
1506     ldr     r4, =HighPal\r
1507 \r
1508     ldrb    r12, [lr, #-0x1a]      @ 0x2220e ~ dirtyPal\r
1509     tst     r12, r12\r
1510     moveq   r3, r4\r
1511     beq     .fl_noshBGR444\r
1512     mov     r12, #0\r
1513     strb    r12, [lr, #-0x1a]\r
1514 \r
1515     mov     lr, #0x40/8\r
1516     @ copy pal:\r
1517 .fl_loopcpBGR444:\r
1518     ldmia   r3!, {r1,r5,r6,r12}\r
1519     subs    lr, lr, #1\r
1520     stmia   r4!, {r1,r5,r6,r12}\r
1521     bne     .fl_loopcpBGR444\r
1522 \r
1523     @ shadowed pixels:\r
1524     mov     r12,    #0x0077\r
1525     orr     r12,r12,#0x0700\r
1526     orr     r12,r12,r12,lsl #16\r
1527     sub     r3, r3, #0x40*2\r
1528     add     r5, r4, #0x80*2\r
1529     mov     lr, #0x40/4\r
1530 .fl_loopcpBGR444_sh:\r
1531     ldmia   r3!, {r1,r6}\r
1532     subs    lr, lr, #1\r
1533     and     r1, r12, r1, lsr #1\r
1534     and     r6, r12, r6, lsr #1\r
1535     stmia   r4!, {r1,r6}\r
1536     stmia   r5!, {r1,r6}\r
1537     bne     .fl_loopcpBGR444_sh\r
1538 \r
1539     @ hilighted pixels:\r
1540     sub     r3, r3, #0x40*2\r
1541     mov     lr, #0x40/2\r
1542 .fl_loopcpBGR444_hi:\r
1543     ldr     r1, [r3], #4\r
1544     TileDoShHi2Pixels444 r1\r
1545     str     r1, [r4], #4\r
1546     subs    lr, lr, #1\r
1547     bne     .fl_loopcpBGR444_hi\r
1548 \r
1549     sub     r3, r4, #0x40*3*2\r
1550     mov     r6, #1\r
1551 \r
1552 \r
1553 .fl_noshBGR444:\r
1554     ldr     r12,=rendstatus\r
1555     eors    r6, r6, #1          @ sh is 0\r
1556     ldr     r12,[r12]\r
1557     mov     lr, #0xff\r
1558     tstne   r12,#PDRAW_ACC_SPRITES\r
1559 \r
1560 .if OVERRIDE_HIGHCOL\r
1561     ldr     r1, =HighCol\r
1562     movne   lr, #0x3f\r
1563     ldr     r1, [r1]\r
1564     mov     lr, lr, lsl #1\r
1565     add     r1, r1, #8\r
1566 .else\r
1567     ldr     r1, =(HighCol+8)\r
1568     movne   lr, #0x3f\r
1569     mov     lr, lr, lsl #1\r
1570 .endif\r
1571 \r
1572 .fl_loopBGR444:\r
1573     ldr     r12, [r1], #4\r
1574     subs    r2, r2, #1\r
1575 \r
1576     and     r4, lr, r12, lsl #1\r
1577     ldrh    r4, [r3, r4]\r
1578     and     r5, lr, r12, lsr #7\r
1579     ldrh    r5, [r3, r5]\r
1580     and     r6, lr, r12, lsr #15\r
1581     ldrh    r6, [r3, r6]\r
1582     and     r12,lr, r12, lsr #23\r
1583     ldrh    r12,[r3, r12]              @ 1c.i.\r
1584     orr     r4, r4, r5, lsl #16\r
1585     orr     r5, r6, r12,lsl #16\r
1586 \r
1587     stmia   r0!, {r4,r5}\r
1588     bne     .fl_loopBGR444\r
1589 \r
1590 \r
1591     ldmfd   sp!, {r4-r6,lr}\r
1592     bx lr\r
1593 \r
1594 \r
1595 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1596 \r
1597 \r
1598 @ Convert 0000bbb0 ggg0rrr0\r
1599 @ to      rrrrrggg gggbbbbb\r
1600 \r
1601 @ r2,r3 - scratch, lr = 0x001c001c, r8 = 0x08610861\r
1602 .macro convRGB565 reg\r
1603     and     r2,   lr,   \reg,lsr #7  @ b\r
1604     and     r3,   lr,   \reg,lsr #3  @ g\r
1605     and     \reg, lr,   \reg,lsl #1  @ r\r
1606     orr     r2,   r2,   r3,  lsl #6\r
1607     orr     \reg, r2,   \reg,lsl #11\r
1608 \r
1609     and     r2,   r8,   \reg,lsr #4\r
1610     orr     \reg, \reg, r2\r
1611 .endm\r
1612 \r
1613 @ trashes: r2-r8,r12,lr; r8 = 0x08610861; r0,r1 are advanced\r
1614 .macro vidConvCpyRGB565_local\r
1615     mov     r12, r2, lsr #3  @ repeats\r
1616     mov     lr, #0x001c0000\r
1617     orr     lr, lr,  #0x01c  @ lr == pattern 0x001c001c\r
1618 \r
1619 0:\r
1620     ldmia   r1!, {r4-r7}\r
1621     subs    r12, r12, #1\r
1622     convRGB565 r4\r
1623     str     r4, [r0], #4\r
1624     convRGB565 r5\r
1625     str     r5, [r0], #4\r
1626     convRGB565 r6\r
1627     str     r6, [r0], #4\r
1628     convRGB565 r7\r
1629     str     r7, [r0], #4\r
1630 \r
1631     bgt     0b\r
1632 .endm\r
1633 \r
1634 \r
1635 .global vidConvCpyRGB565\r
1636 \r
1637 vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1638     stmfd   sp!, {r4-r9,lr}\r
1639     mov     r8,     #0x0061\r
1640     orr     r8, r8, #0x0800\r
1641     orr     r8, r8, r8, lsl #16\r
1642     vidConvCpyRGB565_local\r
1643     ldmfd   sp!, {r4-r9,lr}\r
1644     bx      lr\r
1645 \r
1646 \r
1647 .global PicoDoHighPal555 @ int sh\r
1648 \r
1649 PicoDoHighPal555:\r
1650     stmfd   sp!, {r4-r9,lr}\r
1651     mov     r1, #0\r
1652     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
1653 \r
1654 PicoDoHighPal555_nopush:\r
1655     orr     r9, r1, r0, lsl #31  @ 0:called from FinalizeLine555, 31: s/h\r
1656 \r
1657     ldr     r0, =HighPal\r
1658 \r
1659     mov     r1, #0\r
1660     strb    r1, [r8, #-0x1a]     @ 0x2220e ~ dirtyPal\r
1661 \r
1662     sub     r1, r8, #0x128       @ r1=Pico.cram\r
1663     mov     r2, #0x40\r
1664     mov     r8,     #0x0061\r
1665     orr     r8, r8, #0x0800\r
1666     orr     r8, r8, r8, lsl #16\r
1667 \r
1668     vidConvCpyRGB565_local\r
1669 \r
1670     tst     r9, #(1<<31)\r
1671     beq     PicoDoHighPal555_end\r
1672 \r
1673     ldr     r3, =HighPal\r
1674 \r
1675     @ shadowed pixels:\r
1676     mov     r12,    #0x008e\r
1677     add     r4, r3, #0x40*2\r
1678     orr     r12,r12,#0x7300\r
1679     add     r5, r3, #0xc0*2\r
1680     orr     r12,r12,r12,lsl #16\r
1681     mov     lr, #0x40/4\r
1682 .fl_loopcpRGB555_sh:\r
1683     ldmia   r3!, {r1,r6}\r
1684     subs    lr, lr, #1\r
1685     and     r1, r12, r1, lsr #1\r
1686     and     r6, r12, r6, lsr #1\r
1687     stmia   r4!, {r1,r6}\r
1688     stmia   r5!, {r1,r6}\r
1689     bne     .fl_loopcpRGB555_sh\r
1690 \r
1691     @ hilighted pixels:\r
1692     @  t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;\r
1693     @  t |= (t >> 4) & 0x08610861;\r
1694     @ r8=0x08610861\r
1695     sub     r3, r3, #0x40*2\r
1696     mov     lr, #0x40/4\r
1697 .fl_loopcpRGB555_hi:\r
1698     ldmia   r3!, {r1,r6}\r
1699     and     r1, r12, r1, lsr #1\r
1700     and     r6, r12, r6, lsr #1\r
1701     add     r1, r12, r1\r
1702     add     r6, r12, r6\r
1703     and     r5, r8, r1, lsr #4\r
1704     and     r7, r8, r6, lsr #4\r
1705     orr     r1, r1, r5\r
1706     orr     r6, r6, r7\r
1707     stmia   r4!, {r1,r6}\r
1708     subs    lr, lr, #1\r
1709     bne     .fl_loopcpRGB555_hi\r
1710     mov     r0, #1\r
1711 \r
1712 PicoDoHighPal555_end:\r
1713     tst     r9, #1\r
1714     ldmeqfd sp!, {r4-r9,pc}\r
1715 \r
1716     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
1717     b       FinalizeLineRGB555_pal_done\r
1718 \r
1719 \r
1720 .global FinalizeLine555 @ int sh\r
1721 \r
1722 FinalizeLine555:\r
1723     stmfd   sp!, {r4-r9,lr}\r
1724     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
1725 \r
1726     ldrb    r2, [r8, #-0x1a]     @ 0x2220e ~ dirtyPal\r
1727     mov     r1, #1\r
1728     tst     r2, r2\r
1729     bne     PicoDoHighPal555_nopush\r
1730 \r
1731 FinalizeLineRGB555_pal_done:\r
1732     ldr     r3, =HighPal\r
1733 \r
1734     ldr     r12,=rendstatus\r
1735     eors    r0, r0, #1           @ sh is 0\r
1736     ldr     r12,[r12]\r
1737     mov     lr, #0xff\r
1738     tstne   r12,#PDRAW_ACC_SPRITES\r
1739     movne   lr, #0x3f\r
1740 \r
1741 .if OVERRIDE_HIGHCOL\r
1742     ldr     r1, =HighCol\r
1743     ldr     r0, =DrawLineDest\r
1744     ldr     r1, [r1]\r
1745     ldr     r0, [r0]\r
1746     add     r1, r1, #8\r
1747 .else\r
1748     ldr     r0, =DrawLineDest\r
1749     ldr     r1, =(HighCol+8)\r
1750     ldr     r0, [r0]\r
1751 .endif\r
1752 \r
1753     ldrb    r12, [r8, #12]\r
1754     mov     lr, lr, lsl #1\r
1755 \r
1756     tst     r12, #1\r
1757     movne   r2, #320/8           @ len\r
1758     bne     .fl_no32colRGB555\r
1759     ldr     r4, =PicoOpt\r
1760     mov     r2, #256/8\r
1761     ldr     r4, [r4]\r
1762     tst     r4, #0x4000\r
1763     bne     .fl_32scale_RGB555\r
1764     tst     r4, #0x0100\r
1765     addeq   r0, r0, #32*2\r
1766 \r
1767 .fl_no32colRGB555:\r
1768 \r
1769 #ifdef UNALIGNED_DRAWLINEDEST\r
1770     @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1771     tst     r0, #2\r
1772     bne     .fl_RGB555u\r
1773 #endif\r
1774 \r
1775 .fl_loopRGB555:\r
1776     ldr     r12, [r1], #4\r
1777     ldr     r7,  [r1], #4\r
1778 \r
1779     and     r4, lr, r12, lsl #1\r
1780     ldrh    r4, [r3, r4]\r
1781     and     r5, lr, r12, lsr #7\r
1782     ldrh    r5, [r3, r5]\r
1783     and     r6, lr, r12, lsr #15\r
1784     ldrh    r6, [r3, r6]\r
1785     orr     r4, r4, r5, lsl #16\r
1786 \r
1787     and     r5, lr, r12, lsr #23\r
1788     ldrh    r5, [r3, r5]\r
1789     and     r8, lr, r7, lsl #1\r
1790     ldrh    r8, [r3, r8]\r
1791     orr     r5, r6, r5, lsl #16\r
1792 \r
1793     and     r6, lr, r7, lsr #7\r
1794     ldrh    r6, [r3, r6]\r
1795     and     r12,lr, r7, lsr #15\r
1796     ldrh    r12,[r3, r12]\r
1797     and     r7, lr, r7, lsr #23\r
1798     ldrh    r7, [r3, r7]\r
1799     orr     r8, r8, r6, lsl #16\r
1800 \r
1801     subs    r2, r2, #1\r
1802     orr     r12,r12, r7, lsl #16\r
1803 \r
1804     stmia   r0!, {r4,r5,r8,r12}\r
1805     bne     .fl_loopRGB555\r
1806 \r
1807     ldmfd   sp!, {r4-r9,lr}\r
1808     bx      lr\r
1809 \r
1810 \r
1811 .fl_32scale_RGB555:\r
1812     stmfd   sp!, {r10}\r
1813     mov     r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1814     orr     r9, r9, #0x00e7\r
1815 \r
1816 #ifdef UNALIGNED_DRAWLINEDEST\r
1817     tst     r0, #2\r
1818     bne     .fl_32scale_RGB555u\r
1819 #endif\r
1820 \r
1821 .fl_loop32scale_RGB555:\r
1822     ldr     r12, [r1], #4\r
1823     ldr     r7,  [r1], #4\r
1824 \r
1825     and     r4, lr, r12,lsl #1\r
1826     ldrh    r4, [r3, r4]\r
1827     and     r5, lr, r12,lsr #7\r
1828     ldrh    r5, [r3, r5]\r
1829     and     r4, r4, r9, lsl #2\r
1830     orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0\r
1831     and     r5, r5, r9, lsl #2\r
1832     sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1\r
1833     add     r4, r4, r6, lsl #16       @ pix_d 0, 1\r
1834     and     r6, lr, r12,lsr #15\r
1835     ldrh    r6, [r3, r6]\r
1836     and     r12,lr, r12,lsr #23\r
1837     ldrh    r12,[r3, r12]\r
1838     and     r6, r6, r9, lsl #2\r
1839     add     r5, r5, r6\r
1840     mov     r5, r5, lsr #1\r
1841     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1842     orr     r5, r5, r6, lsl #16\r
1843 \r
1844     and     r6, lr, r7, lsl #1\r
1845     ldrh    r6, [r3, r6]\r
1846     and     r12,r12,r9, lsl #2\r
1847     add     r5, r5, r12,lsl #14       @ pix_d 2, 3\r
1848     and     r6, r6, r9, lsl #2\r
1849     orr     r6, r12,r6, lsl #16       @ pix_d 4, 5\r
1850 \r
1851     and     r12,lr, r7, lsr #7\r
1852     ldrh    r12,[r3, r12]\r
1853     and     r10,lr, r7, lsr #15\r
1854     ldrh    r10,[r3, r10]\r
1855     and     r12,r12,r9, lsl #2\r
1856     sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1\r
1857     add     r8, r8, r6, lsr #18\r
1858     and     r7, lr, r7, lsr #23\r
1859     ldrh    r7, [r3, r7]\r
1860     and     r10,r10,r9, lsl #2\r
1861     orr     r8, r8, r10,lsl #15\r
1862     add     r8, r8, r12,lsl #15       @ pix_d 6, 7\r
1863     sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2\r
1864     and     r7, r7, r9, lsl #2\r
1865     add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3\r
1866     orr     r10,r10,r7, lsl #16       @ pix_d 8, 9\r
1867 \r
1868     subs    r2, r2, #1\r
1869 \r
1870     stmia   r0!, {r4,r5,r6,r8,r10}\r
1871     bne     .fl_loop32scale_RGB555\r
1872 \r
1873     ldmfd   sp!, {r10}\r
1874     ldmfd   sp!, {r4-r9,lr}\r
1875     bx      lr\r
1876 \r
1877 #ifdef UNALIGNED_DRAWLINEDEST\r
1878     @ unaligned versions of loops\r
1879     @ warning: starts drawing 2bytes before dst\r
1880 \r
1881 .fl_RGB555u:\r
1882     sub     r0, r0, #2              @ initial adjustment\r
1883     mov     r8, #0\r
1884 \r
1885 .fl_loopRGB555u:\r
1886     ldr     r12, [r1], #4\r
1887     ldr     r7,  [r1], #4\r
1888 \r
1889     and     r6, lr, r12,lsl #1\r
1890     ldrh    r6, [r3, r6]\r
1891     and     r5, lr, r12,lsr #7\r
1892     ldrh    r5, [r3, r5]\r
1893     orr     r4, r8, r6, lsl #16\r
1894 \r
1895     and     r6, lr, r12,lsr #15\r
1896     ldrh    r6, [r3, r6]\r
1897     and     r8, lr, r12,lsr #23\r
1898     ldrh    r8, [r3, r8]\r
1899     orr     r5, r5, r6, lsl #16\r
1900 \r
1901     and     r6, lr, r7, lsl #1\r
1902     ldrh    r6, [r3, r6]\r
1903     and     r12,lr, r7, lsr #7\r
1904     ldrh    r12,[r3, r12]\r
1905     orr     r6, r8, r6, lsl #16\r
1906 \r
1907     and     r8, lr, r7, lsr #15\r
1908     ldrh    r8, [r3, r8]\r
1909     and     r7, lr, r7, lsr #23\r
1910 \r
1911     subs    r2, r2, #1\r
1912     orr     r12,r12,r8, lsl #16\r
1913     ldrh    r8, [r3, r7]\r
1914 \r
1915     stmia   r0!, {r4,r5,r6,r12}\r
1916     bne     .fl_loopRGB555u\r
1917 \r
1918     strh    r8, [r0], #2\r
1919 \r
1920     ldmfd   sp!, {r4-r9,lr}\r
1921     bx      lr\r
1922 \r
1923 \r
1924 .fl_32scale_RGB555u:\r
1925     sub     r0, r0, #2              @ initial adjustment\r
1926     mov     r4, #0\r
1927 \r
1928     @ r9  f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1929 .fl_loop32scale_RGB555u:\r
1930     ldr     r12, [r1], #4\r
1931     ldr     r7,  [r1], #4\r
1932 \r
1933     and     r6, lr, r12,lsl #1\r
1934     ldrh    r6, [r3, r6]\r
1935     and     r5, lr, r12,lsr #7\r
1936     ldrh    r5, [r3, r5]\r
1937     and     r6, r6, r9, lsl #2\r
1938     orr     r4, r4, r6, lsl #16       @ r4 = pix_d -1, 0\r
1939 \r
1940     and     r5, r5, r9, lsl #2\r
1941     sub     r8, r5, r5, lsr #2        @ r8 = 3/4 pix_s 1\r
1942     add     r6, r8, r6, lsr #2        @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
1943     orr     r5, r6, r5, lsl #15\r
1944 \r
1945     and     r6, lr, r12,lsr #15\r
1946     ldrh    r6, [r3, r6]\r
1947     and     r12,lr, r12,lsr #23\r
1948     ldrh    r12,[r3, r12]\r
1949     and     r6, r6, r9, lsl #2\r
1950     add     r5, r5, r6, lsl #15       @ r5 = pix_d 1, 2\r
1951 \r
1952     and     r8, lr, r7, lsl #1\r
1953     ldrh    r8, [r3, r8]\r
1954     and     r10,lr, r7, lsr #7\r
1955     ldrh    r10,[r3, r10]\r
1956     and     r12,r12,r9, lsl #2\r
1957     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1958     add     r6, r6, r12,lsr #2\r
1959     orr     r6, r6, r12,lsl #16       @ r6 = pix_d 3, 4\r
1960 \r
1961     and     r8, r8, r9, lsl #2\r
1962     and     r10,r10,r9, lsl #2\r
1963     sub     r12,r10,r10,lsr #2        @ r12 = 3/4 pix_s 5\r
1964     orr     r8, r8, r8, lsl #14\r
1965     add     r8, r8, r12,lsl #16       @ r8 = pix_d 5, 6\r
1966     and     r12,lr, r7, lsr #15\r
1967     ldrh    r12,[r3, r12]\r
1968     and     r7, lr, r7, lsr #23\r
1969     ldrh    r7, [r3, r7]\r
1970     and     r12,r12,r9, lsl #2\r
1971     add     r10,r10,r12\r
1972     mov     r10,r10,    lsr #1\r
1973     sub     r12,r12,r12,lsr #2        @ r12 = 3/4 pix_s 6\r
1974     orr     r10,r10,r12,lsl #16\r
1975     and     r7, r7, r9, lsl #2\r
1976     add     r10,r10,r7, lsl #14       @ r10 = pix_d 7, 8\r
1977 \r
1978     subs    r2, r2, #1\r
1979 \r
1980     stmia   r0!, {r4,r5,r6,r8,r10}\r
1981     mov     r4, r7\r
1982     bne     .fl_loop32scale_RGB555u\r
1983 \r
1984     strh    r4, [r0], #2\r
1985 \r
1986     ldmfd   sp!, {r10}\r
1987     ldmfd   sp!, {r4-r9,lr}\r
1988     bx      lr\r
1989 \r
1990 #endif /* UNALIGNED_DRAWLINEDEST */\r
1991 \r
1992 \r
1993 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1994 \r
1995 @ utility\r
1996 .global blockcpy @ void *dst, void *src, size_t n\r
1997 \r
1998 blockcpy:\r
1999     stmfd   sp!, {r4,r5}\r
2000     mov     r2, r2, lsr #4\r
2001 blockcpy_loop:\r
2002     ldmia   r1!, {r3-r5,r12}\r
2003     subs    r2, r2, #1\r
2004     stmia   r0!, {r3-r5,r12}\r
2005     bne     blockcpy_loop\r
2006     ldmfd   sp!, {r4,r5}\r
2007     bx      lr\r
2008 \r
2009 \r
2010 .global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
2011 \r
2012 blockcpy_or:\r
2013     stmfd   sp!, {r4-r6}\r
2014     orr     r3, r3, r3, lsl #8\r
2015     orr     r3, r3, r3, lsl #16\r
2016     mov     r2, r2, lsr #4\r
2017 blockcpy_loop_or:\r
2018     ldmia   r1!, {r4-r6,r12}\r
2019     subs    r2, r2, #1\r
2020     orr     r4, r4, r3\r
2021     orr     r5, r5, r3\r
2022     orr     r6, r6, r3\r
2023     orr     r12,r12,r3\r
2024     stmia   r0!, {r4-r6,r12}\r
2025     bne     blockcpy_loop_or\r
2026     ldmfd   sp!, {r4-r6}\r
2027     bx      lr\r
2028 \r
2029 @ vim:filetype=armasm\r