commodore64: VIC, SID, CIA0, CIA1, RAM have their own domains now, Memory is what is visible to the CPU

This commit is contained in:
saxxonpike 2012-11-12 15:52:31 +00:00
parent 86baf94dd4
commit 2c5f179da2
8 changed files with 315 additions and 134 deletions

View File

@ -81,6 +81,7 @@
<Compile Include="Buffer.cs" />
<Compile Include="Computers\Commodore64\C64.core.cs" />
<Compile Include="Computers\Commodore64\C64.cs" />
<Compile Include="Computers\Commodore64\C64.PeekPoke.cs" />
<Compile Include="Computers\Commodore64\Cartridge.cs" />
<Compile Include="Computers\Commodore64\CartridgeMappers.cs" />
<Compile Include="Computers\Commodore64\Cia.cs" />

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -113,7 +113,13 @@ namespace BizHawk.Emulation.Computers.Commodore64
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>(1);
domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func<int, byte>(PeekMemoryInt), new Action<int,byte>(PokeMemoryInt))); //TODO
domains.Add(new MemoryDomain("Memory", 0x10000, Endian.Little, new Func<int, byte>(PeekMemoryInt), new Action<int, byte>(PokeMemoryInt)));
domains.Add(new MemoryDomain("RAM", 0x10000, Endian.Little, new Func<int, byte>(PeekRAM), new Action<int, byte>(PokeRAM)));
domains.Add(new MemoryDomain("CIA0", 0x10, Endian.Little, new Func<int, byte>(PeekCia0), new Action<int, byte>(PokeCia0)));
domains.Add(new MemoryDomain("CIA1", 0x10, Endian.Little, new Func<int, byte>(PeekCia1), new Action<int, byte>(PokeCia1)));
domains.Add(new MemoryDomain("SID", 0x20, Endian.Little, new Func<int, byte>(PeekSid), new Action<int, byte>(PokeSid)));
domains.Add(new MemoryDomain("VIC", 0x40, Endian.Little, new Func<int, byte>(PeekVic), new Action<int, byte>(PokeVic)));
domains.Add(new MemoryDomain("CRAM", 0x400, Endian.Little, new Func<int, byte>(PeekColorRAM), new Action<int, byte>(PokeColorRAM)));
memoryDomains = domains.AsReadOnly();
}

View File

@ -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<bool> ReadSerial;
public Action<bool> 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;

View File

@ -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;

View File

@ -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

View File

@ -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<int> 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)