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