split memories away from Pico
[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
88fd63ad 356 ldr r11, [r12, #OFS_EST_Pico]\r
357 ldr r10, [r12, #OFS_EST_PicoMem_vram]\r
358 ldrb r5, [r11, #OFS_Pico_video_reg+13] @ pvid->reg[13]\r
359 ldrb r7, [r11, #OFS_Pico_video_reg+11]\r
ea8c405f 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
88fd63ad 369 ldrb r7, [r11, #OFS_Pico_video_reg+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
88fd63ad 400 ldreqb r4, [r11, #OFS_Pico_video_reg+2]\r
cc68a136 401 moveq r4, r4, lsr #3\r
88fd63ad 402 ldrneb r4, [r11, #OFS_Pico_video_reg+4]\r
cc68a136 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
88fd63ad 408 ldr r11, [r11, #OFS_EST_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
88fd63ad 585 ldr r4, [r1, #OFS_EST_Draw2FB]\r
98a27142 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
88fd63ad 591 ldr r10, [r1, #OFS_EST_PicoMem_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
88fd63ad 677 ldr r11, [r3, #OFS_EST_Pico]\r
678 ldrb r12, [r11, #OFS_Pico_video_reg+3] @ pvid->reg[3]\r
cc68a136 679 mov r12, r12, lsl #10\r
680\r
88fd63ad 681 ldr r4, [r11, #OFS_Pico_video_reg+12]\r
cc68a136 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
88fd63ad 692 ldr r10, [r3, #OFS_EST_PicoMem_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
88fd63ad 710 ldr r11, [r3, #OFS_EST_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
88fd63ad 763 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)\r
764 @ r2,r4,r7: scratch, r0=0xf\r
cc68a136 765 Tile 0, 0\r
766 b .dwfloop\r
767\r
768.dwf_hflip:\r
769 Tile 1, 0\r
770 b .dwfloop\r
771\r
772.dwf_vflip:\r
773 tst r9, #0x080000 @ hflip?\r
774 bne .dwf_vflip_hflip\r
775\r
776 Tile 0, 1\r
777 b .dwfloop\r
778\r
779.dwf_vflip_hflip:\r
780 Tile 1, 1\r
781 b .dwfloop\r
782\r
783.dwf_singlecolor:\r
784 TileSinglecol 1\r
785 b .dwfloop\r
786\r
787.dwfloop_exit:\r
788 bic r8, r8, #0xff000000 @ fix r8\r
789 subs r8, r8, #0x010000\r
790 ldmmifd sp!, {r4-r11,pc}\r
791 add r11, r11, #328*8\r
792 add r12, r12, r5 @ nametab+=nametab_step\r
793 b .dwfloop_outer\r
794\r
795.pool\r
796\r
797\r
798@ ---------------- sprites ---------------\r
799\r
800.macro SpriteLoop hflip vflip\r
801.if \vflip\r
802 mov r1, r5, lsr #24 @ height\r
803 mov r0, #328*8\r
804 mla r11, r1, r0, r11 @ scrpos+=height*328*8;\r
805 add r12, r12, r1, lsl #3 @ sy+=height*8\r
806.endif\r
807 mov r0, #0xf\r
808.if \hflip\r
809 and r1, r5, #0xff\r
810 add r8, r8, r1, lsl #3 @ sx+=width*8\r
81158:\r
812 cmp r8, #336\r
813 blt 51f\r
814 add r9, r9, r5, lsr #16\r
815 sub r5, r5, #1 @ sub width\r
816 sub r8, r8, #8\r
817 b 58b\r
818.else\r
819 cmp r8, #0 @ skip tiles hidden on the left of screen\r
820 bgt 51f\r
82158:\r
822 add r9, r9, r5, lsr #16\r
823 sub r5, r5, #1\r
824 adds r8, r8, #8\r
825 ble 58b\r
826 b 51f\r
827.endif\r
828\r
82950: @ outer\r
830.if !\hflip\r
831 add r8, r8, #8 @ sx+=8\r
832.endif\r
833 bic r5, r5, #0xff000000 @ fix height\r
834 orr r5, r5, r5, lsl #16\r
835\r
83651: @ outer_enter\r
837 sub r5, r5, #1 @ width--\r
838 movs r1, r5, lsl #24\r
839 ldmmifd sp!, {r4-r11,pc} @ end of tile\r
840.if \hflip\r
841 subs r8, r8, #8 @ sx-=8\r
842 ldmlefd sp!, {r4-r11,pc} @ tile offscreen\r
843.else\r
844 cmp r8, #328\r
845 ldmgefd sp!, {r4-r11,pc} @ tile offscreen\r
846.endif\r
847 mov r6, r12 @ r6=sy\r
848 add r1, r11, r8 @ pdest=scrpos+sx\r
849 b 53f\r
850\r
85152: @ inner\r
852 add r9, r9, #1<<8 @ tile++\r
853.if !\vflip\r
854 add r6, r6, #8 @ sy+=8\r
855 add r1, r1, #328*8\r
856.endif\r
857\r
85853: @ inner_enter\r
859 @ end of sprite?\r
860 subs r5, r5, #0x01000000\r
861 bmi 50b @ ->outer\r
862.if \vflip\r
863 sub r6, r6, #8 @ sy-=8\r
864 sub r1, r1, #328*8\r
865.endif\r
866\r
867 @ offscreen?\r
868 cmp r6, #(START_ROW*8)\r
869 ble 52b\r
870\r
871 cmp r6, #(END_ROW*8+8)\r
872 bge 52b\r
873\r
88fd63ad 874 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)\r
875 @ r2,r4,r7: scratch, r0=0xf\r
cc68a136 876 Tile \hflip, \vflip\r
877 b 52b\r
878.endm\r
879\r
98a27142 880@ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)\r
cc68a136 881\r
98a27142 882.global DrawSpriteFull\r
cc68a136 883\r
884DrawSpriteFull:\r
885 stmfd sp!, {r4-r11,lr}\r
886\r
887 ldr r3, [r0] @ sprite[0]\r
888 mov r5, r3, lsl #4\r
889 mov r6, r5, lsr #30\r
890 add r6, r6, #1 @ r6=width\r
891 mov r5, r5, lsl #2\r
892 mov r5, r5, lsr #30\r
893 add r5, r5, #1 @ r5=height\r
894\r
895 mov r12, r3, lsl #23\r
896 mov r12, r12, lsr #23\r
cc68a136 897\r
898 ldr lr, [r0, #4] @ lr=code\r
ea8c405f 899 sub r12, r12, #0x78 @ r12=sy\r
cc68a136 900 mov r8, lr, lsl #7\r
901 mov r8, r8, lsr #23\r
902 sub r8, r8, #0x78 @ r8=sx\r
903\r
904 mov r9, lr, lsl #21\r
905 mov r9, r9, lsr #13 @ r9=tile<<8\r
906\r
907 and r3, lr, #0x6000\r
908 mov r3, r3, lsr #9 @ r3=pal=((code>>9)&0x30);\r
909\r
88fd63ad 910 ldr r11, [r1, #OFS_EST_Draw2FB]\r
911 ldr r10, [r1, #OFS_EST_PicoMem_vram]\r
cc68a136 912 sub r1, r12, #(START_ROW*8)\r
913 mov r0, #328\r
914 mla r11, r1, r0, r11 @ scrpos+=(sy-START_ROW*8)*328;\r
915\r
916 orr r5, r5, r5, lsl #16 @\r
917 orr r5, r6, r5, lsl #8 @ r5=width|(height<<8)|(height<<24)\r
918\r
919 tst lr, #0x1000 @ vflip?\r
920 bne .dsf_vflip\r
921\r
922 tst lr, #0x0800 @ hflip?\r
923 bne .dsf_hflip\r
924\r
925 SpriteLoop 0, 0\r
926\r
927.dsf_hflip:\r
928 SpriteLoop 1, 0\r
929\r
930.dsf_vflip:\r
931 tst lr, #0x0800 @ hflip?\r
932 bne .dsf_vflip_hflip\r
933\r
934 SpriteLoop 0, 1\r
935\r
936.dsf_vflip_hflip:\r
937 SpriteLoop 1, 1\r
938\r
939.pool\r
940\r
cff531af 941@ vim:filetype=armasm\r