revised VDP fifo implementation

This commit is contained in:
kub 2020-02-07 22:10:18 +01:00
parent 0f3703fd98
commit 17bd69adc6
5 changed files with 430 additions and 138 deletions

View file

@ -67,6 +67,7 @@ void PicoPower(void)
memset(&Pico.video,0,sizeof(Pico.video));
memset(&Pico.m,0,sizeof(Pico.m));
memset(&Pico.t,0,sizeof(Pico.t));
Pico.video.pending_ints=0;
z80_reset();
@ -182,8 +183,7 @@ int PicoReset(void)
PsndReset(); // pal must be known here
// create an empty "dma" to cause 68k exec start at random frame location
if (Pico.m.dma_xfers == 0 && !(PicoIn.opt & POPT_DIS_VDP_FIFO))
Pico.m.dma_xfers = rand() & 0x1fff;
PicoVideoFIFOWrite(rand() & 0x1fff, 0, 0, PVS_CPURD);
SekFinishIdleDet();
@ -222,57 +222,6 @@ void PicoLoopPrepare(void)
rendstatus_old = -1;
}
// this table is wrong and should be removed
// keeping it for now to compensate wrong timing elswhere, mainly for Outrunners
static const int dma_timings[] = { // Q16
// dma2vram dma2[vs|c]ram vram_fill vram_copy
// VRAM has half the width of VSRAM/CRAM, thus half the performance
( 83<<16)/488, (166<<16)/488, (165<<16)/488, ( 83<<16)/488, // vblank 32cell
(102<<16)/488, (204<<16)/488, (203<<16)/488, (102<<16)/488, // vblank 40cell
( 8<<16)/488, ( 16<<16)/488, ( 15<<16)/488, ( 8<<16)/488, // active 32cell
( 9<<16)/488, ( 18<<16)/488, ( 17<<16)/488, ( 9<<16)/488 // active 40cell
};
static const int dma_bsycles[] = { // Q16
(488<<16)/83, (488<<16)/166, (488<<16)/165, (488<<16)/83,
(488<<16)/102, (488<<16)/204, (488<<16)/203, (488<<16)/102,
(488<<16)/8, (488<<16)/16, (488<<16)/15, (488<<16)/8,
(488<<16)/9, (488<<16)/18, (488<<16)/17, (488<<16)/9
};
// grossly inaccurate.. FIXME FIXXXMEE
PICO_INTERNAL int CheckDMA(int cycles)
{
int burn = 0, xfers_can, dma_op = Pico.video.reg[0x17]>>6; // see gens for 00 and 01 modes
int xfers = Pico.m.dma_xfers;
int dma_op1;
// safety pin
if (cycles <= 0) return 0;
if(!(dma_op&2)) dma_op = (Pico.video.type==1) ? 0 : 1; // setting dma_timings offset here according to Gens
dma_op1 = dma_op;
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] * cycles + 0x8000) >> 16;
if(xfers <= xfers_can)
{
Pico.video.status &= ~SR_DMA;
if (!(dma_op & 2))
burn = xfers * dma_bsycles[dma_op] >> 16;
Pico.m.dma_xfers = 0;
} else {
if(!(dma_op&2)) burn = cycles;
Pico.m.dma_xfers -= xfers_can;
}
Pico.t.dma_end = SekCyclesDone() + burn;
elprintf(EL_VDPDMA, "~Dma %i op=%i can=%i burn=%i [%u]",
Pico.m.dma_xfers, dma_op1, xfers_can, burn, SekCyclesDone());
//dprintf("~aim: %i, cnt: %i", Pico.t.m68c_aim, Pico.t.m68c_cnt);
return burn;
}
#include "pico_cmn.c"
/* sync z80 to 68k */
@ -319,7 +268,7 @@ void PicoFrame(void)
goto end;
}
//if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode
//if(Pico.video.reg[12]&0x2) Pico.video.status ^= SR_ODD; // change odd bit in interlace mode
PicoFrameStart();
PicoFrameHints();