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