commodore64: made some input changes (more fixes to come later), removed some duplication in pin information between PLA, CPU and cartridge port

This commit is contained in:
saxxonpike 2012-11-30 21:12:23 +00:00
parent dca6dfdaeb
commit ae8566a0df
9 changed files with 207 additions and 172 deletions

View File

@ -62,8 +62,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
if (cart != null)
{
chips.cartPort.Connect(cart);
chips.pla.ExRom = chips.cartPort.ExRom;
chips.pla.Game = chips.cartPort.Game;
}
break;
case @".PRG":
@ -163,11 +161,12 @@ namespace BizHawk.Emulation.Computers.Commodore64
cpu = new MOS6510(this);
ram = new Chip4864();
sid = new MOS6581();
pla.UpdatePins();
}
public void ExecutePhase1()
{
pla.UpdatePins();
pla.ExecutePhase1();
cia0.ExecutePhase1();
cia1.ExecutePhase1();
sid.ExecutePhase1();
@ -177,7 +176,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void ExecutePhase2()
{
pla.UpdatePins();
pla.ExecutePhase2();
cia0.ExecutePhase2();
cia1.ExecutePhase2();
sid.ExecutePhase2();
@ -200,4 +199,37 @@ namespace BizHawk.Emulation.Computers.Commodore64
vic.HardReset();
}
}
static public class C64Util
{
static public string ToBinary(uint n, uint charsmin)
{
string result = "";
while (n > 0 || charsmin > 0)
{
result = (((n & 0x1) != 0) ? "1" : "0") + result;
n >>= 1;
if (charsmin > 0)
charsmin--;
}
return result;
}
static public string ToHex(uint n, uint charsmin)
{
string result = "";
while (n > 0 || charsmin > 0)
{
result = "0123456789ABCDEF".Substring((int)(n & 0xF), 1) + result;
n >>= 4;
if (charsmin > 0)
charsmin--;
}
return result;
}
}
}

View File

