32x: various gfx related bugfixes
[picodrive.git] / pico / 32x / draw_arm.s
1 @ vim:filetype=armasm
2
3 .extern Pico32x
4 .extern PicoDraw2FB
5 .extern HighPal
6
7 .equiv P32XV_PRI,  (1<< 7)
8
9 .bss
10 .align 2
11 .global Pico32xNativePal
12 Pico32xNativePal:
13     .word 0
14
15 .text
16 .align 2
17
18
19 .macro call_scan_prep cond
20 .if \cond
21     ldr     r4, =PicoScan32xBegin
22     ldr     r5, =PicoScan32xEnd
23     ldr     r6, =DrawLineDest
24     ldr     r4, [r4]
25     ldr     r5, [r5]
26     stmfd   sp!, {r4,r5,r6}
27 .endif
28 .endm
29
30 .macro call_scan_fin_ge cond
31 .if \cond
32     addge   sp, sp, #4*3
33 .endif
34 .endm
35
36 .macro call_scan_begin cond
37 .if \cond
38     stmfd   sp!, {r1-r3}
39     and     r0, r2, #0xff
40     add     r0, r0, r4
41     mov     lr, pc
42     ldr     pc, [sp, #(3+0)*4]
43     ldr     r0, [sp, #(3+2)*4] @ &DrawLineDest
44     ldmfd   sp!, {r1-r3}
45     ldr     r0, [r0]
46 .endif
47 .endm
48
49 .macro call_scan_end cond
50 .if \cond
51     stmfd   sp!, {r0-r3}
52     and     r0, r2, #0xff
53     add     r0, r0, r4
54     mov     lr, pc
55     ldr     pc, [sp, #(4+1)*4]
56     ldmfd   sp!, {r0-r3}
57 .endif
58 .endm
59
60 @ direct color
61 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
62 .macro make_do_loop_dc name call_scan do_md
63 .global \name
64 \name:
65     stmfd   sp!, {r4-r11,lr}
66
67     ldr     r10,=Pico32x
68     ldr     r11,=PicoDraw2FB
69     ldr     r10,[r10, #0x40] @ Pico32x.vdp_regs[0]
70     ldr     r11,[r11]
71     ldr     r9, =HighPal     @ palmd
72     add     r11,r11,#(328*8) @ r11 = pmd: md data
73     tst     r10,#P32XV_PRI
74     moveq   r10,#0
75     movne   r10,#0x8000      @ r10 = inv_bit
76     call_scan_prep \call_scan
77
78     mov     r4, #0           @ line
79     b       1f @ loop_outer_entry
80
81 0: @ loop_outer:
82     call_scan_end \call_scan
83     add     r4, r4, #1
84     sub     r11,r11,#1       @ adjust for prev read
85     cmp     r4, r2, lsr #16
86     call_scan_fin_ge \call_scan
87     ldmgefd sp!, {r4-r11,pc}
88
89 1: @ loop_outer_entry:
90     call_scan_begin \call_scan
91     mov     r12,r4, lsl #1
92     ldrh    r12,[r1, r12]
93     add     r11,r11,#8
94     mov     r6, #320
95     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
96
97 2: @ loop_inner:
98     ldrb    r7, [r11], #1    @ MD pixel
99     subs    r6, r6, #1
100     blt     0b @ loop_outer
101     ldrh    r8, [r5], #2     @ 32x pixel
102     cmp     r7, r3           @ MD has bg pixel?
103     beq     3f @ draw32x
104     eor     r12,r8, r10
105     ands    r12,r12,#0x8000  @ !((t ^ inv) & 0x8000)
106 .if \do_md
107     mov     r7, r7, lsl #1
108     ldreqh  r12,[r9, r7]
109     streqh  r12,[r0], #2     @ *dst++ = palmd[*pmd]
110 .endif
111     beq     2b @ loop_inner
112
113 3: @ draw32x:
114     and     r12,r8, #0x03e0
115     mov     r8, r8, lsl #11
116     orr     r8, r8, r8, lsr #(10+11)
117     orr     r8, r8, r12,lsl #1
118     bic     r8, r8, #0x0020  @ kill prio bit
119     strh    r8, [r0], #2     @ *dst++ = bgr2rgb(*p32x++)
120     b       2b @ loop_inner
121 .endm
122
123
124 @ packed pixel
125 .macro do_pixel_pp do_md
126     ldrb    r7, [r11], #1    @ MD pixel
127     eor     r12,r5, #1
128     ldrb    r8, [r12]        @ palette index
129     cmp     r7, r3           @ MD has bg pixel?
130     mov     r12,r8,lsl #1
131     ldrh    r8, [r10,r12]    @ t = 32x pixel
132     mov     r7, r7, lsl #1
133     add     r5, r5, #1
134     eorne   r12,r8, #0x20
135     tstne   r12, #0x20
136 .if \do_md
137     ldrneh  r8, [r9, r7]     @ t = palmd[*pmd]
138     subs    r6, r6, #1
139     strh    r8, [r0], #2     @ *dst++ = t
140 .else
141     streqh  r8, [r0], #2
142     addne   r0, r0, #2
143     subs    r6, r6, #1
144 .endif
145 .endm
146
147 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
148 .macro make_do_loop_pp name call_scan do_md
149 .global \name
150 \name:
151     stmfd   sp!, {r4-r11,lr}
152
153     ldr     r11,=PicoDraw2FB
154     ldr     r10,=Pico32xNativePal
155     ldr     r11,[r11]
156     ldr     r10,[r10]
157     ldr     r9, =HighPal     @ palmd
158     add     r11,r11,#(328*8) @ r11 = pmd: md data
159     call_scan_prep \call_scan
160
161     mov     r4, #0           @ line
162     b       1f @ loop_outer_entry
163
164 0: @ loop_outer:
165     call_scan_end \call_scan
166     add     r4, r4, #1
167     cmp     r4, r2, lsr #16
168     call_scan_fin_ge \call_scan
169     ldmgefd sp!, {r4-r11,pc}
170
171 1: @ loop_outer_entry:
172     call_scan_begin \call_scan
173     mov     r12,r4, lsl #1
174     ldrh    r12,[r1, r12]
175     add     r11,r11,#8
176     mov     r6, #320
177     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
178     and     r12,r2, #0x100      @ shift
179     add     r5, r5, r12,lsr #8
180
181 2: @ loop_inner:
182     do_pixel_pp \do_md
183     do_pixel_pp \do_md
184     bgt     2b @ loop_inner
185     b       0b @ loop_outer
186 .endm
187
188
189 @ run length
190 @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg
191 .macro make_do_loop_rl name call_scan do_md
192 .global \name
193 \name:
194     stmfd   sp!, {r4-r11,lr}
195
196     ldr     r11,=PicoDraw2FB
197     ldr     r10,=Pico32xNativePal
198     ldr     r11,[r11]
199     ldr     r10,[r10]
200     ldr     r9, =HighPal     @ palmd
201     add     r11,r11,#(328*8) @ r11 = pmd: md data
202     call_scan_prep \call_scan
203
204     mov     r4, #0           @ line
205     b       1f @ loop_outer_entry
206
207 0: @ loop_outer:
208     call_scan_end \call_scan
209     add     r4, r4, #1
210     sub     r11,r11,#1       @ adjust for prev read
211     cmp     r4, r2, lsr #16
212     call_scan_fin_ge \call_scan
213     ldmgefd sp!, {r4-r11,pc}
214
215 1: @ loop_outer_entry:
216     call_scan_begin \call_scan
217     mov     r12,r4, lsl #1
218     ldrh    r12,[r1, r12]
219     add     r11,r11,#8
220     mov     r6, #320
221     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
222
223 2: @ loop_inner:
224     ldrh    r8, [r5], #2     @ control word
225     and     r12,r8, #0xff
226     mov     r12,r12,lsl #1
227     ldrh    lr, [r10,r12]    @ t = 32x pixel
228     eor     lr, lr, #0x20
229
230 3: @ loop_innermost:
231     ldrb    r7, [r11], #1    @ MD pixel
232     subs    r6, r6, #1
233     blt     0b @ loop_outer
234     cmp     r7, r3           @ MD has bg pixel?
235     mov     r7, r7, lsl #1
236     tstne   lr, #0x20
237 .if \do_md
238     ldrneh  r12,[r9, r7]     @ t = palmd[*pmd]
239     streqh  lr, [r0], #2
240     strneh  r12,[r0], #2     @ *dst++ = t
241 .else
242     streqh  lr, [r0]
243     add     r0, r0, #2
244 .endif
245     subs    r8, r8, #0x100
246     bge     3b @ loop_innermost
247     b       2b @ loop_inner
248 .endm
249
250
251 make_do_loop_dc do_loop_dc,         0, 0
252 make_do_loop_dc do_loop_dc_md,      0, 1
253 make_do_loop_dc do_loop_dc_scan,    1, 0
254 make_do_loop_dc do_loop_dc_scan_md, 1, 1
255
256 make_do_loop_pp do_loop_pp,         0, 0
257 make_do_loop_pp do_loop_pp_md,      0, 1
258 make_do_loop_pp do_loop_pp_scan,    1, 0
259 make_do_loop_pp do_loop_pp_scan_md, 1, 1
260
261 make_do_loop_rl do_loop_rl,         0, 0
262 make_do_loop_rl do_loop_rl_md,      0, 1
263 make_do_loop_rl do_loop_rl_scan,    1, 0
264 make_do_loop_rl do_loop_rl_scan_md, 1, 1
265