PicoVideoRead optimization

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@511 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-07-01 16:12:04 +00:00
parent 2aa27095f2
commit 9761a7d0d4
10 changed files with 90 additions and 64 deletions

View file

@ -344,9 +344,9 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
log_io(a, 8, 0); log_io(a, 8, 0);
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
if ((a&0xe700e0)==0xc00000) // VDP if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
d=PicoVideoRead(a);
else d=OtherRead16(a&~1, 8); d=OtherRead16(a&~1, 8);
if ((a&1)==0) d>>=8; if ((a&1)==0) d>>=8;
end: end:

View file

@ -415,13 +415,7 @@ m_read8_vdp:
tst r0, #0x70000 tst r0, #0x70000
tsteq r0, #0x000e0 tsteq r0, #0x000e0
bxne lr @ invalid read bxne lr @ invalid read
stmfd sp!,{r0,lr} b PicoVideoRead8
bic r0, r0, #1
bl PicoVideoRead
ldmfd sp!,{r1,lr}
tst r1, #1
moveq r0, r0, lsr #8
bx lr
m_read8_ram: m_read8_ram:
ldr r1, =Pico ldr r1, =Pico

View file

@ -469,7 +469,9 @@ m_read8_vdp:
andi $t1, $a0, 0xe0 andi $t1, $a0, 0xe0
or $t0, $t1 or $t0, $t1
bnez $t0, m_read_null # invalid address bnez $t0, m_read_null # invalid address
m_read8_call16 PicoVideoRead nop
j PicoVideoRead8
nop
m_read8_ram: m_read8_ram:
lui $t0, %hi(Pico) lui $t0, %hi(Pico)

View file

