From 6d7acf9eff33cdde5e3eac44a193448ac0cbf541 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 21 Aug 2007 16:53:54 +0000 Subject: [PATCH] asm for DrawStripVSRam git-svn-id: file:///home/notaz/opt/svn/PicoDrive@223 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Draw.c | 17 +++--- Pico/Draw.s | 168 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 154 insertions(+), 31 deletions(-) diff --git a/Pico/Draw.c b/Pico/Draw.c index 2eed289f..582c8cbf 100644 --- a/Pico/Draw.c +++ b/Pico/Draw.c @@ -34,7 +34,7 @@ static int SpriteBlocks; struct TileStrip { int nametab; // Position in VRAM of name table (for this tile line) - int line; // Line number in pixels 0x000-0x3ff within the virtual tilemap + int line; // Line number in pixels 0x000-0x3ff within the virtual tilemap int hscroll; // Horizontal scroll value in pixels for the line int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap int *hc; // cache for high tile codes and their positions @@ -317,12 +317,8 @@ static void DrawStrip(struct TileStrip *ts, int sh) // terminate the cache list *ts->hc = 0; } -#endif // this is messy -#ifndef _ASM_DRAW_C -static -#endif void DrawStripVSRam(struct TileStrip *ts, int plane) { int tilex=0,dx=0,ty=0,code=0,addr=0,cell=0,nametabadd=0; @@ -386,6 +382,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane) // terminate the cache list *ts->hc = 0; } +#endif #ifndef _ASM_DRAW_C static @@ -921,13 +918,13 @@ static void PrepareSprites(int full) height = (hv&3)+1; if(sy > 240 || sy + (height<<3) <= 0) skip|=1<<22; - + width = (hv>>2)+1; code2 = sprite[1]; sx = (code2>>16)&0x1ff; sx -= 0x78; // Get X coordinate + 8 sx_min = 8-(width<<3); - + if((sx <= sx_min && sx >= -0x76) || sx >= 328) skip|=1<<23; else if (sx > sx_min && !skip) { int sbl = (2<>16)&0x7f; if(!link) break; // End of sprites @@ -1205,7 +1202,7 @@ static int DrawDisplay(int sh) if (win&0x80) { if (Scanline>=edge) hvwind=1; } else { if (Scanline< edge) hvwind=1; } - if(!hvwind) { // we might have a vertical window here + if(!hvwind) { // we might have a vertical window here win=pvid->reg[0x11]; edge=win&0x1f; if(win&0x80) { diff --git a/Pico/Draw.s b/Pico/Draw.s index 7643c3db..cb1a6fa7 100644 --- a/Pico/Draw.s +++ b/Pico/Draw.s @@ -14,7 +14,6 @@ .extern HighSprZ .extern rendstatus .extern DrawLineDest -.extern DrawStripVSRam .extern DrawStripInterlace @@ -293,7 +292,6 @@ DrawLayer: add r12, r12, r4, lsl r10 @ nametab+=(ts.line>>3)<hscroll, r5=ts->xmask, r6=ts->hc, r9=ts->cells -@ mov r12,r1, lsl #1 @ r12=(ts->nametab<<1) (halfword compliant) and r10,r2, #7 mov r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1; @@ -422,31 +420,159 @@ DrawLayer: ldmfd sp!, {r4-r11,lr} bx lr +@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .DrawStrip_vsscroll: - @ shit, we have 2-cell column based vscroll - @ let the c code handle this (for now) + rsb r8, r3, #0 + mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3 + bic r8, r8, #0xff000000 + orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|tilex[15:0]) - @ int nametab; // 0x00 - @ int line; // 0x04 - @ int hscroll; // 0x08 - @ int xmask; // 0x0C - @ int *hc; // 0x10 (pointer to cache buffer) - @ int cells; // 0x14 + ldr r4, =Scanline + orr r5, r1, r10, lsl #24 + ldr r4, [r4] + sub r1, r3, #1 + orr r5, r5, r4, lsl #16 @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0]) + and r1, r1, #7 + add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1 - sub sp, sp, #6*4 - orr r2, r1, r10, lsl #24 @ ts.line=ymask|(shift[width]<<24); // save some stuff instead of line - mov r1, r0 @ plane - mov r0, r12, lsr #1 @ halfwords - and r9, r9, #0xff - stmia sp, {r0,r2,r3,r5,r6,r9} + mov r10,r9, lsl #16 + tst r0, r0 + orrne r10,r10, #0x8000 + tst r9, #1<<31 + mov r3, #0 + orr r10,r10, #0xff000000 @ will be adjusted on entering loop + orrne r10,r10, #1<<23 @ r10=(cells[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0]) + movne r3, #0x40 @ default to shadowed pal on sh mode - mov r0, sp - bl DrawStripVSRam @ struct TileStrip *ts, int plane + mvn r9, #0 @ r9=prevcode=-1 - add sp, sp, #6*4 - ldmfd sp!, {r4-r11,lr} - bx lr + @ cache some stuff to avoid mem access + ldr r11,=HighCol + mov r0, #0xf + add r1, r11, r7 @ r1=pdest + + cmp r7, #8 + subne r10,r10, #0x01000000 @ have hscroll, start with negative cell + + + @ r4 & r7 are scratch in this loop +.dsloop_vs_subr1: + sub r1, r1, #8 +.dsloop_vs: @ 40-41 times + add r10,r10, #0x01000000 + and r4, r10, #0x003f0000 + cmp r4, r10, asr #8 + ble .dsloop_exit + + @ calc offset and read tileline code to r7, also calc ty + add r7, lr, #0x012000 + add r7, r7, #0x000180 @ r7=Pico.vsram (Pico+0x22180) + add r7, r7, r10,asr #23 @ vsram + ((cell&~1)<<1) + bic r7, r7, #3 + tst r10,#0x8000 @ plane1? + addne r7, r7, #2 + ldrh r7, [r7] @ r7=vscroll + + bic r10,r10,#0xff @ clear old ty + and r4, r5, #0xff0000 + add r4, r4, r7, lsl #16 + and r4, r4, r5, lsl #16 @ r4=line<<16 + and r7, r4, #0x70000 + orr r10,r10,r7, lsr #15 @ new ty + + mov r4, r4, lsr #19 + mov r7, r5, lsr #24 + mov r4, r4, lsl r7 @ nametabadd + + and r7, r8, r8, lsr #25 + add r7, lr, r7, lsl #1 @ Pico.vram+((tilex&ts->xmask) as halfwords) + add r7, r7, r4, lsl #1 + ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend) + + add r1, r1, #8 + add r8, r8, #1 + + tst r7, #0x8000 + bne .DrawStrip_vs_hiprio + + cmp r7, r9 + beq .DrawStrip_vs_samecode @ we know stuff about this tile already + + mov r9, r7 @ remember code + + movs r2, r9, lsl #20 @ if (code&0x1000) + mov r2, r2, lsl #1 + add r2, r2, r10, lsl #17 + mov r2, r2, lsr #17 + eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe; + + ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels + + bic r7, r3, #0x3f + and r3, r9, #0x6000 + add r3, r7, r3, lsr #9 @ r3=pal=((code&0x6000)>>9); + +.DrawStrip_vs_samecode: + tst r2, r2 + beq .dsloop_vs @ tileline blank + + cmp r2, r2, ror #4 + beq .DrawStrip_vs_SingleColor @ tileline singlecolor + + tst r9, #0x0800 + beq .DrawStrip_vs_TileNorm + + @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r0: helper pattern + TileFlip r0 + b .dsloop_vs + +.DrawStrip_vs_TileNorm: + TileNorm r0 + b .dsloop_vs + +.DrawStrip_vs_SingleColor: + and r4, r2, #0xf + orr r4, r3, r4 + orr r4, r4, r4, lsl #8 + tst r1, #1 @ not aligned? + strneb r4, [r1], #1 + streqh r4, [r1], #2 + strh r4, [r1], #2 + strh r4, [r1], #2 + strh r4, [r1], #2 + strneb r4, [r1], #1 @ have a remaining unaligned pixel? + b .dsloop_vs_subr1 + +.DrawStrip_vs_hiprio: + tst r10, #0x00c00000 + beq .DrawStrip_vs_hiprio_maybempt + sub r0, r1, r11 + orr r7, r7, r0, lsl #16 + orr r7, r7, r10, lsl #25 @ (ty<<25) + tst r7, #0x1000 + eorne r7, r7, #7<<26 @ if(code&0x1000) cval^=7<<26; + str r7, [r6], #4 @ cache hi priority tile + mov r0, #0xf + b .dsloop_vs + +.DrawStrip_vs_hiprio_maybempt: + cmp r7, r9 + beq .dsloop_vs @ must've been empty, otherwise we wouldn't get here + movs r2, r7, lsl #20 @ if (code&0x1000) + mov r2, r2, lsl #1 + add r2, r2, r10, lsl #17 + mov r2, r2, lsr #17 + eorcs r2, r2, #0x0e @ if (code&0x1000) addr^=0xe; + ldr r2, [lr, r2, lsl #1] @ pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels + mov r9, r7 @ remember code + tst r2, r2 + orrne r10, r10, #1<<22 + bne .DrawStrip_vs_hiprio + b .dsloop_vs + + +@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ interlace mode 2? Sonic 2? .DrawStrip_interlace: -- 2.39.5