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