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