add configure, revive pnd build, unify/refactor things
[picodrive.git] / pico / draw2_arm.s
CommitLineData
cff531af 1/*\r
2 * assembly optimized versions of most funtions from draw2.c\r
3 * (C) notaz, 2006-2008\r
4 *\r
5 * This work is licensed under the terms of MAME license.\r
6 * See COPYING file in the top-level directory.\r
7 *\r
8 * this is highly specialized, be careful if changing related C code!\r
9 */\r
cc68a136 10\r
11.extern Pico\r
e5f426aa 12.extern PicoDraw2FB\r
cc68a136 13\r
14@ define these constants in your include file:\r
15@ .equiv START_ROW, 1\r
16@ .equiv END_ROW, 27\r
17@ one row means 8 pixels. If above example was used, (27-1)*8=208 lines would be rendered.\r
18.include "port_config.s"\r
19\r
20\r
21.global BackFillFull @ int reg7\r
22\r
23BackFillFull:\r
24 stmfd sp!, {r4-r9,lr}\r
25\r
e5f426aa 26 ldr lr, =PicoDraw2FB @ lr=PicoDraw2FB\r
ea8c405f 27 mov r0, r0, lsl #26\r
cc68a136 28 ldr lr, [lr]\r
ea8c405f 29 mov r0, r0, lsr #26\r
cc68a136 30 add lr, lr, #328*8\r
31\r
cc68a136 32 orr r0, r0, r0, lsl #8\r
33 orr r0, r0, r0, lsl #16\r
34\r
35 mov r1, r0 @ 25 opcodes wasted?\r
36 mov r2, r0\r
37 mov r3, r0\r
38 mov r4, r0\r
39 mov r5, r0\r
40 mov r6, r0\r
41 mov r7, r0\r
42 mov r8, r0\r
43 mov r9, r0\r
44\r
45 mov r12, #(END_ROW-START_ROW)*8\r
46\r
47 @ go go go!\r
48.bff_loop:\r
49 add lr, lr, #8\r
50 subs r12, r12, #1\r
51\r
52 stmia lr!, {r0-r9} @ 10*4*8\r
53 stmia lr!, {r0-r9}\r
54 stmia lr!, {r0-r9}\r
55 stmia lr!, {r0-r9}\r
56 stmia lr!, {r0-r9}\r
57 stmia lr!, {r0-r9}\r
58 stmia lr!, {r0-r9}\r
59 stmia lr!, {r0-r9}\r
60\r
61 bne .bff_loop\r
62\r
63 ldmfd sp!, {r4-r9,r12}\r
64 bx r12\r
65\r
66.pool\r
67\r
68@ -------- some macros --------\r
69\r
70\r
71@ helper\r
72@ TileLineSinglecol (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: pixels8_old\r
73.macro TileLineSinglecol notsinglecol=0\r
74 and r2, r2, #0xf @ #0x0000000f\r
75.if !\notsinglecol\r
76 cmp r2, r0, lsr #28 @ if these don't match,\r
77 bicne r9, r9, #2 @ it is a sign that whole tile is not singlecolor (only it's lines may be)\r
78.endif\r
79 orr r4, r3, r2\r
80 orr r4, r4, r4, lsl #8\r
81\r
82 tst r1, #1 @ not aligned?\r
83 strneb r4, [r1], #1\r
84 streqh r4, [r1], #2\r
85 strh r4, [r1], #2\r
86 strh r4, [r1], #2\r
87 strh r4, [r1], #2\r
88 strneb r4, [r1], #1 @ have a remaining unaligned pixel?\r
89 sub r1, r1, #8\r
90.if !\notsinglecol\r
91 mov r0, #0xf\r
92 orr r0, r0, r2, lsl #28 @ we will need the old palindex later\r
93.endif\r
94.endm\r
95\r
96@ TileNorm (r1=pdest, r2=pixels8, r3=pal) r0,r4: scratch\r
97.macro TileLineNorm\r
98 ands r4, r0, r2, lsr #12 @ #0x0000f000\r
99 orrne r4, r3, r4\r
100 strneb r4, [r1]\r
101 ands r4, r0, r2, lsr #8 @ #0x00000f00\r
102 orrne r4, r3, r4\r
103 strneb r4, [r1,#1]\r
104 ands r4, r0, r2, lsr #4 @ #0x000000f0\r
105 orrne r4, r3, r4\r
106 strneb r4, [r1,#2]\r
107 ands r4, r0, r2 @ #0x0000000f\r
108 orrne r4, r3, r4\r
109 strneb r4, [r1,#3]\r
110 ands r4, r0, r2, lsr #28 @ #0xf0000000\r
111 orrne r4, r3, r4\r
112 strneb r4, [r1,#4]\r
113 ands r4, r0, r2, lsr #24 @ #0x0f000000\r
114 orrne r4, r3, r4\r
115 strneb r4, [r1,#5]\r
116 ands r4, r0, r2, lsr #20 @ #0x00f00000\r
117 orrne r4, r3, r4\r
118 strneb r4, [r1,#6]\r
119 ands r4, r0, r2, lsr #16 @ #0x000f0000\r
120 orrne r4, r3, r4\r
121 strneb r4, [r1,#7]\r
122.endm\r
123\r
124@ TileFlip (r1=pdest, r2=pixels8, r3=pal) r0,r4: scratch\r
125.macro TileLineFlip\r
126 ands r4, r0, r2, lsr #16 @ #0x000f0000\r
127 orrne r4, r3, r4\r
128 strneb r4, [r1]\r
129 ands r4, r0, r2, lsr #20 @ #0x00f00000\r
130 orrne r4, r3, r4\r
131 strneb r4, [r1,#1]\r
132 ands r4, r0, r2, lsr #24 @ #0x0f000000\r
133 orrne r4, r3, r4\r
134 strneb r4, [r1,#2]\r
135 ands r4, r0, r2, lsr #28 @ #0xf0000000\r
136 orrne r4, r3, r4\r
137 strneb r4, [r1,#3]\r
138 ands r4, r0, r2 @ #0x0000000f\r
139 orrne r4, r3, r4\r
140 strneb r4, [r1,#4]\r
141 ands r4, r0, r2, lsr #4 @ #0x000000f0\r
142 orrne r4, r3, r4\r
143 strneb r4, [r1,#5]\r
144 ands r4, r0, r2, lsr #8 @ #0x00000f00\r
145 orrne r4, r3, r4\r
146 strneb r4, [r1,#6]\r
147 ands r4, r0, r2, lsr #12 @ #0x0000f000\r
148 orrne r4, r3, r4\r
149 strneb r4, [r1,#7]\r
150.endm\r
151\r
152@ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf\r
153.macro Tile hflip vflip\r
154 mov r7, r9, lsl #13 @ r9=code<<8; addr=(code&0x7ff)<<4;\r
155 add r7, r10, r7, lsr #16\r
156 orr r9, r9, #3 @ emptytile=singlecolor=1, r9 must be <code_16> 00000xxx\r
157.if \vflip\r
158 @ we read tilecodes in reverse order if we have vflip\r
159 add r7, r7, #8*4\r
160.endif\r
161 @ loop through 8 lines\r
162 orr r9, r9, #(7<<24)\r
163 b 1f @ loop_enter\r
164\r
1650: @ singlecol_loop\r
166 subs r9, r9, #(1<<24)\r
167 add r1, r1, #328 @ set pointer to next line\r
168 bmi 8f @ loop_exit with r0 restore\r
1691:\r
170.if \vflip\r
171 ldr r2, [r7, #-4]! @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
172.else\r
173 ldr r2, [r7], #4\r
174.endif\r
175 tst r2, r2\r
176 beq 2f @ empty line\r
177 bic r9, r9, #1\r
178 cmp r2, r2, ror #4\r
179 bne 3f @ not singlecolor\r
180 TileLineSinglecol\r
181 b 0b\r
182\r
1832:\r
184 bic r9, r9, #2\r
1852: @ empty_loop\r
186 subs r9, r9, #(1<<24)\r
187 add r1, r1, #328 @ set pointer to next line\r
188 bmi 8f @ loop_exit with r0 restore\r
189.if \vflip\r
190 ldr r2, [r7, #-4]! @ next pack\r
191.else\r
192 ldr r2, [r7], #4\r
193.endif\r
194 mov r0, #0xf @ singlecol_loop might have messed r0\r
195 tst r2, r2\r
196 beq 2b\r
197\r
198 bic r9, r9, #3 @ if we are here, it means we have empty and not empty line\r
199 b 5f\r
200\r
2013: @ not empty, not singlecol\r
202 mov r0, #0xf\r
203 bic r9, r9, #3\r
204 b 6f\r
205\r
2064: @ not empty, not singlecol loop\r
207 subs r9, r9, #(1<<24)\r
208 add r1, r1, #328 @ set pointer to next line\r
209 bmi 9f @ loop_exit\r
210.if \vflip\r
211 ldr r2, [r7, #-4]! @ next pack\r
212.else\r
213 ldr r2, [r7], #4\r
214.endif\r
215 tst r2, r2\r
216 beq 4b @ empty line\r
2175:\r
218 cmp r2, r2, ror #4\r
219 beq 7f @ singlecolor line\r
2206:\r
221.if \hflip\r
222 TileLineFlip\r
223.else\r
224 TileLineNorm\r
225.endif\r
226 b 4b\r
2277:\r
228 TileLineSinglecol 1\r
229 b 4b\r
230\r
2318:\r
232 mov r0, #0xf\r
2339: @ loop_exit\r
234 add r9, r9, #(1<<24) @ fix r9\r
235 sub r1, r1, #328*8 @ restore pdest pointer\r
236.endm\r
237\r
238\r
239@ TileLineSinglecolAl (r1=pdest, r4,r7=color)\r
240.macro TileLineSinglecolAl0\r
241 stmia r1!, {r4,r7}\r
242 add r1, r1, #320\r
243.endm\r
244\r
245.macro TileLineSinglecolAl1\r
246 strb r4, [r1], #1\r
247 strh r4, [r1], #2\r
248 str r4, [r1], #4\r
249 strb r4, [r1], #1+320\r
250@ add r1, r1, #320\r
251.endm\r
252\r
253.macro TileLineSinglecolAl2\r
254 strh r4, [r1], #2\r
255 str r4, [r1], #4\r
256 strh r4, [r1], #2\r
257 add r1, r1, #320\r
258.endm\r
259\r
260.macro TileLineSinglecolAl3\r
261 strb r4, [r1], #1\r
262 str r4, [r1], #4\r
263 strh r4, [r1], #2\r
264 strb r4, [r1], #1+320\r
265@ add r1, r1, #320\r
266.endm\r
267\r
268@ TileSinglecol (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=0xf\r
269@ kaligned==1, if dest is always aligned\r
270.macro TileSinglecol kaligned=0\r
271 and r4, r2, #0xf @ we assume we have good r2 from previous time\r
272 orr r4, r4, r3\r
273 orr r4, r4, r4, lsl #8\r
274 orr r4, r4, r4, lsl #16\r
275 mov r7, r4\r
276\r
277.if !\kaligned\r
278 tst r1, #2 @ not aligned?\r
279 bne 2f\r
280 tst r1, #1\r
281 bne 1f\r
282.endif\r
283\r
284 TileLineSinglecolAl0\r
285 TileLineSinglecolAl0\r
286 TileLineSinglecolAl0\r
287 TileLineSinglecolAl0\r
288 TileLineSinglecolAl0\r
289 TileLineSinglecolAl0\r
290 TileLineSinglecolAl0\r
291 TileLineSinglecolAl0\r
292\r
293.if !\kaligned\r
294 b 4f\r
2951:\r
296 TileLineSinglecolAl1\r
297 TileLineSinglecolAl1\r
298 TileLineSinglecolAl1\r
299 TileLineSinglecolAl1\r
300 TileLineSinglecolAl1\r
301 TileLineSinglecolAl1\r
302 TileLineSinglecolAl1\r
303 TileLineSinglecolAl1\r
304 b 4f\r
305\r
3062:\r
307 tst r1, #1\r
308 bne 3f\r
309\r
310 TileLineSinglecolAl2\r
311 TileLineSinglecolAl2\r
312 TileLineSinglecolAl2\r
313 TileLineSinglecolAl2\r
314 TileLineSinglecolAl2\r
315 TileLineSinglecolAl2\r
316 TileLineSinglecolAl2\r
317 TileLineSinglecolAl2\r
318 b 4f\r
319\r
3203:\r
321 TileLineSinglecolAl3\r
322 TileLineSinglecolAl3\r
323 TileLineSinglecolAl3\r
324 TileLineSinglecolAl3\r
325 TileLineSinglecolAl3\r
326 TileLineSinglecolAl3\r
327 TileLineSinglecolAl3\r
328 TileLineSinglecolAl3\r
329\r
3304:\r
331.endif\r
332 sub r1, r1, #328*8 @ restore pdest pointer\r
333.endm\r
334\r
335\r
336\r
337@ DrawLayerTiles(*hcache, *scrpos, (cells<<24)|(nametab<<9)|(vscroll&0x3ff)<<11|(shift[width]<<8)|planeend, (ymask<<24)|(planestart<<16)|[htab||hscroll]\r
338\r
339@static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend)\r
340\r
341.global DrawLayerFull\r
342\r
343DrawLayerFull:\r
344 stmfd sp!, {r4-r11,lr}\r
345\r
346 mov r6, r1 @ hcache\r
347\r
ea8c405f 348 ldr r11, =(Pico+0x22228) @ Pico.video\r
349 ldr r10, =(Pico+0x10000) @ r10=Pico.vram\r
350 ldrb r5, [r11, #13] @ pvid->reg[13]\r
351 ldrb r7, [r11, #11]\r
352\r
cc68a136 353 sub lr, r3, r2\r
354 and lr, lr, #0x00ff0000 @ lr=cells\r
355\r
cc68a136 356 mov r5, r5, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)\r
357 add r5, r5, r0, lsl #1 @ htab+=plane\r
358 bic r5, r5, #0x00ff0000 @ just in case\r
359\r
cc68a136 360 tst r7, #3 @ full screen scroll? (if ==0)\r
ea8c405f 361 ldrb r7, [r11, #16] @ ??hh??ww\r
cc68a136 362 ldreqh r5, [r10, r5]\r
363 biceq r5, r5, #0x0000fc00 @ r5=hscroll (0-0x3ff)\r
364 movne r5, r5, lsr #1\r
365 orrne r5, r5, #0x8000 @ this marks that we have htab pointer, not hscroll here\r
366\r
cc68a136 367 and r8, r7, #3\r
368\r
369 orr r5, r5, r7, lsl #1+24\r
370 orr r5, r5, #0x1f000000\r
371 cmp r8, #1\r
372 biclt r5, r5, #0x80000000\r
373 biceq r5, r5, #0xc0000000\r
374 bicgt r5, r5, #0xe0000000\r
375\r
376 mov r9, r2, lsl #24\r
377 orr r5, r5, r9, lsr #8 @ r5=(ymask<<24)|(trow<<16)|[htab||hscroll]\r
378\r
379 add r4, r8, #5\r
380 cmp r4, #7\r
381 subge r4, r4, #1 @ r4=shift[width] (5,6,6,7)\r
382\r
383 orr lr, lr, r4 \r
384 orr lr, lr, r3, lsl #24 @ lr=(planeend<<24)|(cells<<16)|shift[width]\r
385\r
386 @ calculate xmask:\r
387 mov r8, r8, lsl #24+5\r
388 orr r8, r8, #0x1f000000\r
389\r
ea8c405f 390 @ Find name table:\r
cc68a136 391 tst r0, r0\r
392 ldreqb r4, [r11, #2]\r
393 moveq r4, r4, lsr #3\r
394 ldrneb r4, [r11, #4]\r
395 and r4, r4, #7\r
396 orr lr, lr, r4, lsl #13 @ lr|=nametab_bits{3}<<13\r
397\r
e5f426aa 398 ldr r11, =PicoDraw2FB @ r11=PicoDraw2FB\r
cc68a136 399 sub r4, r9, #(START_ROW<<24)\r
ea8c405f 400 ldr r11, [r11]\r
cc68a136 401 mov r4, r4, asr #24\r
402 mov r7, #328*8\r
403 mla r11, r4, r7, r11 @ scrpos+=8*328*(planestart-START_ROW);\r
404\r
ea8c405f 405 @ Get vertical scroll value:\r
cc68a136 406 add r7, r10, #0x012000\r
407 add r7, r7, #0x000180 @ r7=Pico.vsram (Pico+0x22180)\r
408 ldr r7, [r7]\r
409 tst r0, r0\r
410 moveq r7, r7, lsl #22\r
411 movne r7, r7, lsl #6\r
412 mov r7, r7, lsr #22 @ r7=vscroll (10 bits)\r
413\r
414 orr lr, lr, r7, lsl #3\r
415 mov lr, lr, ror #24 @ packed: cccccccc nnnvvvvv vvvvvsss pppppppp: cells, nametab, vscroll, shift[width], planeend\r
416\r
417 ands r7, r7, #7\r
418 addne lr, lr, #1 @ we have vertically clipped tiles due to vscroll, so we need 1 more row\r
419\r
420 rsb r7, r7, #8\r
421 str r7, [r6], #4 @ push y-offset to tilecache\r
422 mov r4, #328\r
423 mla r11, r4, r7, r11 @ scrpos+=(8-(vscroll&7))*328;\r
424\r
425 mov r9, #0xff000000 @ r9=(prevcode<<8)|flags: 1~tile empty, 2~tile singlecolor\r
426\r
427.rtrloop_outer:\r
428 mov r4, lr, lsl #11\r
429 mov r4, r4, lsr #25 @ r4=vscroll>>3 (7 bits)\r
430 add r4, r4, r5, lsr #16 @ +trow\r
431 and r4, r4, r5, lsr #24 @ &=ymask\r
432 mov r7, lr, lsr #8\r
433 and r7, r7, #7 @ shift[width]\r
434 mov r0, lr, lsr #9\r
435 and r0, r0, #0x7000 @ nametab\r
436 add r12,r0, r4, lsl r7 @ nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); \r
437\r
438 mov r4, lr, lsr #24\r
439 orr r12,r12,r4, lsl #23\r
440 mov r12,r12,lsl #1 @ (nametab_row|(cells<<24)) (halfword compliant)\r
441\r
442 @ htab?\r
443 tst r5, #0x8000\r
444 moveq r7, r5, lsl #22 @ hscroll (0-3FFh)\r
445 moveq r7, r7, lsr #22\r
446 beq .rtr_hscroll_done\r
447\r
448 @ get hscroll from htab\r
449 mov r7, r5, lsl #17\r
450 ands r4, r5, #0x00ff0000\r
451 add r7, r7, r4, lsl #5 @ +=trow<<4\r
452 andne r4, lr, #0x3800\r
453 subne r7, r7, r4, lsl #7 @ if(trow) htaddr-=(vscroll&7)<<1;\r
454 mov r7, r7, lsr #16 @ halfwords\r
455 ldrh r7, [r10, r7]\r
456\r
457.rtr_hscroll_done:\r
ea8c405f 458 and r8, r8, #0xff000000\r
cc68a136 459 rsb r4, r7, #0 @ r4=tilex=(-ts->hscroll)>>3\r
460 mov r4, r4, asr #3\r
461 and r4, r4, #0xff\r
cc68a136 462 orr r8, r8, r4 @ r8=(xmask<<24)|tilex\r
463\r
464 sub r7, r7, #1\r
465 and r7, r7, #7\r
466 add r7, r7, #1 @ r7=dx=((ts->hscroll-1)&7)+1\r
467\r
468 cmp r7, #8\r
469 subeq r12,r12, #0x01000000 @ we will loop cells+1 times, so loop less when there is no hscroll\r
470\r
471 add r1, r11, r7 @ r1=pdest\r
472 mov r0, #0xf\r
473 b .rtrloop_enter\r
474\r
475 @ r4 & r7 are scratch in this loop\r
476.rtrloop: @ 40-41 times\r
477 add r1, r1, #8\r
478 subs r12,r12, #0x01000000\r
479 add r8, r8, #1\r
480 bmi .rtrloop_exit\r
481\r
482.rtrloop_enter:\r
483 and r7, r8, r8, lsr #24\r
484 add r7, r10, r7, lsl #1\r
485 bic r4, r12, #0xff000000 @ Pico.vram[nametab_row+(tilex&xmask)];\r
486 ldrh r7, [r7, r4] @ r7=code (int, but from unsigned, no sign extend)\r
487\r
488 tst r7, #0x8000\r
489 bne .rtr_hiprio\r
490\r
491 cmp r7, r9, lsr #8\r
492 bne .rtr_notsamecode\r
493 @ we know stuff about this tile already\r
494 tst r9, #1\r
495 bne .rtrloop @ empty tile\r
496 tst r9, #2\r
497 bne .rtr_singlecolor @ singlecolor tile\r
498 b .rtr_samecode\r
499\r
500.rtr_notsamecode:\r
501 and r4, r9, #0x600000\r
502 mov r9, r7, lsl #8 @ remember new code\r
503\r
504 @ update cram\r
505 and r7, r7, #0x6000\r
506 mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);\r
507\r
508.rtr_samecode:\r
509 tst r9, #0x100000 @ vflip?\r
510 bne .rtr_vflip\r
511\r
512 tst r9, #0x080000 @ hflip?\r
513 bne .rtr_hflip\r
514\r
515 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf\r
516 Tile 0, 0\r
517 b .rtrloop\r
518\r
519.rtr_hflip:\r
520 Tile 1, 0\r
521 b .rtrloop\r
522\r
523.rtr_vflip:\r
524 tst r9, #0x080000 @ hflip?\r
525 bne .rtr_vflip_hflip\r
526\r
527 Tile 0, 1\r
528 b .rtrloop\r
529\r
530.rtr_vflip_hflip:\r
531 Tile 1, 1\r
532 b .rtrloop\r
533\r
534.rtr_singlecolor:\r
535 TileSinglecol\r
536 b .rtrloop\r
537\r
538.rtr_hiprio:\r
539 @ *(*hcache)++ = code|(dx<<16)|(trow<<27);\r
540 sub r4, r1, r11\r
541 orr r7, r7, r4, lsl #16\r
542 and r4, r5, #0x00ff0000\r
543 orr r7, r7, r4, lsl #11 @ (trow<<27)\r
544 str r7, [r6], #4 @ cache hi priority tile\r
545 b .rtrloop\r
546\r
547.rtrloop_exit:\r
548 add r5, r5, #0x00010000\r
549 mov r4, r5, lsl #8\r
550 cmp r4, lr, lsl #24\r
551 bge .rtrloop_outer_exit\r
552 add r11, r11, #328*8\r
553 b .rtrloop_outer\r
554\r
555.rtrloop_outer_exit:\r
556\r
557 @ terminate cache list\r
558 mov r0, #0\r
559 str r0, [r6] @ save cache pointer\r
560\r
561 ldmfd sp!, {r4-r11,lr}\r
562 bx lr\r
563\r
564.pool\r
565\r
566\r
567\r
568.global DrawTilesFromCacheF @ int *hc\r
569\r
570DrawTilesFromCacheF:\r
571 stmfd sp!, {r4-r10,lr}\r
572\r
573 mov r9, #0xff000000 @ r9=prevcode=-1\r
574 mvn r6, #0 @ r6=prevy=-1\r
575\r
e5f426aa 576 ldr r4, =PicoDraw2FB @ r4=PicoDraw2FB\r
cc68a136 577 ldr r1, [r0], #4 @ read y offset\r
ea8c405f 578 ldr r4, [r4]\r
cc68a136 579 mov r7, #328\r
580 mla r1, r7, r1, r4\r
581 sub r12, r1, #(328*8*START_ROW) @ r12=scrpos\r
582\r
583 ldr r10, =(Pico+0x10000) @ r10=Pico.vram\r
584 mov r8, r0 @ hc\r
585 mov r0, #0xf\r
586\r
587 @ scratch: r4, r7\r
588 @ *hcache++ = code|(dx<<16)|(trow<<27); // cache it\r
589\r
590.dtfcf_loop:\r
591 ldr r7, [r8], #4 @ read code\r
592 movs r1, r7, lsr #16 @ r1=dx;\r
593 ldmeqfd sp!, {r4-r10,pc} @ dx is never zero, this must be a terminator, return\r
594\r
ea8c405f 595 @ row changed?\r
cc68a136 596 cmp r6, r7, lsr #27\r
597 movne r6, r7, lsr #27\r
598 movne r4, #328*8\r
599 mlane r5, r4, r6, r12 @ r5=pd = scrpos + prevy*328*8\r
600\r
601 bic r1, r1, #0xf800\r
602 add r1, r5, r1 @ r1=pdest (halfwords)\r
603\r
604 mov r7, r7, lsl #16\r
605 mov r7, r7, lsr #16\r
606\r
607 cmp r7, r9, lsr #8\r
608 bne .dtfcf_notsamecode\r
609 @ we know stuff about this tile already\r
610 tst r9, #1\r
611 bne .dtfcf_loop @ empty tile\r
612 tst r9, #2\r
613 bne .dtfcf_singlecolor @ singlecolor tile\r
614 b .dtfcf_samecode\r
615\r
616.dtfcf_notsamecode:\r
617 and r4, r9, #0x600000\r
618 mov r9, r7, lsl #8 @ remember new code\r
619\r
620 @ update cram val\r
621 and r7, r7, #0x6000\r
622 mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);\r
623\r
624\r
625.dtfcf_samecode:\r
626\r
627 tst r9, #0x100000 @ vflip?\r
628 bne .dtfcf_vflip\r
629\r
630 tst r9, #0x080000 @ hflip?\r
631 bne .dtfcf_hflip\r
632\r
633 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf\r
634 Tile 0, 0\r
635 b .dtfcf_loop\r
636\r
637.dtfcf_hflip:\r
638 Tile 1, 0\r
639 b .dtfcf_loop\r
640\r
641.dtfcf_vflip:\r
642 tst r9, #0x080000 @ hflip?\r
643 bne .dtfcf_vflip_hflip\r
644\r
645 Tile 0, 1\r
646 b .dtfcf_loop\r
647\r
648.dtfcf_vflip_hflip:\r
649 Tile 1, 1\r
650 b .dtfcf_loop\r
651\r
652.dtfcf_singlecolor:\r
653 TileSinglecol\r
654 b .dtfcf_loop\r
655\r
656.pool\r
657\r
658\r
659@ @@@@@@@@@@@@@@@\r
660\r
661@ (tile_start<<16)|row_start\r
662.global DrawWindowFull @ int tstart, int tend, int prio\r
663\r
664DrawWindowFull:\r
665 stmfd sp!, {r4-r11,lr}\r
666\r
667 ldr r11, =(Pico+0x22228) @ Pico.video\r
668 ldrb r12, [r11, #3] @ pvid->reg[3]\r
669 mov r12, r12, lsl #10\r
670\r
671 ldr r4, [r11, #12]\r
672 mov r5, #1 @ nametab_step\r
673 tst r4, #1 @ 40 cell mode?\r
674 andne r12, r12, #0xf000 @ 0x3c<<10\r
675 andeq r12, r12, #0xf800\r
676 movne r5, r5, lsl #7\r
677 moveq r5, r5, lsl #6 @ nametab_step\r
678\r
679 and r4, r0, #0xff\r
680 mla r12, r5, r4, r12 @ nametab += nametab_step*start;\r
681\r
682 mov r4, r0, lsr #16 @ r4=start_cell_h\r
683 add r7, r12, r4, lsl #1\r
684\r
685 @ fetch the first code now\r
686 ldr r10, =(Pico+0x10000) @ lr=Pico.vram\r
687 ldrh r7, [r10, r7]\r
688 cmp r2, r7, lsr #15\r
689 ldmnefd sp!, {r4-r11,pc} @ hack: simply assume that whole window uses same priority\r
690\r
691 rsb r8, r4, r1, lsr #16 @ cells (h)\r
692 orr r8, r8, r4, lsl #8\r
693 mov r4, r1, lsl #24\r
694 sub r4, r4, r0, lsl #24\r
695 orr r8, r8, r4, lsr #8 @ r8=cells_h|(start_cell_h<<8)|(cells_v<<16)\r
696 sub r8, r8, #0x010000 @ adjust for algo\r
697\r
698 mov r9, #0xff000000 @ r9=prevcode=-1\r
699\r
e5f426aa 700 ldr r11, =PicoDraw2FB @ r11=scrpos\r
ea8c405f 701 and r4, r0, #0xff\r
cc68a136 702 ldr r11, [r11]\r
ea8c405f 703 sub r4, r4, #START_ROW\r
cc68a136 704 add r11, r11, #328*8\r
705 add r11, r11, #8\r
706\r
cc68a136 707 mov r7, #328*8\r
708 mla r11, r7, r4, r11 @ scrpos+=8*328*(start-START_ROW);\r
709 mov r0, #0xf\r
710\r
711.dwfloop_outer:\r
712 and r6, r8, #0xff00 @ r6=tilex\r
713 add r1, r11, r6, lsr #5 @ r1=pdest\r
714 add r6, r12, r6, lsr #7\r
715 add r6, r10, r6 @ r6=Pico.vram+nametab+tilex\r
716 orr r8, r8, r8, lsl #24\r
717 sub r8, r8, #0x01000000 @ cell loop counter\r
718 b .dwfloop_enter\r
719\r
720 @ r4 & r7 are scratch in this loop\r
721.dwfloop:\r
722 add r1, r1, #8\r
723 subs r8, r8, #0x01000000\r
724 bmi .dwfloop_exit\r
725\r
726.dwfloop_enter:\r
727 ldrh r7, [r6], #2 @ r7=code\r
728\r
729 cmp r7, r9, lsr #8\r
730 bne .dwf_notsamecode\r
731 @ we know stuff about this tile already\r
732 tst r9, #1\r
733 bne .dwfloop @ empty tile\r
734 tst r9, #2\r
735 bne .dwf_singlecolor @ singlecolor tile\r
736 b .dwf_samecode\r
737\r
738.dwf_notsamecode:\r
739 and r4, r9, #0x600000\r
740 mov r9, r7, lsl #8 @ remember new code\r
741\r
742 @ update cram val\r
743 and r7, r7, #0x6000\r
744 mov r3, r7, asr #9 @ r3=pal=((code&0x6000)>>9);\r
745\r
746.dwf_samecode:\r
747\r
748 tst r9, #0x100000 @ vflip?\r
749 bne .dwf_vflip\r
750\r
751 tst r9, #0x080000 @ hflip?\r
752 bne .dwf_hflip\r
753\r
754 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf\r
755 Tile 0, 0\r
756 b .dwfloop\r
757\r
758.dwf_hflip:\r
759 Tile 1, 0\r
760 b .dwfloop\r
761\r
762.dwf_vflip:\r
763 tst r9, #0x080000 @ hflip?\r
764 bne .dwf_vflip_hflip\r
765\r
766 Tile 0, 1\r
767 b .dwfloop\r
768\r
769.dwf_vflip_hflip:\r
770 Tile 1, 1\r
771 b .dwfloop\r
772\r
773.dwf_singlecolor:\r
774 TileSinglecol 1\r
775 b .dwfloop\r
776\r
777.dwfloop_exit:\r
778 bic r8, r8, #0xff000000 @ fix r8\r
779 subs r8, r8, #0x010000\r
780 ldmmifd sp!, {r4-r11,pc}\r
781 add r11, r11, #328*8\r
782 add r12, r12, r5 @ nametab+=nametab_step\r
783 b .dwfloop_outer\r
784\r
785.pool\r
786\r
787\r
788@ ---------------- sprites ---------------\r
789\r
790.macro SpriteLoop hflip vflip\r
791.if \vflip\r
792 mov r1, r5, lsr #24 @ height\r
793 mov r0, #328*8\r
794 mla r11, r1, r0, r11 @ scrpos+=height*328*8;\r
795 add r12, r12, r1, lsl #3 @ sy+=height*8\r
796.endif\r
797 mov r0, #0xf\r
798.if \hflip\r
799 and r1, r5, #0xff\r
800 add r8, r8, r1, lsl #3 @ sx+=width*8\r
80158:\r
802 cmp r8, #336\r
803 blt 51f\r
804 add r9, r9, r5, lsr #16\r
805 sub r5, r5, #1 @ sub width\r
806 sub r8, r8, #8\r
807 b 58b\r
808.else\r
809 cmp r8, #0 @ skip tiles hidden on the left of screen\r
810 bgt 51f\r
81158:\r
812 add r9, r9, r5, lsr #16\r
813 sub r5, r5, #1\r
814 adds r8, r8, #8\r
815 ble 58b\r
816 b 51f\r
817.endif\r
818\r
81950: @ outer\r
820.if !\hflip\r
821 add r8, r8, #8 @ sx+=8\r
822.endif\r
823 bic r5, r5, #0xff000000 @ fix height\r
824 orr r5, r5, r5, lsl #16\r
825\r
82651: @ outer_enter\r
827 sub r5, r5, #1 @ width--\r
828 movs r1, r5, lsl #24\r
829 ldmmifd sp!, {r4-r11,pc} @ end of tile\r
830.if \hflip\r
831 subs r8, r8, #8 @ sx-=8\r
832 ldmlefd sp!, {r4-r11,pc} @ tile offscreen\r
833.else\r
834 cmp r8, #328\r
835 ldmgefd sp!, {r4-r11,pc} @ tile offscreen\r
836.endif\r
837 mov r6, r12 @ r6=sy\r
838 add r1, r11, r8 @ pdest=scrpos+sx\r
839 b 53f\r
840\r
84152: @ inner\r
842 add r9, r9, #1<<8 @ tile++\r
843.if !\vflip\r
844 add r6, r6, #8 @ sy+=8\r
845 add r1, r1, #328*8\r
846.endif\r
847\r
84853: @ inner_enter\r
849 @ end of sprite?\r
850 subs r5, r5, #0x01000000\r
851 bmi 50b @ ->outer\r
852.if \vflip\r
853 sub r6, r6, #8 @ sy-=8\r
854 sub r1, r1, #328*8\r
855.endif\r
856\r
857 @ offscreen?\r
858 cmp r6, #(START_ROW*8)\r
859 ble 52b\r
860\r
861 cmp r6, #(END_ROW*8+8)\r
862 bge 52b\r
863\r
864 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=Pico.vram) r2,r4,r7: scratch, r0=0xf\r
865 Tile \hflip, \vflip\r
866 b 52b\r
867.endm\r
868\r
869\r
870.global DrawSpriteFull @ unsigned int *sprite\r
871\r
872DrawSpriteFull:\r
873 stmfd sp!, {r4-r11,lr}\r
874\r
875 ldr r3, [r0] @ sprite[0]\r
876 mov r5, r3, lsl #4\r
877 mov r6, r5, lsr #30\r
878 add r6, r6, #1 @ r6=width\r
879 mov r5, r5, lsl #2\r
880 mov r5, r5, lsr #30\r
881 add r5, r5, #1 @ r5=height\r
882\r
883 mov r12, r3, lsl #23\r
884 mov r12, r12, lsr #23\r
cc68a136 885\r
886 ldr lr, [r0, #4] @ lr=code\r
ea8c405f 887 sub r12, r12, #0x78 @ r12=sy\r
cc68a136 888 mov r8, lr, lsl #7\r
889 mov r8, r8, lsr #23\r
890 sub r8, r8, #0x78 @ r8=sx\r
891\r
892 mov r9, lr, lsl #21\r
893 mov r9, r9, lsr #13 @ r9=tile<<8\r
894\r
895 and r3, lr, #0x6000\r
896 mov r3, r3, lsr #9 @ r3=pal=((code>>9)&0x30);\r
897\r
e5f426aa 898 ldr r11, =PicoDraw2FB @ r11=scrpos\r
ea8c405f 899 ldr r10, =(Pico+0x10000) @ r10=Pico.vram\r
cc68a136 900 ldr r11, [r11]\r
901 sub r1, r12, #(START_ROW*8)\r
902 mov r0, #328\r
903 mla r11, r1, r0, r11 @ scrpos+=(sy-START_ROW*8)*328;\r
904\r
905 orr r5, r5, r5, lsl #16 @\r
906 orr r5, r6, r5, lsl #8 @ r5=width|(height<<8)|(height<<24)\r
907\r
908 tst lr, #0x1000 @ vflip?\r
909 bne .dsf_vflip\r
910\r
911 tst lr, #0x0800 @ hflip?\r
912 bne .dsf_hflip\r
913\r
914 SpriteLoop 0, 0\r
915\r
916.dsf_hflip:\r
917 SpriteLoop 1, 0\r
918\r
919.dsf_vflip:\r
920 tst lr, #0x0800 @ hflip?\r
921 bne .dsf_vflip_hflip\r
922\r
923 SpriteLoop 0, 1\r
924\r
925.dsf_vflip_hflip:\r
926 SpriteLoop 1, 1\r
927\r
928.pool\r
929\r
cff531af 930@ vim:filetype=armasm\r