diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index e569763ffd..f7f1db8f79 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -106,6 +106,7 @@ + diff --git a/BizHawk.Emulation/Computers/Commodore64/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/Vic.cs index 29c1a374f3..e7a2c9882c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Vic.cs @@ -52,6 +52,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 private void ExecuteCommon() { + cycleFetchG = false; + cycleFetchP = false; + cycleFetchR = false; + cycleFetchS = false; + if (!badlineEnabled && rasterLine == 0x30) badlineEnabled = displayEnable; @@ -137,7 +142,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 { switch (rasterCycle) { - case 0: break; + case 0: + + BASprite(3, 4); + break; case 1: break; case 2: break; case 3: break; diff --git a/BizHawk.Emulation/Computers/Commodore64/VicCycles.cs b/BizHawk.Emulation/Computers/Commodore64/VicCycles.cs new file mode 100644 index 0000000000..3c5c03d5fc --- /dev/null +++ b/BizHawk.Emulation/Computers/Commodore64/VicCycles.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Computers.Commodore64 +{ + public partial class VicII + { + private CycleFlags[] cycleActions; + + private struct CycleFlags + { + public bool baFetch; + public uint baspr0; + public bool baspr0e; + public uint baspr1; + public bool baspr1e; + public uint baspr2; + public bool baspr2e; + public bool chkBrdL0; + public bool chkBrdL1; + public bool chkBrdR0; + public bool chkBrdR1; + public bool chkSprCrunch; + public bool chkSprDisp; + public bool chkSprDma; + public bool chkSprExp; + public uint cycle; + public bool fetchC; + public bool fetchG; + public bool fetchIdle; + public bool fetchRefresh; + public uint phase; + public uint sprDma0; + public bool sprDma0e; + public uint sprDma1; + public bool sprDma1e; + public uint sprDma2; + public bool sprDma2e; + public uint sprPtr; + public bool sprPtre; + public bool updateMcBase; + public bool updateRc; + public bool updateVc; + public uint vis; + public bool vise; + public uint x; + } + + static private uint[,] CycleTableNTSC = + { + { 1, 0, 0x19C, 0x40, 0x13, 0x345, 0 }, + { 1, 1, 0x1A0, 0x40, 0x13, 0x345, 0 }, + { 2, 0, 0x1A4, 0x40, 0x13, 0x345, 0 }, + { 2, 1, 0x1A8, 0x40, 0x13, 0x345, 0 }, + }; + + } + +} diff --git a/BizHawk.Emulation/Computers/Commodore64/VicFunction.cs b/BizHawk.Emulation/Computers/Commodore64/VicFunction.cs index 1f0e7ce44a..31ebd94f62 100644 --- a/BizHawk.Emulation/Computers/Commodore64/VicFunction.cs +++ b/BizHawk.Emulation/Computers/Commodore64/VicFunction.cs @@ -7,16 +7,37 @@ namespace BizHawk.Emulation.Computers.Commodore64 { public partial class VicII { + private void BAClear() + { + ba = false; + prefetchCounter = 0; + } + + private void BASet() + { + if (!ba) + { + ba = true; + prefetchCounter = 4; + } + } + private void BASprite(uint index0) { + if (sprites[index0].dma) + BASet(); } private void BASprite(uint index0, uint index1) { + if (sprites[index0].dma || sprites[index1].dma) + BASet(); } private void BASprite(uint index0, uint index1, uint index2) { + if (sprites[index0].dma || sprites[index1].dma || sprites[index2].dma) + BASet(); } private void CheckBadline() @@ -110,6 +131,36 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } + private uint Fetch0(ushort addr) + { + phaseRead0 = mem.VicRead(addr); + return phaseRead0; + } + + private uint Fetch1(ushort addr) + { + phaseRead1 = mem.VicRead(addr); + return phaseRead1; + } + + private ushort FetchAddr() + { + ushort addr; + + if (cycleFetchG) + addr = idle ? FetchAddrGI() : FetchAddrG(); + else if (cycleFetchP) + addr = FetchAddrP(); + else if (cycleFetchS) + addr = FetchAddrS(); + else if (cycleFetchR) + addr = FetchAddrR(); + else + addr = extraColorMode ? (ushort)0x39FF : (ushort)0x3FFF; + + return addr; + } + private ushort FetchAddrG() { ushort addr; @@ -125,34 +176,26 @@ namespace BizHawk.Emulation.Computers.Commodore64 return addr; } - private uint Fetch0(ushort addr) + private ushort FetchAddrGI() { - if (cycleFetchG) - { - if (!idle) - return FetchG(); - else - return FetchGIdle(); - } - else if (cycleFetchP) - { - return FetchP(); - } - else if (cycleFetchS) - { - return FetchS(); - } - else if (cycleFetchR) - { - return FetchR(); - } - return FetchIdle(); + return (extraColorMode ? (ushort)0x39FF : (ushort)0x3FFF); } - private uint Fetch1(ushort addr) + private ushort FetchAddrP() { - phaseRead1 = mem.VicRead(addr); - return phaseRead1; + return 0; + } + + private ushort FetchAddrR() + { + ushort addr = refreshAddr--; + addr |= 0x3F00; + return addr; + } + + private ushort FetchAddrS() + { + return 0; } private ushort FetchAddrV(uint offset) @@ -165,14 +208,18 @@ namespace BizHawk.Emulation.Computers.Commodore64 return 0; } - private ushort FetchG() + private void FetchG() { - return 0; - } - - private ushort FetchGIdle() - { - return 0; + if (prefetchCounter > 0) + { + videoBuffer[vmli] = 0xFF; + colorBuffer[vmli] = 0; + } + else + { + videoBuffer[vmli] = Fetch1(FetchAddrV(vc)); + colorBuffer[vmli] = (uint)mem.colorRam[vc] & 0xF; + } } private ushort FetchIdle() diff --git a/BizHawk.Emulation/Computers/Commodore64/VicRegs.cs b/BizHawk.Emulation/Computers/Commodore64/VicRegs.cs index ab768a8358..353e342957 100644 --- a/BizHawk.Emulation/Computers/Commodore64/VicRegs.cs +++ b/BizHawk.Emulation/Computers/Commodore64/VicRegs.cs @@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } + private bool ba; private uint backgroundColor0; private uint backgroundColor1; private uint backgroundColor2; @@ -71,6 +72,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 private bool borderOnVerticalEnable; private uint borderRight; private uint borderTop; + private uint[] colorBuffer; + private bool collisionEnabled; private bool columnSelect; private bool cycleFetchG; private bool cycleFetchP; @@ -93,6 +96,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 private bool multiColorMode; private uint phaseRead0; private uint phaseRead1; + private uint prefetchCounter; private uint rasterCycle; private uint rasterIrqLine; private uint rasterLine; @@ -115,6 +119,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 public void SyncState(Serializer ser) { + ser.Sync("ba", ref ba); ser.Sync("backgroundColor0", ref backgroundColor0); ser.Sync("backgroundColor1", ref backgroundColor1); ser.Sync("backgroundColor2", ref backgroundColor2); @@ -131,7 +136,12 @@ namespace BizHawk.Emulation.Computers.Commodore64 ser.Sync("borderOnVerticalEnable", ref borderOnVerticalEnable); ser.Sync("borderRight", ref borderRight); ser.Sync("borderTop", ref borderTop); + ser.Sync("collisionEnabled", ref collisionEnabled); ser.Sync("columnSelect", ref columnSelect); + ser.Sync("cycleFetchG", ref cycleFetchG); + ser.Sync("cycleFetchP", ref cycleFetchP); + ser.Sync("cycleFetchR", ref cycleFetchR); + ser.Sync("cycleFetchS", ref cycleFetchS); ser.Sync("displayEnable", ref displayEnable); ser.Sync("enableIrqDataCollision", ref enableIrqDataCollision); ser.Sync("enableIrqLightPen", ref enableIrqLightPen); @@ -170,7 +180,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 for (int i = 0; i < 8; i++) { - ser.BeginSection("sprite" + i.ToString()); + ser.BeginSection("sprites" + i.ToString()); sprites[i].SyncState(ser); ser.EndSection(); } @@ -480,7 +490,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } private byte Reg18 { - get { return (byte)((videoRam << 4) | (bitmapRam << 1)); } + get { return (byte)((videoRam << 4) | (bitmapRam << 1) | 0x1); } set { videoRam = ((uint)(value & 0xF0)) >> 4; bitmapRam = ((uint)(value & 0x0E)) >> 1; } } private byte Reg19 { @@ -646,64 +656,64 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } private byte Reg20 { - get { return (byte)borderColor; } - set { borderColor = value; } + get { return (byte)(borderColor | 0xF0); } + set { borderColor = (uint)value & 0x0F; } } private byte Reg21 { - get { return (byte)backgroundColor0; } - set { backgroundColor0 = value; } + get { return (byte)(backgroundColor0 | 0xF0); } + set { backgroundColor0 = (uint)value & 0x0F; } } private byte Reg22 { - get { return (byte)backgroundColor1; } - set { backgroundColor1 = value; } + get { return (byte)(backgroundColor1 | 0xF0); } + set { backgroundColor1 = (uint)value & 0x0F; } } private byte Reg23 { - get { return (byte)backgroundColor2; } - set { backgroundColor2 = value; } + get { return (byte)(backgroundColor2 | 0xF0); } + set { backgroundColor2 = (uint)value & 0x0F; } } private byte Reg24 { - get { return (byte)backgroundColor3; } - set { backgroundColor3 = value; } + get { return (byte)(backgroundColor3 | 0xF0); } + set { backgroundColor3 = (uint)value & 0x0F; } } private byte Reg25 { - get { return (byte)spriteMultiColor0; } - set { spriteMultiColor0 = value; } + get { return (byte)(spriteMultiColor0 | 0xF0); } + set { spriteMultiColor0 = (uint)value & 0x0F; } } private byte Reg26 { - get { return (byte)spriteMultiColor1; } - set { spriteMultiColor1 = value; } + get { return (byte)(spriteMultiColor1 | 0xF0); } + set { spriteMultiColor1 = (uint)value & 0x0F; } } private byte Reg27 { - get { return (byte)sprites[0].color; } - set { sprites[0].color = value; } + get { return (byte)(sprites[0].color | 0xF0); } + set { sprites[0].color = (uint)value & 0x0F; } } private byte Reg28 { - get { return (byte)sprites[1].color; } - set { sprites[1].color = value; } + get { return (byte)(sprites[1].color | 0xF0); } + set { sprites[1].color = (uint)value & 0x0F; } } private byte Reg29 { - get { return (byte)sprites[2].color; } - set { sprites[2].color = value; } + get { return (byte)(sprites[2].color | 0xF0); } + set { sprites[2].color = (uint)value & 0x0F; } } private byte Reg2A { - get { return (byte)sprites[3].color; } - set { sprites[3].color = value; } + get { return (byte)(sprites[3].color | 0xF0); } + set { sprites[3].color = (uint)value & 0x0F; } } private byte Reg2B { - get { return (byte)sprites[4].color; } - set { sprites[4].color = value; } + get { return (byte)(sprites[4].color | 0xF0); } + set { sprites[4].color = (uint)value & 0x0F; } } private byte Reg2C { - get { return (byte)sprites[5].color; } - set { sprites[5].color = value; } + get { return (byte)(sprites[5].color | 0xF0); } + set { sprites[5].color = (uint)value & 0x0F; } } private byte Reg2D { - get { return (byte)sprites[6].color; } - set { sprites[6].color = value; } + get { return (byte)(sprites[6].color | 0xF0); } + set { sprites[6].color = (uint)value & 0x0F; } } private byte Reg2E { - get { return (byte)sprites[7].color; } - set { sprites[7].color = value; } + get { return (byte)(sprites[7].color | 0xF0); } + set { sprites[7].color = (uint)value & 0x0F; } } }