overdraw eliminated in AS mode
[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 DrawSpritesSHi @ int prio_unused, int sh\r
951 \r
952 DrawSpritesSHi:\r
953     ldr     r3, =DrawScanline\r
954     ldr     r2, =HighLnSpr\r
955     ldr     r12,[r3]\r
956     mov     r3, #(MAX_LINE_SPRITES+2)\r
957     mla     r2, r12, r3, r2\r
958     ldr     r3, [r2]\r
959     ands    r3, r3, #0x7f\r
960     bxeq    lr\r
961 \r
962     stmfd   sp!, {r4-r11,lr}\r
963     mov     r12,#0xff\r
964     strb    r12,[r2,#1]     @ set end marker\r
965     add     r10,r2, #2\r
966     add     r10,r10,r3      @ r10=HighLnSpr end\r
967 \r
968     str     r1, [sp, #-4]   @ no calls after this point\r
969 \r
970 .if OVERRIDE_HIGHCOL\r
971     ldr     r11,=HighCol\r
972     mov     r12,#0xf\r
973     ldr     r11,[r11]\r
974 .else\r
975     ldr     r11,=HighCol\r
976     mov     r12,#0xf\r
977 .endif\r
978     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
979 \r
980 \r
981 DrawSpriteSHi:\r
982     @ draw next sprite\r
983     ldrb    r0, [r10,#-1]!\r
984     ldr     r1, =HighPreSpr\r
985     ldr     r8, [sp, #-4]\r
986     cmp     r0, #0xff\r
987     ldmeqfd sp!, {r4-r11,pc} @ end of list\r
988     and     r0, r0, #0x7f\r
989     add     r0, r1, r0, lsl #3\r
990 \r
991     ldr     r9, [r0, #4]    @ sprite[1]\r
992     mov     r2, r9, asr #16 @ r2=sx\r
993 \r
994     mov     r9, r9, lsl #16\r
995     mov     r3, r9, lsr #31 @ priority\r
996     mov     r9, r9, lsr #16\r
997     orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]\r
998     and     r4, r9, #0x6000\r
999     orr     r9, r9, r4, lsl #16\r
1000     orr     r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1001     cmp     r12,r9, lsr #28 @ sh/hi with pal3?\r
1002     cmpne   r3, #1          @ if not, is hi prio\r
1003     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn\r
1004 \r
1005     ldr     r3, [r0]        @ sprite[0]\r
1006     ldr     r7, =DrawScanline\r
1007     mov     r6, r3, lsr #28\r
1008     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1009     mov     r5, r3, lsr #24\r
1010     and     r5, r5, #7      @ r5=height\r
1011 \r
1012     mov     r0, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1013 \r
1014     ldr     r7, [r7]\r
1015     sub     r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy\r
1016 \r
1017     tst     r9, #0x1000\r
1018     movne   r0, r5, lsl #3\r
1019     subne   r0, r0, #1\r
1020     subne   r7, r0, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1021 \r
1022     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1023     tst     r9, #0x0800\r
1024     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1025     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1026 \r
1027     mov     r8, r8, lsl #21\r
1028     mov     r8, r8, lsr #17\r
1029     and     r7, r7, #7\r
1030     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1031 \r
1032     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1033 \r
1034     orrs    r3, r9, r9, lsl #4\r
1035     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1036 \r
1037     add     r6, r6, #1         @ inc now\r
1038     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1039     b       .dsprShi_loop_enter\r
1040 \r
1041 .dsprShi_loop:\r
1042     subs    r6, r6, #1         @ width--\r
1043     beq     DrawSpriteSHi\r
1044     adds    r0, r0, #8         @ sx+=8\r
1045     add     r8, r8, r5         @ tile+=delta\r
1046 \r
1047 .dsprShi_loop_enter:\r
1048     ble     .dsprShi_loop     @ sx <= 0\r
1049     cmp     r0, #328\r
1050     bge     DrawSpriteSHi\r
1051 \r
1052     mov     r8, r8, lsl #17\r
1053     mov     r8, r8, lsr #17    @ tile&=0x7fff; // Clip tile address\r
1054 \r
1055     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1056     add     r1, r11, r0        @ r1=pdest\r
1057     tst     r2, r2\r
1058     beq     .dsprShi_loop\r
1059 \r
1060     cmp     r12, r9, lsr #28\r
1061     beq     .dsprShi_shadow\r
1062 \r
1063     cmp     r2, r2, ror #4\r
1064     beq     .dsprShi_SingleColor @ tileline singlecolor \r
1065 \r
1066     tst     r9, #0x0800\r
1067     bne     .dsprShi_TileFlip\r
1068 \r
1069     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1070 @ scratch: r4, r7\r
1071 .dsprShi_TileNorm:\r
1072     TileNorm r12\r
1073     b       .dsprShi_loop\r
1074 \r
1075 .dsprShi_TileFlip:\r
1076     TileFlip r12\r
1077     b       .dsprShi_loop\r
1078 \r
1079 .dsprShi_SingleColor:\r
1080     and     r4, r2, #0xf\r
1081     orr     r4, r3, r4\r
1082     orr     r4, r4, r4, lsl #8\r
1083     tst     r0, #1              @ not aligned?\r
1084     strneb  r4, [r1], #1\r
1085     streqh  r4, [r1], #2\r
1086     strh    r4, [r1], #2\r
1087     strh    r4, [r1], #2\r
1088     strh    r4, [r1], #2\r
1089     strneb  r4, [r1], #1\r
1090     b       .dsprShi_loop\r
1091 \r
1092 .dsprShi_shadow:\r
1093     tst     r9, #0x8000\r
1094     beq     .dsprShi_shadow_lowpri\r
1095 \r
1096     cmp     r2, r2, ror #4\r
1097     beq     .dsprShi_singlec_sh\r
1098 \r
1099     tst     r9, #0x0800\r
1100     bne     .dsprShi_TileFlip_sh\r
1101 \r
1102     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1103 .dsprShi_TileNorm_sh:\r
1104     TileNormSh\r
1105     b       .dsprShi_loop\r
1106 \r
1107 .dsprShi_TileFlip_sh:\r
1108     TileFlipSh\r
1109     b       .dsprShi_loop\r
1110 \r
1111 .dsprShi_singlec_sh:\r
1112     cmp     r2, #0xe0000000\r
1113     bcc     .dsprShi_SingleColor   @ normal singlecolor tileline (carry inverted in ARM)\r
1114     tst     r2, #0x10000000\r
1115     bne     .dsprShi_sh_sh\r
1116     TileSingleHi\r
1117     b       .dsprShi_loop\r
1118 \r
1119 .dsprShi_sh_sh:\r
1120     TileSingleSh\r
1121     b       .dsprShi_loop\r
1122 \r
1123 .dsprShi_shadow_lowpri:\r
1124     tst     r9, #0x800\r
1125     bne     .dsprShi_TileFlip_sh_lp\r
1126 \r
1127 .dsprShi_TileNorm_sh_lp:\r
1128     TileNormSh_onlyop_lp\r
1129     b       .dsprShi_loop\r
1130 \r
1131 .dsprShi_TileFlip_sh_lp:\r
1132     TileFlipSh_onlyop_lp\r
1133     b       .dsprShi_loop\r
1134 \r
1135 .pool\r
1136 \r
1137 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1138 \r
1139 .global DrawAllSprites @ int prio, int sh\r
1140 \r
1141 DrawAllSprites:\r
1142     ldr     r3, =rendstatus\r
1143     orr     r1, r1, r0, lsl #1\r
1144     ldr     r12,[r3]\r
1145     tst     r12,#(PDRAW_ACC_SPRITES|PDRAW_SPRITES_MOVED)\r
1146     beq     das_no_prep\r
1147     stmfd   sp!, {r1,lr}\r
1148     and     r0, r12,#PDRAW_DIRTY_SPRITES\r
1149     bic     r12,r12,#(PDRAW_ACC_SPRITES|PDRAW_SPRITES_MOVED)\r
1150     str     r12,[r3]\r
1151     bl      PrepareSprites\r
1152     ldmfd   sp!, {r1,lr}\r
1153 \r
1154 das_no_prep:\r
1155     ldr     r3, =DrawScanline\r
1156     ldr     r2, =HighLnSpr\r
1157     ldr     r12,[r3]\r
1158     mov     r3, #(MAX_LINE_SPRITES+2)\r
1159     mla     r2, r12, r3, r2\r
1160     ldr     r3, [r2]\r
1161     ands    r3, r3, #0x7f\r
1162     bxeq    lr\r
1163 \r
1164     @ time to do some real work\r
1165     stmfd   sp!, {r4-r11,lr}\r
1166     mov     r12,#0xff\r
1167     strb    r12,[r2,#1]     @ set end marker\r
1168     add     r10,r2, #2\r
1169     add     r10,r10,r3      @ r10=HighLnSpr end\r
1170 \r
1171     str     r1, [sp, #-4]   @ no calls after this point\r
1172 \r
1173 .if OVERRIDE_HIGHCOL\r
1174     ldr     r11,=HighCol\r
1175     mov     r12,#0xf\r
1176     ldr     r11,[r11]\r
1177 .else\r
1178     ldr     r11,=HighCol\r
1179     mov     r12,#0xf\r
1180 .endif\r
1181     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
1182 \r
1183 @ + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size\r
1184 @ + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
1185 \r
1186 DrawSprite: @ was: unsigned int *sprite, int sh, int acc_sprites\r
1187     @ draw next sprite\r
1188     ldrb    r0, [r10,#-1]!\r
1189     ldr     r1, =HighPreSpr\r
1190     ldr     r8, [sp, #-4]\r
1191     mov     r2, r0, lsr #7\r
1192     cmp     r0, #0xff\r
1193     ldmeqfd sp!, {r4-r11,pc} @ end of list\r
1194     cmp     r2, r8, lsr #1\r
1195     bne     DrawSprite      @ wrong priority\r
1196     and     r0, r0, #0x7f\r
1197     add     r0, r1, r0, lsl #3\r
1198 \r
1199 @    stmfd   sp!, {r4-r9,r11,lr}\r
1200 @    orr     r8, r2, r1, lsl #4\r
1201 \r
1202     ldr     r3, [r0]        @ sprite[0]\r
1203     ldr     r7, =DrawScanline\r
1204     mov     r6, r3, lsr #28\r
1205     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1206     mov     r5, r3, lsr #24\r
1207     and     r5, r5, #7      @ r5=height\r
1208 \r
1209     mov     r4, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1210 \r
1211     ldr     r7, [r7]\r
1212     ldr     r9, [r0, #4]\r
1213     sub     r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy\r
1214 \r
1215     mov     r2, r9, asr #16 @ r2=sx\r
1216     mov     r9, r9, lsl #16\r
1217     mov     r9, r9, lsr #16\r
1218     orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]\r
1219 \r
1220     tst     r9, #0x1000\r
1221     movne   r4, r5, lsl #3\r
1222     subne   r4, r4, #1\r
1223     subne   r7, r4, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1224 \r
1225     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1226     tst     r9, #0x0800\r
1227     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1228     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1229 \r
1230     mov     r8, r8, lsl #21\r
1231     mov     r8, r8, lsr #17\r
1232     and     r7, r7, #7\r
1233     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1234 \r
1235 .dspr_continue:\r
1236     @ cache some stuff to avoid mem access\r
1237     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1238     and     r4, r9, #0x6000\r
1239     orr     r9, r9, r4, lsl #16\r
1240     orrs    r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1241 \r
1242     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1243     orrmi   r3, r3, #0x40      @ for sh/hi\r
1244 \r
1245     add     r6, r6, #1         @ inc now\r
1246     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1247     b       .dspr_loop_enter\r
1248 \r
1249 .dspr_loop:\r
1250     subs    r6, r6, #1         @ width--\r
1251     beq     DrawSprite\r
1252     adds    r0, r0, #8         @ sx+=8\r
1253     add     r8, r8, r5         @ tile+=delta\r
1254 \r
1255 .dspr_loop_enter:\r
1256     ble     .dspr_loop         @ sx <= 0\r
1257     cmp     r0, #328\r
1258     bge     DrawSprite\r
1259 \r
1260     mov     r8, r8, lsl #17\r
1261     mov     r8, r8, lsr #17    @ tile&=0x7fff; // Clip tile address\r
1262 \r
1263     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1264     add     r1, r11, r0        @ r1=pdest\r
1265     tst     r2, r2\r
1266     beq     .dspr_loop\r
1267 \r
1268     cmp     r12, r9, lsr #28\r
1269     beq     .dspr_shadow\r
1270 \r
1271     cmp     r2, r2, ror #4\r
1272     beq     .dspr_SingleColor @ tileline singlecolor \r
1273 \r
1274     tst     r9, #0x0800\r
1275     bne     .dspr_TileFlip\r
1276 \r
1277     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1278 @ scratch: r4, r7\r
1279 .dspr_TileNorm:\r
1280     TileNorm r12\r
1281     b       .dspr_loop\r
1282 \r
1283 .dspr_TileFlip:\r
1284     TileFlip r12\r
1285     b       .dspr_loop\r
1286 \r
1287 .dspr_singlec_sh:\r
1288     cmp     r2, #0xe0000000\r
1289     bcs     .dspr_loop          @ operator tileline, ignore\r
1290 \r
1291 .dspr_SingleColor:\r
1292     and     r4, r2, #0xf\r
1293     orr     r4, r3, r4\r
1294     orr     r4, r4, r4, lsl #8\r
1295     tst     r0, #1              @ not aligned?\r
1296     strneb  r4, [r1], #1\r
1297     streqh  r4, [r1], #2\r
1298     strh    r4, [r1], #2\r
1299     strh    r4, [r1], #2\r
1300     strh    r4, [r1], #2\r
1301     strneb  r4, [r1], #1\r
1302     b       .dspr_loop\r
1303 \r
1304 .dspr_shadow:\r
1305     cmp     r2, r2, ror #4\r
1306     beq     .dspr_singlec_sh\r
1307 \r
1308     tst     r9, #0x0800\r
1309     bne     .dspr_TileFlip_sh\r
1310 \r
1311     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1312 .dspr_TileNorm_sh:\r
1313     TileNormSh_noop\r
1314     b       .dspr_loop\r
1315 \r
1316 .dspr_TileFlip_sh:\r
1317     TileFlipSh_noop\r
1318     b       .dspr_loop\r
1319 \r
1320 \r
1321 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1322 \r
1323 .global DrawWindow @ int tstart, int tend, int prio, int sh // int *hcache\r
1324 \r
1325 DrawWindow:\r
1326     stmfd   sp!, {r4-r11,lr}\r
1327 \r
1328     ldr     r11, =(Pico+0x22228)  @ Pico.video\r
1329     ldr     r10, =DrawScanline\r
1330     ldrb    r12, [r11, #3]        @ pvid->reg[3]\r
1331 \r
1332     ldr     r10, [r10]\r
1333     ldr     r4,  [r11, #12]\r
1334     mov     r5,  r10, lsr #3\r
1335     and     r10, r10, #7\r
1336     mov     r10, r10, lsl #1      @ r10=ty\r
1337 \r
1338     mov     r12, r12, lsl #10\r
1339 \r
1340     tst     r4, #1                @ 40 cell mode?\r
1341     andne   r12, r12, #0xf000     @ 0x3c<<10\r
1342     andeq   r12, r12, #0xf800\r
1343     addne   r12, r12, r5, lsl #7\r
1344     addeq   r12, r12, r5, lsl #6  @ nametab\r
1345     add     r12, r12, r0, lsl #2  @ +starttile\r
1346 \r
1347     ldr     r6, =rendstatus\r
1348     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
1349     ldr     r6, [r6]\r
1350 \r
1351     @ fetch the first code now\r
1352     ldrh    r7, [lr, r12]\r
1353 \r
1354     ands    r6, r6, #PDRAW_WND_DIFF_PRIO\r
1355     orr     r6, r6, r2\r
1356 \r
1357     eoreq   r8, r2, r7, lsr #15   @ do prio bits differ?\r
1358     cmpeq   r8, #1\r
1359     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
1360 \r
1361     orr     r6, r6, r3, lsl #8    @ shadow mode\r
1362 \r
1363     sub     r8, r1, r0\r
1364 \r
1365     @ cache some stuff to avoid mem access\r
1366 .if OVERRIDE_HIGHCOL\r
1367     ldr     r11,=HighCol\r
1368     mov     r8, r8, lsl #1        @ cells\r
1369     ldr     r11,[r11]\r
1370     mvn     r9, #0                @ r9=prevcode=-1\r
1371     add     r11,r11,#8\r
1372 .else\r
1373     ldr     r11,=(HighCol+8)\r
1374     mov     r8, r8, lsl #1        @ cells\r
1375     mvn     r9, #0                @ r9=prevcode=-1\r
1376 .endif\r
1377     add     r1, r11, r0, lsl #4   @ r1=pdest\r
1378     mov     r0, #0xf\r
1379     b       .dwloop_enter\r
1380 \r
1381     @ r4,r5 are scratch in this loop\r
1382 .dwloop:\r
1383     add     r1, r1, #8\r
1384 .dwloop_nor1:\r
1385     add     r12, r12, #2    @ halfwords\r
1386     ldrh    r7, [lr, r12]   @ r7=code (int, but from unsigned, no sign extend)\r
1387     subs    r8, r8, #1\r
1388     beq     .dwloop_end     @ done\r
1389 \r
1390     eor     r5, r6, r7, lsr #15\r
1391     tst     r5, #1\r
1392     orrne   r6, r6, #2      @ wrong pri\r
1393     bne     .dwloop\r
1394 \r
1395     cmp     r7, r9\r
1396     beq     .dw_samecode    @ we know stuff about this tile already\r
1397 \r
1398 .dwloop_enter:\r
1399     mov     r9, r7          @ remember code\r
1400 \r
1401     movs    r2, r9, lsl #20 @ if (code&0x1000)\r
1402     mov     r2, r2, lsl #1\r
1403     add     r2, r10, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4; addr+=ty\r
1404     eorcs   r2, r2, #0x0e   @ if (code&0x1000) addr^=0xe;\r
1405 \r
1406     and     r3, r9, #0x6000\r
1407     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
1408 \r
1409     ldr     r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1410 \r
1411 .dw_samecode:\r
1412     tst     r6, #0x100\r
1413     bne     .dw_shadow\r
1414 .dw_shadow_done:\r
1415     tst     r2, r2\r
1416     beq     .dwloop              @ tileline blank\r
1417 \r
1418     cmp     r2, r2, ror #4\r
1419     beq     .dw_SingleColor @ tileline singlecolor \r
1420 \r
1421     tst     r9, #0x0800\r
1422     bne     .dw_TileFlip\r
1423 \r
1424     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
1425 .dw_TileNorm:\r
1426     TileNorm r0\r
1427     b       .dwloop\r
1428 \r
1429 .dw_TileFlip:\r
1430     TileFlip r0\r
1431     b       .dwloop\r
1432 \r
1433 .dw_SingleColor:\r
1434     and     r4, r0, r2         @ #0x0000000f\r
1435     orr     r4, r3, r4\r
1436     orr     r4, r4, r4, lsl #8\r
1437     orr     r4, r4, r4, lsl #16\r
1438     mov     r5, r4\r
1439     stmia   r1!, {r4,r5}\r
1440     b       .dwloop_nor1       @ we incremeted r1 ourselves\r
1441 \r
1442 .dw_shadow:\r
1443     tst     r6, #1             @ hi pri?\r
1444     orreq   r3, r3, #0x40\r
1445     beq     .dw_shadow_done\r
1446     ldr     r4, [r1]\r
1447     mov     r5, #0x3f\r
1448     orr     r5, r5, r5, lsl #8\r
1449     orr     r5, r5, r5, lsl #16\r
1450     and     r4, r4, r5\r
1451     str     r4, [r1]\r
1452     ldr     r4, [r1,#4]\r
1453     and     r4, r4, r5\r
1454     str     r4, [r1,#4]\r
1455     b       .dw_shadow_done\r
1456 \r
1457 .dwloop_end:\r
1458     ldr     r0, =rendstatus\r
1459     ldr     r1, [r0]\r
1460     and     r6, r6, #2\r
1461     orr     r1, r1, r6\r
1462     str     r1, [r0]\r
1463 \r
1464     ldmfd   sp!, {r4-r11,r12}\r
1465     bx      r12\r
1466 \r
1467 \r
1468 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1469 \r
1470 \r
1471 @ hilights 2 pixels in RGB444/BGR444 format\r
1472 .macro TileDoShHi2Pixels444 reg\r
1473     mov     \reg, \reg, ror #12\r
1474     adds    \reg, \reg, #0x40000000\r
1475     orrcs   \reg, \reg, #0xf0000000\r
1476     mov     \reg, \reg, ror #28\r
1477     adds    \reg, \reg, #0x40000000\r
1478     orrcs   \reg, \reg, #0xf0000000\r
1479     mov     \reg, \reg, ror #28\r
1480     adds    \reg, \reg, #0x40000000\r
1481     orrcs   \reg, \reg, #0xf0000000\r
1482     mov     \reg, \reg, ror #24\r
1483     adds    \reg, \reg, #0x40000000\r
1484     orrcs   \reg, \reg, #0xf0000000\r
1485     mov     \reg, \reg, ror #28\r
1486     adds    \reg, \reg, #0x40000000\r
1487     orrcs   \reg, \reg, #0xf0000000\r
1488     mov     \reg, \reg, ror #28\r
1489     adds    \reg, \reg, #0x40000000\r
1490     orrcs   \reg, \reg, #0xf0000000\r
1491     mov     \reg, \reg, ror #12\r
1492 .endm\r
1493 \r
1494 \r
1495 .global FinalizeLineBGR444 @ int sh\r
1496 \r
1497 FinalizeLineBGR444:\r
1498     stmfd   sp!, {r4-r6,lr}\r
1499     mov     r6, r0\r
1500     ldr     lr, =(Pico+0x22228)  @ Pico.video\r
1501     ldr     r0, =DrawLineDest\r
1502     ldrb    r12, [lr, #12]\r
1503     ldr     r0, [r0]\r
1504     sub     r3, lr, #0x128       @ r3=Pico.cram\r
1505 \r
1506     tst     r12, #1\r
1507     movne   r2, #320/4           @ len\r
1508     bne     .fl_no32colBGR444\r
1509     ldr     r4, =PicoOpt\r
1510     mov     r2, #256/4\r
1511     ldr     r4, [r4]\r
1512     tst     r4, #0x100\r
1513     addeq   r0, r0, #32*2\r
1514 \r
1515 .fl_no32colBGR444:\r
1516     tst     r6, r6\r
1517     beq     .fl_noshBGR444\r
1518 \r
1519     ldr     r4, =HighPal\r
1520 \r
1521     ldrb    r12, [lr, #-0x1a]      @ 0x2220e ~ dirtyPal\r
1522     tst     r12, r12\r
1523     moveq   r3, r4\r
1524     beq     .fl_noshBGR444\r
1525     mov     r12, #0\r
1526     strb    r12, [lr, #-0x1a]\r
1527 \r
1528     mov     lr, #0x40/8\r
1529     @ copy pal:\r
1530 .fl_loopcpBGR444:\r
1531     ldmia   r3!, {r1,r5,r6,r12}\r
1532     subs    lr, lr, #1\r
1533     stmia   r4!, {r1,r5,r6,r12}\r
1534     bne     .fl_loopcpBGR444\r
1535 \r
1536     @ shadowed pixels:\r
1537     mov     r12,    #0x0077\r
1538     orr     r12,r12,#0x0700\r
1539     orr     r12,r12,r12,lsl #16\r
1540     sub     r3, r3, #0x40*2\r
1541     add     r5, r4, #0x80*2\r
1542     mov     lr, #0x40/4\r
1543 .fl_loopcpBGR444_sh:\r
1544     ldmia   r3!, {r1,r6}\r
1545     subs    lr, lr, #1\r
1546     and     r1, r12, r1, lsr #1\r
1547     and     r6, r12, r6, lsr #1\r
1548     stmia   r4!, {r1,r6}\r
1549     stmia   r5!, {r1,r6}\r
1550     bne     .fl_loopcpBGR444_sh\r
1551 \r
1552     @ hilighted pixels:\r
1553     sub     r3, r3, #0x40*2\r
1554     mov     lr, #0x40/2\r
1555 .fl_loopcpBGR444_hi:\r
1556     ldr     r1, [r3], #4\r
1557     TileDoShHi2Pixels444 r1\r
1558     str     r1, [r4], #4\r
1559     subs    lr, lr, #1\r
1560     bne     .fl_loopcpBGR444_hi\r
1561 \r
1562     sub     r3, r4, #0x40*3*2\r
1563     mov     r6, #1\r
1564 \r
1565 \r
1566 .fl_noshBGR444:\r
1567     ldr     r12,=rendstatus\r
1568     eors    r6, r6, #1          @ sh is 0\r
1569     ldr     r12,[r12]\r
1570     mov     lr, #0xff\r
1571     tstne   r12,#PDRAW_ACC_SPRITES\r
1572 \r
1573 .if OVERRIDE_HIGHCOL\r
1574     ldr     r1, =HighCol\r
1575     movne   lr, #0x3f\r
1576     ldr     r1, [r1]\r
1577     mov     lr, lr, lsl #1\r
1578     add     r1, r1, #8\r
1579 .else\r
1580     ldr     r1, =(HighCol+8)\r
1581     movne   lr, #0x3f\r
1582     mov     lr, lr, lsl #1\r
1583 .endif\r
1584 \r
1585 .fl_loopBGR444:\r
1586     ldr     r12, [r1], #4\r
1587     subs    r2, r2, #1\r
1588 \r
1589     and     r4, lr, r12, lsl #1\r
1590     ldrh    r4, [r3, r4]\r
1591     and     r5, lr, r12, lsr #7\r
1592     ldrh    r5, [r3, r5]\r
1593     and     r6, lr, r12, lsr #15\r
1594     ldrh    r6, [r3, r6]\r
1595     and     r12,lr, r12, lsr #23\r
1596     ldrh    r12,[r3, r12]              @ 1c.i.\r
1597     orr     r4, r4, r5, lsl #16\r
1598     orr     r5, r6, r12,lsl #16\r
1599 \r
1600     stmia   r0!, {r4,r5}\r
1601     bne     .fl_loopBGR444\r
1602 \r
1603 \r
1604     ldmfd   sp!, {r4-r6,lr}\r
1605     bx lr\r
1606 \r
1607 \r
1608 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1609 \r
1610 \r
1611 @ hilights 2 pixels in RGB555/BGR555 format\r
1612 .macro TileDoShHi2Pixels555 reg\r
1613     adds    \reg, \reg, #0x40000000\r
1614     orrcs   \reg, \reg, #0xf0000000\r
1615     mov     \reg, \reg, ror #27\r
1616     adds    \reg, \reg, #0x40000000\r
1617     orrcs   \reg, \reg, #0xf0000000\r
1618     mov     \reg, \reg, ror #26\r
1619     adds    \reg, \reg, #0x40000000\r
1620     orrcs   \reg, \reg, #0xf0000000\r
1621     mov     \reg, \reg, ror #27\r
1622     adds    \reg, \reg, #0x40000000\r
1623     orrcs   \reg, \reg, #0xf0000000\r
1624     mov     \reg, \reg, ror #27\r
1625     adds    \reg, \reg, #0x40000000\r
1626     orrcs   \reg, \reg, #0xf0000000\r
1627     mov     \reg, \reg, ror #26\r
1628     adds    \reg, \reg, #0x40000000\r
1629     orrcs   \reg, \reg, #0xf0000000\r
1630     mov     \reg, \reg, ror #27\r
1631 .endm\r
1632 \r
1633 \r
1634 @ Convert 0000bbb0 ggg0rrr0\r
1635 @ to      rrrrrggg gggbbbbb\r
1636 \r
1637 @ r2,r3,r9 - scratch, lr = 0x001c001c, r8 = 0x00030003\r
1638 .macro convRGB565 reg\r
1639     and     r2,   lr,   \reg,lsl #1\r
1640     and     r9,   r8,   \reg,lsr #2\r
1641     orr     r2,   r2,   r9           @ r2=red\r
1642     and     r3,   lr,   \reg,lsr #7\r
1643     and     r9,   r8,   \reg,lsr #10\r
1644     orr     r3,   r3,   r9           @ r3=blue\r
1645     and     \reg, \reg, lr,  lsl #3\r
1646     orr     \reg, \reg, \reg,lsl #3  @ green\r
1647     orr     \reg, \reg, r2,  lsl #11 @ add red back\r
1648     orr     \reg, \reg, r3           @ add blue back\r
1649 .endm\r
1650 \r
1651 .global vidConvCpyRGB565\r
1652 \r
1653 vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1654     stmfd   sp!, {r4-r9,lr}\r
1655 \r
1656     mov     r12, r2, lsr #3  @ repeats\r
1657     mov     lr, #0x001c0000\r
1658     orr     lr, lr,  #0x01c  @ lr == pattern 0x001c001c\r
1659     mov     r8, #0x00030000\r
1660     orr     r8, r8,  #0x003\r
1661 \r
1662 .loopRGB565:\r
1663     ldmia   r1!, {r4-r7}\r
1664     subs    r12, r12, #1\r
1665     convRGB565 r4\r
1666     str     r4, [r0], #4\r
1667     convRGB565 r5\r
1668     str     r5, [r0], #4\r
1669     convRGB565 r6\r
1670     str     r6, [r0], #4\r
1671     convRGB565 r7\r
1672     str     r7, [r0], #4\r
1673 \r
1674     bgt     .loopRGB565\r
1675 \r
1676     ldmfd   sp!, {r4-r9,lr}\r
1677     bx      lr\r
1678 \r
1679 \r
1680 \r
1681 .global FinalizeLineRGB555 @ int sh\r
1682 \r
1683 FinalizeLineRGB555:\r
1684     stmfd   sp!, {r4-r8,lr}\r
1685     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
1686     ldr     r4, =HighPal\r
1687 \r
1688     ldrb    r7, [r8, #-0x1a]     @ 0x2220e ~ dirtyPal\r
1689     mov     r6, r0\r
1690     mov     r1, #0\r
1691     tst     r7, r7\r
1692     beq     .fl_noconvRGB555\r
1693     strb    r1, [r8, #-0x1a]\r
1694     sub     r1, r8, #0x128       @ r1=Pico.cram\r
1695     mov     r0, r4\r
1696     mov     r2, #0x40\r
1697     bl      vidConvCpyRGB565\r
1698 \r
1699 .fl_noconvRGB555:\r
1700     mov     r3, r4\r
1701     tst     r6, r6\r
1702     beq     .fl_noshRGB555\r
1703     tst     r7, r7\r
1704     beq     .fl_noshRGB555\r
1705 \r
1706     @ shadowed pixels:\r
1707     mov     r12,    #0x008e\r
1708     orr     r12,r12,#0x7300\r
1709     orr     r12,r12,r12,lsl #16\r
1710     add     r4, r3, #0x40*2\r
1711     add     r5, r3, #0xc0*2\r
1712     mov     lr, #0x40/4\r
1713 .fl_loopcpRGB555_sh:\r
1714     ldmia   r3!, {r1,r6}\r
1715     subs    lr, lr, #1\r
1716     and     r1, r12, r1, lsr #1\r
1717     and     r6, r12, r6, lsr #1\r
1718     stmia   r4!, {r1,r6}\r
1719     stmia   r5!, {r1,r6}\r
1720     bne     .fl_loopcpRGB555_sh\r
1721 \r
1722     @ hilighted pixels:\r
1723     sub     r3, r3, #0x40*2\r
1724     mov     lr, #0x40/2\r
1725 .fl_loopcpRGB555_hi:\r
1726     ldr     r1, [r3], #4\r
1727     TileDoShHi2Pixels555 r1\r
1728     str     r1, [r4], #4\r
1729     subs    lr, lr, #1\r
1730     bne     .fl_loopcpRGB555_hi\r
1731 \r
1732     sub     r3, r3, #0x40*2\r
1733     mov     r6, #1\r
1734 \r
1735 .fl_noshRGB555:\r
1736     ldr     r12,=rendstatus\r
1737     eors    r6, r6, #1          @ sh is 0\r
1738     ldr     r12,[r12]\r
1739     mov     lr, #0xff\r
1740     tstne   r12,#PDRAW_ACC_SPRITES\r
1741     movne   lr, #0x3f\r
1742 \r
1743 .if OVERRIDE_HIGHCOL\r
1744     ldr     r1, =HighCol\r
1745     ldr     r0, =DrawLineDest\r
1746     ldr     r1, [r1]\r
1747     ldr     r0, [r0]\r
1748     add     r1, r1, #8\r
1749 .else\r
1750     ldr     r0, =DrawLineDest\r
1751     ldr     r1, =(HighCol+8)\r
1752     ldr     r0, [r0]\r
1753 .endif\r
1754 \r
1755     ldrb    r12, [r8, #12]\r
1756     mov     lr, lr, lsl #1\r
1757 \r
1758     tst     r12, #1\r
1759     movne   r2, #320/8           @ len\r
1760     bne     .fl_no32colRGB555\r
1761     ldr     r4, =PicoOpt\r
1762     mov     r2, #256/8\r
1763     ldr     r4, [r4]\r
1764     tst     r4, #0x4000\r
1765     bne     .fl_32scale_RGB555\r
1766     tst     r4, #0x0100\r
1767     addeq   r0, r0, #32*2\r
1768 \r
1769 .fl_no32colRGB555:\r
1770 \r
1771 .if UNALIGNED_DRAWLINEDEST\r
1772     @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1773     tst     r0, #2\r
1774     bne     .fl_RGB555u\r
1775 .endif\r
1776 \r
1777 .fl_loopRGB555:\r
1778     ldr     r12, [r1], #4\r
1779     ldr     r7,  [r1], #4\r
1780 \r
1781     and     r4, lr, r12, lsl #1\r
1782     ldrh    r4, [r3, r4]\r
1783     and     r5, lr, r12, lsr #7\r
1784     ldrh    r5, [r3, r5]\r
1785     and     r6, lr, r12, lsr #15\r
1786     ldrh    r6, [r3, r6]\r
1787     orr     r4, r4, r5, lsl #16\r
1788 \r
1789     and     r5, lr, r12, lsr #23\r
1790     ldrh    r5, [r3, r5]\r
1791     and     r8, lr, r7, lsl #1\r
1792     ldrh    r8, [r3, r8]\r
1793     orr     r5, r6, r5, lsl #16\r
1794 \r
1795     and     r6, lr, r7, lsr #7\r
1796     ldrh    r6, [r3, r6]\r
1797     and     r12,lr, r7, lsr #15\r
1798     ldrh    r12,[r3, r12]\r
1799     and     r7, lr, r7, lsr #23\r
1800     ldrh    r7, [r3, r7]\r
1801     orr     r8, r8, r6, lsl #16\r
1802 \r
1803     subs    r2, r2, #1\r
1804     orr     r12,r12, r7, lsl #16\r
1805 \r
1806     stmia   r0!, {r4,r5,r8,r12}\r
1807     bne     .fl_loopRGB555\r
1808 \r
1809     ldmfd   sp!, {r4-r8,lr}\r
1810     bx      lr\r
1811 \r
1812 \r
1813 .fl_32scale_RGB555:\r
1814     stmfd   sp!, {r9,r10}\r
1815     mov     r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1816     orr     r9, r9, #0x00e7\r
1817 \r
1818 .if UNALIGNED_DRAWLINEDEST\r
1819     tst     r0, #2\r
1820     bne     .fl_32scale_RGB555u\r
1821 .endif\r
1822 \r
1823 .fl_loop32scale_RGB555:\r
1824     ldr     r12, [r1], #4\r
1825     ldr     r7,  [r1], #4\r
1826 \r
1827     and     r4, lr, r12,lsl #1\r
1828     ldrh    r4, [r3, r4]\r
1829     and     r5, lr, r12,lsr #7\r
1830     ldrh    r5, [r3, r5]\r
1831     and     r4, r4, r9, lsl #2\r
1832     orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0\r
1833     and     r5, r5, r9, lsl #2\r
1834     sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1\r
1835     add     r4, r4, r6, lsl #16       @ pix_d 0, 1\r
1836     and     r6, lr, r12,lsr #15\r
1837     ldrh    r6, [r3, r6]\r
1838     and     r12,lr, r12,lsr #23\r
1839     ldrh    r12,[r3, r12]\r
1840     and     r6, r6, r9, lsl #2\r
1841     add     r5, r5, r6\r
1842     mov     r5, r5, lsr #1\r
1843     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1844     orr     r5, r5, r6, lsl #16\r
1845 \r
1846     and     r6, lr, r7, lsl #1\r
1847     ldrh    r6, [r3, r6]\r
1848     and     r12,r12,r9, lsl #2\r
1849     add     r5, r5, r12,lsl #14       @ pix_d 2, 3\r
1850     and     r6, r6, r9, lsl #2\r
1851     orr     r6, r12,r6, lsl #16       @ pix_d 4, 5\r
1852 \r
1853     and     r12,lr, r7, lsr #7\r
1854     ldrh    r12,[r3, r12]\r
1855     and     r10,lr, r7, lsr #15\r
1856     ldrh    r10,[r3, r10]\r
1857     and     r12,r12,r9, lsl #2\r
1858     sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1\r
1859     add     r8, r8, r6, lsr #18\r
1860     and     r7, lr, r7, lsr #23\r
1861     ldrh    r7, [r3, r7]\r
1862     and     r10,r10,r9, lsl #2\r
1863     orr     r8, r8, r10,lsl #15\r
1864     add     r8, r8, r12,lsl #15       @ pix_d 6, 7\r
1865     sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2\r
1866     and     r7, r7, r9, lsl #2\r
1867     add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3\r
1868     orr     r10,r10,r7, lsl #16       @ pix_d 8, 9\r
1869 \r
1870     subs    r2, r2, #1\r
1871 \r
1872     stmia   r0!, {r4,r5,r6,r8,r10}\r
1873     bne     .fl_loop32scale_RGB555\r
1874 \r
1875     ldmfd   sp!, {r9,r10}\r
1876     ldmfd   sp!, {r4-r8,lr}\r
1877     bx      lr\r
1878 \r
1879 .if UNALIGNED_DRAWLINEDEST\r
1880     @ unaligned versions of loops\r
1881     @ warning: starts drawing 2bytes before dst\r
1882 \r
1883 .fl_RGB555u:\r
1884     sub     r0, r0, #2              @ initial adjustment\r
1885     mov     r8, #0\r
1886 \r
1887 .fl_loopRGB555u:\r
1888     ldr     r12, [r1], #4\r
1889     ldr     r7,  [r1], #4\r
1890 \r
1891     and     r6, lr, r12,lsl #1\r
1892     ldrh    r6, [r3, r6]\r
1893     and     r5, lr, r12,lsr #7\r
1894     ldrh    r5, [r3, r5]\r
1895     orr     r4, r8, r6, lsl #16\r
1896 \r
1897     and     r6, lr, r12,lsr #15\r
1898     ldrh    r6, [r3, r6]\r
1899     and     r8, lr, r12,lsr #23\r
1900     ldrh    r8, [r3, r8]\r
1901     orr     r5, r5, r6, lsl #16\r
1902 \r
1903     and     r6, lr, r7, lsl #1\r
1904     ldrh    r6, [r3, r6]\r
1905     and     r12,lr, r7, lsr #7\r
1906     ldrh    r12,[r3, r12]\r
1907     orr     r6, r8, r6, lsl #16\r
1908 \r
1909     and     r8, lr, r7, lsr #15\r
1910     ldrh    r8, [r3, r8]\r
1911     and     r7, lr, r7, lsr #23\r
1912 \r
1913     subs    r2, r2, #1\r
1914     orr     r12,r12,r8, lsl #16\r
1915     ldrh    r8, [r3, r7]\r
1916 \r
1917     stmia   r0!, {r4,r5,r6,r12}\r
1918     bne     .fl_loopRGB555u\r
1919 \r
1920     strh    r8, [r0], #2\r
1921 \r
1922     ldmfd   sp!, {r4-r8,lr}\r
1923     bx      lr\r
1924 \r
1925 \r
1926 .fl_32scale_RGB555u:\r
1927     sub     r0, r0, #2              @ initial adjustment\r
1928     mov     r4, #0\r
1929 \r
1930     @ r9  f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1931 .fl_loop32scale_RGB555u:\r
1932     ldr     r12, [r1], #4\r
1933     ldr     r7,  [r1], #4\r
1934 \r
1935     and     r6, lr, r12,lsl #1\r
1936     ldrh    r6, [r3, r6]\r
1937     and     r5, lr, r12,lsr #7\r
1938     ldrh    r5, [r3, r5]\r
1939     and     r6, r6, r9, lsl #2\r
1940     orr     r4, r4, r6, lsl #16       @ r4 = pix_d -1, 0\r
1941 \r
1942     and     r5, r5, r9, lsl #2\r
1943     sub     r8, r5, r5, lsr #2        @ r8 = 3/4 pix_s 1\r
1944     add     r6, r8, r6, lsr #2        @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
1945     orr     r5, r6, r5, lsl #15\r
1946 \r
1947     and     r6, lr, r12,lsr #15\r
1948     ldrh    r6, [r3, r6]\r
1949     and     r12,lr, r12,lsr #23\r
1950     ldrh    r12,[r3, r12]\r
1951     and     r6, r6, r9, lsl #2\r
1952     add     r5, r5, r6, lsl #15       @ r5 = pix_d 1, 2\r
1953 \r
1954     and     r8, lr, r7, lsl #1\r
1955     ldrh    r8, [r3, r8]\r
1956     and     r10,lr, r7, lsr #7\r
1957     ldrh    r10,[r3, r10]\r
1958     and     r12,r12,r9, lsl #2\r
1959     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1960     add     r6, r6, r12,lsr #2\r
1961     orr     r6, r6, r12,lsl #16       @ r6 = pix_d 3, 4\r
1962 \r
1963     and     r8, r8, r9, lsl #2\r
1964     and     r10,r10,r9, lsl #2\r
1965     sub     r12,r10,r10,lsr #2        @ r12 = 3/4 pix_s 5\r
1966     orr     r8, r8, r8, lsl #14\r
1967     add     r8, r8, r12,lsl #16       @ r8 = pix_d 5, 6\r
1968     and     r12,lr, r7, lsr #15\r
1969     ldrh    r12,[r3, r12]\r
1970     and     r7, lr, r7, lsr #23\r
1971     ldrh    r7, [r3, r7]\r
1972     and     r12,r12,r9, lsl #2\r
1973     add     r10,r10,r12\r
1974     mov     r10,r10,    lsr #1\r
1975     sub     r12,r12,r12,lsr #2        @ r12 = 3/4 pix_s 6\r
1976     orr     r10,r10,r12,lsl #16\r
1977     and     r7, r7, r9, lsl #2\r
1978     add     r10,r10,r7, lsl #14       @ r10 = pix_d 7, 8\r
1979 \r
1980     subs    r2, r2, #1\r
1981 \r
1982     stmia   r0!, {r4,r5,r6,r8,r10}\r
1983     mov     r4, r7\r
1984     bne     .fl_loop32scale_RGB555u\r
1985 \r
1986     strh    r4, [r0], #2\r
1987 \r
1988     ldmfd   sp!, {r9,r10}\r
1989     ldmfd   sp!, {r4-r8,lr}\r
1990     bx      lr\r
1991 \r
1992 .endif @ UNALIGNED_DRAWLINEDEST\r
1993 \r
1994 \r
1995 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1996 \r
1997 @ utility\r
1998 .global blockcpy @ void *dst, void *src, size_t n\r
1999 \r
2000 blockcpy:\r
2001     stmfd   sp!, {r4,r5}\r
2002     mov     r2, r2, lsr #4\r
2003 blockcpy_loop:\r
2004     ldmia   r1!, {r3-r5,r12}\r
2005     subs    r2, r2, #1\r
2006     stmia   r0!, {r3-r5,r12}\r
2007     bne     blockcpy_loop\r
2008     ldmfd   sp!, {r4,r5}\r
2009     bx      lr\r
2010 \r
2011 \r
2012 .global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
2013 \r
2014 blockcpy_or:\r
2015     stmfd   sp!, {r4-r6}\r
2016     orr     r3, r3, r3, lsl #8\r
2017     orr     r3, r3, r3, lsl #16\r
2018     mov     r2, r2, lsr #4\r
2019 blockcpy_loop_or:\r
2020     ldmia   r1!, {r4-r6,r12}\r
2021     subs    r2, r2, #1\r
2022     orr     r4, r4, r3\r
2023     orr     r5, r5, r3\r
2024     orr     r6, r6, r3\r
2025     orr     r12,r12,r3\r
2026     stmia   r0!, {r4-r6,r12}\r
2027     bne     blockcpy_loop_or\r
2028     ldmfd   sp!, {r4-r6}\r
2029     bx      lr\r
2030 \r