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);
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
if ((a&0xe700e0)==0xc00000) // VDP
d=PicoVideoRead(a);
else d=OtherRead16(a&~1, 8);
if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
d=OtherRead16(a&~1, 8);
if ((a&1)==0) d>>=8;
end:

View file

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

View file

@ -469,7 +469,9 @@ m_read8_vdp:
andi $t1, $a0, 0xe0
or $t0, $t1
bnez $t0, m_read_null # invalid address
m_read8_call16 PicoVideoRead
nop
j PicoVideoRead8
nop
m_read8_ram:
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.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?
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
else {
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;
if ((a&0xfffff0)==0xc00000) { // VDP
d=PicoVideoRead(a);
if ((a&1)==0) d>>=8;
d=PicoVideoRead8(a);
goto end;
}

View file

@ -35,10 +35,10 @@
static int PicoFrameHints(void)
{
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
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
// draw a frame just after vblank in alternative render mode
@ -53,7 +53,7 @@ static int PicoFrameHints(void)
if (Pico.m.pal) {
line_sample = 68;
if(pv->reg[1]&8) lines_vis = 240;
if (pv->reg[1]&8) lines_vis = 240;
} else {
line_sample = 93;
}
@ -75,7 +75,12 @@ static int PicoFrameHints(void)
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
pv->lwrite_cnt -= 12;
@ -138,6 +143,11 @@ static int PicoFrameHints(void)
#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 (DrawScanline < y)
@ -147,9 +157,6 @@ static int PicoFrameHints(void)
#endif
}
// V-int line (224 or 240)
Pico.m.scanline = y;
// VDP FIFO
pv->lwrite_cnt=0;
Pico.video.status|=0x200;
@ -168,7 +175,6 @@ static int PicoFrameHints(void)
if (pv->reg[0]&0x10) SekInterrupt(4);
}
// V-Interrupt:
pv->status|=0x08; // go into vblank
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.
lines = Pico.m.pal ? 312 : 262;
vcnt_wrap = Pico.m.pal ? 0x103 : 0xEB; // based on Gens
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
#ifdef PICO_CD

View file

@ -237,7 +237,8 @@ struct PicoVideo
int status; // Status bits
unsigned char pending_ints; // pending interrupts: ??VH????
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
@ -504,6 +505,7 @@ void ym2612_unpack_state(void);
// VideoPort.c
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 PicoVideoRead8(unsigned int a);
extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);
// Misc.c

View file

@ -449,24 +449,19 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
{
a&=0x1c;
if (a==0x00) // data port
{
return VideoRead();
}
if (a==0x04) // control port
{
struct PicoVideo *pv=&Pico.video;
unsigned int d;
d=pv->status;
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 (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
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
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);
return d;
@ -489,32 +484,60 @@ 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
if ((a&0x1c)==0x08)
{
unsigned int hc, d;
unsigned int d;
int lineCycles;
lineCycles = (488-SekCyclesLeft)&0x1ff;
d = Pico.m.scanline; // V-Counter
if (Pico.video.reg[12]&1)
hc=hcounts_40[lineCycles];
else hc=hcounts_32[lineCycles];
d = hcounts_40[lineCycles];
else d = hcounts_32[lineCycles];
if (Pico.m.pal) {
if (d >= 0x103) d-=56; // based on Gens
} else {
if (d >= 0xEB) d-=6;
}
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc);
return d | (Pico.video.v_counter << 8);
}
if ((Pico.video.reg[12]&6) == 6) {
// interlace mode 2 (Combat Cars (UE) [!])
d <<= 1;
if (d&0xf00) d|= 1;
}
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc);
d&=0xff; d<<=8;
d|=hc;
return d;
if (a==0x00) // data port
{
return VideoRead();
}
return 0;
}
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 0;

View file

@ -501,10 +501,8 @@ u32 PicoReadM68k8(u32 a)
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
// VDP
if ((a&0xe700e0)==0xc00000) {
d=PicoVideoRead(a);
if ((a&1)==0) d>>=8;
}
if ((a&0xe700e0)==0xc00000)
d=PicoVideoRead8(a);
break;
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>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 OtherRead16
.extern PicoVideoRead
.extern PicoVideoRead8
.extern Read_CDC_Host
.extern m68k_reg_write8
.extern OtherWrite16
@ -611,13 +612,7 @@ m_m68k_read8_vdp:
tst r0, #0x70000
tsteq r0, #0x000e0
bxne lr @ invalid read
stmfd sp!,{r0,lr}
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
b PicoVideoRead8
m_m68k_read8_ram: