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