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