73ee07f79d624b60e5e4f0b8345b4a952765bc86
[picodrive.git] / pico / draw_arm.S
1 /*\r
2  * assembly optimized versions of most funtions from draw.c\r
3  * (C) notaz, 2006-2010,2017\r
4  * (C) irixxxx, 2020-2024\r
5  *\r
6  * This work is licensed under the terms of MAME license.\r
7  * See COPYING file in the top-level directory.\r
8  *\r
9  * this is highly specialized, be careful if changing related C code!\r
10  *\r
11  * NB only does RGB565 output, BGR isn't supported\r
12  */\r
13 \r
14 #include "pico_int_offs.h"\r
15 \r
16 .extern DrawStripInterlace\r
17 \r
18 .equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
19 .equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
20 .equ PDRAW_SHHI_DONE,     (1<<7)\r
21 .equ PDRAW_BORDER_32,     (1<<9)\r
22 .equ PDRAW_32X_SCALE,     (1<<12)\r
23 .equ PDRAW_BGC_DMA,       (1<<14)\r
24 .equ PDRAW_SOFTSCALE,     (1<<15)\r
25 \r
26 @ helpers\r
27 .macro add_c24 d s c\r
28     add     \d, \s, #(\c & 0x00ff00)\r
29 .if \c & 0x0000ff\r
30     add     \d, \d, #(\c & 0x0000ff)\r
31 .endif\r
32 .if \c & 0xff0000\r
33     add     \d, \d, #(\c & 0xff0000)\r
34 .endif\r
35 .endm\r
36 \r
37 .macro TilePixel pat lsrr offs\r
38 .if !\lsrr\r
39     ands    r4, \pat, r2\r
40 .else\r
41     ands    r4, \pat, r2, lsr #\lsrr\r
42 .endif\r
43     orrne   r4, r3, r4\r
44     strneb  r4, [r1,#\offs]\r
45 .endm\r
46 \r
47 @ TileNorm (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
48 .macro TileNorm pat\r
49     TilePixel \pat, 12, 0         @ #0x0000f000\r
50     TilePixel \pat,  8, 1         @ #0x00000f00\r
51     TilePixel \pat,  4, 2         @ #0x000000f0\r
52     TilePixel \pat,  0, 3         @ #0x0000000f\r
53     TilePixel \pat, 28, 4         @ #0xf0000000\r
54     TilePixel \pat, 24, 5         @ #0x0f000000\r
55     TilePixel \pat, 20, 6         @ #0x00f00000\r
56     TilePixel \pat, 16, 7         @ #0x000f0000\r
57 .endm\r
58 \r
59 @ TileFlip (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
60 .macro TileFlip pat\r
61     TilePixel \pat, 16, 0         @ #0x000f0000\r
62     TilePixel \pat, 20, 1         @ #0x00f00000\r
63     TilePixel \pat, 24, 2         @ #0x0f000000\r
64     TilePixel \pat, 28, 3         @ #0xf0000000\r
65     TilePixel \pat,  0, 4         @ #0x0000000f\r
66     TilePixel \pat,  4, 5         @ #0x000000f0\r
67     TilePixel \pat,  8, 6         @ #0x00000f00\r
68     TilePixel \pat, 12, 7         @ #0x0000f000\r
69 .endm\r
70 \r
71 @ shadow/hilight mode\r
72 \r
73\r
74 .macro TilePixelNonSH pat lsrr offs\r
75 .if !\lsrr\r
76     ands    r4, \pat, r2\r
77 .else\r
78     ands    r4, \pat, r2, lsr #\lsrr\r
79 .endif\r
80     beq     0f\r
81     cmp     r4, #0xe\r
82     orr     r4, r3, r4\r
83     biceq   r4, r4, #0x80\r
84     strb    r4, [r1,#\offs]\r
85 0:\r
86 .endm\r
87 \r
88 @ TileNormNonSH (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
89 .macro TileNormNonSH pat\r
90     TilePixelNonSH \pat, 12, 0    @ #0x0000f000\r
91     TilePixelNonSH \pat,  8, 1    @ #0x00000f00\r
92     TilePixelNonSH \pat,  4, 2    @ #0x000000f0\r
93     TilePixelNonSH \pat,  0, 3    @ #0x0000000f\r
94     TilePixelNonSH \pat, 28, 4    @ #0xf0000000\r
95     TilePixelNonSH \pat, 24, 5    @ #0x0f000000\r
96     TilePixelNonSH \pat, 20, 6    @ #0x00f00000\r
97     TilePixelNonSH \pat, 16, 7    @ #0x000f0000\r
98 .endm\r
99 \r
100 @ TileFlipNonSH (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
101 .macro TileFlipNonSH pat\r
102     TilePixelNonSH \pat, 16, 0    @ #0x000f0000\r
103     TilePixelNonSH \pat, 20, 1    @ #0x00f00000\r
104     TilePixelNonSH \pat, 24, 2    @ #0x0f000000\r
105     TilePixelNonSH \pat, 28, 3    @ #0xf0000000\r
106     TilePixelNonSH \pat,  0, 4    @ #0x0000000f\r
107     TilePixelNonSH \pat,  4, 5    @ #0x000000f0\r
108     TilePixelNonSH \pat,  8, 6    @ #0x00000f00\r
109     TilePixelNonSH \pat, 12, 7    @ #0x0000f000\r
110 .endm\r
111 \r
112 @ this one is for hi priority layer\r
113 .macro TilePixelShHP lsrr offs\r
114 .if !\lsrr\r
115     ands    r4, r12, r2\r
116 .else\r
117     ands    r4, r12, r2, lsr #\lsrr\r
118 .endif\r
119     ldreqb  r4, [r1,#\offs]\r
120     orrne   r4, r3, r4\r
121     andeq   r4, r4, #0x7f\r
122     strb    r4, [r1,#\offs]\r
123 .endm\r
124 \r
125 @ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits\r
126 .macro TileNormShHP\r
127     TilePixelShHP 12, 0         @ #0x0000f000\r
128     TilePixelShHP  8, 1         @ #0x00000f00\r
129     TilePixelShHP  4, 2         @ #0x000000f0\r
130     TilePixelShHP  0, 3         @ #0x0000000f\r
131     TilePixelShHP 28, 4         @ #0xf0000000\r
132     TilePixelShHP 24, 5         @ #0x0f000000\r
133     TilePixelShHP 20, 6         @ #0x00f00000\r
134     TilePixelShHP 16, 7         @ #0x000f0000\r
135 .endm\r
136 \r
137 @ TileFlipShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, pat: register with helper pattern 0xf\r
138 .macro TileFlipShHP\r
139     TilePixelShHP 16, 0         @ #0x000f0000\r
140     TilePixelShHP 20, 1         @ #0x00f00000\r
141     TilePixelShHP 24, 2         @ #0x0f000000\r
142     TilePixelShHP 28, 3         @ #0xf0000000\r
143     TilePixelShHP  0, 4         @ #0x0000000f\r
144     TilePixelShHP  4, 5         @ #0x000000f0\r
145     TilePixelShHP  8, 6         @ #0x00000f00\r
146     TilePixelShHP 12, 7         @ #0x0000f000\r
147 .endm\r
148 \r
149 \r
150 @ TileSingleSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx; r12: helper pattern 0xf\r
151 .macro TileSingleSh\r
152     tst     r0, #1              @ not aligned?\r
153     mov     r7, #0x008000\r
154     orr     r7, r7, #0x80\r
155     ldrneb  r4,  [r1], #1\r
156     ldreqh  r4,  [r1], #2        @ 1ci\r
157     ldrh    r12, [r1], #2\r
158     orr     r4,  r4,  r7\r
159     strneb  r4,  [r1, #-3]\r
160     streqh  r4,  [r1, #-4]\r
161     ldrh    r4,  [r1], #2\r
162     orr     r12, r12, r7\r
163     strh    r12, [r1, #-4]\r
164     ldrh    r12, [r1], #2\r
165     orr     r4,  r4,  r7\r
166     strh    r4,  [r1, #-4]\r
167     ldrneb  r4,  [r1]\r
168     orr     r12, r12, r7\r
169     strh    r12, [r1, #-2]\r
170     orrne   r4,  r4,  r7\r
171     strneb  r4,  [r1], #1\r
172     mov     r12, #0xf\r
173 .endm\r
174 \r
175 @ TileSingleHi (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
176 .macro TileSingleHi\r
177     tst     r1,  #1              @ not aligned?\r
178     mov     r7,  #0x004000\r
179     orr     r7,  r7, #0x40\r
180     ldrneb  r4,  [r1], #1\r
181     ldreqh  r4,  [r1], #2        @ 1ci\r
182     ldrh    r12, [r1], #2\r
183     orr     r4,  r4,  r7\r
184     strneb  r4,  [r1, #-3]\r
185     streqh  r4,  [r1, #-4]\r
186     ldrh    r4,  [r1], #2\r
187     orr     r12, r12, r7\r
188     strh    r12, [r1, #-4]\r
189     ldrh    r12, [r1], #2\r
190     orr     r4,  r4,  r7\r
191     strh    r4,  [r1, #-4]\r
192     ldrneb  r4,  [r1]\r
193     orr     r12, r12, r7\r
194     strh    r12, [r1, #-2]\r
195     orrne   r4,  r4,  r7\r
196     strneb  r4,  [r1], #1\r
197     mov     r12, #0xf\r
198 .endm\r
199 \r
200 .macro TileDoShGenPixel shift ofs\r
201 .if \shift\r
202     ands    r4, r12, r2, lsr #\shift\r
203 .else\r
204     ands    r4, r12, r2\r
205 .endif\r
206     beq     0f\r
207     cmp     r4, #0xe\r
208     ldrgeb  r7, [r1,#\ofs]\r
209     orrlt   r7, r3, r4            @ normal\r
210 \r
211     subge   r4, r4, #1\r
212     orrge   r7, r7, r4, lsl #6\r
213     strb    r7, [r1,#\ofs]\r
214 0:\r
215 .endm\r
216 \r
217 @ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
218 .macro TileFlipSh\r
219     TileDoShGenPixel 16,  0 @ #0x000f0000\r
220     TileDoShGenPixel 20,  1 @ #0x00f00000\r
221     TileDoShGenPixel 24,  2 @ #0x0f000000\r
222     TileDoShGenPixel 28,  3 @ #0xf0000000\r
223     TileDoShGenPixel  0,  4 @ #0x0000000f\r
224     TileDoShGenPixel  4,  5 @ #0x000000f0\r
225     TileDoShGenPixel  8,  6 @ #0x00000f00\r
226     TileDoShGenPixel 12,  7 @ #0x0000f000\r
227 .endm\r
228 \r
229 @ TileNormSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
230 .macro TileNormSh\r
231     TileDoShGenPixel 12,  0 @ #0x0000f000\r
232     TileDoShGenPixel  8,  1 @ #0x00000f00\r
233     TileDoShGenPixel  4,  2 @ #0x000000f0\r
234     TileDoShGenPixel  0,  3 @ #0x0000000f\r
235     TileDoShGenPixel 28,  4 @ #0xf0000000\r
236     TileDoShGenPixel 24,  5 @ #0x0f000000\r
237     TileDoShGenPixel 20,  6 @ #0x00f00000\r
238     TileDoShGenPixel 16,  7 @ #0x000f0000\r
239 .endm\r
240 \r
241 .macro TileDoShGenPixel_markop shift ofs\r
242 .if \shift\r
243     ands    r4, r12, r2, lsr #\shift\r
244 .else\r
245     ands    r4, r12, r2\r
246 .endif\r
247     beq     0f\r
248     cmp     r4, #0xe\r
249     ldrgeb  r4, [r1,#\ofs]\r
250     orrlt   r4, r3, r4\r
251     orrge   r4, r4, #0x40\r
252     strb    r4, [r1,#\ofs]\r
253 0:\r
254 .endm\r
255 \r
256 .macro TileFlipSh_markop\r
257     TileDoShGenPixel_markop 16,  0 @ #0x000f0000\r
258     TileDoShGenPixel_markop 20,  1 @ #0x00f00000\r
259     TileDoShGenPixel_markop 24,  2 @ #0x0f000000\r
260     TileDoShGenPixel_markop 28,  3 @ #0xf0000000\r
261     TileDoShGenPixel_markop  0,  4 @ #0x0000000f\r
262     TileDoShGenPixel_markop  4,  5 @ #0x000000f0\r
263     TileDoShGenPixel_markop  8,  6 @ #0x00000f00\r
264     TileDoShGenPixel_markop 12,  7 @ #0x0000f000\r
265 .endm\r
266 \r
267 .macro TileNormSh_markop\r
268     TileDoShGenPixel_markop 12,  0 @ #0x0000f000\r
269     TileDoShGenPixel_markop  8,  1 @ #0x00000f00\r
270     TileDoShGenPixel_markop  4,  2 @ #0x000000f0\r
271     TileDoShGenPixel_markop  0,  3 @ #0x0000000f\r
272     TileDoShGenPixel_markop 28,  4 @ #0xf0000000\r
273     TileDoShGenPixel_markop 24,  5 @ #0x0f000000\r
274     TileDoShGenPixel_markop 20,  6 @ #0x00f00000\r
275     TileDoShGenPixel_markop 16,  7 @ #0x000f0000\r
276 .endm\r
277 \r
278 .macro TileDoShGenPixel_onlyop_lp shift ofs\r
279 .if \shift\r
280     ands    r7, r12, r2, lsr #\shift\r
281 .else\r
282     ands    r7, r12, r2\r
283 .endif\r
284     ldrneb  r4, [r1,#\ofs]\r
285     cmp     r7, #0xe\r
286     blt     0f\r
287 \r
288     tst     r4, #0x40\r
289     bicne   r4, r4, #0x40\r
290     subne   r7, r7, #1\r
291     orrne   r4, r4, r7, lsl #6\r
292     strneb  r4, [r1,#\ofs]\r
293 0:\r
294 .endm\r
295 \r
296 .macro TileFlipSh_onlyop_lp\r
297     TileDoShGenPixel_onlyop_lp 16,  0 @ #0x000f0000\r
298     TileDoShGenPixel_onlyop_lp 20,  1 @ #0x00f00000\r
299     TileDoShGenPixel_onlyop_lp 24,  2 @ #0x0f000000\r
300     TileDoShGenPixel_onlyop_lp 28,  3 @ #0xf0000000\r
301     TileDoShGenPixel_onlyop_lp  0,  4 @ #0x0000000f\r
302     TileDoShGenPixel_onlyop_lp  4,  5 @ #0x000000f0\r
303     TileDoShGenPixel_onlyop_lp  8,  6 @ #0x00000f00\r
304     TileDoShGenPixel_onlyop_lp 12,  7 @ #0x0000f000\r
305 .endm\r
306 \r
307 .macro TileNormSh_onlyop_lp\r
308     TileDoShGenPixel_onlyop_lp 12,  0 @ #0x0000f000\r
309     TileDoShGenPixel_onlyop_lp  8,  1 @ #0x00000f00\r
310     TileDoShGenPixel_onlyop_lp  4,  2 @ #0x000000f0\r
311     TileDoShGenPixel_onlyop_lp  0,  3 @ #0x0000000f\r
312     TileDoShGenPixel_onlyop_lp 28,  4 @ #0xf0000000\r
313     TileDoShGenPixel_onlyop_lp 24,  5 @ #0x0f000000\r
314     TileDoShGenPixel_onlyop_lp 20,  6 @ #0x00f00000\r
315     TileDoShGenPixel_onlyop_lp 16,  7 @ #0x000f0000\r
316 .endm\r
317 \r
318 \r
319 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
320 \r
321 @ struct TileStrip\r
322 @ {\r
323 @   int nametab; // 0x00\r
324 @   int line;    // 0x04\r
325 @   int hscroll; // 0x08\r
326 @   int xmask;   // 0x0C\r
327 @   int *hc;     // 0x10 (pointer to cache buffer)\r
328 @   int cells;   // 0x14\r
329 @ };\r
330 \r
331 @ void DrawLayer(int lflags, int *hcache, int cellskip, int maxcells,\r
332 @                struct PicoEState *est)\r
333 \r
334 .global DrawLayer\r
335 \r
336 DrawLayer:\r
337     ldr     r12, [sp]             @ est\r
338     stmfd   sp!, {r4-r11,lr}\r
339 \r
340     ldr     r11, [r12, #OFS_EST_Pico]\r
341     mov     r8, #1\r
342 \r
343     ldrb    r7, [r11, #OFS_Pico_video_reg+16] @ ??vv??hh\r
344 \r
345     mov     r6, r1                @ hcache\r
346     orr     r9, r3, r0, lsl #29   @ r9=force[31]|sh[30]|plane[29]\r
347     orr     r9, r9, r2, lsl #8    @    |cellskip[15:8]|maxcells[7:0]  (tmp)\r
348 \r
349     mov     r1, r7, lsl #4\r
350     orr     r1, r1, #0x00ff\r
351 \r
352     and     r10, r7,  #3\r
353     cmp     r10, #1\r
354     biclt   r1,  r1, #0xfc00\r
355     biceq   r1,  r1, #0xfe00\r
356     cmp     r10, #2\r
357     moveq   r1,      #0x0007\r
358     movgt   r1,      #0x00ff      @ r1=ymask=(height<<8)|0xff; ...; // Y Mask in pixels\r
359 \r
360     cmp     r10, #2\r
361     addlt   r10, r10, #5\r
362     moveq   r10, #5\r
363     movgt   r10, #7               @ r10=shift[width] (5,6,5,7)\r
364 \r
365     ldr     r2, [r12, #OFS_EST_DrawScanline]\r
366     ldr     lr, [r12, #OFS_EST_PicoMem_vram]\r
367 \r
368     @ Find name table:\r
369     ands    r0,  r0, #1\r
370     ldreqb  r12, [r11, #OFS_Pico_video_reg+2]\r
371     ldrneb  r12, [r11, #OFS_Pico_video_reg+4]\r
372 \r
373     @ calculate xmask:\r
374     mov     r5, r8, lsl r10\r
375     sub     r5, r5, #1            @ r5=xmask\r
376 \r
377     moveq   r12, r12, lsl #10\r
378     movne   r12, r12, lsl #13\r
379     and     r12, r12, #(7<<13)    @ r12=(ts->nametab<<1) (halfword compliant)\r
380 \r
381     ldrh    r8, [r11, #OFS_Pico_video_reg+12]\r
382     ldrb    r7, [r11, #OFS_Pico_video_reg+11]\r
383 \r
384     mov     r4, r8, lsr #8        @ pvid->reg[13]\r
385     mov     r4, r4, lsl #10       @ htab=pvid->reg[13]<<9; (halfwords)\r
386 \r
387     ands    r3, r7, #0x03\r
388     beq     0f\r
389     cmp     r3, #2\r
390     mov     r3, r2, lsl #2        @ htab+=DrawScanline<<1; // Offset by line\r
391     biceq   r3, r3, #0x1f         @ htab&=~0xf; // Offset by tile\r
392     andlt   r3, r3, #0x1f\r
393     add     r4, r4, r3\r
394 0:  add     r4, r4, r0, lsl #1    @ htab+=plane\r
395     bic     r4, r4, #0x00ff0000   @ just in case\r
396     ldrh    r3, [lr, r4]          @ r3=hscroll\r
397 \r
398     tst     r7, #4\r
399     bne     .DrawStrip_vsscroll\r
400 \r
401     @ Get vertical scroll value:\r
402     add_c24 r7, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
403     ldr     r7, [r7]\r
404 \r
405     tst     r8, #2\r
406     tstne   r8, #4\r
407     bne     .DrawStrip_interlace\r
408 \r
409     tst     r0, r0\r
410     moveq   r7, r7, lsl #16\r
411     mov     r7, r7, lsr #16\r
412 \r
413     @ Find the line in the name table\r
414     add     r2, r2, r7\r
415     and     r2, r2, r1\r
416     mov     r4, r2, lsr #3\r
417     add     r10, r10, #1           @ shift[width]++\r
418     add     r12, r12, r4, lsl r10  @ nametab+=(ts.line>>3)<<shift[width];\r
419 \r
420     @ ldmia   r0, {r1,r2,r3,r5,r6,r9} @ r2=line, r3=ts->hscroll, r5=ts->xmask, r6=ts->hc, r9=ts->cells\r
421 \r
422     and     r10,r2,  #7\r
423     mov     r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1;\r
424     orr     r10,r10, r9, lsl #24\r
425 \r
426     rsb     r8, r3, #0\r
427     mov     r8, r8, lsr #3  @ r8=tilex=(-ts->hscroll)>>3\r
428 \r
429     sub     r1, r3, #1\r
430     and     r1, r1, #7\r
431     add     r7, r1, #1      @ r7=dx=((ts->hscroll-1)&7)+1\r
432 \r
433     movs    r3, r9, lsl #1  @ (force[31]|sh[30]) << 1\r
434     mov     r3, #0\r
435     orrmi   r10,r10, #1<<23 @ r10=cells[31:24]|sh[23]|hi_not_empty[22]\r
436 @    orrcc   r10,r10, #1<<20 @   |had_output[21]|!force[20]|hscroll[18:16]|ty[15:0]\r
437     movmi   r3, #0x80       @ default to shadowed pal on sh mode\r
438 \r
439     and     r4, r7, #7\r
440     orr     r10,r10, r4, lsl #16 @ we will process cells+1 if there is scroll\r
441 \r
442     and     r9, r9, #0xff00\r
443     add     r8, r8, r9, lsr #8   @ tilex+=cellskip\r
444     add     r7, r7, r9, lsr #5   @ dx+=cellskip<<3;\r
445     sub     r10,r10,r9, lsl #16  @ cells-=cellskip\r
446 \r
447     @ cache some stuff to avoid mem access\r
448     ldr     r11,[sp, #9*4]       @ est\r
449     mov     r0, #0xf\r
450     ldr     r11,[r11, #OFS_EST_HighCol]\r
451 \r
452     mvn     r9, #0               @ r9=prevcode=-1\r
453     add     r1, r11, r7          @ r1=pdest\r
454 \r
455     @ r10=cells[31:24]|sh[23]|hi_not_empty[22]|had_output[21]|!force[20]|hscroll[18:16]|ty[15:0]\r
456     @ r1=pd+dx r2=pack r3=pal r5=xmask r6=hc r8=tilex r9=prevcode r11=HighCol r12=nametab lr=vram\r
457     @ r4 & r7 are scratch in this loop\r
458 \r
459     ands    r4, r10, #7<<16  @ hscroll?\r
460     beq     .dsloop_subr1\r
461     subs    r10,r10, #0x01000000\r
462     bmi     .dsloop_exit\r
463 \r
464     and     r7, r5, r8         @ do first cut tile\r
465     add     r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)\r
466     ldrh    r9, [r7, r12]      @ r7=code (int, but from unsigned, no sign extend)\r
467 \r
468     add     r8, r8, #1\r
469 \r
470     tst     r9, #0x1000     @ if (code&0x1000)\r
471     mov     r2, r9, lsl #21\r
472     add     r2, r2, r10, lsl #17\r
473     eorne   r2, r2, #0xe<<17 @ if (code&0x1000) addr^=0xe;\r
474 \r
475     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
476 \r
477     mvn     r7, #0\r
478     mov     r4, r4, lsr #16-2  @ (dx&7)*4\r
479     tst     r9, #0x0800\r
480     moveq   r7, r7, lsl r4     @ mask = ~0 [shift] (dx&7)*4\r
481     movne   r7, r7, lsr r4\r
482     bic     r2, r2, r7, ror #16 @ pack&~mask\r
483 \r
484     orr     r9, r9, #0x80000000 @ invalidate oldcode since pack is masked\r
485     b       .DrawStrip_samecode\r
486 \r
487 .dsloop_subr1:\r
488     sub     r1, r1, #8\r
489 .dsloop: @ 40-41 times\r
490     subs    r10,r10, #0x01000000\r
491     bmi     .dsloop_exit\r
492 \r
493     and     r7, r5, r8\r
494     add     r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)\r
495     ldrh    r7, [r7, r12]      @ r7=code (int, but from unsigned, no sign extend)\r
496 \r
497     add     r1, r1, #8\r
498     add     r8, r8, #1\r
499 \r
500     cmp     r7, r9\r
501     beq     .DrawStrip_samecode @ we know stuff about this tile already\r
502 \r
503     mov     r9, r7          @ remember code\r
504 \r
505     tst     r9, #0x1000     @ if (code&0x1000)\r
506     mov     r2, r9, lsl #21\r
507     add     r2, r2, r10, lsl #17\r
508     eorne   r2, r2, #0x0e<<17 @ if (code&0x1000) addr^=0xe;\r
509 \r
510     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
511 .DrawStrip_samecode:\r
512     tst     r9, #0x8000\r
513 @    tstne   r10, #1<<20     @ !force[20]\r
514     bne     .DrawStrip_hiprio\r
515 \r
516     orr     r10, r10, #1<<21 @ seen non hi-prio tile\r
517     tst     r2, r2\r
518     beq     .dsloop              @ tileline blank\r
519 \r
520     bic     r7, r3, #0x7f\r
521     and     r3, r9, #0x6000\r
522     add     r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
523 \r
524     cmp     r2, r2, ror #4\r
525     beq     .DrawStrip_SingleColor @ tileline singlecolor \r
526 \r
527     tst     r9, #0x0800\r
528     bne     .DrawStrip_TileFlip\r
529 \r
530     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
531 .DrawStrip_TileNorm:\r
532     TileNorm r0\r
533     b       .dsloop\r
534 \r
535 .DrawStrip_TileFlip:\r
536     TileFlip r0\r
537     b       .dsloop\r
538 \r
539 .DrawStrip_SingleColor:\r
540     and     r4, r2, #0xf\r
541     orr     r4, r3, r4\r
542     orr     r4, r4, r4, lsl #8\r
543     tst     r1, #1             @ not aligned?\r
544     strneb  r4, [r1], #1\r
545     streqh  r4, [r1], #2\r
546     strh    r4, [r1], #2\r
547     strh    r4, [r1], #2\r
548     strh    r4, [r1], #2\r
549     strneb  r4, [r1], #1       @ have a remaining unaligned pixel?\r
550     b       .dsloop_subr1\r
551 \r
552 .DrawStrip_hiprio:\r
553     tst     r10, #(1<<23)   @ sh[23]\r
554     tsteq   r2, r2          @ if (!sh[23] && code==blank) continue\r
555     beq     .dsloop\r
556 \r
557 @    orr     r10, r10, #1<<22 @ hi_not_empty[22]\r
558     sub     r7, r1, r11\r
559     orr     r7, r9, r7,  lsl #16\r
560     orr     r7, r7, r10, lsl #25 @ (ty<<25)\r
561     tst     r9, #0x1000\r
562     eorne   r7, r7, #0xe<<25 @ if(code&0x1000) cval^=0xe<<25;\r
563     str     r7, [r6], #4    @ cache hi priority tile code\r
564     str     r2, [r6], #4    @ cache hi priority tile data\r
565     b       .dsloop\r
566 \r
567 .dsloop_exit:\r
568     ands    r4,r10, #7<<16        @ hscroll?\r
569     beq     .DrawStrip_noscroll\r
570 \r
571     and     r7, r5, r8         @ do one more cut tile\r
572     add     r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords)\r
573     ldrh    r9, [r7, r12]      @ r7=code (int, but from unsigned, no sign extend)\r
574 \r
575     add     r1, r1, #8\r
576 \r
577     tst     r9, #0x1000     @ if (code&0x1000)\r
578     mov     r2, r9, lsl #21\r
579     add     r2, r2, r10, lsl #17\r
580     eorne   r2, r2, #0x0e<<17 @ if (code&0x1000) addr^=0xe;\r
581 \r
582     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
583 \r
584     mvn     r7, #0\r
585     mov     r4, r4, lsr #16-2  @ (dx&7)*4\r
586     tst     r9, #0x0800\r
587     moveq   r7, r7, lsl r4     @ mask = ~0 [shift] (dx&7)*4\r
588     movne   r7, r7, lsr r4\r
589     and     r2, r2, r7, ror #16 @ pack&mask\r
590 \r
591     bic     r10,r10, #7<<16\r
592     b       .DrawStrip_samecode @ one last time, with last tile now masked\r
593 \r
594 .DrawStrip_noscroll:\r
595     tst     r10, #1<<21 @ seen non hi-prio tile\r
596     ldr     r1, [sp, #9*4]  @ est\r
597     mov     r0, #0\r
598     ldreq   r2, [r1, #OFS_EST_rendstatus]\r
599     str     r0, [r6]    @ terminate the cache list\r
600     orreq   r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
601     streq   r2, [r1, #OFS_EST_rendstatus]\r
602 \r
603     ldmfd   sp!, {r4-r11,pc}\r
604 \r
605 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
606 \r
607 .DrawStrip_vsscroll:\r
608     tst     r8, #1                @ if h40: lflags |= 0x10000\r
609     orrne   r0, r0, #0x10000\r
610 \r
611     rsb     r8, r3, #0\r
612     mov     r8, r8, lsr #3        @ r8=tilex=(-ts->hscroll)>>3\r
613     bic     r8, r8, #0x3fc00000\r
614     orr     r8, r8, r5, lsl #25   @ r8=(xmask[31:25]|had_output[24]|!force[23]|tilex[21:0])\r
615 \r
616     ldr     r11, [sp, #9*4]       @ est\r
617     orr     r5, r1, r10, lsl #24\r
618     ldr     r4, [r11, #OFS_EST_DrawScanline]\r
619     sub     r1, r3, #1\r
620     orr     r5, r5, r4, lsl #16   @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0])\r
621     and     r1, r1, #7\r
622     add     r7, r1, #1            @ r7=dx=((ts->hscroll-1)&7)+1\r
623 \r
624     mov     r10,r9, lsl #16\r
625     orr     r10,r10, #0xff000000  @ will be adjusted on entering loop\r
626     tst     r0, #1\r
627     orrne   r10,r10, #0x8000\r
628     tst     r3, #0x0f             @ hscroll & 0x0f?\r
629     beq     0f\r
630     eor     r3, r3, r7\r
631     sub     r10,r10, #1<<24       @ cell--  // start from negative for hscroll\r
632     tst     r3, #0x08\r
633     subne   r10,r10, #1<<16       @ cells--\r
634     subne   r10,r10, #1<<24       @ cell--  // even more negative\r
635 \r
636     add_c24 r1, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
637     tst     r0, #0x10000          @ h40?\r
638     ldrne   r3, [r1, #0x00]       @ r3=vsram[0x00..0x01]\r
639     ldreq   r3, [r1, #0x40]       @ r3=vsram[0x20..0x21]\r
640     str     r3, [r1, #0x7c]       @ vsram[0x3e..0x3f]=r3\r
641 0:\r
642     tst     r9, #1<<30\r
643     mov     r3, #0\r
644     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
645     movne   r3, #0x80       @ default to shadowed pal on sh mode\r
646 @    tst     r9, #1<<31\r
647 @    orreq   r8, r8, #1<<23\r
648 \r
649     and     r9, r9, #0xff00\r
650     add     r8, r8, r9, lsr #8   @ tilex+=cellskip\r
651     add     r7, r7, r9, lsr #5   @ dx+=cellskip<<3;\r
652     add     r10,r10,r9, lsl #16  @ cell+=cellskip\r
653 \r
654     @ cache some stuff to avoid mem access\r
655     ldr     r11,[sp, #9*4]       @ est\r
656     mov     r0, #0xf\r
657     ldr     r11,[r11, #OFS_EST_HighCol]\r
658 \r
659     mvn     r9, #0               @ r9=prevcode=-1\r
660     add     r1, r11, r7          @ r1=pdest\r
661 \r
662     @ r10=cells[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0]\r
663     @ r8=xmask[31:25]|had_output[24]|!force[23]|tilex[21:0]\r
664     @ r5=shift_width[31:24]|scanline[23:16]|ymask[15:0]\r
665     @ r3=nametabadd[31:16]|must_be_0[15:8]|pal[7:0]\r
666     @ r1=pd+dx r2=pack r6=hc r9=prevcode r11=HighCol r12=nametab lr=vram\r
667     @ r4 & r7 are scratch in this loop\r
668 \r
669     @ need to calc new ty?\r
670     movs    r7, r10, lsl #7       @ (cell&1)?\r
671     bmi     .dsloop_vs_subr1\r
672 \r
673     @ calc offset and read tileline code to r7, also calc ty\r
674     add_c24 r7, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
675     and     r4, r10, #0x3e000000\r
676     add     r7, r7, r4, asr #23   @ vsram + ((cell&0x3e)<<1)\r
677     tst     r10,#0x8000           @ plane1?\r
678     addne   r7, r7, #2\r
679     ldrh    r7, [r7]              @ r7=vscroll\r
680 \r
681     bic     r10,r10,#0xff         @ clear old ty\r
682     and     r4, r5, #0xff0000     @ scanline\r
683     add     r4, r4, r7, lsl #16   @ ... += vscroll\r
684     and     r4, r4, r5, lsl #16   @ ... &= ymask\r
685     and     r7, r4, #0x70000\r
686     orr     r10,r10,r7, lsr #15   @ new ty\r
687 \r
688     mov     r4, r4, lsr #19\r
689     mov     r7, r5, lsr #24\r
690     mov     r4, r4, lsl r7        @ nametabadd\r
691     and     r3, r3, #0xff\r
692     orr     r3, r3, r4, lsl #16   @ r3=(nametabadd[31:16],pal[15:0])\r
693 \r
694 .dsloop_vs_subr1:\r
695     sub     r1, r1, #8\r
696 .dsloop_vs: @ 40-41 times\r
697     add     r10,r10, #0x01000000\r
698     and     r4, r10, #0x003f0000\r
699     cmp     r4, r10, asr #8\r
700     ble     .dsloop_vs_exit\r
701 \r
702     @ need to calc new ty?\r
703     movs    r7, r10, lsl #7       @ (cell&1)?\r
704     bmi     0f\r
705 \r
706     @ calc offset and read tileline code to r7, also calc ty\r
707     add_c24 r7, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
708     and     r4, r10, #0x3e000000\r
709     add     r7, r7, r4, asr #23   @ vsram + ((cell&0x3e)<<1)\r
710     tst     r10,#0x8000           @ plane1?\r
711     addne   r7, r7, #2\r
712     ldrh    r7, [r7]              @ r7=vscroll\r
713 \r
714     bic     r10,r10,#0xff         @ clear old ty\r
715     and     r4, r5, #0xff0000     @ scanline\r
716     add     r4, r4, r7, lsl #16   @ ... += vscroll\r
717     and     r4, r4, r5, lsl #16   @ ... &= ymask\r
718     and     r7, r4, #0x70000\r
719     orr     r10,r10,r7, lsr #15   @ new ty\r
720 \r
721     mov     r4, r4, lsr #19\r
722     mov     r7, r5, lsr #24\r
723     mov     r4, r4, lsl r7        @ nametabadd\r
724     and     r3, r3, #0xff\r
725     orr     r3, r3, r4, lsl #16   @ r3=(nametabadd[31:16],pal[15:0])\r
726 0:\r
727     and     r7, r8, r8, lsr #25\r
728     add     r7, lr, r7, lsl #1    @ PicoMem.vram+((tilex&ts->xmask) as halfwords)\r
729     add     r7, r7, r3, lsr #15\r
730     ldrh    r7, [r7, r12]         @ r7=code (int, but from unsigned, no sign extend)\r
731 \r
732     add     r1, r1, #8\r
733     add     r8, r8, #1\r
734 \r
735     orr     r7, r7, r10, lsl #24  @ code | (ty << 24)\r
736     cmp     r7, r9\r
737     beq     .DrawStrip_vs_samecode @ we know stuff about this tile already\r
738 \r
739     mov     r9, r7          @ remember code\r
740 \r
741     tst     r9, #0x1000     @ if (code&0x1000)\r
742     mov     r2, r9, lsl #21\r
743     add     r2, r2, r10, lsl #17\r
744     eorne   r2, r2, #0x0e<<17 @ if (code&0x1000) addr^=0xe;\r
745 \r
746     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
747 \r
748 .DrawStrip_vs_samecode:\r
749     tst     r9, #0x8000\r
750 @    tstne   r8, #1<<23     @ !force[23]\r
751     bne     .DrawStrip_vs_hiprio\r
752 \r
753     orr     r8, r8, #(1<<24)@ seen non hi-prio tile\r
754     tst     r2, r2\r
755     beq     .dsloop_vs              @ tileline blank\r
756 \r
757     bic     r7, r3, #0x7f\r
758     and     r3, r9, #0x6000\r
759     add     r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9);\r
760 \r
761     cmp     r2, r2, ror #4\r
762     beq     .DrawStrip_vs_SingleColor @ tileline singlecolor \r
763 \r
764     tst     r9, #0x0800\r
765     bne     .DrawStrip_vs_TileFlip\r
766 \r
767     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
768 .DrawStrip_vs_TileNorm:\r
769     TileNorm r0\r
770     b       .dsloop_vs\r
771 \r
772 .DrawStrip_vs_TileFlip:\r
773     TileFlip r0\r
774     b       .dsloop_vs\r
775 \r
776 .DrawStrip_vs_SingleColor:\r
777     and     r4, r2, #0xf\r
778     orr     r4, r3, r4\r
779     orr     r4, r4, r4, lsl #8\r
780     tst     r1, #1             @ not aligned?\r
781     strneb  r4, [r1], #1\r
782     streqh  r4, [r1], #2\r
783     strh    r4, [r1], #2\r
784     strh    r4, [r1], #2\r
785     strh    r4, [r1], #2\r
786     strneb  r4, [r1], #1       @ have a remaining unaligned pixel?\r
787     b       .dsloop_vs_subr1\r
788 \r
789 .DrawStrip_vs_hiprio:\r
790     tst     r10, #(1<<23)   @ sh[23]\r
791     tsteq   r2, r2          @ if (!sh[23] && code==blank) continue\r
792     beq     .dsloop_vs\r
793 \r
794 @    orr     r10, r10, #1<<22 @ hi_not_empty[22]\r
795     sub     r7, r1, r11\r
796     orr     r7, r9, r7,  lsl #16\r
797     orr     r7, r7, r10, lsl #25 @ (ty<<25)\r
798     tst     r9, #0x1000\r
799     eorne   r7, r7, #7<<26  @ if(code&0x1000) cval^=7<<26;\r
800     str     r7, [r6], #4    @ cache hi priority tile code\r
801     str     r2, [r6], #4    @ cache hi priority tile data\r
802     b       .dsloop_vs\r
803 \r
804 .dsloop_vs_exit:\r
805     tst     r8, #(1<<24) @ seen non hi-prio tile\r
806     ldr     r1, [sp, #9*4]  @ est\r
807     mov     r0, #0\r
808     ldreq   r2, [r1, #OFS_EST_rendstatus]\r
809     str     r0, [r6]    @ terminate the cache list\r
810     orreq   r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles\r
811     streq   r2, [r1, #OFS_EST_rendstatus]\r
812 \r
813     ldmfd   sp!, {r4-r11,pc}\r
814 \r
815 \r
816 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
817 \r
818 @ interlace mode 2? Sonic 2?\r
819 .DrawStrip_interlace:\r
820     tst     r0, r0\r
821     movne   r7, r7, lsr #16\r
822     mov     r7, r7, lsl #21\r
823 \r
824     @ Find the line in the name table\r
825     add     r2, r7, r2, lsl #22    @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);\r
826     orr     r1, r1, #0x80000000\r
827     and     r2, r2, r1, ror #10    @ &((ymask<<1)|1)<<21;\r
828     mov     r2, r2, lsr #21\r
829     mov     r4, r2, lsr #4\r
830     mov     r12, r12, lsr #1       @ halfwords\r
831     add     r0, r12, r4, lsl r10   @ nametab+=(ts.line>>4)<<shift[width];\r
832     and     r9, r9, #0xff\r
833 \r
834     sub     sp, sp, #6*4\r
835     stmia   sp, {r0,r2,r3,r5,r6,r9}\r
836 \r
837     mov     r0, sp\r
838     mov     r1, r9, lsr #29\r
839     mov     r2, r9, lsr #8\r
840     and     r2, r2, #0xff\r
841     bl      DrawStripInterlace @ struct TileStrip *ts, int plane_sh, int cellskip\r
842 \r
843     add     sp, sp, #6*4\r
844     ldmfd   sp!, {r4-r11,pc}\r
845 \r
846 .pool\r
847 \r
848 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
849 \r
850 @ void BackFill(int reg7, int sh, struct PicoEState *est)\r
851 \r
852 .global BackFill\r
853 \r
854 BackFill:\r
855     stmfd   sp!, {r4-r9,lr}\r
856 \r
857     ldr     lr, [r2, #OFS_EST_HighCol]\r
858     orr     r0, r0, r1, lsl #7\r
859     orr     r0, r0, r0, lsl #8\r
860     orr     r0, r0, r0, lsl #16\r
861 \r
862     mov     r1, r0\r
863     mov     r2, r0\r
864     mov     r3, r0\r
865     mov     r4, r0\r
866     mov     r5, r0\r
867     mov     r6, r0\r
868     mov     r7, r0\r
869 \r
870     @ go go go!\r
871     add     lr, lr, #8\r
872     stmia   lr!, {r0-r7} @ 10*8*4\r
873     stmia   lr!, {r0-r7}\r
874     stmia   lr!, {r0-r7}\r
875     stmia   lr!, {r0-r7}\r
876     stmia   lr!, {r0-r7}\r
877     stmia   lr!, {r0-r7}\r
878     stmia   lr!, {r0-r7}\r
879     stmia   lr!, {r0-r7}\r
880     stmia   lr!, {r0-r7}\r
881     stmia   lr!, {r0-r7}\r
882 \r
883     ldmfd   sp!, {r4-r9,pc}\r
884 \r
885 \r
886 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
887 \r
888 @ void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est)\r
889 \r
890 .global DrawTilesFromCache\r
891 \r
892 DrawTilesFromCache:\r
893     stmfd   sp!, {r4-r9,r11,lr}\r
894 \r
895     @ cache some stuff to avoid mem access\r
896     ldr     r11,[r3, #OFS_EST_HighCol]\r
897     mov     r12,#0xf\r
898     ldr     lr, [r3, #OFS_EST_PicoMem_vram]\r
899     mov     r9, r3         @ est\r
900 \r
901     ands    r8, r1, #1\r
902     orr     r8, r8, r2, lsl #1\r
903     bne     .dtfc_check_rendflags\r
904 \r
905     @ scratch: r4, r7\r
906 .dtfc_loop:\r
907     ldr     r6, [r0], #4    @ read code\r
908     movs    r1, r6, lsr #16 @ r1=dx;\r
909     ldmeqfd sp!, {r4-r9,r11,pc} @ dx is never zero, this must be a terminator, return\r
910     bic     r4, r1, #0xfe00\r
911     add     r1, r11, r4     @ r1=pdest\r
912 \r
913     ldr     r2, [r0], #4    @ read pixel data\r
914 \r
915     and     r3, r6, #0x6000\r
916     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
917 \r
918     rsbs    r4, r4, r8, lsr #1\r
919     bmi     .dtfc_cut_tile\r
920 \r
921     tst     r8, #1\r
922     bne     .dtfc_shadow\r
923 \r
924     tst     r2, r2\r
925     beq     .dtfc_loop\r
926 \r
927     cmp     r2, r2, ror #4\r
928     beq     .dtfc_SingleColor @ tileline singlecolor \r
929 \r
930     tst     r6, #0x0800\r
931     bne     .dtfc_TileFlip\r
932 \r
933     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
934 .dtfc_TileNorm:\r
935     TileNorm r12\r
936     b       .dtfc_loop\r
937 \r
938 .dtfc_TileFlip:\r
939     TileFlip r12\r
940     b       .dtfc_loop\r
941 \r
942 .dtfc_SingleColor:\r
943     and     r4, r2, #0xf\r
944     orr     r4, r3, r4\r
945     orr     r4, r4, r4, lsl #8\r
946     tst     r1, #1              @ not aligned?\r
947     strneb  r4, [r1], #1\r
948     streqh  r4, [r1], #2\r
949     strh    r4, [r1], #2\r
950     strh    r4, [r1], #2\r
951     strh    r4, [r1], #2\r
952     strneb  r4, [r1], #1        @ have a remaining unaligned pixel?\r
953     b       .dtfc_loop\r
954 \r
955 .dtfc_shadow:\r
956     tst     r2, r2\r
957     beq     .dtfc_shadow_blank\r
958 \r
959     cmp     r2, r2, ror #4\r
960     beq     .dtfc_SingleColor @ tileline singlecolor \r
961 \r
962     tst     r6, #0x0800\r
963     bne     .dtfc_TileFlipShHP\r
964 \r
965     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
966 .dtfc_TileNormShHP:\r
967     TileNormShHP\r
968     b       .dtfc_loop\r
969 \r
970 .dtfc_TileFlipShHP:\r
971     TileFlipShHP\r
972     b       .dtfc_loop\r
973 \r
974 .dtfc_shadow_blank:\r
975     tst     r1, #1\r
976     ldrneb  r4, [r1]\r
977     mov     r6, #0x7f\r
978     and     r4, r4, r6\r
979     strneb  r4, [r1], #1\r
980     ldrh    r4, [r1]\r
981     orr     r6, r6, r6, lsl #8\r
982     and     r4, r4, r6\r
983     strh    r4, [r1], #2\r
984     ldrh    r4, [r1]\r
985     and     r4, r4, r6\r
986     strh    r4, [r1], #2\r
987     ldrh    r4, [r1]\r
988     and     r4, r4, r6\r
989     strh    r4, [r1], #2\r
990     ldrh    r4, [r1]\r
991     and     r4, r4, r6\r
992     streqh  r4, [r1]\r
993     strneb  r4, [r1]\r
994     b       .dtfc_loop\r
995 \r
996 .dtfc_cut_tile:\r
997     cmn     r4, #8\r
998     ble     .dtfc_loop      @ off limits\r
999 \r
1000     rsb     r4, r4, #0      @ 1-7\r
1001     mov     r4, r4, lsl #2\r
1002     mvn     r12,#0\r
1003     tst     r6, #0x0800     @ flipped?\r
1004     moveq   r12,r12, lsl r4\r
1005     movne   r12,r12, lsr r4\r
1006     and     r2, r2, r12, ror #16\r
1007     mov     r12,#0xf\r
1008     tst     r8, #1\r
1009     bne     .dtfc_shadow\r
1010     tst     r2, r2\r
1011     beq     .dtfc_loop\r
1012     tst     r6, #0x0800\r
1013     beq     .dtfc_TileNorm\r
1014     b       .dtfc_TileFlip\r
1015 \r
1016 @ check if we have detected layer covered with hi-prio tiles:\r
1017 .dtfc_check_rendflags:\r
1018     ldr     r2, [r9, #OFS_EST_rendstatus]\r
1019     tst     r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE)\r
1020     beq     .dtfc_loop\r
1021     bic     r8, r8, #1      @ sh/hi mode off\r
1022     tst     r2, #PDRAW_SHHI_DONE\r
1023     bne     .dtfc_loop      @ already processed\r
1024     orr     r2, r2, #PDRAW_SHHI_DONE\r
1025     str     r2, [r9, #OFS_EST_rendstatus]\r
1026 \r
1027     add     r1, r11,#8\r
1028     mov     r3, #320/4/4\r
1029     mov     r6, #0x7f\r
1030     orr     r6, r6, r6, lsl #8\r
1031     orr     r6, r6, r6, lsl #16\r
1032 .dtfc_loop_shprep:\r
1033     ldmia   r1, {r2,r4,r5,r7}\r
1034     subs    r3, r3, #1\r
1035     and     r2, r2, r6\r
1036     and     r4, r4, r6\r
1037     and     r5, r5, r6\r
1038     and     r7, r7, r6\r
1039     stmia   r1!,{r2,r4,r5,r7}\r
1040     bne     .dtfc_loop_shprep\r
1041 \r
1042     b       .dtfc_loop\r
1043 \r
1044 .pool\r
1045 \r
1046 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1047 \r
1048 \r
1049 @ void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est)\r
1050 \r
1051 .global DrawSpritesSHi\r
1052 \r
1053 DrawSpritesSHi:\r
1054     ldrb    r3, [r0]\r
1055     mov     r12,#0xff\r
1056     ands    r3, r3, #0x7f\r
1057     bxeq    lr\r
1058 \r
1059     stmfd   sp!, {r1,r3-r11,lr} @ +est\r
1060     strb    r12,[r0,#3]     @ set end marker\r
1061     ldrb    r12,[r0,#1]\r
1062     add     r10,r0, #4      @ r10=HighLnSpr end\r
1063     mvn     r12,r12\r
1064     tst     r12,#0x6        @ masking in slot 1 and tile ovfl?\r
1065     ldmeqfd sp!, {r1,r3-r11,pc}\r
1066     add     r10,r10,r3      @ r10=HighLnSpr end\r
1067 \r
1068     ldrb    r12,[r10,#0]    @ width of last sprite\r
1069     ldr     r11,[r1, #OFS_EST_HighCol]\r
1070     str     r12,[sp, #4]\r
1071     mov     r12,#0xf\r
1072     ldr     lr, [r1, #OFS_EST_PicoMem_vram]\r
1073 \r
1074 \r
1075 DrawSpriteSHi:\r
1076     @ draw next sprite\r
1077     ldr     r7, [sp]        @ est\r
1078     ldrb    r0, [r10,#-1]!\r
1079     ldr     r1, [r7, #OFS_EST_HighPreSpr]\r
1080     cmp     r0, #0xff\r
1081     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
1082     and     r0, r0, #0x7f\r
1083     add     r0, r1, r0, lsl #3\r
1084 \r
1085     ldr     r9, [r0, #4]    @ sprite[1]\r
1086     mov     r2, r9, asr #16 @ r2=sx\r
1087 \r
1088     mov     r9, r9, lsl #16\r
1089     mov     r3, r9, lsr #31 @ priority\r
1090     mov     r9, r9, lsr #16\r
1091 @    orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]   @@ sh is always on here now\r
1092     and     r4, r9, #0x6000\r
1093     orr     r9, r9, r4, lsl #16\r
1094     orr     r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1095     cmp     r12,r9, lsr #28 @ sh/hi with pal3?\r
1096     cmpne   r3, #1          @ if not, is it hi prio?\r
1097     strne   r3, [sp, #4]    @ reset last sprite width\r
1098     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn\r
1099 \r
1100     ldr     r3, [r0]        @ sprite[0]\r
1101     mov     r6, r3, lsr #28\r
1102     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1103     mov     r5, r3, lsr #24\r
1104     and     r5, r5, #7      @ r5=height\r
1105 \r
1106     ldr     r7, [r7, #OFS_EST_DrawScanline]\r
1107     mov     r0, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1108 \r
1109     sub     r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy\r
1110 \r
1111     tst     r9, #0x1000\r
1112     movne   r0, r5, lsl #3\r
1113     subne   r0, r0, #1\r
1114     subne   r7, r0, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1115 \r
1116     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1117     tst     r9, #0x0800\r
1118     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1119     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1120 \r
1121     mov     r8, r8, lsl #21\r
1122     mov     r8, r8, lsr #17\r
1123     and     r7, r7, #7\r
1124     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1125 \r
1126     ldr     r0, [sp, #4]\r
1127     add     r6, r6, #1         @ inc now\r
1128     cmp     r0, #0             @ check width of last sprite\r
1129     movne   r6, r0\r
1130     movne   r0, #0\r
1131     strne   r0, [sp, #4]\r
1132 \r
1133     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1134     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1135 \r
1136     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1137     b       .dsprShi_loop_enter\r
1138 \r
1139 .dsprShi_loop:\r
1140     subs    r6, r6, #1         @ width--\r
1141     beq     DrawSpriteSHi\r
1142     adds    r0, r0, #8         @ sx+=8\r
1143     add     r8, r8, r5         @ tile+=delta\r
1144 \r
1145 .dsprShi_loop_enter:\r
1146     ble     .dsprShi_loop     @ sx <= 0\r
1147     cmp     r0, #328\r
1148     bge     DrawSpriteSHi\r
1149 \r
1150     bic     r8, r8, #0xf8000   @ tile&=0x7fff; // Clip tile address\r
1151     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
1152     add     r1, r11, r0        @ r1=pdest\r
1153     tst     r2, r2\r
1154     beq     .dsprShi_loop\r
1155 \r
1156     cmp     r12, r9, lsr #28\r
1157     beq     .dsprShi_shadow\r
1158 \r
1159     cmp     r2, r2, ror #4\r
1160     beq     .dsprShi_SingleColor @ tileline singlecolor \r
1161 \r
1162     tst     r9, #0x0800\r
1163     bne     .dsprShi_TileFlip\r
1164 \r
1165     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1166 @ scratch: r4, r7\r
1167 .dsprShi_TileNorm:\r
1168     TileNorm r12\r
1169     b       .dsprShi_loop\r
1170 \r
1171 .dsprShi_TileFlip:\r
1172     TileFlip r12\r
1173     b       .dsprShi_loop\r
1174 \r
1175 .dsprShi_SingleColor:\r
1176     and     r4, r2, #0xf\r
1177     orr     r4, r3, r4\r
1178     orr     r4, r4, r4, lsl #8\r
1179     tst     r0, #1              @ not aligned?\r
1180     strneb  r4, [r1], #1\r
1181     streqh  r4, [r1], #2\r
1182     strh    r4, [r1], #2\r
1183     strh    r4, [r1], #2\r
1184     strh    r4, [r1], #2\r
1185     strneb  r4, [r1], #1\r
1186     b       .dsprShi_loop\r
1187 \r
1188 .dsprShi_shadow:\r
1189     tst     r9, #0x8000\r
1190     beq     .dsprShi_shadow_lowpri\r
1191 \r
1192     cmp     r2, r2, ror #4\r
1193     beq     .dsprShi_singlec_sh\r
1194 \r
1195     tst     r9, #0x0800\r
1196     bne     .dsprShi_TileFlip_sh\r
1197 \r
1198     @ (r1=pdest, r2=pixels8, r3=pal) r4, r7: scratch, r12: helper pattern\r
1199 .dsprShi_TileNorm_sh:\r
1200     TileNormSh\r
1201     b       .dsprShi_loop\r
1202 \r
1203 .dsprShi_TileFlip_sh:\r
1204     TileFlipSh\r
1205     b       .dsprShi_loop\r
1206 \r
1207 .dsprShi_singlec_sh:\r
1208     cmp     r2, #0xe0000000\r
1209     bcc     .dsprShi_SingleColor   @ normal singlecolor tileline (carry inverted in ARM)\r
1210     tst     r2, #0x10000000\r
1211     bne     .dsprShi_sh_sh\r
1212     TileSingleHi\r
1213     b       .dsprShi_loop\r
1214 \r
1215 .dsprShi_sh_sh:\r
1216     TileSingleSh\r
1217     b       .dsprShi_loop\r
1218 \r
1219 .dsprShi_shadow_lowpri:\r
1220     tst     r9, #0x800\r
1221     bne     .dsprShi_TileFlip_sh_lp\r
1222 \r
1223 .dsprShi_TileNorm_sh_lp:\r
1224     TileNormSh_onlyop_lp\r
1225     b       .dsprShi_loop\r
1226 \r
1227 .dsprShi_TileFlip_sh_lp:\r
1228     TileFlipSh_onlyop_lp\r
1229     b       .dsprShi_loop\r
1230 \r
1231 .pool\r
1232 \r
1233 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1234 \r
1235 @ void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
1236 @                     struct PicoEState *est)\r
1237 \r
1238 .global DrawAllSprites\r
1239 \r
1240 DrawAllSprites:\r
1241     orr     r1, r2, r1, lsl #1\r
1242     ldr     r2, [r0]\r
1243     ands    r2, r2, #0x7f\r
1244     bxeq    lr\r
1245 \r
1246     @ time to do some real work\r
1247     stmfd   sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est\r
1248     mov     r12,#0xff\r
1249     strb    r12,[r0,#3]     @ set end marker\r
1250     ldrb    r12,[r0,#1]\r
1251     add     r10,r0 ,#4\r
1252     mvn     r12,r12\r
1253     tst     r12,#0x6        @ masking in slot 1 and tile ovfl?\r
1254     ldmeqfd sp!, {r1,r3-r11,pc}\r
1255     add     r10,r10,r2      @ r10=HighLnSpr end\r
1256 \r
1257     ldrb    r12,[r10,#0]    @ width of last sprite\r
1258     ldr     r11,[r3, #OFS_EST_HighCol]\r
1259     orr     r1 ,r1 ,r12,lsl #24\r
1260     str     r1, [sp]\r
1261     mov     r12,#0xf\r
1262     ldr     lr, [r3, #OFS_EST_PicoMem_vram]\r
1263 \r
1264 @ + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size\r
1265 @ + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
1266 \r
1267 DrawSprite:\r
1268     @ draw next sprite\r
1269     ldrb    r0, [r10,#-1]!\r
1270     ldr     r4, [sp]        @ sh|prio<<1|lastw<<24\r
1271     ldr     r7, [sp, #4]    @ est\r
1272     mov     r2, r0, lsl #24\r
1273     cmp     r0, #0xff\r
1274     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
1275     eors    r2, r2, r4, lsl #30\r
1276     bic     r2, r4, #0xff000000\r
1277     str     r2, [sp]\r
1278     bmi     DrawSprite      @ wrong priority\r
1279     ldr     r1, [r7, #OFS_EST_HighPreSpr]\r
1280     and     r0, r0, #0x7f\r
1281     add     r0, r1, r0, lsl #3\r
1282 \r
1283     ldr     r3, [r0]        @ sprite[0]\r
1284     ldr     r7, [r7, #OFS_EST_DrawScanline]\r
1285     mov     r6, r3, lsr #28\r
1286     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1287     mov     r5, r3, lsr #24\r
1288     and     r5, r5, #7      @ r5=height\r
1289 \r
1290     mov     r8, r3, lsl #16 @ r8=sy<<16 (tmp)\r
1291 \r
1292     ldr     r9, [r0, #4]\r
1293     sub     r7, r7, r8, asr #16 @ r7=row=DrawScanline-sy\r
1294 \r
1295     mov     r2, r9, asr #16 @ r2=sx\r
1296     mov     r9, r9, lsl #16\r
1297     mov     r9, r9, lsr #16\r
1298     orr     r9, r9, r4, lsl #31 @ r9=code|sh[31]\r
1299 \r
1300     tst     r9, #0x1000\r
1301     movne   r8, r5, lsl #3\r
1302     subne   r8, r8, #1\r
1303     subne   r7, r8, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1304 \r
1305     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1306     tst     r9, #0x0800\r
1307     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1308     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1309 \r
1310     mov     r8, r8, lsl #21\r
1311     mov     r8, r8, lsr #17\r
1312     and     r7, r7, #7\r
1313     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1314 \r
1315     add     r6, r6, #1         @ inc now\r
1316     cmp     r4, #0x1000000     @ check width of last sprite\r
1317     movhs   r6, r4, lsr #24\r
1318 \r
1319     @ cache some stuff to avoid mem access\r
1320     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1321     and     r4, r9, #0x6000\r
1322     orr     r9, r9, r4, lsl #16\r
1323     orrs    r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1324 \r
1325     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1326     orrmi   r3, r3, #0x80      @ for sh/hi\r
1327 \r
1328     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1329     b       .dspr_loop_enter\r
1330 \r
1331 .dspr_loop:\r
1332     subs    r6, r6, #1         @ width--\r
1333     beq     DrawSprite\r
1334     adds    r0, r0, #8         @ sx+=8\r
1335     add     r8, r8, r5         @ tile+=delta\r
1336 \r
1337 .dspr_loop_enter:\r
1338     ble     .dspr_loop         @ sx <= 0\r
1339     cmp     r0, #328\r
1340     bge     DrawSprite\r
1341 \r
1342     bic     r8, r8, #0xf8000   @ tile&=0x7fff; // Clip tile address\r
1343     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
1344     add     r1, r11, r0        @ r1=pdest\r
1345     tst     r2, r2\r
1346     beq     .dspr_loop\r
1347 \r
1348     cmp     r12, r9, lsr #28\r
1349     beq     .dspr_shadow\r
1350 \r
1351     tst     r9, #0x80000000\r
1352     bne     .dspr_shnonsh\r
1353 \r
1354     cmp     r2, r2, ror #4\r
1355     beq     .dspr_SingleColor @ tileline singlecolor \r
1356 \r
1357     tst     r9, #0x0800\r
1358     bne     .dspr_TileFlip\r
1359 \r
1360     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1361 @ scratch: r4, r7\r
1362 .dspr_TileNorm:\r
1363     TileNorm r12\r
1364     b       .dspr_loop\r
1365 \r
1366 .dspr_TileFlip:\r
1367     TileFlip r12\r
1368     b       .dspr_loop\r
1369 \r
1370 .dspr_singlec_sh:\r
1371     cmp     r2, #0xe0000000\r
1372     bcs     .dspr_TileNorm_sh   @ op. tileline, markop. XXX: maybe add a spec. handler?\r
1373 \r
1374 .dspr_SingleColor:\r
1375     and     r4, r2, #0xf\r
1376     orr     r4, r3, r4\r
1377     orr     r4, r4, r4, lsl #8\r
1378     tst     r0, #1              @ not aligned?\r
1379     strneb  r4, [r1], #1\r
1380     streqh  r4, [r1], #2\r
1381     strh    r4, [r1], #2\r
1382     strh    r4, [r1], #2\r
1383     strh    r4, [r1], #2\r
1384     strneb  r4, [r1], #1\r
1385     b       .dspr_loop\r
1386 \r
1387 .dspr_shnonsh:\r
1388     tst     r9, #0x0800\r
1389     bne     .dspr_TileFlipNonSH\r
1390 \r
1391     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1392 @ scratch: r4, r7\r
1393 .dspr_TileNormNonSH:\r
1394     TileNormNonSH r12\r
1395     b       .dspr_loop\r
1396 \r
1397 .dspr_TileFlipNonSH:\r
1398     TileFlipNonSH r12\r
1399     b       .dspr_loop\r
1400 \r
1401 .dspr_shadow:\r
1402     cmp     r2, r2, ror #4\r
1403     beq     .dspr_singlec_sh\r
1404 \r
1405     tst     r9, #0x0800\r
1406     bne     .dspr_TileFlip_sh\r
1407 \r
1408     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1409 .dspr_TileNorm_sh:\r
1410     TileNormSh_markop\r
1411     b       .dspr_loop\r
1412 \r
1413 .dspr_TileFlip_sh:\r
1414     TileFlipSh_markop\r
1415     b       .dspr_loop\r
1416 \r
1417 \r
1418 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1419 \r
1420 @ void DrawWindow(int tstart, int tend, int prio, int sh\r
1421 @                 struct PicoEState *est)\r
1422 \r
1423 .global DrawWindow\r
1424 \r
1425 DrawWindow:\r
1426     ldr     r12, [sp]             @ est\r
1427     stmfd   sp!, {r4-r11,lr}\r
1428 \r
1429     ldr     r6,  [r12, #OFS_EST_Pico]\r
1430     ldr     r10, [r12, #OFS_EST_DrawScanline]\r
1431     mov     r11, r12              @ est\r
1432     ldrb    r12, [r6, #OFS_Pico_video_reg+3] @ pvid->reg[3]\r
1433 \r
1434     ldr     r4,  [r6, #OFS_Pico_video_reg+12]\r
1435     mov     r5,  r10, lsr #3\r
1436     and     r10, r10, #7\r
1437     mov     r10, r10, lsl #1      @ r10=ty\r
1438 \r
1439     ldr     r6, [r11, #OFS_EST_rendstatus]\r
1440     ldr     lr, [r11, #OFS_EST_PicoMem_vram]\r
1441 \r
1442     mov     r12, r12, lsl #10\r
1443 \r
1444     tst     r4, #1                @ 40 cell mode?\r
1445     andne   r12, r12, #0xf000     @ 0x3c<<10\r
1446     andeq   r12, r12, #0xf800\r
1447     addne   r12, r12, r5, lsl #7\r
1448     addeq   r12, r12, r5, lsl #6  @ nametab\r
1449     add     r12, r12, r0, lsl #2  @ +starttile\r
1450 \r
1451     ands    r6, r6, #PDRAW_WND_DIFF_PRIO\r
1452     cmpeq   r2, #1                @ prio && !(rendstatus & WND_DIFF_PRIO)?\r
1453     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
1454 \r
1455     orr     r6, r6, r2\r
1456     orr     r6, r6, r3, lsl #8    @ shadow mode\r
1457 \r
1458     sub     r8, r1, r0\r
1459 \r
1460     @ cache some stuff to avoid mem access\r
1461     ldr     r11, [r11, #OFS_EST_HighCol]\r
1462     mov     r8, r8, lsl #1        @ cells\r
1463     mvn     r9, #0                @ r9=prevcode=-1\r
1464     add     r1, r11, r0, lsl #4   @ r1=pdest=HighCol+starttile (+8 added in loop)\r
1465     mov     r0, #0xf\r
1466 \r
1467     @ r4,r5 are scratch in this loop\r
1468 .dwloop:\r
1469     add     r1, r1, #8\r
1470 .dwloop_nor1:\r
1471     ldrh    r7, [lr, r12]   @ r7=code (int, but from unsigned, no sign extend)\r
1472     add     r12, r12, #2    @ halfwords\r
1473     subs    r8, r8, #1\r
1474     bmi     .dwloop_end     @ done\r
1475 \r
1476     eor     r5, r6, r7, lsr #15\r
1477     tst     r5, #1\r
1478     orrne   r6, r6, #PDRAW_WND_DIFF_PRIO @ wrong pri\r
1479     bne     .dwloop\r
1480 \r
1481     cmp     r7, r9\r
1482     beq     .dw_samecode    @ we know stuff about this tile already\r
1483 \r
1484     mov     r9, r7          @ remember code\r
1485 \r
1486     tst     r9, #0x1000     @ if (code&0x1000)\r
1487     mov     r2, r9, lsl #21\r
1488     add     r2, r2, r10, lsl #17\r
1489     eorne   r2, r2, #0xe<<17 @ if (code&0x1000) addr^=0xe;\r
1490 \r
1491     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1492 \r
1493     and     r3, r9, #0x6000\r
1494     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
1495 \r
1496 .dw_samecode:\r
1497     tst     r6, #0x100\r
1498     bne     .dw_shadow\r
1499 .dw_shadow_done:\r
1500     tst     r2, r2\r
1501     beq     .dwloop              @ tileline blank\r
1502 \r
1503     cmp     r2, r2, ror #4\r
1504     beq     .dw_SingleColor @ tileline singlecolor \r
1505 \r
1506     tst     r9, #0x0800\r
1507     bne     .dw_TileFlip\r
1508 \r
1509     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
1510 .dw_TileNorm:\r
1511     TileNorm r0\r
1512     b       .dwloop\r
1513 \r
1514 .dw_TileFlip:\r
1515     TileFlip r0\r
1516     b       .dwloop\r
1517 \r
1518 .dw_SingleColor:\r
1519     and     r4, r0, r2         @ #0x0000000f\r
1520     orr     r4, r3, r4\r
1521     orr     r4, r4, r4, lsl #8\r
1522     orr     r4, r4, r4, lsl #16\r
1523     mov     r5, r4\r
1524     stmia   r1!, {r4,r5}\r
1525     b       .dwloop_nor1       @ we incremented r1 ourselves\r
1526 \r
1527 .dw_shadow:\r
1528     tst     r6, #1             @ hi pri?\r
1529     orreq   r3, r3, #0x80\r
1530     beq     .dw_shadow_done\r
1531     ldr     r4, [r1]\r
1532     mov     r5, #0x7f\r
1533     orr     r5, r5, r5, lsl #8\r
1534     orr     r5, r5, r5, lsl #16\r
1535     and     r4, r4, r5\r
1536     str     r4, [r1]\r
1537     ldr     r4, [r1,#4]\r
1538     and     r4, r4, r5\r
1539     str     r4, [r1,#4]\r
1540     b       .dw_shadow_done\r
1541 \r
1542 .dwloop_end:\r
1543     and     r2, r6, #PDRAW_WND_DIFF_PRIO\r
1544     ldmfd   sp!, {r4-r11,lr}\r
1545     ldr     r0, [sp]\r
1546     ldr     r1, [r0, #OFS_EST_rendstatus]\r
1547     orr     r1, r1, r2\r
1548     str     r1, [r0, #OFS_EST_rendstatus]\r
1549 \r
1550     bx      lr\r
1551 \r
1552 \r
1553 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1554 \r
1555 \r
1556 @ Convert 0000bbb0 ggg0rrr0\r
1557 @ to      rrrrrggg gggbbbbb\r
1558 \r
1559 @ r2,r3 - scratch, lr = 0x001c001c, r8 = 0x08610861\r
1560 .macro convRGB565 reg\r
1561     and     r2,   lr,   \reg,lsr #7  @ b\r
1562     and     r3,   lr,   \reg,lsr #3  @ g\r
1563     and     \reg, lr,   \reg,lsl #1  @ r\r
1564     orr     r2,   r2,   r3,  lsl #6\r
1565     orr     \reg, r2,   \reg,lsl #11\r
1566 \r
1567     and     r2,   r8,   \reg,lsr #4\r
1568     orr     \reg, \reg, r2\r
1569 \r
1570     orr     r3,   \reg, \reg,lsr #1\r
1571     and     r3,   r3,   r8,lsl #2\r
1572     bic     r3,   r3,   r2,lsl #2\r
1573     orr     \reg, \reg, r3,lsr #1\r
1574 .endm\r
1575 \r
1576 @ trashes: r2-r8,r12,lr; r8 = 0x08610861; r0,r1 are advanced\r
1577 .macro vidConvCpyRGB565_local\r
1578     mov     r12, r2, lsr #3  @ repeats\r
1579     mov     lr, #0x001c0000\r
1580     orr     lr, lr,  #0x01c  @ lr == pattern 0x001c001c\r
1581 \r
1582 0:\r
1583     ldmia   r1!, {r4-r7}\r
1584     subs    r12, r12, #1\r
1585     convRGB565 r4\r
1586     str     r4, [r0], #4\r
1587     convRGB565 r5\r
1588     str     r5, [r0], #4\r
1589     convRGB565 r6\r
1590     str     r6, [r0], #4\r
1591     convRGB565 r7\r
1592     str     r7, [r0], #4\r
1593 \r
1594     bgt     0b\r
1595 .endm\r
1596 \r
1597 \r
1598 .global vidConvCpyRGB565\r
1599 \r
1600 vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1601     stmfd   sp!, {r4-r9,lr}\r
1602     mov     r8,     #0x0061\r
1603     orr     r8, r8, #0x0800\r
1604     orr     r8, r8, r8, lsl #16\r
1605     vidConvCpyRGB565_local\r
1606     ldmfd   sp!, {r4-r9,pc}\r
1607 \r
1608 \r
1609 @ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
1610 \r
1611 .global PicoDoHighPal555\r
1612 \r
1613 PicoDoHighPal555:\r
1614     stmfd   sp!, {r4-r10,lr}\r
1615     mov     r10,r2               @ est\r
1616     ldr     r8, [r10, #OFS_EST_Pico]\r
1617 \r
1618     mov     r9, r0\r
1619 \r
1620     add     r0, r10, #OFS_EST_HighPal\r
1621 \r
1622     mov     r1, #0\r
1623     strb    r1, [r8, #OFS_Pico_m_dirtyPal]\r
1624 \r
1625     ldr     r1, [r10, #OFS_EST_PicoMem_cram]\r
1626     mov     r2, #0x40\r
1627     mov     r8,     #0x0061\r
1628     orr     r8, r8, #0x0800\r
1629     orr     r8, r8, r8, lsl #16\r
1630 \r
1631     vidConvCpyRGB565_local\r
1632 \r
1633     cmp     r9, #0\r
1634     beq     PicoDoHighPal555_end\r
1635 \r
1636     add     r3, r10, #OFS_EST_HighPal\r
1637     add     r4, r3, #0x40*2\r
1638 \r
1639     @ hilighted pixels (0x40-0x7f):\r
1640     @  t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;\r
1641     @  t += 0x08610861;\r
1642     @ r8=0x08610861\r
1643     mov     r12,    #0x008e\r
1644     orr     r12,r12,#0x7300\r
1645     orr     r12,r12,r12,lsl #16\r
1646     add     r10,r12,r8\r
1647     mov     lr, #0x40/4\r
1648 .fl_loopcpRGB555_hi:\r
1649     ldmia   r3!, {r1,r6}\r
1650     and     r1, r12, r1, lsr #1\r
1651     and     r6, r12, r6, lsr #1\r
1652     add     r1, r10, r1\r
1653     add     r6, r10, r6\r
1654     stmia   r4!, {r1,r6}\r
1655     subs    lr, lr, #1\r
1656     bne     .fl_loopcpRGB555_hi\r
1657 \r
1658     sub     r3, r3, #0x40*2\r
1659     @ shadowed (0x80-0xbf), shadow|hilight (aka normal, 0xc0-0xff) pixels:\r
1660     @ t = (dpal[i] >> 1) & 0x738e738e;\r
1661     @ t += ((t>>2|t>>1|t>>0) & (0x08610861<<1));\r
1662     add     r5, r3, #0xc0*2\r
1663     mov     lr, #0x40/4\r
1664 .fl_loopcpRGB555_sh:\r
1665     ldmia   r3!, {r1,r6}\r
1666     subs    lr, lr, #1\r
1667     stmia   r5!, {r1,r6} @ 0xc0, normal\r
1668     and     r1, r12, r1, lsr #1\r
1669     orr     r0, r1, r1, lsr #1\r
1670     orr     r0, r0, r1, lsr #2\r
1671     and     r0, r0, r8, lsl #1\r
1672     add     r1, r1, r0\r
1673     and     r6, r12, r6, lsr #1\r
1674     orr     r0, r6, r6, lsr #1\r
1675     orr     r0, r0, r6, lsr #2\r
1676     and     r0, r0, r8, lsl #1\r
1677     add     r6, r6, r0\r
1678     stmia   r4!, {r1,r6}\r
1679     bne     .fl_loopcpRGB555_sh\r
1680 \r
1681     mov     r0, #1\r
1682 PicoDoHighPal555_end:\r
1683     ldmfd   sp!, {r4-r10,pc}\r
1684 \r
1685 \r
1686 @ void FinalizeLine555(int sh, int line, struct PicoEState *est)\r
1687 \r
1688 .global FinalizeLine555\r
1689 \r
1690 FinalizeLine555:\r
1691     ldr     r3, [r2, #OFS_EST_rendstatus]\r
1692     mov     r0, r2\r
1693     tst     r3, #PDRAW_BGC_DMA\r
1694     bne     BgcDMA\r
1695 \r
1696     stmfd   sp!, {r4-r11,lr}\r
1697     mov     r11,r2               @ est\r
1698     mov     r4, r3\r
1699 \r
1700     bl      PicoDrawUpdateHighPal\r
1701 \r
1702     ldr     r8, [r11, #OFS_EST_Pico]\r
1703     add     r3, r11, #OFS_EST_HighPal\r
1704 \r
1705     mov     lr, #0xff\r
1706     mov     lr, lr, lsl #1\r
1707 \r
1708     ldr     r5, [r11, #OFS_EST_PicoOpt]\r
1709     ldr     r1, [r11, #OFS_EST_HighCol]\r
1710     ldr     r0, [r11, #OFS_EST_DrawLineDest]\r
1711     ldr     r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]\r
1712     ldrb    r12,[r8, #OFS_Pico_video_reg+12]\r
1713     ldrb    r6, [r8, #OFS_Pico_video_reg+0]\r
1714     ldr     r2, [r8, #OFS_Pico_m_hardware]\r
1715     add     r1, r1, #8\r
1716 \r
1717     tst     r7, #0x20           @ GG ?\r
1718     tstne   r2, #0x2            @ LCD ?\r
1719     bne     .fl_gg20col\r
1720 \r
1721     tst     r7, #0x10           @ SMS ?\r
1722     beq     .fl_noSMS\r
1723 \r
1724     tst     r6, #0x20\r
1725     movne   r2, #248/8          @ len = 248\r
1726     addne   r1, r1, #8          @ ps += 8\r
1727     moveq   r2, #256/8          @ len = 256\r
1728     b       .fl_check32scaling\r
1729 \r
1730 .fl_gg20col:\r
1731     mov     r2, #160/8          @ len = 160\r
1732     tst     r4, #PDRAW_SOFTSCALE\r
1733     bne     .fl_20scale_RGB555  @ scale 160->320\r
1734     b       .fl_checkborder\r
1735 \r
1736 .fl_noSMS:\r
1737     tst     r12, #1             @ h32?\r
1738     movne   r2, #320/8          @ len = 320\r
1739     bne     .fl_40colRGB555\r
1740     mov     r2, #256/8          @ len = 256\r
1741 \r
1742 .fl_check32scaling:\r
1743     tst     r4, #PDRAW_SOFTSCALE\r
1744     rsbne   r7, r2, #256/8\r
1745     addne   r0, r0, r7, lsl #3  @ pd += (256-len)>>1\r
1746     bne     .fl_32scale_RGB555  @ scale 256->320\r
1747 \r
1748 .fl_checkborder:\r
1749     tst     r4, #PDRAW_BORDER_32\r
1750     rsbne   r7, r2, #320/8      @ pd += (320-len)/2\r
1751     addne   r0, r0, r7, lsl #3\r
1752 \r
1753 .fl_40colRGB555:\r
1754 #ifdef UNALIGNED_DRAWLINEDEST\r
1755     @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1756     tst     r0, #2\r
1757     bne     .fl_RGB555u\r
1758 #endif\r
1759 \r
1760 .fl_loopRGB555:\r
1761     ldr     r12, [r1], #4\r
1762     ldr     r7,  [r1], #4\r
1763 \r
1764     and     r4, lr, r12, lsl #1\r
1765     ldrh    r4, [r3, r4]\r
1766     and     r5, lr, r12, lsr #7\r
1767     ldrh    r5, [r3, r5]\r
1768     and     r6, lr, r12, lsr #15\r
1769     ldrh    r6, [r3, r6]\r
1770     orr     r4, r4, r5, lsl #16\r
1771 \r
1772     and     r5, lr, r12, lsr #23\r
1773     ldrh    r5, [r3, r5]\r
1774     and     r8, lr, r7, lsl #1\r
1775     ldrh    r8, [r3, r8]\r
1776     orr     r5, r6, r5, lsl #16\r
1777 \r
1778     and     r6, lr, r7, lsr #7\r
1779     ldrh    r6, [r3, r6]\r
1780     and     r12,lr, r7, lsr #15\r
1781     ldrh    r12,[r3, r12]\r
1782     and     r7, lr, r7, lsr #23\r
1783     ldrh    r7, [r3, r7]\r
1784     orr     r8, r8, r6, lsl #16\r
1785 \r
1786     subs    r2, r2, #1\r
1787     orr     r12,r12, r7, lsl #16\r
1788 \r
1789     stmia   r0!, {r4,r5,r8,r12}\r
1790     bne     .fl_loopRGB555\r
1791 \r
1792     ldmfd   sp!, {r4-r11,pc}\r
1793 \r
1794 \r
1795 .fl_32scale_RGB555:\r
1796     ldr     r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]\r
1797 \r
1798     mov     r9, #0xf700 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1799     orr     r9, r9, #0x00de\r
1800 \r
1801 #ifdef UNALIGNED_DRAWLINEDEST\r
1802     tst     r0, #2\r
1803     bne     .fl_32scale_RGB555u\r
1804 #endif\r
1805 \r
1806     and     r5, r5, #0x3\r
1807     add     pc, pc, r5, lsl #2\r
1808     nop\r
1809     b       .fl_32scale_nn\r
1810     b       .fl_32scale_snn\r
1811     b       .fl_32scale_bl2\r
1812     b       .fl_32scale_bl4\r
1813 \r
1814 .fl_32scale_nn:\r
1815     ldr     r12, [r1], #4\r
1816     ldr     r7,  [r1], #4\r
1817 \r
1818     and     r4, lr, r12, lsl #1\r
1819     ldrh    r4, [r3, r4]\r
1820     and     r5, lr, r12, lsr #7\r
1821     ldrh    r5, [r3, r5]\r
1822     and     r6, lr, r12, lsr #15\r
1823     ldrh    r6, [r3, r6]\r
1824     and     r10,lr, r12, lsr #23\r
1825     ldrh    r10,[r3, r10]\r
1826 \r
1827     orr     r4, r4, r5, lsl #16\r
1828     orr     r5, r6, r6, lsl #16\r
1829 \r
1830     and     r6, lr, r7, lsl #1\r
1831     ldrh    r6, [r3, r6]\r
1832     and     r8, lr, r7, lsr #7\r
1833     ldrh    r8, [r3, r8]\r
1834     and     r12,lr, r7, lsr #15\r
1835     ldrh    r12,[r3, r12]\r
1836     and     r7, lr, r7, lsr #23\r
1837     ldrh    r7, [r3, r7]\r
1838 \r
1839     orr     r6, r10,r6, lsl  #16\r
1840     orr     r8, r8,r12, lsl #16\r
1841 \r
1842     subs    r2, r2, #1\r
1843 \r
1844     orr     r10,r12,r7, lsl #16\r
1845 \r
1846     stmia   r0!, {r4,r5,r6,r8,r10}\r
1847     bne     .fl_32scale_nn\r
1848 \r
1849     b       .fl_32scale_8bit\r
1850 \r
1851 .fl_32scale_snn:\r
1852     ldr     r12, [r1], #4\r
1853     ldr     r7,  [r1], #4\r
1854 \r
1855     and     r4, lr, r12, lsl #1\r
1856     ldrh    r4, [r3, r4]\r
1857     and     r5, lr, r12, lsr #7\r
1858     ldrh    r5, [r3, r5]\r
1859     and     r6, lr, r12, lsr #15\r
1860     ldrh    r6, [r3, r6]\r
1861     and     r10,lr, r12, lsr #23\r
1862     ldrh    r10,[r3, r10]\r
1863 \r
1864     and     r4, r4, r9\r
1865     and     r5, r5, r9\r
1866     orr     r4, r4, r5, lsl #16\r
1867     and     r6, r6, r9\r
1868     add     r5, r5, r6\r
1869     mov     r5, r5, lsr #1\r
1870     orr     r5, r5, r6, lsl #16\r
1871 \r
1872     and     r6, lr, r7, lsl #1\r
1873     ldrh    r6, [r3, r6]\r
1874     and     r8, lr, r7, lsr #7\r
1875     ldrh    r8, [r3, r8]\r
1876     and     r12,lr, r7, lsr #15\r
1877     ldrh    r12,[r3, r12]\r
1878     and     r7, lr, r7, lsr #23\r
1879     ldrh    r7, [r3, r7]\r
1880 \r
1881     and     r6, r6, r9\r
1882     and     r10,r10,r9\r
1883     orr     r6, r10,r6, lsl  #16\r
1884     and     r12,r12,r9\r
1885     and     r7, r7, r9\r
1886     orr     r10,r12,r7, lsl #16\r
1887 \r
1888     and     r8, r8, r9\r
1889     add     r12,r12,r8\r
1890     mov     r12,r12,lsr #1\r
1891     orr     r8, r8,r12, lsl #16\r
1892 \r
1893     subs    r2, r2, #1\r
1894 \r
1895     stmia   r0!, {r4,r5,r6,r8,r10}\r
1896     bne     .fl_32scale_snn\r
1897 \r
1898     b       .fl_32scale_8bit\r
1899 \r
1900 .fl_32scale_bl2:\r
1901     ldr     r12, [r1], #4\r
1902     ldr     r7,  [r1], #4\r
1903 \r
1904     and     r4, lr, r12, lsl #1\r
1905     ldrh    r4, [r3, r4]\r
1906     and     r5, lr, r12, lsr #7\r
1907     ldrh    r5, [r3, r5]\r
1908     and     r6, lr, r12, lsr #15\r
1909     ldrh    r6, [r3, r6]\r
1910 \r
1911     and     r4, r4, r9\r
1912     and     r5, r5, r9\r
1913     add     r10,r4, r5\r
1914     mov     r10,r10,lsr #1\r
1915     orr     r4, r4, r10,lsl #16         @ px0 | (px0+px1)/2\r
1916 \r
1917     and     r6, r6, r9\r
1918     add     r5, r5, r6\r
1919     mov     r5, r5, lsr #1\r
1920     orr     r5, r5, r6, lsl #16         @ (px1+px2)/2 | px2\r
1921 \r
1922     and     r10,lr, r12, lsr #23\r
1923     ldrh    r10,[r3, r10]\r
1924     and     r8, lr, r7, lsl #1\r
1925     ldrh    r8, [r3, r8]\r
1926 \r
1927     and     r10,r10,r9\r
1928     and     r8, r8, r9\r
1929     orr     r6, r10,r8, lsl  #16        @ px3 | px4\r
1930 \r
1931     and     r12,lr, r7, lsr #15\r
1932     ldrh    r12,[r3, r12]\r
1933     and     r10, lr, r7, lsr #23\r
1934     ldrh    r10, [r3, r10]\r
1935     and     r7, lr, r7, lsr #7\r
1936     ldrh    r7, [r3, r7]\r
1937 \r
1938     and     r12,r12,r9\r
1939     and     r10,r10,r9\r
1940     orr     r10,r12,r10, lsl #16        @ px6 | px7\r
1941 \r
1942     and     r7, r7, r9\r
1943     add     r12,r12,r7\r
1944     add     r8, r8, r7\r
1945     mov     r8, r8, lsr #1\r
1946     mov     r12,r12,lsr #1\r
1947     orr     r8, r8,r12, lsl #16         @ (px4+px5)/2 | (px5+px6)/2\r
1948 \r
1949     subs    r2, r2, #1\r
1950 \r
1951     stmia   r0!, {r4,r5,r6,r8,r10}\r
1952     bne     .fl_32scale_bl2\r
1953 \r
1954     b       .fl_32scale_8bit\r
1955 \r
1956 .fl_32scale_bl4:\r
1957     // TODO this should reflect the bl4 C algorithm, but it doesn't, it's bln.\r
1958     and     r9, r9, r9, lsl #1        @ nuke 2 LSBs to avoid spilling for n/4\r
1959 .fl_32loop_bl4:\r
1960     ldr     r12, [r1], #4\r
1961     ldr     r7,  [r1], #4\r
1962 \r
1963     and     r4, lr, r12,lsl #1\r
1964     ldrh    r4, [r3, r4]\r
1965     and     r5, lr, r12,lsr #7\r
1966     ldrh    r5, [r3, r5]\r
1967 \r
1968     @ r4 = 1/4px0+3/4px1 : px0\r
1969     and     r4, r4, r9\r
1970     orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0\r
1971     and     r5, r5, r9\r
1972     sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1\r
1973     add     r4, r4, r6, lsl #16       @ pix_d 0, 1\r
1974 \r
1975     and     r6, lr, r12,lsr #15\r
1976     ldrh    r6, [r3, r6]\r
1977     and     r12,lr, r12,lsr #23\r
1978     ldrh    r12,[r3, r12]\r
1979 \r
1980     @ r5 = 3/4px2+1/4px3 : (px1+px2)/2\r
1981     and     r6, r6, r9\r
1982     add     r5, r5, r6\r
1983     mov     r5, r5, lsr #1\r
1984     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1985     orr     r5, r5, r6, lsl #16\r
1986 \r
1987     and     r6, lr, r7, lsl #1\r
1988     ldrh    r6, [r3, r6]\r
1989     and     r12,r12,r9\r
1990     add     r5, r5, r12,lsl #14       @ pix_d 2, 3\r
1991 \r
1992     @ r6 = px4 : px3\r
1993     and     r6, r6, r9\r
1994     orr     r6, r12,r6, lsl #16       @ pix_d 4, 5\r
1995 \r
1996     @ r8 = (px5+px6)/2 : 1/4px4+3/4px5\r
1997     and     r12,lr, r7, lsr #7\r
1998     ldrh    r12,[r3, r12]\r
1999     and     r10,lr, r7, lsr #15\r
2000     ldrh    r10,[r3, r10]\r
2001     and     r12,r12,r9\r
2002     sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1\r
2003     add     r8, r8, r6, lsr #18\r
2004 \r
2005     and     r7, lr, r7, lsr #23\r
2006     ldrh    r7, [r3, r7]\r
2007     and     r10,r10,r9\r
2008     orr     r8, r8, r10,lsl #15\r
2009     add     r8, r8, r12,lsl #15       @ pix_d 6, 7\r
2010 \r
2011     @ r10 = px7 : 3/4px6+1/4px7\r
2012     sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2\r
2013     and     r7, r7, r9\r
2014     add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3\r
2015     orr     r10,r10,r7, lsl #16       @ pix_d 8, 9\r
2016 \r
2017     subs    r2, r2, #1\r
2018 \r
2019     stmia   r0!, {r4,r5,r6,r8,r10}\r
2020     bne     .fl_32loop_bl4\r
2021 \r
2022 .fl_32scale_8bit:\r
2023     ldr     r4, [r11, #OFS_EST_rendstatus]\r
2024     add     r0, r1, #320-256\r
2025     mov     r2, #256/8\r
2026     tst     r4, #PDRAW_32X_SCALE\r
2027     ldmeqfd sp!, {r4-r11,pc}\r
2028     mov     lr, #0xff\r
2029 \r
2030 .fl_32scale_8bit_nn:\r
2031     ldr     r7,  [r1, #-4]!\r
2032     ldr     r12, [r1, #-4]!\r
2033 \r
2034     and     r4, lr, r12, lsl #0\r
2035     and     r5, lr, r12, lsr #8\r
2036     and     r6, lr, r12, lsr #16\r
2037     and     r10,lr, r12, lsr #24\r
2038     \r
2039     orr     r4, r4, r5, lsl #8\r
2040     orr     r5, r6, r6, lsl #8\r
2041 \r
2042     and     r6, lr, r7, lsl #0\r
2043     and     r8, lr, r7, lsr #8\r
2044     and     r12,lr, r7, lsr #16\r
2045     and     r7, lr, r7, lsr #24\r
2046 \r
2047     orr     r6, r10,r6, lsl  #8\r
2048     orr     r8, r8,r12, lsl #8\r
2049 \r
2050     subs    r2, r2, #1\r
2051 \r
2052     orr     r10,r12,r7, lsl #8\r
2053 \r
2054     strh    r10, [r0, #-2]!\r
2055     strh    r8, [r0, #-2]!\r
2056     strh    r6, [r0, #-2]!\r
2057     strh    r5, [r0, #-2]!\r
2058     strh    r4, [r0, #-2]!\r
2059 \r
2060     bne     .fl_32scale_8bit_nn\r
2061 \r
2062     ldmfd   sp!, {r4-r11,pc}\r
2063 \r
2064 \r
2065 .fl_20scale_RGB555:\r
2066     ldr     r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]\r
2067 \r
2068     mov     r9, #0xf700 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
2069     orr     r9, r9, #0x00de\r
2070 \r
2071 #ifdef UNALIGNED_DRAWLINEDEST\r
2072     tst     r0, #2\r
2073     bne     .fl_20scale_RGB555u\r
2074 #endif\r
2075 \r
2076     and     r5, r5, #0x2\r
2077     add     pc, pc, r5, lsl #1\r
2078     nop\r
2079     b       .fl_20scale_nn\r
2080     b       .fl_20scale_bl2\r
2081 \r
2082 .fl_20scale_nn:\r
2083     ldr     r12, [r1], #4\r
2084     ldr     r7,  [r1], #4\r
2085 \r
2086     and     r4, lr, r12, lsl #1\r
2087     ldrh    r4, [r3, r4]\r
2088     and     r5, lr, r12, lsr #7\r
2089     ldrh    r5, [r3, r5]\r
2090     and     r6, lr, r12, lsr #15\r
2091     ldrh    r6, [r3, r6]\r
2092     and     r8 ,lr, r12, lsr #23\r
2093     ldrh    r8 ,[r3, r8]\r
2094 \r
2095     orr     r4, r4, r4, lsl #16\r
2096     orr     r5, r5, r5, lsl #16\r
2097     orr     r6, r6, r6, lsl #16\r
2098     orr     r8, r8, r8, lsl #16\r
2099     stmia   r0!, {r4,r5,r6,r8}\r
2100 \r
2101     and     r4, lr, r7, lsl #1\r
2102     ldrh    r4, [r3, r4]\r
2103     and     r5, lr, r7, lsr #7\r
2104     ldrh    r5, [r3, r5]\r
2105     and     r6 ,lr, r7, lsr #15\r
2106     ldrh    r6 ,[r3, r6]\r
2107     and     r8, lr, r7, lsr #23\r
2108     ldrh    r8, [r3, r8]\r
2109 \r
2110     orr     r4, r4, r4, lsl #16\r
2111     orr     r5, r5, r5, lsl #16\r
2112     orr     r6, r6, r6, lsl #16\r
2113     orr     r8, r8, r8, lsl #16\r
2114     stmia   r0!, {r4,r5,r6,r8}\r
2115 \r
2116     subs    r2, r2, #1\r
2117     bne     .fl_20scale_nn\r
2118 \r
2119     ldmfd   sp!, {r4-r11,pc}\r
2120 \r
2121 \r
2122 .fl_20scale_bl2:\r
2123     ldr     r8,  [r1]\r
2124     and     r8, lr, r8, lsl #1\r
2125     ldrh    r8, [r3, r8]\r
2126     and     r8, r8, r9\r
2127     mov     r8, r8, lsl #16\r
2128 \r
2129 .fl_20loop_bl2:\r
2130     ldr     r12, [r1], #4\r
2131     ldr     r7,  [r1], #4\r
2132 \r
2133     and     r4, lr, r12, lsl #1\r
2134     ldrh    r4, [r3, r4]\r
2135     and     r5, lr, r12, lsr #7\r
2136     ldrh    r5, [r3, r5]\r
2137     and     r6, lr, r12, lsr #15\r
2138     ldrh    r6, [r3, r6]\r
2139 \r
2140     and     r4, r4, r9\r
2141     add     r10,r4, r8, lsr #16\r
2142     mov     r10,r10,lsr #1\r
2143     orr     r4, r10,r4, lsl #16         @ (px-1+px0)/2 | px0\r
2144 \r
2145     and     r8 ,lr, r12, lsr #23\r
2146     ldrh    r8 ,[r3, r8]\r
2147 \r
2148     and     r5, r5, r9\r
2149     add     r10,r5, r4, lsr #16\r
2150     mov     r10,r10,lsr #1\r
2151     orr     r5, r10,r5, lsl #16         @ (px0 +px1)/2 | px1\r
2152 \r
2153     and     r6, r6, r9\r
2154     add     r10,r6, r5, lsr #16\r
2155     mov     r10,r10,lsr #1\r
2156     orr     r6, r10,r6, lsl #16         @ (px1 +px2)/2 | px2\r
2157 \r
2158     and     r8, r8, r9\r
2159     add     r10,r8, r6, lsr #16\r
2160     mov     r10,r10,lsr #1\r
2161     orr     r8, r10,r8, lsl #16         @ (px2 +px3)/2 | px3\r
2162 \r
2163     stmia   r0!, {r4,r5,r6,r8}\r
2164 \r
2165     and     r4, lr, r7, lsl #1\r
2166     ldrh    r4, [r3, r4]\r
2167     and     r5, lr, r7, lsr #7\r
2168     ldrh    r5, [r3, r5]\r
2169     and     r6, lr, r7, lsr #15\r
2170     ldrh    r6, [r3, r6]\r
2171 \r
2172     and     r4, r4, r9\r
2173     add     r10,r4, r8, lsr #16\r
2174     mov     r10,r10,lsr #1\r
2175     orr     r4, r10,r4, lsl #16         @ (px-1+px0)/2 | px0\r
2176 \r
2177     and     r8 ,lr, r7, lsr #23\r
2178     ldrh    r8 ,[r3, r8]\r
2179 \r
2180     and     r5, r5, r9\r
2181     add     r10,r5, r4, lsr #16\r
2182     mov     r10,r10,lsr #1\r
2183     orr     r5, r10,r5, lsl #16         @ (px0 +px1)/2 | px1\r
2184 \r
2185     and     r6, r6, r9\r
2186     add     r10,r6, r5, lsr #16\r
2187     mov     r10,r10,lsr #1\r
2188     orr     r6, r10,r6, lsl #16         @ (px1 +px2)/2 | px2\r
2189 \r
2190     and     r8, r8, r9\r
2191     add     r10,r8, r6, lsr #16\r
2192     mov     r10,r10,lsr #1\r
2193     orr     r8, r10,r8, lsl #16         @ (px2 +px3)/2 | px3\r
2194 \r
2195     subs    r2, r2, #1\r
2196     stmia   r0!, {r4,r5,r6,r8}\r
2197     bne     .fl_20loop_bl2\r
2198 \r
2199     ldmfd   sp!, {r4-r11,pc}\r
2200 \r
2201 \r
2202 #ifdef UNALIGNED_DRAWLINEDEST\r
2203     @ unaligned versions of loops\r
2204     @ warning: starts drawing 2bytes before dst\r
2205 \r
2206 .fl_RGB555u:\r
2207     sub     r0, r0, #2              @ initial adjustment\r
2208     mov     r8, #0\r
2209 \r
2210 .fl_loopRGB555u:\r
2211     ldr     r12, [r1], #4\r
2212     ldr     r7,  [r1], #4\r
2213 \r
2214     and     r6, lr, r12,lsl #1\r
2215     ldrh    r6, [r3, r6]\r
2216     and     r5, lr, r12,lsr #7\r
2217     ldrh    r5, [r3, r5]\r
2218     orr     r4, r8, r6, lsl #16\r
2219 \r
2220     and     r6, lr, r12,lsr #15\r
2221     ldrh    r6, [r3, r6]\r
2222     and     r8, lr, r12,lsr #23\r
2223     ldrh    r8, [r3, r8]\r
2224     orr     r5, r5, r6, lsl #16\r
2225 \r
2226     and     r6, lr, r7, lsl #1\r
2227     ldrh    r6, [r3, r6]\r
2228     and     r12,lr, r7, lsr #7\r
2229     ldrh    r12,[r3, r12]\r
2230     orr     r6, r8, r6, lsl #16\r
2231 \r
2232     and     r8, lr, r7, lsr #15\r
2233     ldrh    r8, [r3, r8]\r
2234     and     r7, lr, r7, lsr #23\r
2235 \r
2236     subs    r2, r2, #1\r
2237     orr     r12,r12,r8, lsl #16\r
2238     ldrh    r8, [r3, r7]\r
2239 \r
2240     stmia   r0!, {r4,r5,r6,r12}\r
2241     bne     .fl_loopRGB555u\r
2242 \r
2243     strh    r8, [r0], #2\r
2244 \r
2245     ldmfd   sp!, {r4-r11,pc}\r
2246 \r
2247 \r
2248 .fl_32scale_RGB555u:\r
2249     sub     r0, r0, #2              @ initial adjustment\r
2250     mov     r4, #0\r
2251 \r
2252     @ r9  f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
2253 .fl_loop32scale_RGB555u:\r
2254     ldr     r12, [r1], #4\r
2255     ldr     r7,  [r1], #4\r
2256 \r
2257     and     r6, lr, r12,lsl #1\r
2258     ldrh    r6, [r3, r6]\r
2259     and     r5, lr, r12,lsr #7\r
2260     ldrh    r5, [r3, r5]\r
2261     and     r6, r6, r9\r
2262     orr     r4, r4, r6, lsl #16       @ r4 = pix_d -1, 0\r
2263 \r
2264     and     r5, r5, r9\r
2265     sub     r8, r5, r5, lsr #2        @ r8 = 3/4 pix_s 1\r
2266     add     r6, r8, r6, lsr #2        @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
2267     orr     r5, r6, r5, lsl #15\r
2268 \r
2269     and     r6, lr, r12,lsr #15\r
2270     ldrh    r6, [r3, r6]\r
2271     and     r12,lr, r12,lsr #23\r
2272     ldrh    r12,[r3, r12]\r
2273     and     r6, r6, r9\r
2274     add     r5, r5, r6, lsl #15       @ r5 = pix_d 1, 2\r
2275 \r
2276     and     r8, lr, r7, lsl #1\r
2277     ldrh    r8, [r3, r8]\r
2278     and     r10,lr, r7, lsr #7\r
2279     ldrh    r10,[r3, r10]\r
2280     and     r12,r12,r9\r
2281     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
2282     add     r6, r6, r12,lsr #2\r
2283     orr     r6, r6, r12,lsl #16       @ r6 = pix_d 3, 4\r
2284 \r
2285     and     r8, r8, r9\r
2286     and     r10,r10,r9\r
2287     sub     r12,r10,r10,lsr #2        @ r12 = 3/4 pix_s 5\r
2288     orr     r8, r8, r8, lsl #14\r
2289     add     r8, r8, r12,lsl #16       @ r8 = pix_d 5, 6\r
2290     and     r12,lr, r7, lsr #15\r
2291     ldrh    r12,[r3, r12]\r
2292     and     r7, lr, r7, lsr #23\r
2293     ldrh    r7, [r3, r7]\r
2294     and     r12,r12,r9\r
2295     add     r10,r10,r12\r
2296     mov     r10,r10,    lsr #1\r
2297     sub     r12,r12,r12,lsr #2        @ r12 = 3/4 pix_s 6\r
2298     orr     r10,r10,r12,lsl #16\r
2299     and     r7, r7, r9\r
2300     add     r10,r10,r7, lsl #14       @ r10 = pix_d 7, 8\r
2301 \r
2302     subs    r2, r2, #1\r
2303 \r
2304     stmia   r0!, {r4,r5,r6,r8,r10}\r
2305     mov     r4, r7\r
2306     bne     .fl_loop32scale_RGB555u\r
2307 \r
2308     strh    r4, [r0], #2\r
2309 \r
2310     ldmfd   sp!, {r4-r11,pc}\r
2311 \r
2312 #endif /* UNALIGNED_DRAWLINEDEST */\r
2313 \r
2314 \r
2315 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
2316 \r
2317 @ utility\r
2318 .global blockcpy @ void *dst, void *src, size_t n\r
2319 \r
2320 blockcpy:\r
2321     stmfd   sp!, {r4,r5}\r
2322     cmp     r0, r1\r
2323     bhs     blockcpyhi\r
2324 \r
2325     subs    r2, r2, #16\r
2326     blt     blockcpy2\r
2327 blockcpy_loop:\r
2328     ldmia   r1!, {r3-r5,r12}\r
2329     subs    r2, r2, #16\r
2330     stmia   r0!, {r3-r5,r12}\r
2331     bge     blockcpy_loop\r
2332 \r
2333 blockcpy2:\r
2334     adds    r2, r2, #16-4\r
2335     ldmltfd sp!, {r4,r5}\r
2336     bxlt    lr\r
2337 \r
2338 blockcpy_loop2:\r
2339     ldr     r3, [r1], #4\r
2340     subs    r2, r2, #4\r
2341     str     r3, [r0], #4\r
2342     bge     blockcpy_loop2\r
2343 \r
2344     ldmfd   sp!, {r4,r5}\r
2345     bx      lr\r
2346 \r
2347 blockcpyhi:\r
2348     add     r0, r0, r2\r
2349     add     r1, r1, r2\r
2350 \r
2351     subs    r2, r2, #16\r
2352     blt     blockcpyhi2\r
2353 blockcpyhi_loop:\r
2354     ldmdb   r1!, {r3-r5,r12}\r
2355     subs    r2, r2, #16\r
2356     stmdb   r0!, {r3-r5,r12}\r
2357     bge     blockcpyhi_loop\r
2358 \r
2359 blockcpyhi2:\r
2360     adds    r2, r2, #16-4\r
2361     ldmltfd sp!, {r4,r5}\r
2362     bxlt    lr\r
2363 \r
2364 blockcpyhi_loop2:\r
2365     ldr     r3, [r1, #-4]!\r
2366     subs    r2, r2, #4\r
2367     str     r3, [r0, #-4]!\r
2368     bge     blockcpyhi_loop2\r
2369 \r
2370     ldmfd   sp!, {r4,r5}\r
2371     bx      lr\r
2372 \r
2373 \r
2374 .global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
2375 \r
2376 blockcpy_or:\r
2377     stmfd   sp!, {r4-r6}\r
2378     orr     r3, r3, r3, lsl #8\r
2379     orr     r3, r3, r3, lsl #16\r
2380     cmp     r0, r1\r
2381     bhs     blockcpyhi_or\r
2382 \r
2383     subs    r2, r2, #16\r
2384     blt     blockcpy_or2\r
2385 blockcpy_loop_or:\r
2386     ldmia   r1!, {r4-r6,r12}\r
2387     subs    r2, r2, #16\r
2388     orr     r4, r4, r3\r
2389     orr     r5, r5, r3\r
2390     orr     r6, r6, r3\r
2391     orr     r12,r12,r3\r
2392     stmia   r0!, {r4-r6,r12}\r
2393     bge     blockcpy_loop_or\r
2394 \r
2395 blockcpy_or2:\r
2396     adds    r2, r2, #16-4\r
2397     ldmltfd sp!, {r4-r6}\r
2398     bxlt    lr\r
2399 \r
2400 blockcpy_loop_or2:\r
2401     ldr     r4, [r1], #4\r
2402     subs    r2, r2, #4\r
2403     orr     r4, r4, r3\r
2404     str     r4, [r0], #4\r
2405     bge     blockcpy_loop_or2\r
2406 \r
2407     ldmfd   sp!, {r4-r6}\r
2408     bx      lr\r
2409 \r
2410 blockcpyhi_or:\r
2411     add     r0, r0, r2\r
2412     add     r1, r1, r2\r
2413 \r
2414     subs    r2, r2, #16\r
2415     blt     blockcpyhi_or2\r
2416 blockcpyhi_loop_or:\r
2417     ldmdb   r1!, {r4-r6,r12}\r
2418     subs    r2, r2, #16\r
2419     orr     r4, r4, r3\r
2420     orr     r5, r5, r3\r
2421     orr     r6, r6, r3\r
2422     orr     r12,r12,r3\r
2423     stmdb   r0!, {r4-r6,r12}\r
2424     bge     blockcpyhi_loop_or\r
2425 \r
2426 blockcpyhi_or2:\r
2427     adds    r2, r2, #16-4\r
2428     ldmltfd sp!, {r4-r6}\r
2429     bxlt    lr\r
2430 \r
2431 blockcpyhi_loop_or2:\r
2432     ldr     r4, [r1, #-4]!\r
2433     subs    r2, r2, #4\r
2434     orr     r4, r4, r3\r
2435     str     r4, [r0, #-4]!\r
2436     bge     blockcpyhi_loop_or2\r
2437 \r
2438     ldmfd   sp!, {r4-r6}\r
2439     bx      lr\r
2440 \r
2441 @ vim:filetype=armasm\r