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