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