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