removed Cyclone idle debug
[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 Scanline\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, =Scanline         @ 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+=Scanline<<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, =Scanline\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+(Scanline<<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, =Scanline\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=Scanline-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     r6, #0x4000\r
1136     tstne   r6, #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, =Scanline\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     teqne   r2, r7, lsr #15       @ do prio bits differ?\r
1298     ldmnefd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
1299 \r
1300     orr     r6, r6, r3, lsl #8    @ shadow mode\r
1301 \r
1302     sub     r8, r1, r0\r
1303 \r
1304     @ cache some stuff to avoid mem access\r
1305 .if OVERRIDE_HIGHCOL\r
1306     ldr     r11,=HighCol\r
1307     mov     r8, r8, lsl #1        @ cells\r
1308     ldr     r11,[r11]\r
1309     mvn     r9, #0                @ r9=prevcode=-1\r
1310     add     r11,r11,#8\r
1311 .else\r
1312     ldr     r11,=(HighCol+8)\r
1313     mov     r8, r8, lsl #1        @ cells\r
1314     mvn     r9, #0                @ r9=prevcode=-1\r
1315 .endif\r
1316     add     r1, r11, r0, lsl #4   @ r1=pdest\r
1317     mov     r0, #0xf\r
1318     b       .dwloop_enter\r
1319 \r
1320     @ r4,r5 are scratch in this loop\r
1321 .dwloop:\r
1322     add     r1, r1, #8\r
1323 .dwloop_nor1:\r
1324     add     r12, r12, #2    @ halfwords\r
1325     ldrh    r7, [lr, r12]   @ r7=code (int, but from unsigned, no sign extend)\r
1326     subs    r8, r8, #1\r
1327     beq     .dwloop_end     @ done\r
1328 \r
1329     eor     r5, r6, r7, lsr #15\r
1330     tst     r5, #1\r
1331     orrne   r6, r6, #2      @ wrong pri\r
1332     bne     .dwloop\r
1333 \r
1334     cmp     r7, r9\r
1335     beq     .dw_samecode    @ we know stuff about this tile already\r
1336 \r
1337 .dwloop_enter:\r
1338     mov     r9, r7          @ remember code\r
1339 \r
1340     movs    r2, r9, lsl #20 @ if (code&0x1000)\r
1341     mov     r2, r2, lsl #1\r
1342     add     r2, r10, r2, lsr #17 @ r2=addr=(code&0x7ff)<<4; addr+=ty\r
1343     eorcs   r2, r2, #0x0e   @ if (code&0x1000) addr^=0xe;\r
1344 \r
1345     and     r3, r9, #0x6000\r
1346     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
1347 \r
1348     ldr     r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1349 \r
1350 .dw_samecode:\r
1351     tst     r6, #0x100\r
1352     bne     .dw_shadow\r
1353 .dw_shadow_done:\r
1354     tst     r2, r2\r
1355     beq     .dwloop              @ tileline blank\r
1356 \r
1357     cmp     r2, r2, ror #4\r
1358     beq     .dw_SingleColor @ tileline singlecolor \r
1359 \r
1360     tst     r9, #0x0800\r
1361     bne     .dw_TileFlip\r
1362 \r
1363     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
1364 .dw_TileNorm:\r
1365     TileNorm r0\r
1366     b       .dwloop\r
1367 \r
1368 .dw_TileFlip:\r
1369     TileFlip r0\r
1370     b       .dwloop\r
1371 \r
1372 .dw_SingleColor:\r
1373     and     r4, r0, r2         @ #0x0000000f\r
1374     orr     r4, r3, r4\r
1375     orr     r4, r4, r4, lsl #8\r
1376     orr     r4, r4, r4, lsl #16\r
1377     mov     r5, r4\r
1378     stmia   r1!, {r4,r5}\r
1379     b       .dwloop_nor1       @ we incremeted r1 ourselves\r
1380 \r
1381 .dw_shadow:\r
1382     tst     r6, #1             @ hi pri?\r
1383     orreq   r3, r3, #0x40\r
1384     beq     .dw_shadow_done\r
1385     ldr     r4, [r1]\r
1386     mov     r5, #0x3f\r
1387     orr     r5, r5, r5, lsl #8\r
1388     orr     r5, r5, r5, lsl #16\r
1389     and     r4, r4, r5\r
1390     str     r4, [r1]\r
1391     ldr     r4, [r1,#4]\r
1392     and     r4, r4, r5\r
1393     str     r4, [r1,#4]\r
1394     b       .dw_shadow_done\r
1395 \r
1396 .dwloop_end:\r
1397     ldr     r0, =rendstatus\r
1398     ldr     r1, [r0]\r
1399     and     r6, r6, #2\r
1400     orr     r1, r1, r6\r
1401     str     r1, [r0]\r
1402 \r
1403     ldmfd   sp!, {r4-r11,r12}\r
1404     bx      r12\r
1405 \r
1406 \r
1407 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1408 \r
1409 \r
1410 @ hilights 2 pixels in RGB444/BGR444 format\r
1411 .macro TileDoShHi2Pixels444 reg\r
1412     mov     \reg, \reg, ror #12\r
1413     adds    \reg, \reg, #0x40000000\r
1414     orrcs   \reg, \reg, #0xf0000000\r
1415     mov     \reg, \reg, ror #28\r
1416     adds    \reg, \reg, #0x40000000\r
1417     orrcs   \reg, \reg, #0xf0000000\r
1418     mov     \reg, \reg, ror #28\r
1419     adds    \reg, \reg, #0x40000000\r
1420     orrcs   \reg, \reg, #0xf0000000\r
1421     mov     \reg, \reg, ror #24\r
1422     adds    \reg, \reg, #0x40000000\r
1423     orrcs   \reg, \reg, #0xf0000000\r
1424     mov     \reg, \reg, ror #28\r
1425     adds    \reg, \reg, #0x40000000\r
1426     orrcs   \reg, \reg, #0xf0000000\r
1427     mov     \reg, \reg, ror #28\r
1428     adds    \reg, \reg, #0x40000000\r
1429     orrcs   \reg, \reg, #0xf0000000\r
1430     mov     \reg, \reg, ror #12\r
1431 .endm\r
1432 \r
1433 \r
1434 .global FinalizeLineBGR444 @ int sh\r
1435 \r
1436 FinalizeLineBGR444:\r
1437     stmfd   sp!, {r4-r6,lr}\r
1438     mov     r6, r0\r
1439     ldr     lr, =(Pico+0x22228)  @ Pico.video\r
1440     ldr     r0, =DrawLineDest\r
1441     ldrb    r12, [lr, #12]\r
1442     ldr     r0, [r0]\r
1443     sub     r3, lr, #0x128       @ r3=Pico.cram\r
1444 \r
1445     tst     r12, #1\r
1446     movne   r2, #320/4           @ len\r
1447     bne     .fl_no32colBGR444\r
1448     ldr     r4, =PicoOpt\r
1449     mov     r2, #256/4\r
1450     ldr     r4, [r4]\r
1451     tst     r4, #0x100\r
1452     addeq   r0, r0, #32*2\r
1453 \r
1454 .fl_no32colBGR444:\r
1455     tst     r6, r6\r
1456     beq     .fl_noshBGR444\r
1457 \r
1458     ldr     r4, =HighPal\r
1459 \r
1460     ldrb    r12, [lr, #-0x1a]      @ 0x2220e ~ dirtyPal\r
1461     tst     r12, r12\r
1462     moveq   r3, r4\r
1463     beq     .fl_noshBGR444\r
1464     mov     r12, #0\r
1465     strb    r12, [lr, #-0x1a]\r
1466 \r
1467     mov     lr, #0x40/8\r
1468     @ copy pal:\r
1469 .fl_loopcpBGR444:\r
1470     ldmia   r3!, {r1,r5,r6,r12}\r
1471     subs    lr, lr, #1\r
1472     stmia   r4!, {r1,r5,r6,r12}\r
1473     bne     .fl_loopcpBGR444\r
1474 \r
1475     @ shadowed pixels:\r
1476     mov     r12,    #0x0077\r
1477     orr     r12,r12,#0x0700\r
1478     orr     r12,r12,r12,lsl #16\r
1479     sub     r3, r3, #0x40*2\r
1480     add     r5, r4, #0x80*2\r
1481     mov     lr, #0x40/4\r
1482 .fl_loopcpBGR444_sh:\r
1483     ldmia   r3!, {r1,r6}\r
1484     subs    lr, lr, #1\r
1485     and     r1, r12, r1, lsr #1\r
1486     and     r6, r12, r6, lsr #1\r
1487     stmia   r4!, {r1,r6}\r
1488     stmia   r5!, {r1,r6}\r
1489     bne     .fl_loopcpBGR444_sh\r
1490 \r
1491     @ hilighted pixels:\r
1492     sub     r3, r3, #0x40*2\r
1493     mov     lr, #0x40/2\r
1494 .fl_loopcpBGR444_hi:\r
1495     ldr     r1, [r3], #4\r
1496     TileDoShHi2Pixels444 r1\r
1497     str     r1, [r4], #4\r
1498     subs    lr, lr, #1\r
1499     bne     .fl_loopcpBGR444_hi\r
1500 \r
1501     sub     r3, r4, #0x40*3*2\r
1502     mov     r6, #1\r
1503 \r
1504 \r
1505 .fl_noshBGR444:\r
1506     ldr     r12,=rendstatus\r
1507     eors    r6, r6, #1          @ sh is 0\r
1508     ldr     r12,[r12]\r
1509     mov     lr, #0xff\r
1510     tstne   r12,#(1<<2)         @ and PDRAW_ACC_SPRITES\r
1511 \r
1512 .if OVERRIDE_HIGHCOL\r
1513     ldr     r1, =HighCol\r
1514     movne   lr, #0x3f\r
1515     ldr     r1, [r1]\r
1516     mov     lr, lr, lsl #1\r
1517     add     r1, r1, #8\r
1518 .else\r
1519     ldr     r1, =(HighCol+8)\r
1520     movne   lr, #0x3f\r
1521     mov     lr, lr, lsl #1\r
1522 .endif\r
1523 \r
1524 .fl_loopBGR444:\r
1525     ldr     r12, [r1], #4\r
1526     subs    r2, r2, #1\r
1527 \r
1528     and     r4, lr, r12, lsl #1\r
1529     ldrh    r4, [r3, r4]\r
1530     and     r5, lr, r12, lsr #7\r
1531     ldrh    r5, [r3, r5]\r
1532     and     r6, lr, r12, lsr #15\r
1533     ldrh    r6, [r3, r6]\r
1534     and     r12,lr, r12, lsr #23\r
1535     ldrh    r12,[r3, r12]              @ 1c.i.\r
1536     orr     r4, r4, r5, lsl #16\r
1537     orr     r5, r6, r12,lsl #16\r
1538 \r
1539     stmia   r0!, {r4,r5}\r
1540     bne     .fl_loopBGR444\r
1541 \r
1542 \r
1543     ldmfd   sp!, {r4-r6,lr}\r
1544     bx lr\r
1545 \r
1546 \r
1547 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1548 \r
1549 \r
1550 @ hilights 2 pixels in RGB555/BGR555 format\r
1551 .macro TileDoShHi2Pixels555 reg\r
1552     adds    \reg, \reg, #0x40000000\r
1553     orrcs   \reg, \reg, #0xf0000000\r
1554     mov     \reg, \reg, ror #27\r
1555     adds    \reg, \reg, #0x40000000\r
1556     orrcs   \reg, \reg, #0xf0000000\r
1557     mov     \reg, \reg, ror #26\r
1558     adds    \reg, \reg, #0x40000000\r
1559     orrcs   \reg, \reg, #0xf0000000\r
1560     mov     \reg, \reg, ror #27\r
1561     adds    \reg, \reg, #0x40000000\r
1562     orrcs   \reg, \reg, #0xf0000000\r
1563     mov     \reg, \reg, ror #27\r
1564     adds    \reg, \reg, #0x40000000\r
1565     orrcs   \reg, \reg, #0xf0000000\r
1566     mov     \reg, \reg, ror #26\r
1567     adds    \reg, \reg, #0x40000000\r
1568     orrcs   \reg, \reg, #0xf0000000\r
1569     mov     \reg, \reg, ror #27\r
1570 .endm\r
1571 \r
1572 \r
1573 @ Convert 0000bbb0 ggg0rrr0\r
1574 @ to      rrrrrggg gggbbbbb\r
1575 \r
1576 @ r2,r3,r9 - scratch, lr = 0x001c001c, r8 = 0x00030003\r
1577 .macro convRGB565 reg\r
1578     and     r2,   lr,   \reg,lsl #1\r
1579     and     r9,   r8,   \reg,lsr #2\r
1580     orr     r2,   r2,   r9           @ r2=red\r
1581     and     r3,   lr,   \reg,lsr #7\r
1582     and     r9,   r8,   \reg,lsr #10\r
1583     orr     r3,   r3,   r9           @ r3=blue\r
1584     and     \reg, \reg, lr,  lsl #3\r
1585     orr     \reg, \reg, \reg,lsl #3  @ green\r
1586     orr     \reg, \reg, r2,  lsl #11 @ add red back\r
1587     orr     \reg, \reg, r3           @ add blue back\r
1588 .endm\r
1589 \r
1590 .global vidConvCpyRGB565\r
1591 \r
1592 vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1593     stmfd   sp!, {r4-r9,lr}\r
1594 \r
1595     mov     r12, r2, lsr #3  @ repeats\r
1596     mov     lr, #0x001c0000\r
1597     orr     lr, lr,  #0x01c  @ lr == pattern 0x001c001c\r
1598     mov     r8, #0x00030000\r
1599     orr     r8, r8,  #0x003\r
1600 \r
1601 .loopRGB565:\r
1602     ldmia   r1!, {r4-r7}\r
1603     subs    r12, r12, #1\r
1604     convRGB565 r4\r
1605     str     r4, [r0], #4\r
1606     convRGB565 r5\r
1607     str     r5, [r0], #4\r
1608     convRGB565 r6\r
1609     str     r6, [r0], #4\r
1610     convRGB565 r7\r
1611     str     r7, [r0], #4\r
1612 \r
1613     bgt     .loopRGB565\r
1614 \r
1615     ldmfd   sp!, {r4-r9,lr}\r
1616     bx      lr\r
1617 \r
1618 \r
1619 \r
1620 .global FinalizeLineRGB555 @ int sh\r
1621 \r
1622 FinalizeLineRGB555:\r
1623     stmfd   sp!, {r4-r8,lr}\r
1624     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
1625     ldr     r4, =HighPal\r
1626 \r
1627     ldrb    r7, [r8, #-0x1a]     @ 0x2220e ~ dirtyPal\r
1628     mov     r6, r0\r
1629     mov     r1, #0\r
1630     tst     r7, r7\r
1631     beq     .fl_noconvRGB555\r
1632     strb    r1, [r8, #-0x1a]\r
1633     sub     r1, r8, #0x128       @ r1=Pico.cram\r
1634     mov     r0, r4\r
1635     mov     r2, #0x40\r
1636     bl      vidConvCpyRGB565\r
1637 \r
1638 .fl_noconvRGB555:\r
1639     mov     r3, r4\r
1640     tst     r6, r6\r
1641     beq     .fl_noshRGB555\r
1642     tst     r7, r7\r
1643     beq     .fl_noshRGB555\r
1644 \r
1645     @ shadowed pixels:\r
1646     mov     r12,    #0x008e\r
1647     orr     r12,r12,#0x7300\r
1648     orr     r12,r12,r12,lsl #16\r
1649     add     r4, r3, #0x40*2\r
1650     add     r5, r3, #0xc0*2\r
1651     mov     lr, #0x40/4\r
1652 .fl_loopcpRGB555_sh:\r
1653     ldmia   r3!, {r1,r6}\r
1654     subs    lr, lr, #1\r
1655     and     r1, r12, r1, lsr #1\r
1656     and     r6, r12, r6, lsr #1\r
1657     stmia   r4!, {r1,r6}\r
1658     stmia   r5!, {r1,r6}\r
1659     bne     .fl_loopcpRGB555_sh\r
1660 \r
1661     @ hilighted pixels:\r
1662     sub     r3, r3, #0x40*2\r
1663     mov     lr, #0x40/2\r
1664 .fl_loopcpRGB555_hi:\r
1665     ldr     r1, [r3], #4\r
1666     TileDoShHi2Pixels555 r1\r
1667     str     r1, [r4], #4\r
1668     subs    lr, lr, #1\r
1669     bne     .fl_loopcpRGB555_hi\r
1670 \r
1671     sub     r3, r3, #0x40*2\r
1672     mov     r6, #1\r
1673 \r
1674 .fl_noshRGB555:\r
1675     ldr     r12,=rendstatus\r
1676     eors    r6, r6, #1          @ sh is 0\r
1677     ldr     r12,[r12]\r
1678     mov     lr, #0xff\r
1679     tstne   r12,#(1<<2)         @ and PDRAW_ACC_SPRITES\r
1680     movne   lr, #0x3f\r
1681 \r
1682 .if OVERRIDE_HIGHCOL\r
1683     ldr     r1, =HighCol\r
1684     ldr     r0, =DrawLineDest\r
1685     ldr     r1, [r1]\r
1686     ldr     r0, [r0]\r
1687     add     r1, r1, #8\r
1688 .else\r
1689     ldr     r0, =DrawLineDest\r
1690     ldr     r1, =(HighCol+8)\r
1691     ldr     r0, [r0]\r
1692 .endif\r
1693 \r
1694     ldrb    r12, [r8, #12]\r
1695     mov     lr, lr, lsl #1\r
1696 \r
1697     tst     r12, #1\r
1698     movne   r2, #320/8           @ len\r
1699     bne     .fl_no32colRGB555\r
1700     ldr     r4, =PicoOpt\r
1701     mov     r2, #256/8\r
1702     ldr     r4, [r4]\r
1703     tst     r4, #0x4000\r
1704     bne     .fl_32scale_RGB555\r
1705     tst     r4, #0x0100\r
1706     addeq   r0, r0, #32*2\r
1707 \r
1708 .fl_no32colRGB555:\r
1709 \r
1710 .if UNALIGNED_DRAWLINEDEST\r
1711     @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1712     tst     r0, #2\r
1713     bne     .fl_RGB555u\r
1714 .endif\r
1715 \r
1716 .fl_loopRGB555:\r
1717     ldr     r12, [r1], #4\r
1718     ldr     r7,  [r1], #4\r
1719 \r
1720     and     r4, lr, r12, lsl #1\r
1721     ldrh    r4, [r3, r4]\r
1722     and     r5, lr, r12, lsr #7\r
1723     ldrh    r5, [r3, r5]\r
1724     and     r6, lr, r12, lsr #15\r
1725     ldrh    r6, [r3, r6]\r
1726     orr     r4, r4, r5, lsl #16\r
1727 \r
1728     and     r5, lr, r12, lsr #23\r
1729     ldrh    r5, [r3, r5]\r
1730     and     r8, lr, r7, lsl #1\r
1731     ldrh    r8, [r3, r8]\r
1732     orr     r5, r6, r5, lsl #16\r
1733 \r
1734     and     r6, lr, r7, lsr #7\r
1735     ldrh    r6, [r3, r6]\r
1736     and     r12,lr, r7, lsr #15\r
1737     ldrh    r12,[r3, r12]\r
1738     and     r7, lr, r7, lsr #23\r
1739     ldrh    r7, [r3, r7]\r
1740     orr     r8, r8, r6, lsl #16\r
1741 \r
1742     subs    r2, r2, #1\r
1743     orr     r12,r12, r7, lsl #16\r
1744 \r
1745     stmia   r0!, {r4,r5,r8,r12}\r
1746     bne     .fl_loopRGB555\r
1747 \r
1748     ldmfd   sp!, {r4-r8,lr}\r
1749     bx      lr\r
1750 \r
1751 \r
1752 .fl_32scale_RGB555:\r
1753     stmfd   sp!, {r9,r10}\r
1754     mov     r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1755     orr     r9, r9, #0x00e7\r
1756 \r
1757 .if UNALIGNED_DRAWLINEDEST\r
1758     tst     r0, #2\r
1759     bne     .fl_32scale_RGB555u\r
1760 .endif\r
1761 \r
1762 .fl_loop32scale_RGB555:\r
1763     ldr     r12, [r1], #4\r
1764     ldr     r7,  [r1], #4\r
1765 \r
1766     and     r4, lr, r12,lsl #1\r
1767     ldrh    r4, [r3, r4]\r
1768     and     r5, lr, r12,lsr #7\r
1769     ldrh    r5, [r3, r5]\r
1770     and     r4, r4, r9, lsl #2\r
1771     orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0\r
1772     and     r5, r5, r9, lsl #2\r
1773     sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1\r
1774     add     r4, r4, r6, lsl #16       @ pix_d 0, 1\r
1775     and     r6, lr, r12,lsr #15\r
1776     ldrh    r6, [r3, r6]\r
1777     and     r12,lr, r12,lsr #23\r
1778     ldrh    r12,[r3, r12]\r
1779     and     r6, r6, r9, lsl #2\r
1780     add     r5, r5, r6\r
1781     mov     r5, r5, lsr #1\r
1782     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1783     orr     r5, r5, r6, lsl #16\r
1784 \r
1785     and     r6, lr, r7, lsl #1\r
1786     ldrh    r6, [r3, r6]\r
1787     and     r12,r12,r9, lsl #2\r
1788     add     r5, r5, r12,lsl #14       @ pix_d 2, 3\r
1789     and     r6, r6, r9, lsl #2\r
1790     orr     r6, r12,r6, lsl #16       @ pix_d 4, 5\r
1791 \r
1792     and     r12,lr, r7, lsr #7\r
1793     ldrh    r12,[r3, r12]\r
1794     and     r10,lr, r7, lsr #15\r
1795     ldrh    r10,[r3, r10]\r
1796     and     r12,r12,r9, lsl #2\r
1797     sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1\r
1798     add     r8, r8, r6, lsr #18\r
1799     and     r7, lr, r7, lsr #23\r
1800     ldrh    r7, [r3, r7]\r
1801     and     r10,r10,r9, lsl #2\r
1802     orr     r8, r8, r10,lsl #15\r
1803     add     r8, r8, r12,lsl #15       @ pix_d 6, 7\r
1804     sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2\r
1805     and     r7, r7, r9, lsl #2\r
1806     add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3\r
1807     orr     r10,r10,r7, lsl #16       @ pix_d 8, 9\r
1808 \r
1809     subs    r2, r2, #1\r
1810 \r
1811     stmia   r0!, {r4,r5,r6,r8,r10}\r
1812     bne     .fl_loop32scale_RGB555\r
1813 \r
1814     ldmfd   sp!, {r9,r10}\r
1815     ldmfd   sp!, {r4-r8,lr}\r
1816     bx      lr\r
1817 \r
1818 .if UNALIGNED_DRAWLINEDEST\r
1819     @ unaligned versions of loops\r
1820     @ warning: starts drawing 2bytes before dst\r
1821 \r
1822 .fl_RGB555u:\r
1823     sub     r0, r0, #2              @ initial adjustment\r
1824     mov     r8, #0\r
1825 \r
1826 .fl_loopRGB555u:\r
1827     ldr     r12, [r1], #4\r
1828     ldr     r7,  [r1], #4\r
1829 \r
1830     and     r6, lr, r12,lsl #1\r
1831     ldrh    r6, [r3, r6]\r
1832     and     r5, lr, r12,lsr #7\r
1833     ldrh    r5, [r3, r5]\r
1834     orr     r4, r8, r6, lsl #16\r
1835 \r
1836     and     r6, lr, r12,lsr #15\r
1837     ldrh    r6, [r3, r6]\r
1838     and     r8, lr, r12,lsr #23\r
1839     ldrh    r8, [r3, r8]\r
1840     orr     r5, r5, r6, lsl #16\r
1841 \r
1842     and     r6, lr, r7, lsl #1\r
1843     ldrh    r6, [r3, r6]\r
1844     and     r12,lr, r7, lsr #7\r
1845     ldrh    r12,[r3, r12]\r
1846     orr     r6, r8, r6, lsl #16\r
1847 \r
1848     and     r8, lr, r7, lsr #15\r
1849     ldrh    r8, [r3, r8]\r
1850     and     r7, lr, r7, lsr #23\r
1851 \r
1852     subs    r2, r2, #1\r
1853     orr     r12,r12,r8, lsl #16\r
1854     ldrh    r8, [r3, r7]\r
1855 \r
1856     stmia   r0!, {r4,r5,r6,r12}\r
1857     bne     .fl_loopRGB555u\r
1858 \r
1859     strh    r8, [r0], #2\r
1860 \r
1861     ldmfd   sp!, {r4-r8,lr}\r
1862     bx      lr\r
1863 \r
1864 \r
1865 .fl_32scale_RGB555u:\r
1866     sub     r0, r0, #2              @ initial adjustment\r
1867     mov     r4, #0\r
1868 \r
1869     @ r9  f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1870 .fl_loop32scale_RGB555u:\r
1871     ldr     r12, [r1], #4\r
1872     ldr     r7,  [r1], #4\r
1873 \r
1874     and     r6, lr, r12,lsl #1\r
1875     ldrh    r6, [r3, r6]\r
1876     and     r5, lr, r12,lsr #7\r
1877     ldrh    r5, [r3, r5]\r
1878     and     r6, r6, r9, lsl #2\r
1879     orr     r4, r4, r6, lsl #16       @ r4 = pix_d -1, 0\r
1880 \r
1881     and     r5, r5, r9, lsl #2\r
1882     sub     r8, r5, r5, lsr #2        @ r8 = 3/4 pix_s 1\r
1883     add     r6, r8, r6, lsr #2        @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
1884     orr     r5, r6, r5, lsl #15\r
1885 \r
1886     and     r6, lr, r12,lsr #15\r
1887     ldrh    r6, [r3, r6]\r
1888     and     r12,lr, r12,lsr #23\r
1889     ldrh    r12,[r3, r12]\r
1890     and     r6, r6, r9, lsl #2\r
1891     add     r5, r5, r6, lsl #15       @ r5 = pix_d 1, 2\r
1892 \r
1893     and     r8, lr, r7, lsl #1\r
1894     ldrh    r8, [r3, r8]\r
1895     and     r10,lr, r7, lsr #7\r
1896     ldrh    r10,[r3, r10]\r
1897     and     r12,r12,r9, lsl #2\r
1898     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1899     add     r6, r6, r12,lsr #2\r
1900     orr     r6, r6, r12,lsl #16       @ r6 = pix_d 3, 4\r
1901 \r
1902     and     r8, r8, r9, lsl #2\r
1903     and     r10,r10,r9, lsl #2\r
1904     sub     r12,r10,r10,lsr #2        @ r12 = 3/4 pix_s 5\r
1905     orr     r8, r8, r8, lsl #14\r
1906     add     r8, r8, r12,lsl #16       @ r8 = pix_d 5, 6\r
1907     and     r12,lr, r7, lsr #15\r
1908     ldrh    r12,[r3, r12]\r
1909     and     r7, lr, r7, lsr #23\r
1910     ldrh    r7, [r3, r7]\r
1911     and     r12,r12,r9, lsl #2\r
1912     add     r10,r10,r12\r
1913     mov     r10,r10,    lsr #1\r
1914     sub     r12,r12,r12,lsr #2        @ r12 = 3/4 pix_s 6\r
1915     orr     r10,r10,r12,lsl #16\r
1916     and     r7, r7, r9, lsl #2\r
1917     add     r10,r10,r7, lsl #14       @ r10 = pix_d 7, 8\r
1918 \r
1919     subs    r2, r2, #1\r
1920 \r
1921     stmia   r0!, {r4,r5,r6,r8,r10}\r
1922     mov     r4, r7\r
1923     bne     .fl_loop32scale_RGB555u\r
1924 \r
1925     strh    r4, [r0], #2\r
1926 \r
1927     ldmfd   sp!, {r9,r10}\r
1928     ldmfd   sp!, {r4-r8,lr}\r
1929     bx      lr\r
1930 \r
1931 .endif @ UNALIGNED_DRAWLINEDEST\r
1932 \r
1933 \r
1934 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1935 \r
1936 @ utility\r
1937 .global blockcpy @ void *dst, void *src, size_t n\r
1938 \r
1939 blockcpy:\r
1940     stmfd   sp!, {r4,r5}\r
1941     mov     r2, r2, lsr #4\r
1942 blockcpy_loop:\r
1943     ldmia   r1!, {r3-r5,r12}\r
1944     subs    r2, r2, #1\r
1945     stmia   r0!, {r3-r5,r12}\r
1946     bne     blockcpy_loop\r
1947     ldmfd   sp!, {r4,r5}\r
1948     bx      lr\r
1949 \r
1950 \r
1951 .global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
1952 \r
1953 blockcpy_or:\r
1954     stmfd   sp!, {r4-r6}\r
1955     orr     r3, r3, r3, lsl #8\r
1956     orr     r3, r3, r3, lsl #16\r
1957     mov     r2, r2, lsr #4\r
1958 blockcpy_loop_or:\r
1959     ldmia   r1!, {r4-r6,r12}\r
1960     subs    r2, r2, #1\r
1961     orr     r4, r4, r3\r
1962     orr     r5, r5, r3\r
1963     orr     r6, r6, r3\r
1964     orr     r12,r12,r3\r
1965     stmia   r0!, {r4-r6,r12}\r
1966     bne     blockcpy_loop_or\r
1967     ldmfd   sp!, {r4-r6}\r
1968     bx      lr\r
1969 \r