commodore64: badline timing fix

This commit is contained in:
saxxonpike 2012-11-23 12:02:26 +00:00
parent 608ebc4a99
commit 24ee005be7
5 changed files with 182 additions and 31 deletions

View File

@ -102,6 +102,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
// perform the cycle // perform the cycle
for (int i = 0; i < cyclesPerFrame; i++) for (int i = 0; i < cyclesPerFrame; i++)
{ {
if (signal.CpuAEC)
{
cpu.ExecuteOne();
}
vic.PerformCycle(); vic.PerformCycle();
cpu.IRQ = signal.CpuIRQ; cpu.IRQ = signal.CpuIRQ;
cpu.NMI = signal.CpuNMI; cpu.NMI = signal.CpuNMI;
@ -112,10 +116,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
sid.PerformCycle(); sid.PerformCycle();
if (diskDriveAttached) if (diskDriveAttached)
diskDrive.PerformCycle(); diskDrive.PerformCycle();
if (signal.CpuAEC)
{
cpu.ExecuteOne();
}
} }
_islag = !mem.inputWasRead; _islag = !mem.inputWasRead;

View File

@ -475,7 +475,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
int timer = regs.T[index]; int timer = regs.T[index];
timer--; timer--;
if (timer < 0) if (timer == 0)
{ {
underflow[index] = true; underflow[index] = true;
if (regs.RUNMODE[index]) if (regs.RUNMODE[index])
@ -491,7 +491,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
} }
regs.IT[index] |= underflow[index]; regs.IT[index] |= underflow[index];
regs.T[index] = timer; regs.T[index] = timer & 0xFFFF;
} }
public void TimerTick(int index) public void TimerTick(int index)

View File

@ -67,6 +67,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public bool writeTrigger = true; public bool writeTrigger = true;
// ports // ports
public DataPortConnector cpuIO;
public DataPortConnector cpuPort; public DataPortConnector cpuPort;
public DataPortBus cpuPortBus = new DataPortBus(); public DataPortBus cpuPortBus = new DataPortBus();
@ -101,6 +102,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
cpuPort = cpuPortBus.Connect(); cpuPort = cpuPortBus.Connect();
cpuPortBus.AttachWriteHook(UpdateLayout); cpuPortBus.AttachWriteHook(UpdateLayout);
cpuIO = cpuPortBus.Connect();
cpuIO.Latch = 0x17;
cia1.AttachWriteHook(0, UpdateVicOffset); cia1.AttachWriteHook(0, UpdateVicOffset);
HardReset(); HardReset();
} }

View File

