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