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