mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
asm for DrawStripVSRam
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@223 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
d524c827cd
commit
6d7acf9eff
2 changed files with 154 additions and 31 deletions
17
Pico/Draw.c
17
Pico/Draw.c
|
@ -34,7 +34,7 @@ static int SpriteBlocks;
|
||||||
struct TileStrip
|
struct TileStrip
|
||||||
{
|
{
|
||||||
int nametab; // Position in VRAM of name table (for this tile line)
|
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 hscroll; // Horizontal scroll value in pixels for the line
|
||||||
int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap
|
int xmask; // X-Mask (0x1f - 0x7f) for horizontal wraparound in the tilemap
|
||||||
int *hc; // cache for high tile codes and their positions
|
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
|
// terminate the cache list
|
||||||
*ts->hc = 0;
|
*ts->hc = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// this is messy
|
// this is messy
|
||||||
#ifndef _ASM_DRAW_C
|
|
||||||
static
|
|
||||||
#endif
|
|
||||||
void DrawStripVSRam(struct TileStrip *ts, int plane)
|
void DrawStripVSRam(struct TileStrip *ts, int plane)
|
||||||
{
|
{
|
||||||
int tilex=0,dx=0,ty=0,code=0,addr=0,cell=0,nametabadd=0;
|
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
|
// terminate the cache list
|
||||||
*ts->hc = 0;
|
*ts->hc = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _ASM_DRAW_C
|
#ifndef _ASM_DRAW_C
|
||||||
static
|
static
|
||||||
|
@ -921,13 +918,13 @@ static void PrepareSprites(int full)
|
||||||
height = (hv&3)+1;
|
height = (hv&3)+1;
|
||||||
|
|
||||||
if(sy > 240 || sy + (height<<3) <= 0) skip|=1<<22;
|
if(sy > 240 || sy + (height<<3) <= 0) skip|=1<<22;
|
||||||
|
|
||||||
width = (hv>>2)+1;
|
width = (hv>>2)+1;
|
||||||
code2 = sprite[1];
|
code2 = sprite[1];
|
||||||
sx = (code2>>16)&0x1ff;
|
sx = (code2>>16)&0x1ff;
|
||||||
sx -= 0x78; // Get X coordinate + 8
|
sx -= 0x78; // Get X coordinate + 8
|
||||||
sx_min = 8-(width<<3);
|
sx_min = 8-(width<<3);
|
||||||
|
|
||||||
if((sx <= sx_min && sx >= -0x76) || sx >= 328) skip|=1<<23;
|
if((sx <= sx_min && sx >= -0x76) || sx >= 328) skip|=1<<23;
|
||||||
else if (sx > sx_min && !skip) {
|
else if (sx > sx_min && !skip) {
|
||||||
int sbl = (2<<height)-1;
|
int sbl = (2<<height)-1;
|
||||||
|
@ -935,10 +932,10 @@ static void PrepareSprites(int full)
|
||||||
if(shi < 0) shi=0; // negative sy
|
if(shi < 0) shi=0; // negative sy
|
||||||
sblocks |= sbl<<shi;
|
sblocks |= sbl<<shi;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pd++ = (width<<28)|(height<<24)|skip|(hv<<16)|((unsigned short)sy);
|
*pd++ = (width<<28)|(height<<24)|skip|(hv<<16)|((unsigned short)sy);
|
||||||
*pd++ = (sx<<16)|((unsigned short)code2);
|
*pd++ = (sx<<16)|((unsigned short)code2);
|
||||||
|
|
||||||
// Find next sprite
|
// Find next sprite
|
||||||
link=(code>>16)&0x7f;
|
link=(code>>16)&0x7f;
|
||||||
if(!link) break; // End of sprites
|
if(!link) break; // End of sprites
|
||||||
|
@ -1205,7 +1202,7 @@ static int DrawDisplay(int sh)
|
||||||
if (win&0x80) { if (Scanline>=edge) hvwind=1; }
|
if (win&0x80) { if (Scanline>=edge) hvwind=1; }
|
||||||
else { 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];
|
win=pvid->reg[0x11];
|
||||||
edge=win&0x1f;
|
edge=win&0x1f;
|
||||||
if(win&0x80) {
|
if(win&0x80) {
|
||||||
|
|
168
Pico/Draw.s
168
Pico/Draw.s
|
@ -14,7 +14,6 @@
|
||||||
.extern HighSprZ
|
.extern HighSprZ
|
||||||
.extern rendstatus
|
.extern rendstatus
|
||||||
.extern DrawLineDest
|
.extern DrawLineDest
|
||||||
.extern DrawStripVSRam
|
|
||||||
.extern DrawStripInterlace
|
.extern DrawStripInterlace
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,7 +292,6 @@ DrawLayer:
|
||||||
add r12, r12, r4, lsl r10 @ nametab+=(ts.line>>3)<<shift[width];
|
add r12, r12, r4, lsl r10 @ nametab+=(ts.line>>3)<<shift[width];
|
||||||
|
|
||||||
@ ldmia r0, {r1,r2,r3,r5,r6,r9} @ r2=line, r3=ts->hscroll, r5=ts->xmask, r6=ts->hc, r9=ts->cells
|
@ ldmia r0, {r1,r2,r3,r5,r6,r9} @ r2=line, r3=ts->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
|
and r10,r2, #7
|
||||||
mov r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1;
|
mov r10,r10, lsl #1 @ r10=ty=(ts->line&7)<<1;
|
||||||
|
@ -422,31 +420,159 @@ DrawLayer:
|
||||||
ldmfd sp!, {r4-r11,lr}
|
ldmfd sp!, {r4-r11,lr}
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
|
||||||
.DrawStrip_vsscroll:
|
.DrawStrip_vsscroll:
|
||||||
@ shit, we have 2-cell column based vscroll
|
rsb r8, r3, #0
|
||||||
@ let the c code handle this (for now)
|
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
|
ldr r4, =Scanline
|
||||||
@ int line; // 0x04
|
orr r5, r1, r10, lsl #24
|
||||||
@ int hscroll; // 0x08
|
ldr r4, [r4]
|
||||||
@ int xmask; // 0x0C
|
sub r1, r3, #1
|
||||||
@ int *hc; // 0x10 (pointer to cache buffer)
|
orr r5, r5, r4, lsl #16 @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0])
|
||||||
@ int cells; // 0x14
|
and r1, r1, #7
|
||||||
|
add r7, r1, #1 @ r7=dx=((ts->hscroll-1)&7)+1
|
||||||
|
|
||||||
sub sp, sp, #6*4
|
mov r10,r9, lsl #16
|
||||||
orr r2, r1, r10, lsl #24 @ ts.line=ymask|(shift[width]<<24); // save some stuff instead of line
|
tst r0, r0
|
||||||
mov r1, r0 @ plane
|
orrne r10,r10, #0x8000
|
||||||
mov r0, r12, lsr #1 @ halfwords
|
tst r9, #1<<31
|
||||||
and r9, r9, #0xff
|
mov r3, #0
|
||||||
stmia sp, {r0,r2,r3,r5,r6,r9}
|
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
|
mvn r9, #0 @ r9=prevcode=-1
|
||||||
bl DrawStripVSRam @ struct TileStrip *ts, int plane
|
|
||||||
|
|
||||||
add sp, sp, #6*4
|
@ cache some stuff to avoid mem access
|
||||||
ldmfd sp!, {r4-r11,lr}
|
ldr r11,=HighCol
|
||||||
bx lr
|
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?
|
@ interlace mode 2? Sonic 2?
|
||||||
.DrawStrip_interlace:
|
.DrawStrip_interlace:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue