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