40d5c4431698dc5d4bc4b8e3c2f6c0562b980867
[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     bl      DrawStripInterlace @ struct TileStrip *ts, int plane_sh\r
840 \r
841     add     sp, sp, #6*4\r
842     ldmfd   sp!, {r4-r11,pc}\r
843 \r
844 .pool\r
845 \r
846 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
847 \r
848 @ void BackFill(int reg7, int sh, struct PicoEState *est)\r
849 \r
850 .global BackFill\r
851 \r
852 BackFill:\r
853     stmfd   sp!, {r4-r9,lr}\r
854 \r
855     ldr     lr, [r2, #OFS_EST_HighCol]\r
856     orr     r0, r0, r1, lsl #7\r
857     orr     r0, r0, r0, lsl #8\r
858     orr     r0, r0, r0, lsl #16\r
859 \r
860     mov     r1, r0\r
861     mov     r2, r0\r
862     mov     r3, r0\r
863     mov     r4, r0\r
864     mov     r5, r0\r
865     mov     r6, r0\r
866     mov     r7, r0\r
867 \r
868     @ go go go!\r
869     add     lr, lr, #8\r
870     stmia   lr!, {r0-r7} @ 10*8*4\r
871     stmia   lr!, {r0-r7}\r
872     stmia   lr!, {r0-r7}\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 \r
881     ldmfd   sp!, {r4-r9,pc}\r
882 \r
883 \r
884 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
885 \r
886 @ void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est)\r
887 \r
888 .global DrawTilesFromCache\r
889 \r
890 DrawTilesFromCache:\r
891     stmfd   sp!, {r4-r9,r11,lr}\r
892 \r
893     @ cache some stuff to avoid mem access\r
894     ldr     r11,[r3, #OFS_EST_HighCol]\r
895     mov     r12,#0xf\r
896     ldr     lr, [r3, #OFS_EST_PicoMem_vram]\r
897     mov     r9, r3         @ est\r
898 \r
899     ands    r8, r1, #1\r
900     orr     r8, r8, r2, lsl #1\r
901     bne     .dtfc_check_rendflags\r
902 \r
903     @ scratch: r4, r7\r
904 .dtfc_loop:\r
905     ldr     r6, [r0], #4    @ read code\r
906     movs    r1, r6, lsr #16 @ r1=dx;\r
907     ldmeqfd sp!, {r4-r9,r11,pc} @ dx is never zero, this must be a terminator, return\r
908     bic     r4, r1, #0xfe00\r
909     add     r1, r11, r4     @ r1=pdest\r
910 \r
911     ldr     r2, [r0], #4    @ read pixel data\r
912 \r
913     and     r3, r6, #0x6000\r
914     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
915 \r
916     rsbs    r4, r4, r8, lsr #1\r
917     bmi     .dtfc_cut_tile\r
918 \r
919     tst     r8, #1\r
920     bne     .dtfc_shadow\r
921 \r
922     tst     r2, r2\r
923     beq     .dtfc_loop\r
924 \r
925     cmp     r2, r2, ror #4\r
926     beq     .dtfc_SingleColor @ tileline singlecolor \r
927 \r
928     tst     r6, #0x0800\r
929     bne     .dtfc_TileFlip\r
930 \r
931     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
932 .dtfc_TileNorm:\r
933     TileNorm r12\r
934     b       .dtfc_loop\r
935 \r
936 .dtfc_TileFlip:\r
937     TileFlip r12\r
938     b       .dtfc_loop\r
939 \r
940 .dtfc_SingleColor:\r
941     and     r4, r2, #0xf\r
942     orr     r4, r3, r4\r
943     orr     r4, r4, r4, lsl #8\r
944     tst     r1, #1              @ not aligned?\r
945     strneb  r4, [r1], #1\r
946     streqh  r4, [r1], #2\r
947     strh    r4, [r1], #2\r
948     strh    r4, [r1], #2\r
949     strh    r4, [r1], #2\r
950     strneb  r4, [r1], #1        @ have a remaining unaligned pixel?\r
951     b       .dtfc_loop\r
952 \r
953 .dtfc_shadow:\r
954     tst     r2, r2\r
955     beq     .dtfc_shadow_blank\r
956 \r
957     cmp     r2, r2, ror #4\r
958     beq     .dtfc_SingleColor @ tileline singlecolor \r
959 \r
960     tst     r6, #0x0800\r
961     bne     .dtfc_TileFlipShHP\r
962 \r
963     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
964 .dtfc_TileNormShHP:\r
965     TileNormShHP\r
966     b       .dtfc_loop\r
967 \r
968 .dtfc_TileFlipShHP:\r
969     TileFlipShHP\r
970     b       .dtfc_loop\r
971 \r
972 .dtfc_shadow_blank:\r
973     tst     r1, #1\r
974     ldrneb  r4, [r1]\r
975     mov     r6, #0x7f\r
976     and     r4, r4, r6\r
977     strneb  r4, [r1], #1\r
978     ldrh    r4, [r1]\r
979     orr     r6, r6, r6, lsl #8\r
980     and     r4, r4, r6\r
981     strh    r4, [r1], #2\r
982     ldrh    r4, [r1]\r
983     and     r4, r4, r6\r
984     strh    r4, [r1], #2\r
985     ldrh    r4, [r1]\r
986     and     r4, r4, r6\r
987     strh    r4, [r1], #2\r
988     ldrh    r4, [r1]\r
989     and     r4, r4, r6\r
990     streqh  r4, [r1]\r
991     strneb  r4, [r1]\r
992     b       .dtfc_loop\r
993 \r
994 .dtfc_cut_tile:\r
995     cmn     r4, #8\r
996     ble     .dtfc_loop      @ off limits\r
997 \r
998     rsb     r4, r4, #0      @ 1-7\r
999     mov     r4, r4, lsl #2\r
1000     mvn     r12,#0\r
1001     tst     r6, #0x0800     @ flipped?\r
1002     moveq   r12,r12, lsl r4\r
1003     movne   r12,r12, lsr r4\r
1004     and     r2, r2, r12, ror #16\r
1005     mov     r12,#0xf\r
1006     tst     r8, #1\r
1007     bne     .dtfc_shadow\r
1008     tst     r2, r2\r
1009     beq     .dtfc_loop\r
1010     tst     r6, #0x0800\r
1011     beq     .dtfc_TileNorm\r
1012     b       .dtfc_TileFlip\r
1013 \r
1014 @ check if we have detected layer covered with hi-prio tiles:\r
1015 .dtfc_check_rendflags:\r
1016     ldr     r2, [r9, #OFS_EST_rendstatus]\r
1017     tst     r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE)\r
1018     beq     .dtfc_loop\r
1019     bic     r8, r8, #1      @ sh/hi mode off\r
1020     tst     r2, #PDRAW_SHHI_DONE\r
1021     bne     .dtfc_loop      @ already processed\r
1022     orr     r2, r2, #PDRAW_SHHI_DONE\r
1023     str     r2, [r9, #OFS_EST_rendstatus]\r
1024 \r
1025     add     r1, r11,#8\r
1026     mov     r3, #320/4/4\r
1027     mov     r6, #0x7f\r
1028     orr     r6, r6, r6, lsl #8\r
1029     orr     r6, r6, r6, lsl #16\r
1030 .dtfc_loop_shprep:\r
1031     ldmia   r1, {r2,r4,r5,r7}\r
1032     subs    r3, r3, #1\r
1033     and     r2, r2, r6\r
1034     and     r4, r4, r6\r
1035     and     r5, r5, r6\r
1036     and     r7, r7, r6\r
1037     stmia   r1!,{r2,r4,r5,r7}\r
1038     bne     .dtfc_loop_shprep\r
1039 \r
1040     b       .dtfc_loop\r
1041 \r
1042 .pool\r
1043 \r
1044 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1045 \r
1046 \r
1047 @ void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est)\r
1048 \r
1049 .global DrawSpritesSHi\r
1050 \r
1051 DrawSpritesSHi:\r
1052     ldrb    r3, [r0]\r
1053     mov     r12,#0xff\r
1054     ands    r3, r3, #0x7f\r
1055     bxeq    lr\r
1056 \r
1057     stmfd   sp!, {r1,r3-r11,lr} @ +est\r
1058     strb    r12,[r0,#3]     @ set end marker\r
1059     ldrb    r12,[r0,#1]\r
1060     add     r10,r0, #4      @ r10=HighLnSpr end\r
1061     mvn     r12,r12\r
1062     tst     r12,#0x6        @ masking in slot 1 and tile ovfl?\r
1063     ldmeqfd sp!, {r1,r3-r11,pc}\r
1064     add     r10,r10,r3      @ r10=HighLnSpr end\r
1065 \r
1066     ldrb    r12,[r10,#0]    @ width of last sprite\r
1067     ldr     r11,[r1, #OFS_EST_HighCol]\r
1068     str     r12,[sp, #4]\r
1069     mov     r12,#0xf\r
1070     ldr     lr, [r1, #OFS_EST_PicoMem_vram]\r
1071 \r
1072 \r
1073 DrawSpriteSHi:\r
1074     @ draw next sprite\r
1075     ldr     r7, [sp]        @ est\r
1076     ldrb    r0, [r10,#-1]!\r
1077     ldr     r1, [r7, #OFS_EST_HighPreSpr]\r
1078     cmp     r0, #0xff\r
1079     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
1080     and     r0, r0, #0x7f\r
1081     add     r0, r1, r0, lsl #3\r
1082 \r
1083     ldr     r9, [r0, #4]    @ sprite[1]\r
1084     mov     r2, r9, asr #16 @ r2=sx\r
1085 \r
1086     mov     r9, r9, lsl #16\r
1087     mov     r3, r9, lsr #31 @ priority\r
1088     mov     r9, r9, lsr #16\r
1089 @    orr     r9, r9, r8, lsl #31 @ r9=code|sh[31]   @@ sh is always on here now\r
1090     and     r4, r9, #0x6000\r
1091     orr     r9, r9, r4, lsl #16\r
1092     orr     r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1093     cmp     r12,r9, lsr #28 @ sh/hi with pal3?\r
1094     cmpne   r3, #1          @ if not, is it hi prio?\r
1095     strne   r3, [sp, #4]    @ reset last sprite width\r
1096     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn\r
1097 \r
1098     ldr     r3, [r0]        @ sprite[0]\r
1099     mov     r6, r3, lsr #28\r
1100     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1101     mov     r5, r3, lsr #24\r
1102     and     r5, r5, #7      @ r5=height\r
1103 \r
1104     ldr     r7, [r7, #OFS_EST_DrawScanline]\r
1105     mov     r0, r3, lsl #16 @ r4=sy<<16 (tmp)\r
1106 \r
1107     sub     r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy\r
1108 \r
1109     tst     r9, #0x1000\r
1110     movne   r0, r5, lsl #3\r
1111     subne   r0, r0, #1\r
1112     subne   r7, r0, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1113 \r
1114     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1115     tst     r9, #0x0800\r
1116     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1117     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1118 \r
1119     mov     r8, r8, lsl #21\r
1120     mov     r8, r8, lsr #17\r
1121     and     r7, r7, #7\r
1122     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1123 \r
1124     ldr     r0, [sp, #4]\r
1125     add     r6, r6, #1         @ inc now\r
1126     cmp     r0, #0             @ check width of last sprite\r
1127     movne   r6, r0\r
1128     movne   r0, #0\r
1129     strne   r0, [sp, #4]\r
1130 \r
1131     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1132     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1133 \r
1134     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1135     b       .dsprShi_loop_enter\r
1136 \r
1137 .dsprShi_loop:\r
1138     subs    r6, r6, #1         @ width--\r
1139     beq     DrawSpriteSHi\r
1140     adds    r0, r0, #8         @ sx+=8\r
1141     add     r8, r8, r5         @ tile+=delta\r
1142 \r
1143 .dsprShi_loop_enter:\r
1144     ble     .dsprShi_loop     @ sx <= 0\r
1145     cmp     r0, #328\r
1146     bge     DrawSpriteSHi\r
1147 \r
1148     bic     r8, r8, #0xf8000   @ tile&=0x7fff; // Clip tile address\r
1149     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
1150     add     r1, r11, r0        @ r1=pdest\r
1151     tst     r2, r2\r
1152     beq     .dsprShi_loop\r
1153 \r
1154     cmp     r12, r9, lsr #28\r
1155     beq     .dsprShi_shadow\r
1156 \r
1157     cmp     r2, r2, ror #4\r
1158     beq     .dsprShi_SingleColor @ tileline singlecolor \r
1159 \r
1160     tst     r9, #0x0800\r
1161     bne     .dsprShi_TileFlip\r
1162 \r
1163     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1164 @ scratch: r4, r7\r
1165 .dsprShi_TileNorm:\r
1166     TileNorm r12\r
1167     b       .dsprShi_loop\r
1168 \r
1169 .dsprShi_TileFlip:\r
1170     TileFlip r12\r
1171     b       .dsprShi_loop\r
1172 \r
1173 .dsprShi_SingleColor:\r
1174     and     r4, r2, #0xf\r
1175     orr     r4, r3, r4\r
1176     orr     r4, r4, r4, lsl #8\r
1177     tst     r0, #1              @ not aligned?\r
1178     strneb  r4, [r1], #1\r
1179     streqh  r4, [r1], #2\r
1180     strh    r4, [r1], #2\r
1181     strh    r4, [r1], #2\r
1182     strh    r4, [r1], #2\r
1183     strneb  r4, [r1], #1\r
1184     b       .dsprShi_loop\r
1185 \r
1186 .dsprShi_shadow:\r
1187     tst     r9, #0x8000\r
1188     beq     .dsprShi_shadow_lowpri\r
1189 \r
1190     cmp     r2, r2, ror #4\r
1191     beq     .dsprShi_singlec_sh\r
1192 \r
1193     tst     r9, #0x0800\r
1194     bne     .dsprShi_TileFlip_sh\r
1195 \r
1196     @ (r1=pdest, r2=pixels8, r3=pal) r4, r7: scratch, r12: helper pattern\r
1197 .dsprShi_TileNorm_sh:\r
1198     TileNormSh\r
1199     b       .dsprShi_loop\r
1200 \r
1201 .dsprShi_TileFlip_sh:\r
1202     TileFlipSh\r
1203     b       .dsprShi_loop\r
1204 \r
1205 .dsprShi_singlec_sh:\r
1206     cmp     r2, #0xe0000000\r
1207     bcc     .dsprShi_SingleColor   @ normal singlecolor tileline (carry inverted in ARM)\r
1208     tst     r2, #0x10000000\r
1209     bne     .dsprShi_sh_sh\r
1210     TileSingleHi\r
1211     b       .dsprShi_loop\r
1212 \r
1213 .dsprShi_sh_sh:\r
1214     TileSingleSh\r
1215     b       .dsprShi_loop\r
1216 \r
1217 .dsprShi_shadow_lowpri:\r
1218     tst     r9, #0x800\r
1219     bne     .dsprShi_TileFlip_sh_lp\r
1220 \r
1221 .dsprShi_TileNorm_sh_lp:\r
1222     TileNormSh_onlyop_lp\r
1223     b       .dsprShi_loop\r
1224 \r
1225 .dsprShi_TileFlip_sh_lp:\r
1226     TileFlipSh_onlyop_lp\r
1227     b       .dsprShi_loop\r
1228 \r
1229 .pool\r
1230 \r
1231 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1232 \r
1233 @ void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
1234 @                     struct PicoEState *est)\r
1235 \r
1236 .global DrawAllSprites\r
1237 \r
1238 DrawAllSprites:\r
1239     orr     r1, r2, r1, lsl #1\r
1240     ldr     r2, [r0]\r
1241     ands    r2, r2, #0x7f\r
1242     bxeq    lr\r
1243 \r
1244     @ time to do some real work\r
1245     stmfd   sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est\r
1246     mov     r12,#0xff\r
1247     strb    r12,[r0,#3]     @ set end marker\r
1248     ldrb    r12,[r0,#1]\r
1249     add     r10,r0 ,#4\r
1250     mvn     r12,r12\r
1251     tst     r12,#0x6        @ masking in slot 1 and tile ovfl?\r
1252     ldmeqfd sp!, {r1,r3-r11,pc}\r
1253     add     r10,r10,r2      @ r10=HighLnSpr end\r
1254 \r
1255     ldrb    r12,[r10,#0]    @ width of last sprite\r
1256     ldr     r11,[r3, #OFS_EST_HighCol]\r
1257     orr     r1 ,r1 ,r12,lsl #24\r
1258     str     r1, [sp]\r
1259     mov     r12,#0xf\r
1260     ldr     lr, [r3, #OFS_EST_PicoMem_vram]\r
1261 \r
1262 @ + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size\r
1263 @ + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
1264 \r
1265 DrawSprite:\r
1266     @ draw next sprite\r
1267     ldrb    r0, [r10,#-1]!\r
1268     ldr     r4, [sp]        @ sh|prio<<1|lastw<<24\r
1269     ldr     r7, [sp, #4]    @ est\r
1270     mov     r2, r0, lsl #24\r
1271     cmp     r0, #0xff\r
1272     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
1273     eors    r2, r2, r4, lsl #30\r
1274     bic     r2, r4, #0xff000000\r
1275     str     r2, [sp]\r
1276     bmi     DrawSprite      @ wrong priority\r
1277     ldr     r1, [r7, #OFS_EST_HighPreSpr]\r
1278     and     r0, r0, #0x7f\r
1279     add     r0, r1, r0, lsl #3\r
1280 \r
1281     ldr     r3, [r0]        @ sprite[0]\r
1282     ldr     r7, [r7, #OFS_EST_DrawScanline]\r
1283     mov     r6, r3, lsr #28\r
1284     sub     r6, r6, #1      @ r6=width-1 (inc later)\r
1285     mov     r5, r3, lsr #24\r
1286     and     r5, r5, #7      @ r5=height\r
1287 \r
1288     mov     r8, r3, lsl #16 @ r8=sy<<16 (tmp)\r
1289 \r
1290     ldr     r9, [r0, #4]\r
1291     sub     r7, r7, r8, asr #16 @ r7=row=DrawScanline-sy\r
1292 \r
1293     mov     r2, r9, asr #16 @ r2=sx\r
1294     mov     r9, r9, lsl #16\r
1295     mov     r9, r9, lsr #16\r
1296     orr     r9, r9, r4, lsl #31 @ r9=code|sh[31]\r
1297 \r
1298     tst     r9, #0x1000\r
1299     movne   r8, r5, lsl #3\r
1300     subne   r8, r8, #1\r
1301     subne   r7, r8, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
1302 \r
1303     add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
1304     tst     r9, #0x0800\r
1305     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
1306     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
1307 \r
1308     mov     r8, r8, lsl #21\r
1309     mov     r8, r8, lsr #17\r
1310     and     r7, r7, #7\r
1311     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
1312 \r
1313     add     r6, r6, #1         @ inc now\r
1314     cmp     r4, #0x1000000     @ check width of last sprite\r
1315     movhs   r6, r4, lsr #24\r
1316 \r
1317     @ cache some stuff to avoid mem access\r
1318     mov     r5, r5, lsl #4     @ delta<<=4; // Delta of address\r
1319     and     r4, r9, #0x6000\r
1320     orr     r9, r9, r4, lsl #16\r
1321     orrs    r9, r9, #0x10000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
1322 \r
1323     mov     r3, r4, lsr #9     @ r3=pal=((code>>9)&0x30);\r
1324     orrmi   r3, r3, #0x80      @ for sh/hi\r
1325 \r
1326     adds    r0, r2, #0         @ mov sx to r0 and set ZV flags\r
1327     b       .dspr_loop_enter\r
1328 \r
1329 .dspr_loop:\r
1330     subs    r6, r6, #1         @ width--\r
1331     beq     DrawSprite\r
1332     adds    r0, r0, #8         @ sx+=8\r
1333     add     r8, r8, r5         @ tile+=delta\r
1334 \r
1335 .dspr_loop_enter:\r
1336     ble     .dspr_loop         @ sx <= 0\r
1337     cmp     r0, #328\r
1338     bge     DrawSprite\r
1339 \r
1340     bic     r8, r8, #0xf8000   @ tile&=0x7fff; // Clip tile address\r
1341     ldr     r2, [lr, r8, lsl #1] @ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
1342     add     r1, r11, r0        @ r1=pdest\r
1343     tst     r2, r2\r
1344     beq     .dspr_loop\r
1345 \r
1346     cmp     r12, r9, lsr #28\r
1347     beq     .dspr_shadow\r
1348 \r
1349     tst     r9, #0x80000000\r
1350     bne     .dspr_shnonsh\r
1351 \r
1352     cmp     r2, r2, ror #4\r
1353     beq     .dspr_SingleColor @ tileline singlecolor \r
1354 \r
1355     tst     r9, #0x0800\r
1356     bne     .dspr_TileFlip\r
1357 \r
1358     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1359 @ scratch: r4, r7\r
1360 .dspr_TileNorm:\r
1361     TileNorm r12\r
1362     b       .dspr_loop\r
1363 \r
1364 .dspr_TileFlip:\r
1365     TileFlip r12\r
1366     b       .dspr_loop\r
1367 \r
1368 .dspr_singlec_sh:\r
1369     cmp     r2, #0xe0000000\r
1370     bcs     .dspr_TileNorm_sh   @ op. tileline, markop. XXX: maybe add a spec. handler?\r
1371 \r
1372 .dspr_SingleColor:\r
1373     and     r4, r2, #0xf\r
1374     orr     r4, r3, r4\r
1375     orr     r4, r4, r4, lsl #8\r
1376     tst     r0, #1              @ not aligned?\r
1377     strneb  r4, [r1], #1\r
1378     streqh  r4, [r1], #2\r
1379     strh    r4, [r1], #2\r
1380     strh    r4, [r1], #2\r
1381     strh    r4, [r1], #2\r
1382     strneb  r4, [r1], #1\r
1383     b       .dspr_loop\r
1384 \r
1385 .dspr_shnonsh:\r
1386     tst     r9, #0x0800\r
1387     bne     .dspr_TileFlipNonSH\r
1388 \r
1389     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1390 @ scratch: r4, r7\r
1391 .dspr_TileNormNonSH:\r
1392     TileNormNonSH r12\r
1393     b       .dspr_loop\r
1394 \r
1395 .dspr_TileFlipNonSH:\r
1396     TileFlipNonSH r12\r
1397     b       .dspr_loop\r
1398 \r
1399 .dspr_shadow:\r
1400     cmp     r2, r2, ror #4\r
1401     beq     .dspr_singlec_sh\r
1402 \r
1403     tst     r9, #0x0800\r
1404     bne     .dspr_TileFlip_sh\r
1405 \r
1406     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
1407 .dspr_TileNorm_sh:\r
1408     TileNormSh_markop\r
1409     b       .dspr_loop\r
1410 \r
1411 .dspr_TileFlip_sh:\r
1412     TileFlipSh_markop\r
1413     b       .dspr_loop\r
1414 \r
1415 \r
1416 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1417 \r
1418 @ void DrawWindow(int tstart, int tend, int prio, int sh\r
1419 @                 struct PicoEState *est)\r
1420 \r
1421 .global DrawWindow\r
1422 \r
1423 DrawWindow:\r
1424     ldr     r12, [sp]             @ est\r
1425     stmfd   sp!, {r4-r11,lr}\r
1426 \r
1427     ldr     r6,  [r12, #OFS_EST_Pico]\r
1428     ldr     r10, [r12, #OFS_EST_DrawScanline]\r
1429     mov     r11, r12              @ est\r
1430     ldrb    r12, [r6, #OFS_Pico_video_reg+3] @ pvid->reg[3]\r
1431 \r
1432     ldr     r4,  [r6, #OFS_Pico_video_reg+12]\r
1433     mov     r5,  r10, lsr #3\r
1434     and     r10, r10, #7\r
1435     mov     r10, r10, lsl #1      @ r10=ty\r
1436 \r
1437     ldr     r6, [r11, #OFS_EST_rendstatus]\r
1438     ldr     lr, [r11, #OFS_EST_PicoMem_vram]\r
1439 \r
1440     mov     r12, r12, lsl #10\r
1441 \r
1442     tst     r4, #1                @ 40 cell mode?\r
1443     andne   r12, r12, #0xf000     @ 0x3c<<10\r
1444     andeq   r12, r12, #0xf800\r
1445     addne   r12, r12, r5, lsl #7\r
1446     addeq   r12, r12, r5, lsl #6  @ nametab\r
1447     add     r12, r12, r0, lsl #2  @ +starttile\r
1448 \r
1449     ands    r6, r6, #PDRAW_WND_DIFF_PRIO\r
1450     cmpeq   r2, #1                @ prio && !(rendstatus & WND_DIFF_PRIO)?\r
1451     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
1452 \r
1453     orr     r6, r6, r2\r
1454     orr     r6, r6, r3, lsl #8    @ shadow mode\r
1455 \r
1456     sub     r8, r1, r0\r
1457 \r
1458     @ cache some stuff to avoid mem access\r
1459     ldr     r11, [r11, #OFS_EST_HighCol]\r
1460     mov     r8, r8, lsl #1        @ cells\r
1461     mvn     r9, #0                @ r9=prevcode=-1\r
1462     add     r1, r11, r0, lsl #4   @ r1=pdest=HighCol+starttile (+8 added in loop)\r
1463     mov     r0, #0xf\r
1464 \r
1465     @ r4,r5 are scratch in this loop\r
1466 .dwloop:\r
1467     add     r1, r1, #8\r
1468 .dwloop_nor1:\r
1469     ldrh    r7, [lr, r12]   @ r7=code (int, but from unsigned, no sign extend)\r
1470     add     r12, r12, #2    @ halfwords\r
1471     subs    r8, r8, #1\r
1472     bmi     .dwloop_end     @ done\r
1473 \r
1474     eor     r5, r6, r7, lsr #15\r
1475     tst     r5, #1\r
1476     orrne   r6, r6, #PDRAW_WND_DIFF_PRIO @ wrong pri\r
1477     bne     .dwloop\r
1478 \r
1479     cmp     r7, r9\r
1480     beq     .dw_samecode    @ we know stuff about this tile already\r
1481 \r
1482     mov     r9, r7          @ remember code\r
1483 \r
1484     tst     r9, #0x1000     @ if (code&0x1000)\r
1485     mov     r2, r9, lsl #21\r
1486     add     r2, r2, r10, lsl #17\r
1487     eorne   r2, r2, #0xe<<17 @ if (code&0x1000) addr^=0xe;\r
1488 \r
1489     ldr     r2, [lr, r2, lsr #16] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
1490 \r
1491     and     r3, r9, #0x6000\r
1492     mov     r3, r3, lsr #9  @ r3=pal=((code&0x6000)>>9);\r
1493 \r
1494 .dw_samecode:\r
1495     tst     r6, #0x100\r
1496     bne     .dw_shadow\r
1497 .dw_shadow_done:\r
1498     tst     r2, r2\r
1499     beq     .dwloop              @ tileline blank\r
1500 \r
1501     cmp     r2, r2, ror #4\r
1502     beq     .dw_SingleColor @ tileline singlecolor \r
1503 \r
1504     tst     r9, #0x0800\r
1505     bne     .dw_TileFlip\r
1506 \r
1507     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern\r
1508 .dw_TileNorm:\r
1509     TileNorm r0\r
1510     b       .dwloop\r
1511 \r
1512 .dw_TileFlip:\r
1513     TileFlip r0\r
1514     b       .dwloop\r
1515 \r
1516 .dw_SingleColor:\r
1517     and     r4, r0, r2         @ #0x0000000f\r
1518     orr     r4, r3, r4\r
1519     orr     r4, r4, r4, lsl #8\r
1520     orr     r4, r4, r4, lsl #16\r
1521     mov     r5, r4\r
1522     stmia   r1!, {r4,r5}\r
1523     b       .dwloop_nor1       @ we incremeted r1 ourselves\r
1524 \r
1525 .dw_shadow:\r
1526     tst     r6, #1             @ hi pri?\r
1527     orreq   r3, r3, #0x80\r
1528     beq     .dw_shadow_done\r
1529     ldr     r4, [r1]\r
1530     mov     r5, #0x7f\r
1531     orr     r5, r5, r5, lsl #8\r
1532     orr     r5, r5, r5, lsl #16\r
1533     and     r4, r4, r5\r
1534     str     r4, [r1]\r
1535     ldr     r4, [r1,#4]\r
1536     and     r4, r4, r5\r
1537     str     r4, [r1,#4]\r
1538     b       .dw_shadow_done\r
1539 \r
1540 .dwloop_end:\r
1541     and     r2, r6, #PDRAW_WND_DIFF_PRIO\r
1542     ldmfd   sp!, {r4-r11,lr}\r
1543     ldr     r0, [sp]\r
1544     ldr     r1, [r0, #OFS_EST_rendstatus]\r
1545     orr     r1, r1, r2\r
1546     str     r1, [r0, #OFS_EST_rendstatus]\r
1547 \r
1548     bx      lr\r
1549 \r
1550 \r
1551 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
1552 \r
1553 \r
1554 @ Convert 0000bbb0 ggg0rrr0\r
1555 @ to      rrrrrggg gggbbbbb\r
1556 \r
1557 @ r2,r3 - scratch, lr = 0x001c001c, r8 = 0x08610861\r
1558 .macro convRGB565 reg\r
1559     and     r2,   lr,   \reg,lsr #7  @ b\r
1560     and     r3,   lr,   \reg,lsr #3  @ g\r
1561     and     \reg, lr,   \reg,lsl #1  @ r\r
1562     orr     r2,   r2,   r3,  lsl #6\r
1563     orr     \reg, r2,   \reg,lsl #11\r
1564 \r
1565     and     r2,   r8,   \reg,lsr #4\r
1566     orr     \reg, \reg, r2\r
1567 .endm\r
1568 \r
1569 @ trashes: r2-r8,r12,lr; r8 = 0x08610861; r0,r1 are advanced\r
1570 .macro vidConvCpyRGB565_local\r
1571     mov     r12, r2, lsr #3  @ repeats\r
1572     mov     lr, #0x001c0000\r
1573     orr     lr, lr,  #0x01c  @ lr == pattern 0x001c001c\r
1574 \r
1575 0:\r
1576     ldmia   r1!, {r4-r7}\r
1577     subs    r12, r12, #1\r
1578     convRGB565 r4\r
1579     str     r4, [r0], #4\r
1580     convRGB565 r5\r
1581     str     r5, [r0], #4\r
1582     convRGB565 r6\r
1583     str     r6, [r0], #4\r
1584     convRGB565 r7\r
1585     str     r7, [r0], #4\r
1586 \r
1587     bgt     0b\r
1588 .endm\r
1589 \r
1590 \r
1591 .global vidConvCpyRGB565\r
1592 \r
1593 vidConvCpyRGB565: @ void *to, void *from, int pixels\r
1594     stmfd   sp!, {r4-r9,lr}\r
1595     mov     r8,     #0x0061\r
1596     orr     r8, r8, #0x0800\r
1597     orr     r8, r8, r8, lsl #16\r
1598     vidConvCpyRGB565_local\r
1599     ldmfd   sp!, {r4-r9,pc}\r
1600 \r
1601 \r
1602 @ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
1603 \r
1604 .global PicoDoHighPal555\r
1605 \r
1606 PicoDoHighPal555:\r
1607     stmfd   sp!, {r4-r10,lr}\r
1608     mov     r10,r2               @ est\r
1609     ldr     r8, [r10, #OFS_EST_Pico]\r
1610 \r
1611     mov     r9, r0\r
1612 \r
1613     add     r0, r10, #OFS_EST_HighPal\r
1614 \r
1615     mov     r1, #0\r
1616     strb    r1, [r8, #OFS_Pico_m_dirtyPal]\r
1617 \r
1618     ldr     r1, [r10, #OFS_EST_PicoMem_cram]\r
1619     mov     r2, #0x40\r
1620     mov     r8,     #0x0061\r
1621     orr     r8, r8, #0x0800\r
1622     orr     r8, r8, r8, lsl #16\r
1623 \r
1624     vidConvCpyRGB565_local\r
1625 \r
1626     cmp     r9, #0\r
1627     beq     PicoDoHighPal555_end\r
1628 \r
1629     add     r3, r10, #OFS_EST_HighPal\r
1630     add     r4, r3, #0x40*2\r
1631 \r
1632     @ hilighted pixels (0x40-0x7f):\r
1633     @  t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;\r
1634     @  t |= (t >> 4) & 0x08610861;\r
1635     @ r8=0x08610861\r
1636     mov     r12,    #0x008e\r
1637     orr     r12,r12,#0x7300\r
1638     orr     r12,r12,r12,lsl #16\r
1639     mov     lr, #0x40/4\r
1640 .fl_loopcpRGB555_hi:\r
1641     ldmia   r3!, {r1,r6}\r
1642     and     r1, r12, r1, lsr #1\r
1643     and     r6, r12, r6, lsr #1\r
1644     add     r1, r12, r1\r
1645     add     r6, r12, r6\r
1646     and     r5, r8, r1, lsr #4\r
1647     and     r7, r8, r6, lsr #4\r
1648     orr     r1, r1, r5\r
1649     orr     r6, r6, r7\r
1650     stmia   r4!, {r1,r6}\r
1651     subs    lr, lr, #1\r
1652     bne     .fl_loopcpRGB555_hi\r
1653 \r
1654     sub     r3, r3, #0x40*2\r
1655     @ shadowed (0x80-0xbf), shadow|hilight (aka normal, 0xc0-0xff) pixels:\r
1656     add     r5, r3, #0xc0*2\r
1657     mov     lr, #0x40/4\r
1658 .fl_loopcpRGB555_sh:\r
1659     ldmia   r3!, {r1,r6}\r
1660     subs    lr, lr, #1\r
1661     stmia   r5!, {r1,r6} @ 0xc0, normal\r
1662     and     r1, r12, r1, lsr #1\r
1663     and     r6, r12, r6, lsr #1\r
1664     stmia   r4!, {r1,r6}\r
1665     bne     .fl_loopcpRGB555_sh\r
1666 \r
1667     mov     r0, #1\r
1668 PicoDoHighPal555_end:\r
1669     ldmfd   sp!, {r4-r10,pc}\r
1670 \r
1671 \r
1672 @ void FinalizeLine555(int sh, int line, struct PicoEState *est)\r
1673 \r
1674 .global FinalizeLine555\r
1675 \r
1676 FinalizeLine555:\r
1677     ldr     r3, [r2, #OFS_EST_rendstatus]\r
1678     mov     r0, r2\r
1679     tst     r3, #PDRAW_BGC_DMA\r
1680     bne     BgcDMA\r
1681 \r
1682     stmfd   sp!, {r4-r11,lr}\r
1683     mov     r11,r2               @ est\r
1684     mov     r4, r3\r
1685 \r
1686     bl      PicoDrawUpdateHighPal\r
1687 \r
1688     ldr     r8, [r11, #OFS_EST_Pico]\r
1689     add     r3, r11, #OFS_EST_HighPal\r
1690 \r
1691     mov     lr, #0xff\r
1692     mov     lr, lr, lsl #1\r
1693 \r
1694     ldr     r5, [r11, #OFS_EST_PicoOpt]\r
1695     ldr     r1, [r11, #OFS_EST_HighCol]\r
1696     ldr     r0, [r11, #OFS_EST_DrawLineDest]\r
1697     ldr     r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]\r
1698     ldrb    r12,[r8, #OFS_Pico_video_reg+12]\r
1699     ldrb    r6, [r8, #OFS_Pico_video_reg+0]\r
1700     ldr     r2, [r8, #OFS_Pico_m_hardware]\r
1701     add     r1, r1, #8\r
1702 \r
1703     tst     r7, #0x20           @ GG ?\r
1704     tstne   r2, #0x2            @ LCD ?\r
1705     bne     .fl_gg20col\r
1706 \r
1707     tst     r7, #0x10           @ SMS ?\r
1708     beq     .fl_noSMS\r
1709 \r
1710     tst     r6, #0x20\r
1711     movne   r2, #248/8          @ len = 248\r
1712     addne   r1, r1, #8          @ ps += 8\r
1713     moveq   r2, #256/8          @ len = 256\r
1714     b       .fl_check32scaling\r
1715 \r
1716 .fl_gg20col:\r
1717     mov     r2, #160/8          @ len = 160\r
1718     tst     r4, #PDRAW_SOFTSCALE\r
1719     bne     .fl_20scale_RGB555  @ scale 160->320\r
1720     b       .fl_checkborder\r
1721 \r
1722 .fl_noSMS:\r
1723     tst     r12, #1             @ h32?\r
1724     movne   r2, #320/8          @ len = 320\r
1725     bne     .fl_40colRGB555\r
1726     mov     r2, #256/8          @ len = 256\r
1727 \r
1728 .fl_check32scaling:\r
1729     tst     r4, #PDRAW_SOFTSCALE\r
1730     rsbne   r7, r2, #256/8\r
1731     addne   r0, r0, r7, lsl #3  @ pd += (256-len)>>1\r
1732     bne     .fl_32scale_RGB555  @ scale 256->320\r
1733 \r
1734 .fl_checkborder:\r
1735     tst     r4, #PDRAW_BORDER_32\r
1736     rsbne   r7, r2, #320/8      @ pd += (320-len)/2\r
1737     addne   r0, r0, r7, lsl #3\r
1738 \r
1739 .fl_40colRGB555:\r
1740 #ifdef UNALIGNED_DRAWLINEDEST\r
1741     @ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer\r
1742     tst     r0, #2\r
1743     bne     .fl_RGB555u\r
1744 #endif\r
1745 \r
1746 .fl_loopRGB555:\r
1747     ldr     r12, [r1], #4\r
1748     ldr     r7,  [r1], #4\r
1749 \r
1750     and     r4, lr, r12, lsl #1\r
1751     ldrh    r4, [r3, r4]\r
1752     and     r5, lr, r12, lsr #7\r
1753     ldrh    r5, [r3, r5]\r
1754     and     r6, lr, r12, lsr #15\r
1755     ldrh    r6, [r3, r6]\r
1756     orr     r4, r4, r5, lsl #16\r
1757 \r
1758     and     r5, lr, r12, lsr #23\r
1759     ldrh    r5, [r3, r5]\r
1760     and     r8, lr, r7, lsl #1\r
1761     ldrh    r8, [r3, r8]\r
1762     orr     r5, r6, r5, lsl #16\r
1763 \r
1764     and     r6, lr, r7, lsr #7\r
1765     ldrh    r6, [r3, r6]\r
1766     and     r12,lr, r7, lsr #15\r
1767     ldrh    r12,[r3, r12]\r
1768     and     r7, lr, r7, lsr #23\r
1769     ldrh    r7, [r3, r7]\r
1770     orr     r8, r8, r6, lsl #16\r
1771 \r
1772     subs    r2, r2, #1\r
1773     orr     r12,r12, r7, lsl #16\r
1774 \r
1775     stmia   r0!, {r4,r5,r8,r12}\r
1776     bne     .fl_loopRGB555\r
1777 \r
1778     ldmfd   sp!, {r4-r11,pc}\r
1779 \r
1780 \r
1781 .fl_32scale_RGB555:\r
1782     ldr     r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]\r
1783 \r
1784     mov     r9, #0xf700 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
1785     orr     r9, r9, #0x00de\r
1786 \r
1787 #ifdef UNALIGNED_DRAWLINEDEST\r
1788     tst     r0, #2\r
1789     bne     .fl_32scale_RGB555u\r
1790 #endif\r
1791 \r
1792     and     r5, r5, #0x3\r
1793     add     pc, pc, r5, lsl #2\r
1794     nop\r
1795     b       .fl_32scale_nn\r
1796     b       .fl_32scale_snn\r
1797     b       .fl_32scale_bl2\r
1798     b       .fl_32scale_bl4\r
1799 \r
1800 .fl_32scale_nn:\r
1801     ldr     r12, [r1], #4\r
1802     ldr     r7,  [r1], #4\r
1803 \r
1804     and     r4, lr, r12, lsl #1\r
1805     ldrh    r4, [r3, r4]\r
1806     and     r5, lr, r12, lsr #7\r
1807     ldrh    r5, [r3, r5]\r
1808     and     r6, lr, r12, lsr #15\r
1809     ldrh    r6, [r3, r6]\r
1810     and     r10,lr, r12, lsr #23\r
1811     ldrh    r10,[r3, r10]\r
1812 \r
1813     orr     r4, r4, r5, lsl #16\r
1814     orr     r5, r6, r6, lsl #16\r
1815 \r
1816     and     r6, lr, r7, lsl #1\r
1817     ldrh    r6, [r3, r6]\r
1818     and     r8, lr, r7, lsr #7\r
1819     ldrh    r8, [r3, r8]\r
1820     and     r12,lr, r7, lsr #15\r
1821     ldrh    r12,[r3, r12]\r
1822     and     r7, lr, r7, lsr #23\r
1823     ldrh    r7, [r3, r7]\r
1824 \r
1825     orr     r6, r10,r6, lsl  #16\r
1826     orr     r8, r8,r12, lsl #16\r
1827 \r
1828     subs    r2, r2, #1\r
1829 \r
1830     orr     r10,r12,r7, lsl #16\r
1831 \r
1832     stmia   r0!, {r4,r5,r6,r8,r10}\r
1833     bne     .fl_32scale_nn\r
1834 \r
1835     b       .fl_32scale_8bit\r
1836 \r
1837 .fl_32scale_snn:\r
1838     ldr     r12, [r1], #4\r
1839     ldr     r7,  [r1], #4\r
1840 \r
1841     and     r4, lr, r12, lsl #1\r
1842     ldrh    r4, [r3, r4]\r
1843     and     r5, lr, r12, lsr #7\r
1844     ldrh    r5, [r3, r5]\r
1845     and     r6, lr, r12, lsr #15\r
1846     ldrh    r6, [r3, r6]\r
1847     and     r10,lr, r12, lsr #23\r
1848     ldrh    r10,[r3, r10]\r
1849 \r
1850     and     r4, r4, r9\r
1851     and     r5, r5, r9\r
1852     orr     r4, r4, r5, lsl #16\r
1853     and     r6, r6, r9\r
1854     add     r5, r5, r6\r
1855     mov     r5, r5, lsr #1\r
1856     orr     r5, r5, r6, lsl #16\r
1857 \r
1858     and     r6, lr, r7, lsl #1\r
1859     ldrh    r6, [r3, r6]\r
1860     and     r8, lr, r7, lsr #7\r
1861     ldrh    r8, [r3, r8]\r
1862     and     r12,lr, r7, lsr #15\r
1863     ldrh    r12,[r3, r12]\r
1864     and     r7, lr, r7, lsr #23\r
1865     ldrh    r7, [r3, r7]\r
1866 \r
1867     and     r6, r6, r9\r
1868     and     r10,r10,r9\r
1869     orr     r6, r10,r6, lsl  #16\r
1870     and     r12,r12,r9\r
1871     and     r7, r7, r9\r
1872     orr     r10,r12,r7, lsl #16\r
1873 \r
1874     and     r8, r8, r9\r
1875     add     r12,r12,r8\r
1876     mov     r12,r12,lsr #1\r
1877     orr     r8, r8,r12, lsl #16\r
1878 \r
1879     subs    r2, r2, #1\r
1880 \r
1881     stmia   r0!, {r4,r5,r6,r8,r10}\r
1882     bne     .fl_32scale_snn\r
1883 \r
1884     b       .fl_32scale_8bit\r
1885 \r
1886 .fl_32scale_bl2:\r
1887     ldr     r12, [r1], #4\r
1888     ldr     r7,  [r1], #4\r
1889 \r
1890     and     r4, lr, r12, lsl #1\r
1891     ldrh    r4, [r3, r4]\r
1892     and     r5, lr, r12, lsr #7\r
1893     ldrh    r5, [r3, r5]\r
1894     and     r6, lr, r12, lsr #15\r
1895     ldrh    r6, [r3, r6]\r
1896 \r
1897     and     r4, r4, r9\r
1898     and     r5, r5, r9\r
1899     add     r10,r4, r5\r
1900     mov     r10,r10,lsr #1\r
1901     orr     r4, r4, r10,lsl #16         @ px0 | (px0+px1)/2\r
1902 \r
1903     and     r6, r6, r9\r
1904     add     r5, r5, r6\r
1905     mov     r5, r5, lsr #1\r
1906     orr     r5, r5, r6, lsl #16         @ (px1+px2)/2 | px2\r
1907 \r
1908     and     r10,lr, r12, lsr #23\r
1909     ldrh    r10,[r3, r10]\r
1910     and     r8, lr, r7, lsl #1\r
1911     ldrh    r8, [r3, r8]\r
1912 \r
1913     and     r10,r10,r9\r
1914     and     r8, r8, r9\r
1915     orr     r6, r10,r8, lsl  #16        @ px3 | px4\r
1916 \r
1917     and     r12,lr, r7, lsr #15\r
1918     ldrh    r12,[r3, r12]\r
1919     and     r10, lr, r7, lsr #23\r
1920     ldrh    r10, [r3, r10]\r
1921     and     r7, lr, r7, lsr #7\r
1922     ldrh    r7, [r3, r7]\r
1923 \r
1924     and     r12,r12,r9\r
1925     and     r10,r10,r9\r
1926     orr     r10,r12,r10, lsl #16        @ px6 | px7\r
1927 \r
1928     and     r7, r7, r9\r
1929     add     r12,r12,r7\r
1930     add     r8, r8, r7\r
1931     mov     r8, r8, lsr #1\r
1932     mov     r12,r12,lsr #1\r
1933     orr     r8, r8,r12, lsl #16         @ (px4+px5)/2 | (px5+px6)/2\r
1934 \r
1935     subs    r2, r2, #1\r
1936 \r
1937     stmia   r0!, {r4,r5,r6,r8,r10}\r
1938     bne     .fl_32scale_bl2\r
1939 \r
1940     b       .fl_32scale_8bit\r
1941 \r
1942 .fl_32scale_bl4:\r
1943     // TODO this should reflect the bl4 C algorithm, but it doesn't, it's bln.\r
1944     and     r9, r9, r9, lsl #1        @ nuke 2 LSBs to avoid spilling for n/4\r
1945 .fl_32loop_bl4:\r
1946     ldr     r12, [r1], #4\r
1947     ldr     r7,  [r1], #4\r
1948 \r
1949     and     r4, lr, r12,lsl #1\r
1950     ldrh    r4, [r3, r4]\r
1951     and     r5, lr, r12,lsr #7\r
1952     ldrh    r5, [r3, r5]\r
1953 \r
1954     @ r4 = 1/4px0+3/4px1 : px0\r
1955     and     r4, r4, r9\r
1956     orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0\r
1957     and     r5, r5, r9\r
1958     sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1\r
1959     add     r4, r4, r6, lsl #16       @ pix_d 0, 1\r
1960 \r
1961     and     r6, lr, r12,lsr #15\r
1962     ldrh    r6, [r3, r6]\r
1963     and     r12,lr, r12,lsr #23\r
1964     ldrh    r12,[r3, r12]\r
1965 \r
1966     @ r5 = 3/4px2+1/4px3 : (px1+px2)/2\r
1967     and     r6, r6, r9\r
1968     add     r5, r5, r6\r
1969     mov     r5, r5, lsr #1\r
1970     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
1971     orr     r5, r5, r6, lsl #16\r
1972 \r
1973     and     r6, lr, r7, lsl #1\r
1974     ldrh    r6, [r3, r6]\r
1975     and     r12,r12,r9\r
1976     add     r5, r5, r12,lsl #14       @ pix_d 2, 3\r
1977 \r
1978     @ r6 = px4 : px3\r
1979     and     r6, r6, r9\r
1980     orr     r6, r12,r6, lsl #16       @ pix_d 4, 5\r
1981 \r
1982     @ r8 = (px5+px6)/2 : 1/4px4+3/4px5\r
1983     and     r12,lr, r7, lsr #7\r
1984     ldrh    r12,[r3, r12]\r
1985     and     r10,lr, r7, lsr #15\r
1986     ldrh    r10,[r3, r10]\r
1987     and     r12,r12,r9\r
1988     sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1\r
1989     add     r8, r8, r6, lsr #18\r
1990 \r
1991     and     r7, lr, r7, lsr #23\r
1992     ldrh    r7, [r3, r7]\r
1993     and     r10,r10,r9\r
1994     orr     r8, r8, r10,lsl #15\r
1995     add     r8, r8, r12,lsl #15       @ pix_d 6, 7\r
1996 \r
1997     @ r10 = px7 : 3/4px6+1/4px7\r
1998     sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2\r
1999     and     r7, r7, r9\r
2000     add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3\r
2001     orr     r10,r10,r7, lsl #16       @ pix_d 8, 9\r
2002 \r
2003     subs    r2, r2, #1\r
2004 \r
2005     stmia   r0!, {r4,r5,r6,r8,r10}\r
2006     bne     .fl_32loop_bl4\r
2007 \r
2008 .fl_32scale_8bit:\r
2009     ldr     r4, [r11, #OFS_EST_rendstatus]\r
2010     add     r0, r1, #320-256\r
2011     mov     r2, #256/8\r
2012     tst     r4, #PDRAW_32X_SCALE\r
2013     ldmeqfd sp!, {r4-r11,pc}\r
2014     mov     lr, #0xff\r
2015 \r
2016 .fl_32scale_8bit_nn:\r
2017     ldr     r7,  [r1, #-4]!\r
2018     ldr     r12, [r1, #-4]!\r
2019 \r
2020     and     r4, lr, r12, lsl #0\r
2021     and     r5, lr, r12, lsr #8\r
2022     and     r6, lr, r12, lsr #16\r
2023     and     r10,lr, r12, lsr #24\r
2024     \r
2025     orr     r4, r4, r5, lsl #8\r
2026     orr     r5, r6, r6, lsl #8\r
2027 \r
2028     and     r6, lr, r7, lsl #0\r
2029     and     r8, lr, r7, lsr #8\r
2030     and     r12,lr, r7, lsr #16\r
2031     and     r7, lr, r7, lsr #24\r
2032 \r
2033     orr     r6, r10,r6, lsl  #8\r
2034     orr     r8, r8,r12, lsl #8\r
2035 \r
2036     subs    r2, r2, #1\r
2037 \r
2038     orr     r10,r12,r7, lsl #8\r
2039 \r
2040     strh    r10, [r0, #-2]!\r
2041     strh    r8, [r0, #-2]!\r
2042     strh    r6, [r0, #-2]!\r
2043     strh    r5, [r0, #-2]!\r
2044     strh    r4, [r0, #-2]!\r
2045 \r
2046     bne     .fl_32scale_8bit_nn\r
2047 \r
2048     ldmfd   sp!, {r4-r11,pc}\r
2049 \r
2050 \r
2051 .fl_20scale_RGB555:\r
2052     ldr     r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]\r
2053 \r
2054     mov     r9, #0xf700 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
2055     orr     r9, r9, #0x00de\r
2056 \r
2057 #ifdef UNALIGNED_DRAWLINEDEST\r
2058     tst     r0, #2\r
2059     bne     .fl_20scale_RGB555u\r
2060 #endif\r
2061 \r
2062     and     r5, r5, #0x2\r
2063     add     pc, pc, r5, lsl #1\r
2064     nop\r
2065     b       .fl_20scale_nn\r
2066     b       .fl_20scale_bl2\r
2067 \r
2068 .fl_20scale_nn:\r
2069     ldr     r12, [r1], #4\r
2070     ldr     r7,  [r1], #4\r
2071 \r
2072     and     r4, lr, r12, lsl #1\r
2073     ldrh    r4, [r3, r4]\r
2074     and     r5, lr, r12, lsr #7\r
2075     ldrh    r5, [r3, r5]\r
2076     and     r6, lr, r12, lsr #15\r
2077     ldrh    r6, [r3, r6]\r
2078     and     r8 ,lr, r12, lsr #23\r
2079     ldrh    r8 ,[r3, r8]\r
2080 \r
2081     orr     r4, r4, r4, lsl #16\r
2082     orr     r5, r5, r5, lsl #16\r
2083     orr     r6, r6, r6, lsl #16\r
2084     orr     r8, r8, r8, lsl #16\r
2085     stmia   r0!, {r4,r5,r6,r8}\r
2086 \r
2087     and     r4, lr, r7, lsl #1\r
2088     ldrh    r4, [r3, r4]\r
2089     and     r5, lr, r7, lsr #7\r
2090     ldrh    r5, [r3, r5]\r
2091     and     r6 ,lr, r7, lsr #15\r
2092     ldrh    r6 ,[r3, r6]\r
2093     and     r8, lr, r7, lsr #23\r
2094     ldrh    r8, [r3, r8]\r
2095 \r
2096     orr     r4, r4, r4, lsl #16\r
2097     orr     r5, r5, r5, lsl #16\r
2098     orr     r6, r6, r6, lsl #16\r
2099     orr     r8, r8, r8, lsl #16\r
2100     stmia   r0!, {r4,r5,r6,r8}\r
2101 \r
2102     subs    r2, r2, #1\r
2103     bne     .fl_20scale_nn\r
2104 \r
2105     ldmfd   sp!, {r4-r11,pc}\r
2106 \r
2107 \r
2108 .fl_20scale_bl2:\r
2109     ldr     r8,  [r1]\r
2110     and     r8, lr, r8, lsl #1\r
2111     ldrh    r8, [r3, r8]\r
2112     and     r8, r8, r9\r
2113     mov     r8, r8, lsl #16\r
2114 \r
2115 .fl_20loop_bl2:\r
2116     ldr     r12, [r1], #4\r
2117     ldr     r7,  [r1], #4\r
2118 \r
2119     and     r4, lr, r12, lsl #1\r
2120     ldrh    r4, [r3, r4]\r
2121     and     r5, lr, r12, lsr #7\r
2122     ldrh    r5, [r3, r5]\r
2123     and     r6, lr, r12, lsr #15\r
2124     ldrh    r6, [r3, r6]\r
2125 \r
2126     and     r4, r4, r9\r
2127     add     r10,r4, r8, lsr #16\r
2128     mov     r10,r10,lsr #1\r
2129     orr     r4, r10,r4, lsl #16         @ (px-1+px0)/2 | px0\r
2130 \r
2131     and     r8 ,lr, r12, lsr #23\r
2132     ldrh    r8 ,[r3, r8]\r
2133 \r
2134     and     r5, r5, r9\r
2135     add     r10,r5, r4, lsr #16\r
2136     mov     r10,r10,lsr #1\r
2137     orr     r5, r10,r5, lsl #16         @ (px0 +px1)/2 | px1\r
2138 \r
2139     and     r6, r6, r9\r
2140     add     r10,r6, r5, lsr #16\r
2141     mov     r10,r10,lsr #1\r
2142     orr     r6, r10,r6, lsl #16         @ (px1 +px2)/2 | px2\r
2143 \r
2144     and     r8, r8, r9\r
2145     add     r10,r8, r6, lsr #16\r
2146     mov     r10,r10,lsr #1\r
2147     orr     r8, r10,r8, lsl #16         @ (px2 +px3)/2 | px3\r
2148 \r
2149     stmia   r0!, {r4,r5,r6,r8}\r
2150 \r
2151     and     r4, lr, r7, lsl #1\r
2152     ldrh    r4, [r3, r4]\r
2153     and     r5, lr, r7, lsr #7\r
2154     ldrh    r5, [r3, r5]\r
2155     and     r6, lr, r7, lsr #15\r
2156     ldrh    r6, [r3, r6]\r
2157 \r
2158     and     r4, r4, r9\r
2159     add     r10,r4, r8, lsr #16\r
2160     mov     r10,r10,lsr #1\r
2161     orr     r4, r10,r4, lsl #16         @ (px-1+px0)/2 | px0\r
2162 \r
2163     and     r8 ,lr, r7, lsr #23\r
2164     ldrh    r8 ,[r3, r8]\r
2165 \r
2166     and     r5, r5, r9\r
2167     add     r10,r5, r4, lsr #16\r
2168     mov     r10,r10,lsr #1\r
2169     orr     r5, r10,r5, lsl #16         @ (px0 +px1)/2 | px1\r
2170 \r
2171     and     r6, r6, r9\r
2172     add     r10,r6, r5, lsr #16\r
2173     mov     r10,r10,lsr #1\r
2174     orr     r6, r10,r6, lsl #16         @ (px1 +px2)/2 | px2\r
2175 \r
2176     and     r8, r8, r9\r
2177     add     r10,r8, r6, lsr #16\r
2178     mov     r10,r10,lsr #1\r
2179     orr     r8, r10,r8, lsl #16         @ (px2 +px3)/2 | px3\r
2180 \r
2181     subs    r2, r2, #1\r
2182     stmia   r0!, {r4,r5,r6,r8}\r
2183     bne     .fl_20loop_bl2\r
2184 \r
2185     ldmfd   sp!, {r4-r11,pc}\r
2186 \r
2187 \r
2188 #ifdef UNALIGNED_DRAWLINEDEST\r
2189     @ unaligned versions of loops\r
2190     @ warning: starts drawing 2bytes before dst\r
2191 \r
2192 .fl_RGB555u:\r
2193     sub     r0, r0, #2              @ initial adjustment\r
2194     mov     r8, #0\r
2195 \r
2196 .fl_loopRGB555u:\r
2197     ldr     r12, [r1], #4\r
2198     ldr     r7,  [r1], #4\r
2199 \r
2200     and     r6, lr, r12,lsl #1\r
2201     ldrh    r6, [r3, r6]\r
2202     and     r5, lr, r12,lsr #7\r
2203     ldrh    r5, [r3, r5]\r
2204     orr     r4, r8, r6, lsl #16\r
2205 \r
2206     and     r6, lr, r12,lsr #15\r
2207     ldrh    r6, [r3, r6]\r
2208     and     r8, lr, r12,lsr #23\r
2209     ldrh    r8, [r3, r8]\r
2210     orr     r5, r5, r6, lsl #16\r
2211 \r
2212     and     r6, lr, r7, lsl #1\r
2213     ldrh    r6, [r3, r6]\r
2214     and     r12,lr, r7, lsr #7\r
2215     ldrh    r12,[r3, r12]\r
2216     orr     r6, r8, r6, lsl #16\r
2217 \r
2218     and     r8, lr, r7, lsr #15\r
2219     ldrh    r8, [r3, r8]\r
2220     and     r7, lr, r7, lsr #23\r
2221 \r
2222     subs    r2, r2, #1\r
2223     orr     r12,r12,r8, lsl #16\r
2224     ldrh    r8, [r3, r7]\r
2225 \r
2226     stmia   r0!, {r4,r5,r6,r12}\r
2227     bne     .fl_loopRGB555u\r
2228 \r
2229     strh    r8, [r0], #2\r
2230 \r
2231     ldmfd   sp!, {r4-r11,pc}\r
2232 \r
2233 \r
2234 .fl_32scale_RGB555u:\r
2235     sub     r0, r0, #2              @ initial adjustment\r
2236     mov     r4, #0\r
2237 \r
2238     @ r9  f800 07e0 001f | e000 0780 001c | 3800 01e0 0007\r
2239 .fl_loop32scale_RGB555u:\r
2240     ldr     r12, [r1], #4\r
2241     ldr     r7,  [r1], #4\r
2242 \r
2243     and     r6, lr, r12,lsl #1\r
2244     ldrh    r6, [r3, r6]\r
2245     and     r5, lr, r12,lsr #7\r
2246     ldrh    r5, [r3, r5]\r
2247     and     r6, r6, r9\r
2248     orr     r4, r4, r6, lsl #16       @ r4 = pix_d -1, 0\r
2249 \r
2250     and     r5, r5, r9\r
2251     sub     r8, r5, r5, lsr #2        @ r8 = 3/4 pix_s 1\r
2252     add     r6, r8, r6, lsr #2        @ r6 = (1/4 pix_s 0) + (3/4 pix_s 1)\r
2253     orr     r5, r6, r5, lsl #15\r
2254 \r
2255     and     r6, lr, r12,lsr #15\r
2256     ldrh    r6, [r3, r6]\r
2257     and     r12,lr, r12,lsr #23\r
2258     ldrh    r12,[r3, r12]\r
2259     and     r6, r6, r9\r
2260     add     r5, r5, r6, lsl #15       @ r5 = pix_d 1, 2\r
2261 \r
2262     and     r8, lr, r7, lsl #1\r
2263     ldrh    r8, [r3, r8]\r
2264     and     r10,lr, r7, lsr #7\r
2265     ldrh    r10,[r3, r10]\r
2266     and     r12,r12,r9\r
2267     sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2\r
2268     add     r6, r6, r12,lsr #2\r
2269     orr     r6, r6, r12,lsl #16       @ r6 = pix_d 3, 4\r
2270 \r
2271     and     r8, r8, r9\r
2272     and     r10,r10,r9\r
2273     sub     r12,r10,r10,lsr #2        @ r12 = 3/4 pix_s 5\r
2274     orr     r8, r8, r8, lsl #14\r
2275     add     r8, r8, r12,lsl #16       @ r8 = pix_d 5, 6\r
2276     and     r12,lr, r7, lsr #15\r
2277     ldrh    r12,[r3, r12]\r
2278     and     r7, lr, r7, lsr #23\r
2279     ldrh    r7, [r3, r7]\r
2280     and     r12,r12,r9\r
2281     add     r10,r10,r12\r
2282     mov     r10,r10,    lsr #1\r
2283     sub     r12,r12,r12,lsr #2        @ r12 = 3/4 pix_s 6\r
2284     orr     r10,r10,r12,lsl #16\r
2285     and     r7, r7, r9\r
2286     add     r10,r10,r7, lsl #14       @ r10 = pix_d 7, 8\r
2287 \r
2288     subs    r2, r2, #1\r
2289 \r
2290     stmia   r0!, {r4,r5,r6,r8,r10}\r
2291     mov     r4, r7\r
2292     bne     .fl_loop32scale_RGB555u\r
2293 \r
2294     strh    r4, [r0], #2\r
2295 \r
2296     ldmfd   sp!, {r4-r11,pc}\r
2297 \r
2298 #endif /* UNALIGNED_DRAWLINEDEST */\r
2299 \r
2300 \r
2301 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
2302 \r
2303 @ utility\r
2304 .global blockcpy @ void *dst, void *src, size_t n\r
2305 \r
2306 blockcpy:\r
2307     stmfd   sp!, {r4,r5}\r
2308     cmp     r0, r1\r
2309     bhs     blockcpyhi\r
2310 \r
2311     subs    r2, r2, #16\r
2312     blt     blockcpy2\r
2313 blockcpy_loop:\r
2314     ldmia   r1!, {r3-r5,r12}\r
2315     subs    r2, r2, #16\r
2316     stmia   r0!, {r3-r5,r12}\r
2317     bge     blockcpy_loop\r
2318 \r
2319 blockcpy2:\r
2320     adds    r2, r2, #16-4\r
2321     ldmltfd sp!, {r4,r5}\r
2322     bxlt    lr\r
2323 \r
2324 blockcpy_loop2:\r
2325     ldr     r3, [r1], #4\r
2326     subs    r2, r2, #4\r
2327     str     r3, [r0], #4\r
2328     bge     blockcpy_loop2\r
2329 \r
2330     ldmfd   sp!, {r4,r5}\r
2331     bx      lr\r
2332 \r
2333 blockcpyhi:\r
2334     add     r0, r0, r2\r
2335     add     r1, r1, r2\r
2336 \r
2337     subs    r2, r2, #16\r
2338     blt     blockcpyhi2\r
2339 blockcpyhi_loop:\r
2340     ldmdb   r1!, {r3-r5,r12}\r
2341     subs    r2, r2, #16\r
2342     stmdb   r0!, {r3-r5,r12}\r
2343     bge     blockcpyhi_loop\r
2344 \r
2345 blockcpyhi2:\r
2346     adds    r2, r2, #16-4\r
2347     ldmltfd sp!, {r4,r5}\r
2348     bxlt    lr\r
2349 \r
2350 blockcpyhi_loop2:\r
2351     ldr     r3, [r1, #-4]!\r
2352     subs    r2, r2, #4\r
2353     str     r3, [r0, #-4]!\r
2354     bge     blockcpyhi_loop2\r
2355 \r
2356     ldmfd   sp!, {r4,r5}\r
2357     bx      lr\r
2358 \r
2359 \r
2360 .global blockcpy_or @ void *dst, void *src, size_t n, int pat\r
2361 \r
2362 blockcpy_or:\r
2363     stmfd   sp!, {r4-r6}\r
2364     orr     r3, r3, r3, lsl #8\r
2365     orr     r3, r3, r3, lsl #16\r
2366     cmp     r0, r1\r
2367     bhs     blockcpyhi_or\r
2368 \r
2369     subs    r2, r2, #16\r
2370     blt     blockcpy_or2\r
2371 blockcpy_loop_or:\r
2372     ldmia   r1!, {r4-r6,r12}\r
2373     subs    r2, r2, #16\r
2374     orr     r4, r4, r3\r
2375     orr     r5, r5, r3\r
2376     orr     r6, r6, r3\r
2377     orr     r12,r12,r3\r
2378     stmia   r0!, {r4-r6,r12}\r
2379     bge     blockcpy_loop_or\r
2380 \r
2381 blockcpy_or2:\r
2382     adds    r2, r2, #16-4\r
2383     ldmltfd sp!, {r4-r6}\r
2384     bxlt    lr\r
2385 \r
2386 blockcpy_loop_or2:\r
2387     ldr     r4, [r1], #4\r
2388     subs    r2, r2, #4\r
2389     orr     r4, r4, r3\r
2390     str     r4, [r0], #4\r
2391     bge     blockcpy_loop_or2\r
2392 \r
2393     ldmfd   sp!, {r4-r6}\r
2394     bx      lr\r
2395 \r
2396 blockcpyhi_or:\r
2397     add     r0, r0, r2\r
2398     add     r1, r1, r2\r
2399 \r
2400     subs    r2, r2, #16\r
2401     blt     blockcpyhi_or2\r
2402 blockcpyhi_loop_or:\r
2403     ldmdb   r1!, {r4-r6,r12}\r
2404     subs    r2, r2, #16\r
2405     orr     r4, r4, r3\r
2406     orr     r5, r5, r3\r
2407     orr     r6, r6, r3\r
2408     orr     r12,r12,r3\r
2409     stmdb   r0!, {r4-r6,r12}\r
2410     bge     blockcpyhi_loop_or\r
2411 \r
2412 blockcpyhi_or2:\r
2413     adds    r2, r2, #16-4\r
2414     ldmltfd sp!, {r4-r6}\r
2415     bxlt    lr\r
2416 \r
2417 blockcpyhi_loop_or2:\r
2418     ldr     r4, [r1, #-4]!\r
2419     subs    r2, r2, #4\r
2420     orr     r4, r4, r3\r
2421     str     r4, [r0, #-4]!\r
2422     bge     blockcpyhi_loop_or2\r
2423 \r
2424     ldmfd   sp!, {r4-r6}\r
2425     bx      lr\r
2426 \r
2427 @ vim:filetype=armasm\r