@ -218,7 +218,8 @@ PICO_INTERNAL int CheckDMA(void)
if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode? if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode?
if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display? if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?
xfers_can = dma_timings[dma_op]; xfers_can = dma_timings[dma_op];
if(xfers <= xfers_can) { if(xfers <= xfers_can)
{
if(dma_op&2) Pico.video.status&=~2; // dma no longer busy if(dma_op&2) Pico.video.status&=~2; // dma no longer busy
else { else {
burn = xfers * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division.. burn = xfers * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..

View file

@ -22,8 +22,7 @@ static u32 PicoReadPico8(u32 a)
a&=0xffffff; a&=0xffffff;
if ((a&0xfffff0)==0xc00000) { // VDP if ((a&0xfffff0)==0xc00000) { // VDP
d=PicoVideoRead(a); d=PicoVideoRead8(a);
if ((a&1)==0) d>>=8;
goto end; goto end;
} }

View file

@ -35,10 +35,10 @@
static int PicoFrameHints(void) static int PicoFrameHints(void)
{ {
struct PicoVideo *pv=&Pico.video; struct PicoVideo *pv=&Pico.video;
int lines, y, lines_vis = 224, line_sample, skip; int lines, y, lines_vis = 224, line_sample, skip, vcnt_wrap;
int hint; // Hint counter int hint; // Hint counter
Pico.m.scanline = 0; pv->v_counter = Pico.m.scanline = 0;
if ((PicoOpt&POPT_ALT_RENDERER) && !PicoSkipFrame && (pv->reg[1]&0x40)) { // fast rend., display enabled if ((PicoOpt&POPT_ALT_RENDERER) && !PicoSkipFrame && (pv->reg[1]&0x40)) { // fast rend., display enabled
// draw a frame just after vblank in alternative render mode // draw a frame just after vblank in alternative render mode
@ -53,7 +53,7 @@ static int PicoFrameHints(void)
if (Pico.m.pal) { if (Pico.m.pal) {
line_sample = 68; line_sample = 68;
if(pv->reg[1]&8) lines_vis = 240; if (pv->reg[1]&8) lines_vis = 240;
} else { } else {
line_sample = 93; line_sample = 93;
} }
@ -75,7 +75,12 @@ static int PicoFrameHints(void)
for (y = 0; y < lines_vis; y++) for (y = 0; y < lines_vis; y++)
{ {
Pico.m.scanline = y; pv->v_counter = Pico.m.scanline = y;
if ((pv->reg[12]&6) == 6) { // interlace mode 2
pv->v_counter <<= 1;
pv->v_counter |= pv->v_counter >> 8;
pv->v_counter &= 0xff;
}
// VDP FIFO // VDP FIFO
pv->lwrite_cnt -= 12; pv->lwrite_cnt -= 12;
@ -138,6 +143,11 @@ static int PicoFrameHints(void)
#endif #endif
} }
// V-int line (224 or 240)
Pico.m.scanline = y;
pv->v_counter = 0xe0; // bad for 240 mode
if ((pv->reg[12]&6) == 6) pv->v_counter = 0xc1;
if (!skip) if (!skip)
{ {
if (DrawScanline < y) if (DrawScanline < y)
@ -147,9 +157,6 @@ static int PicoFrameHints(void)
#endif #endif
} }
// V-int line (224 or 240)
Pico.m.scanline = y;
// VDP FIFO // VDP FIFO
pv->lwrite_cnt=0; pv->lwrite_cnt=0;
Pico.video.status|=0x200; Pico.video.status|=0x200;
@ -168,7 +175,6 @@ static int PicoFrameHints(void)
if (pv->reg[0]&0x10) SekInterrupt(4); if (pv->reg[0]&0x10) SekInterrupt(4);
} }
// V-Interrupt:
pv->status|=0x08; // go into vblank pv->status|=0x08; // go into vblank
pv->pending_ints|=0x20; pv->pending_ints|=0x20;
@ -212,10 +218,16 @@ static int PicoFrameHints(void)
// PAL line count might actually be 313 according to Steve Snake, but that would complicate things. // PAL line count might actually be 313 according to Steve Snake, but that would complicate things.
lines = Pico.m.pal ? 312 : 262; lines = Pico.m.pal ? 312 : 262;
vcnt_wrap = Pico.m.pal ? 0x103 : 0xEB; // based on Gens
for (y++; y < lines; y++) for (y++; y < lines; y++)
{ {
Pico.m.scanline = y; pv->v_counter = Pico.m.scanline = y;
if (y >= vcnt_wrap)
pv->v_counter -= Pico.m.pal ? 56 : 6;
if ((pv->reg[12]&6) == 6)
pv->v_counter = (pv->v_counter << 1) | 1;
pv->v_counter &= 0xff;
PAD_DELAY PAD_DELAY
#ifdef PICO_CD #ifdef PICO_CD

View file

@ -237,7 +237,8 @@ struct PicoVideo
int status; // Status bits int status; // Status bits
unsigned char pending_ints; // pending interrupts: ??VH???? unsigned char pending_ints; // pending interrupts: ??VH????
signed char lwrite_cnt; // VDP write count during active display line signed char lwrite_cnt; // VDP write count during active display line
unsigned char pad[0x12]; unsigned short v_counter; // V-counter
unsigned char pad[0x10];
}; };
struct PicoMisc struct PicoMisc
@ -504,6 +505,7 @@ void ym2612_unpack_state(void);
// VideoPort.c // VideoPort.c
PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d); PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d);
PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a); PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a);
PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a);
extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp); extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);
// Misc.c // Misc.c

View file

