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