drc: support ms ABI
[picodrive.git] / pico / draw2_arm.S
... / ...
CommitLineData
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
10\r
11#include "pico_int_o32.h"\r
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
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
26\r
27@ void BackFillFull(void *dst, int reg7)\r
28\r
29.global BackFillFull\r
30\r
31BackFillFull:\r
32 stmfd sp!, {r4-r9,lr}\r
33\r
34 add lr, r0, #328*8\r
35 mov r0, r1, lsl #26\r
36 mov r0, r0, lsr #26\r
37\r
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
69 ldmfd sp!, {r4-r9,lr}\r
70 bx lr\r
71\r
72.pool\r
73\r
74@ -------- some macros --------\r
75\r
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
86\r
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
354@ void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,\r
355@ struct PicoEState *est)\r
356\r
357.global DrawLayerFull\r
358\r
359DrawLayerFull:\r
360 ldr r12,[sp] @ est\r
361 stmfd sp!, {r4-r11,lr}\r
362\r
363 mov r6, r1 @ hcache\r
364\r
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
369\r
370 sub lr, r3, r2\r
371 and lr, lr, #0x00ff0000 @ lr=cells\r
372\r
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
377 tst r7, #3 @ full screen scroll? (if ==0)\r
378 ldrb r7, [r11, #OFS_Pico_video_reg+16] @ ??hh??ww\r
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
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
407 @ Find name table:\r
408 tst r0, r0\r
409 ldreqb r4, [r11, #OFS_Pico_video_reg+2]\r
410 moveq r4, r4, lsr #3\r
411 ldrneb r4, [r11, #OFS_Pico_video_reg+4]\r
412 and r4, r4, #7\r
413 orr lr, lr, r4, lsl #13 @ lr|=nametab_bits{3}<<13\r
414\r
415 ldr r11,[sp, #9*4] @ est\r
416 sub r4, r9, #(START_ROW<<24)\r
417 ldr r11, [r11, #OFS_EST_Draw2FB]\r
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
422 @ Get vertical scroll value:\r
423 add_c24 r7, r10, (OFS_PMEM_vsram-OFS_PMEM_vram)\r
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
474 and r8, r8, #0xff000000\r
475 rsb r4, r7, #0 @ r4=tilex=(-ts->hscroll)>>3\r
476 mov r4, r4, asr #3\r
477 and r4, r4, #0xff\r
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
583@ void DrawTilesFromCacheF(int *hc, struct PicoEState *est)\r
584\r
585.global DrawTilesFromCacheF\r
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
593 ldr r4, [r1, #OFS_EST_Draw2FB]\r
594 ldr r2, [r0], #4 @ read y offset\r
595 mov r7, #328\r
596 mla r2, r7, r2, r4\r
597 sub r12, r2, #(328*8*START_ROW) @ r12=scrpos\r
598\r
599 ldr r10, [r1, #OFS_EST_PicoMem_vram]\r
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
611 @ row changed?\r
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
678@ void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)\r
679\r
680.global DrawWindowFull\r
681\r
682DrawWindowFull:\r
683 stmfd sp!, {r4-r11,lr}\r
684\r
685 ldr r11, [r3, #OFS_EST_Pico]\r
686 ldrb r12, [r11, #OFS_Pico_video_reg+3] @ pvid->reg[3]\r
687 mov r12, r12, lsl #10\r
688\r
689 ldr r4, [r11, #OFS_Pico_video_reg+12]\r
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
700 ldr r10, [r3, #OFS_EST_PicoMem_vram]\r
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
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
718 ldr r11, [r3, #OFS_EST_Draw2FB]\r
719 and r4, r0, #0xff\r
720 add r11, r11, #328*8\r
721 sub r4, r4, #START_ROW\r
722 add r11, r11, #8\r
723\r
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
771 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)\r
772 @ r2,r4,r7: scratch, r0=0xf\r
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
882 @ Tile (r1=pdest, r3=pal, r9=prevcode, r10=PicoMem.vram)\r
883 @ r2,r4,r7: scratch, r0=0xf\r
884 Tile \hflip, \vflip\r
885 b 52b\r
886.endm\r
887\r
888@ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)\r
889\r
890.global DrawSpriteFull\r
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
905\r
906 ldr lr, [r0, #4] @ lr=code\r
907 sub r12, r12, #0x78 @ r12=sy\r
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
918 ldr r11, [r1, #OFS_EST_Draw2FB]\r
919 ldr r10, [r1, #OFS_EST_PicoMem_vram]\r
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
949@ vim:filetype=armasm\r