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