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