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