@ -10,8 +10,29 @@ namespace BizHawk.Emulation.Computers.Commodore64
{
private PortAdapter inputAdapter0;
private PortAdapter inputAdapter1;
private byte[] joystickMatrix = new byte[2];
private byte[] keyboardMatrix = new byte[8];
private bool[,] joystickPressed = new bool[2, 5];
private bool[,] keyboardPressed = new bool[8, 8];
static private string[,] joystickMatrix = new string[2, 5]
{
{"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button"},
{"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button"}
};
static private string[,] keyboardMatrix = new string[8, 8]
{
{"Key Insert/Delete", "Key Return", "Key Cursor Left/Right", "Key F7", "Key F1", "Key F3", "Key F5", "Key Cursor Up/Down"},
{"Key 3", "Key W", "Key A", "Key 4", "Key Z", "Key S", "Key E", "Key Left Shift"},
{"Key 5", "Key R", "Key D", "Key 6", "Key C", "Key F", "Key T", "Key X"},
{"Key 7", "Key Y", "Key G", "Key 8", "Key B", "Key H", "Key U", "Key V"},
{"Key 9", "Key I", "Key J", "Key 0", "Key M", "Key K", "Key O", "Key N"},
{"Key Plus", "Key P", "Key L", "Key Minus", "Key Period", "Key Colon", "Key At", "Key Comma"},
{"Key Pound", "Key Asterisk", "Key Semicolon", "Key Clear/Home", "Key Right Shift", "Key Equal", "Key Up Arrow", "Key Slash"},
{"Key 1", "Key Left Arrow", "Key Control", "Key 2", "Key Space", "Key Commodore", "Key Q", "Key Run/Stop"}
};
static private byte[] inputBitMask = new byte[] { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
static private byte[] inputBitSelect = new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
private void InitInput()
{
@ -21,99 +42,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
private void PollInput()
{
joystickMatrix[0] = 0xFF;
joystickMatrix[0] &= controller["P1 Up"] ? (byte)0xFE : (byte)0xFF;
joystickMatrix[0] &= controller["P1 Down"] ? (byte)0xFD : (byte)0xFF;
joystickMatrix[0] &= controller["P1 Left"] ? (byte)0xFB : (byte)0xFF;
joystickMatrix[0] &= controller["P1 Right"] ? (byte)0xF7 : (byte)0xFF;
joystickMatrix[0] &= controller["P1 Button"] ? (byte)0xEF : (byte)0xFF;
// scan joysticks
for (uint i = 0; i < 2; i++)
{
for (uint j = 0; j < 5; j++)
{
joystickPressed[i, j] = controller[joystickMatrix[i, j]];
}
}
joystickMatrix[1] = 0xFF;
joystickMatrix[1] &= controller["P2 Up"] ? (byte)0xFE : (byte)0xFF;
joystickMatrix[1] &= controller["P2 Down"] ? (byte)0xFD : (byte)0xFF;
joystickMatrix[1] &= controller["P2 Left"] ? (byte)0xFB : (byte)0xFF;
joystickMatrix[1] &= controller["P2 Right"] ? (byte)0xF7 : (byte)0xFF;
joystickMatrix[1] &= controller["P2 Button"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[0] = 0xFF;
keyboardMatrix[0] &= controller["Key Insert/Delete"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[0] &= controller["Key Return"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[0] &= controller["Key Cursor Left/Right"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[0] &= controller["Key F7"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[0] &= controller["Key F1"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[0] &= controller["Key F3"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[0] &= controller["Key F5"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[0] &= controller["Key Cursor Up/Down"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[1] = 0xFF;
keyboardMatrix[1] &= controller["Key 3"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[1] &= controller["Key W"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[1] &= controller["Key A"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[1] &= controller["Key 4"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[1] &= controller["Key Z"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[1] &= controller["Key S"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[1] &= controller["Key E"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[1] &= controller["Key Left Shift"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[2] = 0xFF;
keyboardMatrix[2] &= controller["Key 5"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[2] &= controller["Key R"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[2] &= controller["Key D"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[2] &= controller["Key 6"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[2] &= controller["Key C"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[2] &= controller["Key F"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[2] &= controller["Key T"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[2] &= controller["Key X"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[3] = 0xFF;
keyboardMatrix[3] &= controller["Key 7"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[3] &= controller["Key Y"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[3] &= controller["Key G"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[3] &= controller["Key 8"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[3] &= controller["Key B"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[3] &= controller["Key H"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[3] &= controller["Key U"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[3] &= controller["Key V"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[4] = 0xFF;
keyboardMatrix[4] &= controller["Key 9"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[4] &= controller["Key I"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[4] &= controller["Key J"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[4] &= controller["Key 0"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[4] &= controller["Key M"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[4] &= controller["Key K"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[4] &= controller["Key O"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[4] &= controller["Key N"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[5] = 0xFF;
keyboardMatrix[5] &= controller["Key Plus"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[5] &= controller["Key P"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[5] &= controller["Key L"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[5] &= controller["Key Minus"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[5] &= controller["Key Period"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[5] &= controller["Key Colon"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[5] &= controller["Key At"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[5] &= controller["Key Comma"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[6] = 0xFF;
keyboardMatrix[6] &= controller["Key Pound"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Asterisk"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Semicolon"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Clear/Home"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Right Shift"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Equal"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Up Arrow"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[6] &= controller["Key Slash"] ? (byte)0x7F : (byte)0xFF;
keyboardMatrix[7] = 0xFF;
keyboardMatrix[7] &= controller["Key 1"] ? (byte)0xFE : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Left Arrow"] ? (byte)0xFD : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Control"] ? (byte)0xFB : (byte)0xFF;
keyboardMatrix[7] &= controller["Key 2"] ? (byte)0xF7 : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Space"] ? (byte)0xEF : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Commodore"] ? (byte)0xDF : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Q"] ? (byte)0xBF : (byte)0xFF;
keyboardMatrix[7] &= controller["Key Run/Stop"] ? (byte)0x7F : (byte)0xFF;
// scan keyboard
for (uint i = 0; i < 8; i++)
{
for (uint j = 0; j < 8; j++)
{
keyboardPressed[i, j] = controller[keyboardMatrix[i, j]];
}
}
}
private void WriteInputPort()
@ -123,29 +68,34 @@ namespace BizHawk.Emulation.Computers.Commodore64
byte portA = inputAdapter0.Data;
byte portB = inputAdapter1.Data;
byte resultA = 0xFF;
byte resultB = 0xFF;
if ((portA & 0x01) == 0)
portB &= keyboardMatrix[0];
if ((portA & 0x02) == 0)
portB &= keyboardMatrix[1];
if ((portA & 0x04) == 0)
portB &= keyboardMatrix[2];
if ((portA & 0x08) == 0)
portB &= keyboardMatrix[3];
if ((portA & 0x10) == 0)
portB &= keyboardMatrix[4];
if ((portA & 0x20) == 0)
portB &= keyboardMatrix[5];
if ((portA & 0x40) == 0)
portB &= keyboardMatrix[6];
if ((portA & 0x80) == 0)
portB &= keyboardMatrix[7];
for (uint i = 0; i < 5; i++)
{
if (joystickPressed[1, i])
resultA &= inputBitMask[i];
if (joystickPressed[0, i])
resultB &= inputBitMask[i];
}
portA &= joystickMatrix[1];
portB &= joystickMatrix[0];
for (uint i = 0; i < 8; i++)
{
for (uint j = 0; j < 8; j++)
{
if (keyboardPressed[i, j])
{
if (((portA & inputBitSelect[i]) == 0) || ((portB & inputBitSelect[j]) == 0))
{
resultA &= inputBitMask[i];
resultB &= inputBitMask[j];
}
}
}
}
inputAdapter0.Data = portA;
inputAdapter1.Data = portB;
inputAdapter0.ForceWrite((byte)(resultA & portB));
inputAdapter1.Data = resultB;
}
}
}

View File

@ -21,6 +21,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridges
pinExRom = exrom;
validCartridge = true;
// default to empty banks
romA = new byte[1];
romB = new byte[1];
romA[0] = 0xFF;
romB[0] = 0xFF;
for (int i = 0; i < newAddresses.Count; i++)
{

View File

@ -123,7 +123,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
portDir = val;
else if (addr == 0x0001)
SetPortData(val);
chips.pla.Poke(addr, val);
else
chips.pla.Poke(addr, val);
}
public byte Read(ushort addr)
@ -156,11 +157,26 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
get { return pinAEC; }
}
public bool Charen
{
get { return pinCharen; }
}
public bool HiRam
{
get { return pinHiram; }
}
public bool IRQ
{
get { return pinIRQ; }
}
public bool LoRam
{
get { return pinLoram; }
}
public bool NMI
{
get { return pinNMI; }
@ -190,6 +206,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
set
{
byte val = Port.CPUWrite(PortData, value, portDir);
Console.WriteLine("CPU write DTA: val=" + C64Util.ToBinary(value, 8) + " dir=" + C64Util.ToBinary(portDir, 8) + " new=" + C64Util.ToBinary(val, 8));
SetPortData(val);
}
}
@ -197,7 +214,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public byte PortDirection
{
get { return portDir; }
set { portDir = value; }
set
{
Console.WriteLine("CPU write DIR: val=" + C64Util.ToBinary(value, 8));
portDir = value;
}
}
private void SetPortData(byte val)
@ -206,15 +227,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
pinCassetteButton = ((val & 0x10) != 0);
pinCassetteMotor = ((val & 0x20) != 0);
if (!chips.pla.UltimaxMode)
{
pinLoram = ((val & 0x01) != 0);
pinHiram = ((val & 0x02) != 0);
pinCharen = ((val & 0x04) != 0);
chips.pla.LoRam = pinLoram;
chips.pla.HiRam = pinHiram;
chips.pla.Charen = pinCharen;
}
pinLoram = ((val & 0x01) != 0);
pinHiram = ((val & 0x02) != 0);
pinCharen = ((val & 0x04) != 0);
unusedPin0 = ((val & 0x40) != 0);
unusedPin1 = ((val & 0x80) != 0);

View File

@ -237,12 +237,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
u = (t == 0);
t--;
intTimer[index] |= (t == 0);
}
break;
case InMode.Phase2:
// every clock
u = (t == 0);
t--;
intTimer[index] |= (t == 0);
break;
case InMode.TimerAUnderflow:
// every underflow[0]
@ -250,6 +252,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
u = (t == 0);
t--;
intTimer[index] |= (t == 0);
}
break;
case InMode.TimerAUnderflowCNT:
@ -258,6 +261,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
u = (t == 0);
t--;
intTimer[index] |= (t == 0);
}
break;
}
@ -284,8 +288,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
break;
}
}
intTimer[index] = true;
}
underflow[index] = u;

View File

@ -47,53 +47,69 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private C64Chips chips;
private bool cia0portRead;
private PLACpuMap map;
private bool pinCharen;
private bool pinExRom;
private bool pinGame;
private bool pinHiRam;
private bool pinLoRam;
private bool pinCharenLast;
private bool pinExRomLast;
private bool pinGameLast;
private bool pinHiRamLast;
private bool pinLoRamLast;
private bool ultimax;
private ushort vicBank;
public MOSPLA(C64Chips newChips)
{
chips = newChips;
pinExRom = true;
pinGame = true;
}
public void HardReset()
{
pinCharen = true;
pinHiRam = true;
pinLoRam = true;
UpdateMap();
}
// ------------------------------------
public void ExecutePhase1()
{
UpdatePins();
}
public void ExecutePhase2()
{
UpdatePins();
}
public void UpdatePins()
{
if ((ExRom != pinExRomLast) || (Game != pinGameLast) || (LoRam != pinLoRamLast) || (HiRam != pinHiRamLast) || (Charen != pinCharenLast))
{
UpdateMap();
pinExRomLast = ExRom;
pinGameLast = Game;
pinLoRamLast = LoRam;
pinHiRamLast = HiRam;
pinCharenLast = Charen;
}
}
// ------------------------------------
public bool Charen
{
get { return pinCharen; }
set { if (pinCharen != value) { pinCharen = value; UpdateMap(); } }
get { return chips.cpu.Charen; }
}
public bool ExRom
{
get { return pinExRom; }
set { if (pinExRom != value) { pinExRom = value; UpdateMap(); } }
get { return chips.cartPort.ExRom; }
}
public bool Game
{
get { return pinGame; }
set { if (pinGame != value) { pinGame = value; UpdateMap(); } }
get { return chips.cartPort.Game; }
}
public bool HiRam
{
get { return pinHiRam; }
set { if (pinHiRam != value) { pinHiRam = value; UpdateMap(); } }
get { return chips.cpu.HiRam; }
}
public bool InputWasRead
@ -104,17 +120,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public bool LoRam
{
get { return pinLoRam; }
set { if (pinLoRam != value) { pinLoRam = value; UpdateMap(); } }
get { return chips.cpu.LoRam; }
}
public bool UltimaxMode
{
get { return ultimax; }
get { return (!Game && ExRom); }
}
private void UpdateMap()
{
bool pinGame = Game;
bool pinExRom = ExRom;
bool pinCharen = Charen;
bool pinHiRam = HiRam;
bool pinLoRam = LoRam;
ultimax = false;
if (pinCharen && pinHiRam && pinLoRam && pinGame && pinExRom)
{
@ -303,15 +324,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
}
public void UpdatePins()
{
// called after all cartridge routines in case
// game/exrom configuration changes
Game = chips.cartPort.Game;
ExRom = chips.cartPort.ExRom;
}
// ------------------------------------
private PLABank Bank(ushort addr)

View File

@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
static public byte CPUWrite(byte latch, byte val, byte dir)
{
byte result;
result = (byte)(latch & ~dir);
result = (byte)(latch & (byte)(~dir & 0xFF));
result |= (byte)(val & dir);
return result;
}
@ -19,25 +19,27 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
byte result;
result = (byte)(latch & dir);
result |= (byte)(val & ~dir);
result |= (byte)(val & (byte)(~dir & 0xFF));
return result;
}
static public PortAdapter GetAdapter(Func<byte> newRead, Action<byte> newWrite)
static public PortAdapter GetAdapter(Func<byte> newRead, Action<byte> newWrite, Action<byte> newWriteForce)
{
return new PortAdapter(newRead, newWrite);
return new PortAdapter(newRead, newWrite, newWriteForce);
}
}
public class PortAdapter
{
private Action<byte> actWrite;
private Action<byte> actWriteForce;
private Func<byte> funcRead;
public PortAdapter(Func<byte> newRead, Action<byte> newWrite)
public PortAdapter(Func<byte> newRead, Action<byte> newWrite, Action<byte> newWriteForce)
{
funcRead = newRead;
actWrite = newWrite;
actWriteForce = newWriteForce;
}
public byte Data
@ -51,5 +53,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
actWrite(value);
}
}
public void ForceWrite(byte val)
{
actWriteForce(val);
}
}
}

View File

@ -265,8 +265,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private uint waveform;
private uint[][] waveTable;
public Voice()
public Voice(uint[][] newWaveTable)
{
waveTable = newWaveTable;
HardReset();
}
@ -576,7 +577,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
voices = new Voice[3];
for (int i = 0; i < 3; i++)
voices[i] = new Voice();
voices[i] = new Voice(newWaveformTable);
voiceOutput = new uint[3];
filterEnable = new bool[3];
@ -649,7 +650,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public byte Read(ushort addr)
{
byte result = 0xFF;
byte result = 0x00;
switch (addr)
{
case 0x19:
@ -664,7 +665,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private byte ReadRegister(ushort addr)
{
byte result = 0xFF;
byte result = 0x00;
switch (addr)
{

View File

@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
get
{
return Port.GetAdapter(ReadPort0, ExternalWritePort0);
return Port.GetAdapter(ReadPort0, ExternalWritePort0, ExternalWriteForce0);
}
}
@ -39,10 +39,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
get
{
return Port.GetAdapter(ReadPort1, ExternalWritePort1);
return Port.GetAdapter(ReadPort1, ExternalWritePort1, ExternalWriteForce1);
}
}
private void ExternalWriteForce0(byte data)
{
portData[0] = data;
}
private void ExternalWriteForce1(byte data)
{
portData[1] = data;
}
private void ExternalWritePort(uint index, byte data)
{
portData[index] = Port.ExternalWrite(portData[index], data, portDir[index]);