cff531af |
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 | @* |
5a681086 |
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 |
e51e5983 |
67 | @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg |
5a681086 |
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 |
7a961c19 |
78 | and r4, r2, #0xff |
79 | mov r5, #328 |
6b5feeba |
80 | lsl r3, #26 @ mdbg << 26 |
7a961c19 |
81 | mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data |
5a681086 |
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 |
6b5feeba |
111 | cmp r3, r7, lsl #26 @ MD has bg pixel? |
5a681086 |
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 |
07e5dbab |
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. |
e51e5983 |
136 | @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg |
5a681086 |
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 |
7a961c19 |
147 | and r4, r2, #0xff |
148 | mov r5, #328 |
6b5feeba |
149 | lsl r3, #26 @ mdbg << 26 |
7a961c19 |
150 | mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data |
5a681086 |
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 |
07e5dbab |
168 | mov r6, #320/2 |
5a681086 |
169 | add r5, r1, r12, lsl #1 @ p32x = dram + dram[l] |
e51e5983 |
170 | and r12,r2, #0x100 @ shift |
171 | add r5, r5, r12,lsr #8 |
5a681086 |
172 | |
173 | 2: @ loop_inner: |
07e5dbab |
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 |
6b5feeba |
196 | cmpne r3, r12, lsl #26 @ MD has bg pixel? |
07e5dbab |
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 |
6b5feeba |
203 | cmpne r3, lr, lsl #26 @ MD has bg pixel? |
07e5dbab |
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 |
6b5feeba |
212 | cmpne r3, lr, lsl #26 @ MD has bg pixel? |
07e5dbab |
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 |
6b5feeba |
270 | cmp r3, lr, lsl #26 @ MD has bg pixel? |
07e5dbab |
271 | .if \do_md |
272 | mov r12,r12,lsl #1 |
273 | ldrneh r12,[r9, r12] @ t = palmd[*pmd] |
274 | moveq r12,r7 |
6b5feeba |
275 | cmp r3, lr, lsl #26 |
07e5dbab |
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] |
6b5feeba |
283 | cmp r3, lr, lsl #26 |
07e5dbab |
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 |
5a681086 |
290 | .endm |
291 | |
292 | |
293 | @ run length |
e51e5983 |
294 | @ unsigned short *dst, unsigned short *dram, int lines_sft_offs, int mdbg |
5a681086 |
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 |
7a961c19 |
305 | and r4, r2, #0xff |
306 | mov r5, #328 |
6b5feeba |
307 | lsl r3, #26 @ mdbg << 26 |
7a961c19 |
308 | mla r11,r4,r5,r11 @ r11 = pmd = PicoDraw2FB + offs*328: md data |
5a681086 |
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 |
6b5feeba |
341 | cmp r3, r7, lsl #26 @ MD has bg pixel? |
5a681086 |
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 | |
cff531af |
373 | @ vim:filetype=armasm |