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