new 32x renderers, auto fskip change, massive refactoring
[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_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_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
179 2: @ loop_inner:
180     do_pixel_pp \do_md
181     do_pixel_pp \do_md
182     bgt     2b @ loop_inner
183     b       0b @ loop_outer
184 .endm
185
186
187 @ run length
188 @ unsigned short *dst, unsigned short *dram, int lines_offs, int mdbg
189 .macro make_do_loop_rl name call_scan do_md
190 .global \name
191 \name:
192     stmfd   sp!, {r4-r11,lr}
193
194     ldr     r11,=PicoDraw2FB
195     ldr     r10,=Pico32xNativePal
196     ldr     r11,[r11]
197     ldr     r10,[r10]
198     ldr     r9, =HighPal     @ palmd
199     add     r11,r11,#(328*8) @ r11 = pmd: md data
200     call_scan_prep \call_scan
201
202     mov     r4, #0           @ line
203     b       1f @ loop_outer_entry
204
205 0: @ loop_outer:
206     call_scan_end \call_scan
207     add     r4, r4, #1
208     sub     r11,r11,#1       @ adjust for prev read
209     cmp     r4, r2, lsr #16
210     call_scan_fin_ge \call_scan
211     ldmgefd sp!, {r4-r11,pc}
212
213 1: @ loop_outer_entry:
214     call_scan_begin \call_scan
215     mov     r12,r4, lsl #1
216     ldrh    r12,[r1, r12]
217     add     r11,r11,#8
218     mov     r6, #320
219     add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
220
221 2: @ loop_inner:
222     ldrh    r8, [r5], #2     @ control word
223     and     r12,r8, #0xff
224     mov     r12,r12,lsl #1
225     ldrh    lr, [r10,r12]    @ t = 32x pixel
226     eor     lr, lr, #0x20
227
228 3: @ loop_innermost:
229     ldrb    r7, [r11], #1    @ MD pixel
230     subs    r6, r6, #1
231     blt     0b @ loop_outer
232     cmp     r7, r3           @ MD has bg pixel?
233     mov     r7, r7, lsl #1
234     tstne   lr, #0x20
235 .if \do_md
236     ldrneh  r12,[r9, r7]     @ t = palmd[*pmd]
237     streqh  lr, [r0], #2
238     strneh  r12,[r0], #2     @ *dst++ = t
239 .else
240     streqh  lr, [r0]
241     add     r0, r0, #2
242 .endif
243     subs    r8, r8, #0x100
244     bge     3b @ loop_innermost
245     b       2b @ loop_inner
246 .endm
247
248
249 make_do_loop_dc do_loop_dc,         0, 0
250 make_do_loop_dc do_loop_dc_md,      0, 1
251 make_do_loop_dc do_loop_dc_scan,    1, 0
252 make_do_loop_dc do_loop_dc_scan_md, 1, 1
253
254 make_do_loop_pp do_loop_pp,         0, 0
255 make_do_loop_pp do_loop_pp_md,      0, 1
256 make_do_loop_pp do_loop_pp_scan,    1, 0
257 make_do_loop_pp do_loop_pp_scan_md, 1, 1
258
259 make_do_loop_rl do_loop_rl,         0, 0
260 make_do_loop_rl do_loop_rl_md,      0, 1
261 make_do_loop_rl do_loop_rl_scan,    1, 0
262 make_do_loop_rl do_loop_rl_scan_md, 1, 1
263