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