32x: fix bg color tests
[picodrive.git] / pico / 32x / draw_arm.s
1 @*
2 @* PicoDrive
3 @* (C) notaz, 2010
4 @*
5 @* This work is licensed under the terms of MAME license.
6 @* See COPYING file in the top-level directory.
7 @*
8
9 .extern Pico32x
10 .extern PicoDraw2FB
11 .extern HighPal
12
13 .equiv P32XV_PRI,  (1<< 7)
14
15 .bss
16 .align 2
17 .global Pico32xNativePal
18 Pico32xNativePal:
19     .word 0
20
21 .text
22 .align 2
23
24
25 .macro call_scan_prep cond
26 .if \cond
27     ldr     r4, =PicoScan32xBegin
28     ldr     r5, =PicoScan32xEnd
29     ldr     r6, =DrawLineDest
30     ldr     r4, [r4]
31     ldr     r5, [r5]
32     stmfd   sp!, {r4,r5,r6}
33 .endif
34 .endm
35
36 .macro call_scan_fin_ge cond
37 .if \cond
38     addge   sp, sp, #4*3
39 .endif
40 .endm
41
42 .macro call_scan_begin cond
43 .if \cond
44     stmfd   sp!, {r1-r3}
45     and     r0, r2, #0xff
46     add     r0, r0, r4
47     mov     lr, pc
48     ldr     pc, [sp, #(3+0)*4]
49     ldr     r0, [sp, #(3+2)*4] @ &DrawLineDest
50     ldmfd   sp!, {r1-r3}
51     ldr     r0, [r0]
52 .endif
53 .endm
54
55 .macro call_scan_end cond
56 .if \cond
57     stmfd   sp!, {r0-r3}
58     and     r0, r2, #0xff
59     add     r0, r0, r4
60     mov     lr, pc
61     ldr     pc, [sp, #(4+1)*4]
62     ldmfd   sp!, {r0-r3}
63 .endif
64 .endm
65
66 @ direct color
67 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
68 .macro make_do_loop_dc name call_scan do_md
69 .global \name
70 \name:
71     stmfd   sp!, {r4-r11,lr}
72
73     ldr     r10,=Pico32x
74     ldr     r11,=PicoDraw2FB
75     ldr     r10,[r10, #0x40] @ Pico32x.vdp_regs[0]
76     ldr     r11,[r11]
77     ldr     r9, =HighPal     @ palmd
78     and     r4, r2, #0xff
79     mov     r5, #328
80     lsl     r3, #26          @ mdbg << 26
81     mla     r11,r4,r5,r11    @ r11 = pmd = PicoDraw2FB + offs*328: md data
82     tst     r10,#P32XV_PRI
83     moveq   r10,#0
84     movne   r10,#0x8000      @ r10 = inv_bit
85     call_scan_prep \call_scan
86
87     mov     r4, #0           @ line
88     b       1f @ loop_outer_entry
89
90 0: @ loop_outer:
91     call_scan_end \call_scan
92     add     r4, r4, #1
93     sub     r11,r11,#1       @ adjust for prev read
94     cmp     r4, r2, lsr #16
95     call_scan_fin_ge \call_scan
96     ldmgefd sp!, {r4-r11,pc}
97
98 1: @ loop_outer_entry:
99     call_scan_begin \call_scan
100     mov     r12,r4, lsl #1
101     ldrh    r12,[r1, r12]
102     add     r11,r11,#8
103     mov     r6, #320
104     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
105
106 2: @ loop_inner:
107     ldrb    r7, [r11], #1    @ MD pixel
108     subs    r6, r6, #1
109     blt     0b @ loop_outer
110     ldrh    r8, [r5], #2     @ 32x pixel
111     cmp     r3, r7, lsl #26  @ MD has bg pixel?
112     beq     3f @ draw32x
113     eor     r12,r8, r10
114     ands    r12,r12,#0x8000  @ !((t ^ inv) & 0x8000)
115 .if \do_md
116     mov     r7, r7, lsl #1
117     ldreqh  r12,[r9, r7]
118     streqh  r12,[r0], #2     @ *dst++ = palmd[*pmd]
119 .endif
120     beq     2b @ loop_inner
121
122 3: @ draw32x:
123     and     r12,r8, #0x03e0
124     mov     r8, r8, lsl #11
125     orr     r8, r8, r8, lsr #(10+11)
126     orr     r8, r8, r12,lsl #1
127     bic     r8, r8, #0x0020  @ kill prio bit
128     strh    r8, [r0], #2     @ *dst++ = bgr2rgb(*p32x++)
129     b       2b @ loop_inner
130 .endm
131
132
133 @ packed pixel
134 @ note: this may read a few bytes over the end of PicoDraw2FB and dram,
135 @       so those should have a bit more alloc'ed than really needed.
136 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
137 .macro make_do_loop_pp name call_scan do_md
138 .global \name
139 \name:
140     stmfd   sp!, {r4-r11,lr}
141
142     ldr     r11,=PicoDraw2FB
143     ldr     r10,=Pico32xNativePal
144     ldr     r11,[r11]
145     ldr     r10,[r10]
146     ldr     r9, =HighPal     @ palmd
147     and     r4, r2, #0xff
148     mov     r5, #328
149     lsl     r3, #26          @ mdbg << 26
150     mla     r11,r4,r5,r11    @ r11 = pmd = PicoDraw2FB + offs*328: md data
151     call_scan_prep \call_scan
152
153     mov     r4, #0           @ line
154     b       1f @ loop_outer_entry
155
156 0: @ loop_outer:
157     call_scan_end \call_scan
158     add     r4, r4, #1
159     cmp     r4, r2, lsr #16
160     call_scan_fin_ge \call_scan
161     ldmgefd sp!, {r4-r11,pc}
162
163 1: @ loop_outer_entry:
164     call_scan_begin \call_scan
165     mov     r12,r4, lsl #1
166     ldrh    r12,[r1, r12]
167     add     r11,r11,#8
168     mov     r6, #320/2
169     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
170     and     r12,r2, #0x100      @ shift
171     add     r5, r5, r12,lsr #8
172
173 2: @ loop_inner:
174 @ r4,r6 - counters; r5 - 32x data; r9,r10 - md,32x pal; r11 - md data
175 @ r7,r8,r12,lr - temp
176     tst     r5, #1
177     ldreqb  r8, [r5], #2
178     ldrb    r7, [r5, #-1]
179     ldrneb  r8, [r5, #2]!    @ r7,r8 - pixel 0,1 index
180     subs    r6, r6, #1
181     blt     0b @ loop_outer
182     cmp     r7, r8
183     beq     5f @ check_fill @ +8
184
185 3: @ no_fill:
186     mov     r12,r7, lsl #1
187     mov     lr, r8, lsl #1
188     ldrh    r7, [r10,r12]
189     ldrh    r8, [r10,lr]
190     add     r11,r11,#2
191
192     eor     r12,r7, #0x20
193     tst     r12,#0x20
194     ldrneb  r12,[r11,#-2]    @ MD pixel 0
195     eor     lr, r8, #0x20
196     cmpne   r3, r12, lsl #26 @ MD has bg pixel?
197 .if \do_md
198     mov     r12,r12,lsl #1
199     ldrneh  r7, [r9, r12]    @ t = palmd[pmd[0]]
200     tst     lr, #0x20
201     ldrneb  lr, [r11,#-1]    @ MD pixel 1
202     strh    r7, [r0], #2
203     cmpne   r3, lr, lsl #26  @ MD has bg pixel?
204     mov     lr, lr, lsl #1
205     ldrneh  r8, [r9, lr]     @ t = palmd[pmd[1]]
206     strh    r8, [r0], #2
207 .else
208     streqh  r7, [r0]
209     tst     lr, #0x20
210     ldrneb  lr, [r11,#-1]    @ MD pixel 1
211     add     r0, r0, #4
212     cmpne   r3, lr, lsl #26  @ MD has bg pixel?
213     streqh  r8, [r0, #-2]
214 .endif
215     b       2b @ loop_inner
216
217 5: @ check_fill
218     @ count pixels, align if needed
219     bic     r12,r5, #1
220     ldrh    r12,[r12]
221     orr     lr, r7, r7, lsl #8
222     cmp     r12,lr
223     bne     3b @ no_fill
224
225     tst     r5, #1
226     sub     lr, r5, #2       @ starting r5 (32x render data start)
227     addeq   r5, r5, #2
228     addne   r5, r5, #1       @ add for the check above
229     add     r6, r6, #1       @ restore from dec
230     orr     r7, r7, r7, lsl #8
231 6:
232     sub     r12,r5, lr
233     ldrh    r8, [r5], #2
234     cmp     r12,r6, lsl #1
235     ldrh    r12,[r5], #2
236     bge     7f @ count_done
237     cmp     r8, r7
238     cmpeq   r12,r7
239     beq     6b
240
241 7: @ count_done
242     sub     r5, r5, #4      @ undo readahead
243
244     @ fix alignment and check type
245     sub     r8, r5, lr
246     tst     r8, #1
247     subne   r5, r5, #1
248     subne   r8, r8, #1
249
250     and     r7, r7, #0xff
251     cmp     r8, r6, lsl #1
252     mov     r7, r7, lsl #1
253     movgt   r8, r6, lsl #1  @ r8=count
254     ldrh    r7, [r10,r7]
255     sub     r6, r6, r8, lsr #1 @ adjust counter
256     tst     r7, #0x20
257     beq     9f @ bg_mode
258
259     add     r11,r11,r8
260 8:
261     subs    r8, r8, #2
262     strgeh  r7, [r0], #2
263     strgeh  r7, [r0], #2
264     bgt     8b
265     b       2b @ loop_inner
266
267 9: @ bg_mode:
268     ldrb    r12,[r11],#1     @ MD pixel
269     ldrb    lr, [r11],#1
270     cmp     r3, lr, lsl #26  @ MD has bg pixel?
271 .if \do_md
272     mov     r12,r12,lsl #1
273     ldrneh  r12,[r9, r12]    @ t = palmd[*pmd]
274     moveq   r12,r7
275     cmp     r3, lr, lsl #26
276     mov     lr, lr, lsl #1
277     ldrneh  lr, [r9, lr]
278     moveq   lr, r7
279     strh    r12,[r0], #2
280     strh    lr, [r0], #2
281 .else
282     streqh  r7, [r0]
283     cmp     r3, lr, lsl #26
284     streqh  r7, [r0, #2]
285     add     r0, r0, #4
286 .endif
287     subs    r8, r8, #2
288     bgt     9b @ bg_mode
289     b       2b @ loop_inner
290 .endm
291
292
293 @ run length
294 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
295 .macro make_do_loop_rl name call_scan do_md
296 .global \name
297 \name:
298     stmfd   sp!, {r4-r11,lr}
299
300     ldr     r11,=PicoDraw2FB
301     ldr     r10,=Pico32xNativePal
302     ldr     r11,[r11]
303     ldr     r10,[r10]
304     ldr     r9, =HighPal     @ palmd
305     and     r4, r2, #0xff
306     mov     r5, #328
307     lsl     r3, #26          @ mdbg << 26
308     mla     r11,r4,r5,r11    @ r11 = pmd = PicoDraw2FB + offs*328: md data
309     call_scan_prep \call_scan
310
311     mov     r4, #0           @ line
312     b       1f @ loop_outer_entry
313
314 0: @ loop_outer:
315     call_scan_end \call_scan
316     add     r4, r4, #1
317     sub     r11,r11,#1       @ adjust for prev read
318     cmp     r4, r2, lsr #16
319     call_scan_fin_ge \call_scan
320     ldmgefd sp!, {r4-r11,pc}
321
322 1: @ loop_outer_entry:
323     call_scan_begin \call_scan
324     mov     r12,r4, lsl #1
325     ldrh    r12,[r1, r12]
326     add     r11,r11,#8
327     mov     r6, #320
328     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
329
330 2: @ loop_inner:
331     ldrh    r8, [r5], #2     @ control word
332     and     r12,r8, #0xff
333     mov     r12,r12,lsl #1
334     ldrh    lr, [r10,r12]    @ t = 32x pixel
335     eor     lr, lr, #0x20
336
337 3: @ loop_innermost:
338     ldrb    r7, [r11], #1    @ MD pixel
339     subs    r6, r6, #1
340     blt     0b @ loop_outer
341     cmp     r3, r7, lsl #26  @ MD has bg pixel?
342     mov     r7, r7, lsl #1
343     tstne   lr, #0x20
344 .if \do_md
345     ldrneh  r12,[r9, r7]     @ t = palmd[*pmd]
346     streqh  lr, [r0], #2
347     strneh  r12,[r0], #2     @ *dst++ = t
348 .else
349     streqh  lr, [r0]
350     add     r0, r0, #2
351 .endif
352     subs    r8, r8, #0x100
353     bge     3b @ loop_innermost
354     b       2b @ loop_inner
355 .endm
356
357
358 make_do_loop_dc do_loop_dc,         0, 0
359 make_do_loop_dc do_loop_dc_md,      0, 1
360 make_do_loop_dc do_loop_dc_scan,    1, 0
361 make_do_loop_dc do_loop_dc_scan_md, 1, 1
362
363 make_do_loop_pp do_loop_pp,         0, 0
364 make_do_loop_pp do_loop_pp_md,      0, 1
365 make_do_loop_pp do_loop_pp_scan,    1, 0
366 make_do_loop_pp do_loop_pp_scan_md, 1, 1
367
368 make_do_loop_rl do_loop_rl,         0, 0
369 make_do_loop_rl do_loop_rl_md,      0, 1
370 make_do_loop_rl do_loop_rl_scan,    1, 0
371 make_do_loop_rl do_loop_rl_scan_md, 1, 1
372
373 @ vim:filetype=armasm