From 2c5f179da2fbbe991a4dc0e0bf42af4ac4f4a653 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Mon, 12 Nov 2012 15:52:31 +0000 Subject: [PATCH] commodore64: VIC, SID, CIA0, CIA1, RAM have their own domains now, Memory is what is visible to the CPU --- BizHawk.Emulation/BizHawk.Emulation.csproj | 1 + .../Computers/Commodore64/C64.PeekPoke.cs | 85 ++++++++++ .../Computers/Commodore64/C64.core.cs | 27 ++-- .../Computers/Commodore64/C64.cs | 8 +- .../Computers/Commodore64/Cia.cs | 149 +++++++++++------- .../Computers/Commodore64/MemBus.cs | 62 ++++++++ .../Computers/Commodore64/Sid.cs | 10 ++ .../Computers/Commodore64/VicII.cs | 107 ++++++------- 8 files changed, 315 insertions(+), 134 deletions(-) create mode 100644 BizHawk.Emulation/Computers/Commodore64/C64.PeekPoke.cs diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index dbe44868ec..681e5b5168 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -81,6 +81,7 @@ + diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.PeekPoke.cs b/BizHawk.Emulation/Computers/Commodore64/C64.PeekPoke.cs new file mode 100644 index 0000000000..ee90ce9fa1 --- /dev/null +++ b/BizHawk.Emulation/Computers/Commodore64/C64.PeekPoke.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Computers.Commodore64 +{ + public partial class C64 : IEmulator + { + public byte PeekCia0(int addr) + { + return cia0.Peek(addr); + } + + public byte PeekCia1(int addr) + { + return cia1.Peek(addr); + } + + public byte PeekColorRAM(int addr) + { + return (byte)((mem.colorRam[addr & 0x3FF] & 0xF) | mem.busData); + } + + public byte PeekMemory(ushort addr) + { + return mem.Peek(addr); + } + + public byte PeekMemoryInt(int addr) + { + return mem.Peek((ushort)(addr & 0xFFFF)); + } + + public byte PeekRAM(int addr) + { + return mem.PeekRam(addr); + } + + public byte PeekSid(int addr) + { + return sid.Peek(addr); + } + + public byte PeekVic(int addr) + { + return vic.Peek(addr); + } + + public void PokeCia0(int addr, byte val) + { + cia0.Poke(addr, val); + } + + public void PokeCia1(int addr, byte val) + { + cia1.Poke(addr, val); + } + + public void PokeColorRAM(int addr, byte val) + { + mem.colorRam[addr & 0x3FF] = (byte)(val & 0xF); + } + + public void PokeMemoryInt(int addr, byte val) + { + mem.Poke((ushort)(addr & 0xFFFF), val); + } + + public void PokeRAM(int addr, byte val) + { + mem.PokeRam(addr, val); + } + + public void PokeSid(int addr, byte val) + { + sid.Poke(addr, val); + } + + public void PokeVic(int addr, byte val) + { + vic.Poke(addr, val); + } + } +} diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs index 0be0cd59b5..72f5c9c7ed 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs @@ -7,6 +7,12 @@ using BizHawk.Emulation.CPUs.M6502; namespace BizHawk.Emulation.Computers.Commodore64 { + public enum Region + { + NTSC, + PAL + } + public partial class C64 : IEmulator { // input @@ -36,16 +42,16 @@ namespace BizHawk.Emulation.Computers.Commodore64 cpu.DummyReadMemory = PeekMemory; // initialize cia timers - cia0 = new Cia(signal); + cia0 = new Cia(signal, Region.NTSC); cia0.ports[0] = new DirectionalDataPort(0x00, 0x00, 0xFF); cia0.ports[1] = new DirectionalDataPort(0x00, 0x00, 0xFF); - cia1 = new Cia(signal); + cia1 = new Cia(signal, Region.NTSC); cia1.ports[0] = new DirectionalDataPort(0x00, 0x00, 0xFF); cia1.ports[1] = new DirectionalDataPort(0x00, 0x00, 0xFF); // initialize vic signal = new ChipSignals(); - vic = new VicII(signal, VicIIMode.NTSC); + vic = new VicII(signal, Region.NTSC); // initialize sid sid = new Sid(); @@ -83,21 +89,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } - public byte PeekMemory(ushort addr) - { - return mem.Peek(addr); - } - - public byte PeekMemoryInt(int addr) - { - return mem.Peek((ushort)(addr & 0xFFFF)); - } - - public void PokeMemoryInt(int addr, byte val) - { - // todo - } - public void PollInput() { input.Poll(); diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index 582519547e..4f12476d51 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -113,7 +113,13 @@ namespace BizHawk.Emulation.Computers.Commodore64 private void SetupMemoryDomains() { var domains = new List(1); - domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func(PeekMemoryInt), new Action(PokeMemoryInt))); //TODO + domains.Add(new MemoryDomain("Memory", 0x10000, Endian.Little, new Func(PeekMemoryInt), new Action(PokeMemoryInt))); + domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func(PeekRAM), new Action(PokeRAM))); + domains.Add(new MemoryDomain("CIA0", 0x10, Endian.Little, new Func(PeekCia0), new Action(PokeCia0))); + domains.Add(new MemoryDomain("CIA1", 0x10, Endian.Little, new Func(PeekCia1), new Action(PokeCia1))); + domains.Add(new MemoryDomain("SID", 0x20, Endian.Little, new Func(PeekSid), new Action(PokeSid))); + domains.Add(new MemoryDomain("VIC", 0x40, Endian.Little, new Func(PeekVic), new Action(PokeVic))); + domains.Add(new MemoryDomain("CRAM", 0x400, Endian.Little, new Func(PeekColorRAM), new Action(PokeColorRAM))); memoryDomains = domains.AsReadOnly(); } diff --git a/BizHawk.Emulation/Computers/Commodore64/Cia.cs b/BizHawk.Emulation/Computers/Commodore64/Cia.cs index 53fdf34af5..816a16f3b1 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Cia.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Cia.cs @@ -7,42 +7,38 @@ namespace BizHawk.Emulation.Computers.Commodore64 { public class CiaRegs { - public bool ALARM; - public int ALARM10; - public int ALARMHR; - public int ALARMMIN; - public bool ALARMPM; - public int ALARMSEC; - public int[] DOR = new int[2]; - public bool IALARM; - public bool IFLG; - public int[] INMODE = new int[2]; - public bool IRQ; - public bool ISP; - public bool[] IT = new bool[2]; - public bool[] LOAD = new bool[2]; - public bool[] OUTMODE = new bool[2]; - public bool[] PBON = new bool[2]; - public int[] PR = new int[2]; - public bool[] RUNMODE = new bool[2]; - public int SDR; - public bool SPMODE; - public bool[] START = new bool[2]; - public int[] T = new int[2]; - public int[] TLATCH = new int[2]; - public int TOD10; - public bool TODIN; - public int TODHR; - public int TODMIN; - public bool TODPM; - public int TODSEC; + public bool ALARM; // alarm enabled + public int ALARM10; // alarm 10ths of a second + public int ALARMHR; // alarm hours + public int ALARMMIN; // alarm minutes + public bool ALARMPM; // alarm AM/PM + public int ALARMSEC; // alarm seconds + public bool IALARM; // alarm interrupt triggered + public bool IFLG; // interrupt triggered on FLAG pin + public int[] INMODE = new int[2]; // timer input mode + public bool IRQ; // interrupt triggered + public bool ISP; // shift register interrupt + public bool[] IT = new bool[2]; // timer interrupt + public bool[] LOAD = new bool[2]; // force load timer + public bool[] OUTMODE = new bool[2]; // timer output mode + public bool[] PBON = new bool[2]; // port bit modify on + public bool[] RUNMODE = new bool[2]; // running mode + public int SDR; // serial shift register + public bool SPMODE; // shift register mode + public bool[] START = new bool[2]; // timer enabled + public int[] T = new int[2]; // timer counter + public int[] TLATCH = new int[2]; // timer latch (internal) + public int TOD10; // time of day 10ths of a second + public bool TODIN; // time of day/alarm set + public int TODHR; // time of day hour + public int TODMIN; // time of day minute + public bool TODPM; // time of day AM/PM + public int TODSEC; // time of day seconds - private DirectionalDataPort[] ports; private ChipSignals signal; - public CiaRegs(ChipSignals newSignal, DirectionalDataPort[] newPorts) + public CiaRegs(ChipSignals newSignal) { - ports = newPorts; signal = newSignal; // power on state @@ -64,18 +60,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 addr &= 0x0F; switch (addr) { - case 0x00: - result = ports[0].Data; - break; - case 0x01: - result = ports[1].Data; - break; - case 0x02: - result = ports[0].Direction; - break; - case 0x03: - result = ports[1].Direction; - break; case 0x04: result = (T[0] & 0xFF); break; @@ -145,18 +129,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 addr &= 0x0F; switch (addr) { - case 0x00: - ports[0].Data = val; - break; - case 0x01: - ports[1].Data = val; - break; - case 0x02: - ports[0].Direction = val; - break; - case 0x03: - ports[1].Direction = val; - break; case 0x04: T[0] &= 0xFF00; T[0] |= val; @@ -236,7 +208,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 public Func ReadSerial; public Action WriteSerial; - public Cia(ChipSignals newSignal) + public Cia(ChipSignals newSignal, Region newRegion) { signal = newSignal; ReadSerial = ReadSerialDummy; @@ -248,10 +220,28 @@ namespace BizHawk.Emulation.Computers.Commodore64 { outputBitMask = new byte[] { 0x40, 0x80 }; ports = new DirectionalDataPort[2]; - regs = new CiaRegs(signal, ports); + regs = new CiaRegs(signal); underflow = new bool[2]; } + public byte Peek(int addr) + { + addr &= 0xF; + switch (addr) + { + case 0x00: + return ports[0].Data; + case 0x01: + return ports[1].Data; + case 0x02: + return ports[0].Direction; + case 0x03: + return ports[1].Direction; + default: + return regs[addr]; + } + } + public void PerformCycle() { lastCNT = thisCNT; @@ -289,12 +279,43 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } + public void Poke(int addr, byte val) + { + addr &= 0xF; + switch (addr) + { + case 0x00: + ports[0].Data = val; + break; + case 0x01: + ports[1].Data = val; + break; + case 0x02: + ports[0].Direction = val; + break; + case 0x03: + ports[1].Direction = val; + break; + default: + regs[addr] = val; + break; + } + } + public byte Read(ushort addr) { byte result; switch (addr) { + case 0x00: + return ports[0].Data; + case 0x01: + return ports[1].Data; + case 0x02: + return ports[0].Direction; + case 0x03: + return ports[1].Direction; case 0x0D: // reading this reg clears it result = regs[0x0D]; @@ -358,6 +379,18 @@ namespace BizHawk.Emulation.Computers.Commodore64 { switch (addr) { + case 0x00: + ports[0].Data = val; + break; + case 0x01: + ports[1].Data = val; + break; + case 0x02: + ports[0].Direction = val; + break; + case 0x03: + ports[1].Direction = val; + break; case 0x04: regs.TLATCH[0] &= 0xFF00; regs.TLATCH[0] |= val; diff --git a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs index 9bc15b7c82..b58f79a774 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs @@ -260,6 +260,68 @@ namespace BizHawk.Emulation.Computers.Commodore64 return result; } + public byte PeekRam(int addr) + { + return ram[addr & 0xFFFF]; + } + + public void Poke(ushort addr, byte val) + { + if (addr == 0x0000) + { + cpuPort.Direction = val; + } + else if (addr == 0x0001) + { + cpuPort.Data = val; + UpdateLayout(); + } + else + { + MemoryDesignation des = GetDesignation(addr); + + switch (des) + { + case MemoryDesignation.Vic: + vic.Poke(addr, val); + break; + case MemoryDesignation.Sid: + sid.Poke(addr, val); + break; + case MemoryDesignation.ColorRam: + colorRam[addr & 0x03FF] = (byte)(val & 0x0F); + break; + case MemoryDesignation.Cia0: + cia0.Poke(addr, val); + break; + case MemoryDesignation.Cia1: + cia1.Poke(addr, val); + break; + case MemoryDesignation.Expansion0: + if (cart != null) + cart.WritePort(addr, val); + break; + case MemoryDesignation.Expansion1: + break; + case MemoryDesignation.RAM: + break; + default: + break; + } + + // write through to ram + if (des != MemoryDesignation.Disabled) + { + ram[addr] = val; + } + } + } + + public void PokeRam(int addr, byte val) + { + ram[addr & 0xFFFF] = val; + } + public byte Read(ushort addr) { byte result; diff --git a/BizHawk.Emulation/Computers/Commodore64/Sid.cs b/BizHawk.Emulation/Computers/Commodore64/Sid.cs index 0c12744a28..e37a14dc6c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Sid.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Sid.cs @@ -298,6 +298,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 regs = new SidRegs(); } + public byte Peek(int addr) + { + return regs[addr & 0x1F]; + } + public void PerformCycle() { // accumulator is 24 bits @@ -315,6 +320,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } + public void Poke(int addr, byte val) + { + regs[addr & 0x1F] = val; + } + private void ProcessEnvelope(int index) { // envelope counter is 15 bits diff --git a/BizHawk.Emulation/Computers/Commodore64/VicII.cs b/BizHawk.Emulation/Computers/Commodore64/VicII.cs index cf7dca2e07..f21a96bd12 100644 --- a/BizHawk.Emulation/Computers/Commodore64/VicII.cs +++ b/BizHawk.Emulation/Computers/Commodore64/VicII.cs @@ -5,63 +5,57 @@ using System.Text; namespace BizHawk.Emulation.Computers.Commodore64 { - public enum VicIIMode - { - NTSC, - PAL - } - public class VicIIRegs { - public bool BMM; - public int[] BxC = new int[4]; - public int CB; - public bool CSEL; - public bool DEN; - public int EC; - public bool ECM; - public bool ELP; - public bool EMBC; - public bool EMMC; - public bool ERST; - public bool ILP; - public bool IMBC; - public bool IMMC; - public bool IRQ; - public bool IRST; - public int LPX; - public int LPY; + public bool BMM; // bitmap mode + public int[] BxC = new int[4]; // background colors + public int CB; // character bitmap offset + public bool CSEL; // column select + public bool DEN; // display enabled + public int EC; // border color + public bool ECM; // extra color mode + public bool ELP; // enable lightpen interrupt + public bool EMBC; // enable sprite-data interrupt + public bool EMMC; // enable sprite-sprite interrupt + public bool ERST; // enable raster line interrupt + public bool ILP; // light pen interrupt active + public bool IMBC; // sprite-data interrupt active + public bool IMMC; // sprite-sprite interrupt active + public bool IRQ; // interrupt was triggered + public bool IRST; // raster line interrupt active + public int LPX; // lightpen X coordinate + public int LPY; // lightpen Y coordinate public int[] MC = new int[8]; // (internal) public int[] MCBASE = new int[8]; // (internal) - public bool MCM; + public bool MCM; // multicolor mode public bool[] MD = new bool[8]; // (internal) public bool[] MDMA = new bool[8]; // (internal) - public int[] MMx = new int[2]; + public int[] MMx = new int[2]; // sprite extra color public int[] MPTR = new int[8]; // (internal) public Int32[] MSR = new Int32[8]; // (internal) public bool[] MSRA = new bool[8]; // (internal) public int[] MSRC = new int[8]; // (internal) - public int[] MxC = new int[8]; - public bool[] MxD = new bool[8]; - public bool[] MxDP = new bool[8]; - public bool[] MxE = new bool[8]; - public bool[] MxM = new bool[8]; - public bool[] MxMC = new bool[8]; - public int[] MxX = new int[8]; - public bool[] MxXE = new bool[8]; - public int[] MxY = new int[8]; - public bool[] MxYE = new bool[8]; + public int[] MxC = new int[8]; // sprite color + public bool[] MxD = new bool[8]; // sprite-data collision + public bool[] MxDP = new bool[8]; // sprite priority + public bool[] MxE = new bool[8]; // sprite enabled + public bool[] MxM = new bool[8]; // sprite-sprite collision + public bool[] MxMC = new bool[8]; // sprite multicolor + public int[] MxX = new int[8]; // sprite X coordinate + public bool[] MxXE = new bool[8]; // sprite X expansion + public int[] MxY = new int[8]; // sprite Y coordinate + public bool[] MxYE = new bool[8]; // sprite Y expansion public bool[] MYE = new bool[8]; // (internal) - public int RASTER; + public int RASTER; // current raster line public int RC; // (internal) - public bool RES; - public bool RSEL; + public bool RES; // reset bit (does nothing in this version of the VIC) + public bool RSEL; // row select public int VC; // (internal) public int VCBASE; // (internal) - public int VM; + public int VM; // video memory offset public int VMLI; // (internal) - public int XSCROLL; - public int YSCROLL; + public int XSCROLL; // X scroll position + public int YSCROLL; // Y scroll position public VicIIRegs() { @@ -441,16 +435,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } - public enum VicIITask - { - Idle, - VideoMatrix, - CharGen, - SpritePointer, - SpriteData, - DramRefresh - } - public partial class VicII : IVideoProvider { // graphics buffer @@ -516,7 +500,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 public int spriteFetchStartCycle; public int spriteFetchIndex; public bool spriteForeground; - public VicIITask task; public int totalCycles; public bool vBlank; public int visibleBottom; @@ -536,13 +519,13 @@ namespace BizHawk.Emulation.Computers.Commodore64 private Action FetchG; private Func Plotter; - public VicII(ChipSignals newSignal, VicIIMode videoMode) + public VicII(ChipSignals newSignal, Region newRegion) { signal = newSignal; - switch (videoMode) + switch (newRegion) { - case VicIIMode.NTSC: + case Region.NTSC: totalCycles = 65; rasterTotalLines = 263; rasterLineLeft = 0x19C; @@ -558,7 +541,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 visibleHeight = 232; renderOffset = 0; break; - case VicIIMode.PAL: + case Region.PAL: break; default: break; @@ -670,6 +653,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 spriteFetchIndex = 17; } + public byte Peek(int addr) + { + return regs[addr & 0x3F]; + } + public void PerformCycle() { if (cycle >= totalCycles) @@ -687,6 +675,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 signal.VicIRQ = regs.IRQ; } + public void Poke(int addr, byte val) + { + regs[addr & 0x3F] = val; + } + private void ProcessDisplayRegisters() { // display enable check on line 030 (this must be run every cycle)