sound: remove cd rate limitations
[picodrive.git] / pico / 32x / draw_arm.s
... / ...
CommitLineData
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
18Pico32xNativePal:
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
900: @ 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
981: @ 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
1062: @ 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
1223: @ 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
1560: @ 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
1631: @ 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
1732: @ 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
1853: @ 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
2175: @ 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
2316:
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
2417: @ 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
2608:
261 subs r8, r8, #2
262 strgeh r7, [r0], #2
263 strgeh r7, [r0], #2
264 bgt 8b
265 b 2b @ loop_inner
266
2679: @ 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
3140: @ 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
3221: @ 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
3302: @ 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
3373: @ 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
358make_do_loop_dc do_loop_dc, 0, 0
359make_do_loop_dc do_loop_dc_md, 0, 1
360make_do_loop_dc do_loop_dc_scan, 1, 0
361make_do_loop_dc do_loop_dc_scan_md, 1, 1
362
363make_do_loop_pp do_loop_pp, 0, 0
364make_do_loop_pp do_loop_pp_md, 0, 1
365make_do_loop_pp do_loop_pp_scan, 1, 0
366make_do_loop_pp do_loop_pp_scan_md, 1, 1
367
368make_do_loop_rl do_loop_rl, 0, 0
369make_do_loop_rl do_loop_rl_md, 0, 1
370make_do_loop_rl do_loop_rl_scan, 1, 0
371make_do_loop_rl do_loop_rl_scan_md, 1, 1
372
373@ vim:filetype=armasm