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