@ -7,17 +7,17 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
public partial class VicIINew : IVideoProvider public partial class VicIINew : IVideoProvider
{ {
private int baCount;
private int cycle; private int cycle;
private Action[][] pipeline; private Action[][] pipeline;
private bool pipelineGAccess; private bool pipelineGAccess;
private bool pipelineMemoryBusy;
private int pipelineLength; private int pipelineLength;
private void ExecutePipeline() private void ExecutePipeline()
{ {
pipelineGAccess = false; pipelineGAccess = false;
pipelineMemoryBusy = false;
advanceX = true; advanceX = true;
baCount = 0;
foreach (Action a in pipeline[cycle]) foreach (Action a in pipeline[cycle])
a(); a();
@ -29,7 +29,18 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineRasterAdvance(); PipelineRasterAdvance();
} }
signal.VicAEC = !pipelineMemoryBusy; PipelineBA(baCount > 0);
if (baCount > 0)
{
if (fetchCounter > 0)
fetchCounter--;
signal.VicAEC = (fetchCounter != 0);
}
else
{
fetchCounter = 0;
signal.VicAEC = true;
}
} }
private void InitPipeline(Region region) private void InitPipeline(Region region)
@ -374,7 +385,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ // 54 { // 54
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineSpriteMYEFlip,
PipelineSpriteEnable0, PipelineSpriteEnable0,
PipelineRender PipelineRender
}, },
@ -382,6 +392,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ // 55 { // 55
PipelineCycle, PipelineCycle,
PipelineSpriteEnable1, PipelineSpriteEnable1,
PipelineSpriteMYEFlip,
PipelineIdle, PipelineIdle,
PipelineRender PipelineRender
}, },
@ -456,6 +467,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineIRQ0, PipelineIRQ0,
PipelineFetchSprite3P, PipelineFetchSprite3P,
PipelineBASprite3,
PipelineBASprite4,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -463,72 +476,96 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineIRQ1, PipelineIRQ1,
PipelineFetchSprite3S, PipelineFetchSprite3S,
PipelineBASprite3,
PipelineBASprite4,
PipelineBASprite5,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 2 { // 2
PipelineCycle, PipelineCycle,
PipelineFetchSprite4P, PipelineFetchSprite4P,
PipelineBASprite4,
PipelineBASprite5,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 3 { // 3
PipelineCycle, PipelineCycle,
PipelineFetchSprite4S, PipelineFetchSprite4S,
PipelineBASprite4,
PipelineBASprite5,
PipelineBASprite6,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 4 { // 4
PipelineCycle, PipelineCycle,
PipelineFetchSprite5P, PipelineFetchSprite5P,
PipelineBASprite5,
PipelineBASprite6,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 5 { // 5
PipelineCycle, PipelineCycle,
PipelineFetchSprite5S, PipelineFetchSprite5S,
PipelineBASprite5,
PipelineBASprite6,
PipelineBASprite7,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 6 { // 6
PipelineCycle, PipelineCycle,
PipelineFetchSprite6P, PipelineFetchSprite6P,
PipelineBASprite6,
PipelineBASprite7,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 7 { // 7
PipelineCycle, PipelineCycle,
PipelineFetchSprite6S, PipelineFetchSprite6S,
PipelineBASprite6,
PipelineBASprite7,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 8 { // 8
PipelineCycle, PipelineCycle,
PipelineFetchSprite7P, PipelineFetchSprite7P,
PipelineBASprite7,
PipelineBAForceLag,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 9 { // 9
PipelineCycle, PipelineCycle,
PipelineFetchSprite7S, PipelineFetchSprite7S,
PipelineBASprite7,
PipelineBAForceLag,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 10 { // 10
PipelineCycle, PipelineCycle,
PipelineDramRefresh, PipelineDramRefresh,
PipelineBAForceLag,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 11 { // 11
PipelineCycle, PipelineCycle,
PipelineDramRefresh, PipelineDramRefresh,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 12 { // 12
PipelineCycle, PipelineCycle,
PipelineDramRefresh, PipelineDramRefresh,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -536,13 +573,14 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineVCReset, PipelineVCReset,
PipelineDramRefresh, PipelineDramRefresh,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 14 { // 14
PipelineCycle, PipelineCycle,
PipelineDramRefresh, PipelineDramRefresh,
PipelineBadlineDelay, PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -550,234 +588,273 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineSpriteMCBASEAdvance, PipelineSpriteMCBASEAdvance,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 16 { // 16
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 17 { // 17
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 18 { // 18
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 19 { // 19
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 20 { // 20
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 21 { // 21
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 22 { // 22
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 23 { // 23
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 24 { // 24
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 25 { // 25
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 26 { // 26
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 27 { // 27
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 28 { // 28
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 29 { // 29
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 30 { // 30
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 31 { // 31
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 32 { // 32
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 33 { // 33
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 34 { // 34
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 35 { // 35
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 36 { // 36
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 37 { // 37
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 38 { // 38
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 39 { // 39
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 40 { // 40
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 41 { // 41
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 42 { // 42
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 43 { // 43
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 44 { // 44
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 45 { // 45
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 46 { // 46
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 47 { // 47
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 48 { // 48
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 49 { // 49
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 50 { // 50
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 51 { // 51
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 52 { // 52
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 53 { // 53
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineBAFetch,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -785,6 +862,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineFetchC, PipelineFetchC,
PipelineSpriteEnable0, PipelineSpriteEnable0,
PipelineBASprite0,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -793,12 +871,15 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineSpriteEnable1, PipelineSpriteEnable1,
PipelineSpriteMYEFlip, PipelineSpriteMYEFlip,
PipelineIdle, PipelineIdle,
PipelineBASprite0,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 56 { // 56
PipelineCycle, PipelineCycle,
PipelineIdle, PipelineIdle,
PipelineBASprite0,
PipelineBASprite1,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -807,30 +888,42 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineSpriteDMA, PipelineSpriteDMA,
PipelineRCReset, PipelineRCReset,
PipelineFetchSprite0P, PipelineFetchSprite0P,
PipelineBASprite0,
PipelineBASprite1,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 58 { // 58
PipelineCycle, PipelineCycle,
PipelineFetchSprite0S, PipelineFetchSprite0S,
PipelineBASprite0,
PipelineBASprite1,
PipelineBASprite2,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 59 { // 59
PipelineCycle, PipelineCycle,
PipelineFetchSprite1P, PipelineFetchSprite1P,
PipelineBASprite1,
PipelineBASprite2,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 60 { // 60
PipelineCycle, PipelineCycle,
PipelineFetchSprite1S, PipelineFetchSprite1S,
PipelineBASprite1,
PipelineBASprite2,
PipelineBASprite3,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
{ // 61 { // 61
PipelineCycle, PipelineCycle,
PipelineFetchSprite2P, PipelineFetchSprite2P,
PipelineBASprite2,
PipelineBASprite3,
PipelineRender PipelineRender
}, },
new Action[] new Action[]
@ -838,6 +931,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
PipelineCycle, PipelineCycle,
PipelineFetchSprite2S, PipelineFetchSprite2S,
PipelineBorderCheck, PipelineBorderCheck,
PipelineBASprite2,
PipelineBASprite3,
PipelineBASprite4,
PipelineRender PipelineRender
} }
}; };
@ -847,10 +943,76 @@ namespace BizHawk.Emulation.Computers.Commodore64
pipelineLength = pipeline.Length; pipelineLength = pipeline.Length;
} }
private void PipelineBadlineDelay() private void PipelineBA(bool val)
{
if (val)
{
if (signal.VicAEC == true && fetchCounter == 0)
fetchCounter = 4;
}
else
{
fetchCounter = 0;
}
}
private void PipelineBAFetch()
{ {
if (badline) if (badline)
pipelineMemoryBusy = true; baCount++;
}
private void PipelineBAForceLag()
{
baCount++;
}
private void PipelineBASprite0()
{
if (sprites[0].MDMA)
baCount++;
}
private void PipelineBASprite1()
{
if (sprites[1].MDMA)
baCount++;
}
private void PipelineBASprite2()
{
if (sprites[2].MDMA)
baCount++;
}
private void PipelineBASprite3()
{
if (sprites[3].MDMA)
baCount++;
}
private void PipelineBASprite4()
{
if (sprites[4].MDMA)
baCount++;
}
private void PipelineBASprite5()
{
if (sprites[5].MDMA)
baCount++;
}
private void PipelineBASprite6()
{
if (sprites[6].MDMA)
baCount++;
}
private void PipelineBASprite7()
{
if (sprites[7].MDMA)
baCount++;
} }
private void PipelineBorderCheck() private void PipelineBorderCheck()
@ -867,7 +1029,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
displayEnabled = (displayEnabled | DEN); displayEnabled = (displayEnabled | DEN);
if (RASTER >= 0x030 && RASTER < 0x0F8) if (RASTER >= 0x030 && RASTER < 0x0F8)
badline = ((YSCROLL == (RASTER & 0x07)) && displayEnabled); badline = badline | ((YSCROLL == (RASTER & 0x07)) && displayEnabled);
else else
badline = false; badline = false;
@ -906,7 +1068,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
int cAddress = (VM << 10) | VC; int cAddress = (VM << 10) | VC;
characterDataBus = mem.VicRead((ushort)cAddress); characterDataBus = mem.VicRead((ushort)cAddress);
colorDataBus = mem.colorRam[VC]; colorDataBus = mem.colorRam[VC];
pipelineMemoryBusy = true;
} }
else else
{ {
@ -1053,7 +1214,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
sprites[index].MSR = mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC))); sprites[index].MSR = mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC)));
sprites[index].MC++; sprites[index].MC++;
pipelineMemoryBusy = true;
} }
} }
@ -1067,7 +1227,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
sprites[index].MSR |= mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC))); sprites[index].MSR |= mem.VicRead((ushort)((sprites[index].MPTR << 6) | (sprites[index].MC)));
sprites[index].MC++; sprites[index].MC++;
} }
pipelineMemoryBusy = true;
} }
} }
@ -1280,6 +1439,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
displayEnabled = false; displayEnabled = false;
rasterX = rasterLeft; rasterX = rasterLeft;
} }
badline = false;
} }
private void PipelineRCReset() private void PipelineRCReset()
@ -1354,19 +1514,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
} }
} }
private void PipelineSetBA(bool val)
{
if (val)
{
if (fetchCounter == 0)
fetchCounter = 4;
}
else
{
fetchCounter = 0;
}
}
private void PipelineSprites() private void PipelineSprites()
{ {
int pixelOwner = -1; int pixelOwner = -1;

View File

@ -74,7 +74,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
// pipeline // pipeline
ser.Sync("CYCLE", ref cycle); ser.Sync("CYCLE", ref cycle);
ser.Sync("PIPELINEGACCESS", ref pipelineGAccess); ser.Sync("PIPELINEGACCESS", ref pipelineGAccess);
ser.Sync("PIPELINEMEMORYBUSY", ref pipelineMemoryBusy);
// sprites // sprites
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)