@ -449,24 +449,19 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
{ {
a&=0x1c; a&=0x1c;
if (a==0x00) // data port
{
return VideoRead();
}
if (a==0x04) // control port if (a==0x04) // control port
{ {
struct PicoVideo *pv=&Pico.video; struct PicoVideo *pv=&Pico.video;
unsigned int d; unsigned int d;
d=pv->status; d=pv->status;
if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast) //if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
if (!(pv->reg[1]&0x40)) d|=0x0008; // set V-Blank if display is disabled
if (SekCyclesLeft < 84+4) d|=0x0004; // H-Blank (Sonic3 vs) if (SekCyclesLeft < 84+4) d|=0x0004; // H-Blank (Sonic3 vs)
d|=(pv->pending_ints&0x20)<<2; // V-int pending? d |= ((pv->reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled
d |= (pv->pending_ints&0x20)<<2; // V-int pending?
if (d&0x100) pv->status&=~0x100; // FIFO no longer full if (d&0x100) pv->status&=~0x100; // FIFO no longer full
pv->pending=0; // ctrl port reads clear write-pending flag (Charles MacDonald) pv->pending = 0; // ctrl port reads clear write-pending flag (Charles MacDonald)
elprintf(EL_SR, "SR read: %04x @ %06x", d, SekPc); elprintf(EL_SR, "SR read: %04x @ %06x", d, SekPc);
return d; return d;
@ -489,31 +484,59 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
// check: Sonic 3D Blast bonus, Cannon Fodder, Chase HQ II, 3 Ninjas kick back, Road Rash 3, Skitchin', Wheel of Fortune // check: Sonic 3D Blast bonus, Cannon Fodder, Chase HQ II, 3 Ninjas kick back, Road Rash 3, Skitchin', Wheel of Fortune
if ((a&0x1c)==0x08) if ((a&0x1c)==0x08)
{ {
unsigned int hc, d; unsigned int d;
int lineCycles; int lineCycles;
lineCycles = (488-SekCyclesLeft)&0x1ff; lineCycles = (488-SekCyclesLeft)&0x1ff;
d = Pico.m.scanline; // V-Counter
if (Pico.video.reg[12]&1) if (Pico.video.reg[12]&1)
hc=hcounts_40[lineCycles]; d = hcounts_40[lineCycles];
else hc=hcounts_32[lineCycles]; else d = hcounts_32[lineCycles];
if (Pico.m.pal) { elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc);
if (d >= 0x103) d-=56; // based on Gens return d | (Pico.video.v_counter << 8);
} else {
if (d >= 0xEB) d-=6;
} }
if ((Pico.video.reg[12]&6) == 6) { if (a==0x00) // data port
// interlace mode 2 (Combat Cars (UE) [!]) {
d <<= 1; return VideoRead();
if (d&0xf00) d|= 1;
} }
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc); return 0;
d&=0xff; d<<=8; }
d|=hc;
unsigned int PicoVideoRead8(unsigned int a)
{
unsigned int d;
a&=0x1d;
switch (a)
{
case 0: return VideoRead() >> 8;
case 1: return VideoRead() & 0xff;
case 4: // control port/status reg
d = Pico.video.status >> 8;
if (d&1) Pico.video.status&=~0x100; // FIFO no longer full
Pico.video.pending = 0;
elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc);
return d;
case 5:
d = Pico.video.status & 0xff;
//if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
d |= ((Pico.video.reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled
d |= (Pico.video.pending_ints&0x20)<<2; // V-int pending?
if (SekCyclesLeft < 84+4) d |= 4; // H-Blank
Pico.video.pending = 0;
elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc);
return d;
case 8: // hv counter
elprintf(EL_HVCNT, "vcounter: %02x (%i) @ %06x", Pico.video.v_counter, SekCyclesDone(), SekPc);
return Pico.video.v_counter;
case 9:
d = (488-SekCyclesLeft)&0x1ff;
if (Pico.video.reg[12]&1)
d = hcounts_40[d];
else d = hcounts_32[d];
elprintf(EL_HVCNT, "hcounter: %02x (%i) @ %06x", d, SekCyclesDone(), SekPc);
return d; return d;
} }

View file

@ -501,10 +501,8 @@ u32 PicoReadM68k8(u32 a)
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1: case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1: case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
// VDP // VDP
if ((a&0xe700e0)==0xc00000) { if ((a&0xe700e0)==0xc00000)
d=PicoVideoRead(a); d=PicoVideoRead8(a);
if ((a&1)==0) d>>=8;
}
break; break;
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1: case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:
case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1: case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:

View file

@ -126,6 +126,7 @@ m_s68k_decode_write_table:
.extern z80Read8 .extern z80Read8
.extern OtherRead16 .extern OtherRead16
.extern PicoVideoRead .extern PicoVideoRead
.extern PicoVideoRead8
.extern Read_CDC_Host .extern Read_CDC_Host
.extern m68k_reg_write8 .extern m68k_reg_write8
.extern OtherWrite16 .extern OtherWrite16
@ -611,13 +612,7 @@ m_m68k_read8_vdp:
tst r0, #0x70000 tst r0, #0x70000
tsteq r0, #0x000e0 tsteq r0, #0x000e0
bxne lr @ invalid read bxne lr @ invalid read
stmfd sp!,{r0,lr} b PicoVideoRead8
bic r0, r0, #1
bl PicoVideoRead @ TODO: implement it in asm
ldmfd sp!,{r1,lr}
tst r1, #1
moveq r0, r0, lsr #8
bx lr
m_m68k_read8_ram: m_m68k_read8_ram: