commodore64: Add 6526 2-cycle timer delay, seems to pass more tests now. CPU Dataport inputs on lower 3 bits are always high now, may fix some paging issues. Fix joystick input so that only port A is affected on pure outputs.

This commit is contained in:
saxxonpike 2012-12-01 08:40:08 +00:00
parent 207e974d9e
commit d951094e6d
3 changed files with 63 additions and 14 deletions

View File

@ -97,9 +97,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
inputAdapter0.Data = resultA;
inputAdapter1.Data = resultB;
inputAdapter1.Data = (byte)(joyB & resultB);
inputAdapter0.MaskWrite(joyB);
inputAdapter1.MaskWrite(joyA);
}
}
}

View File

@ -21,6 +21,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private bool pinCharen;
private bool pinLoram;
private bool pinHiram;
private bool pinNMILast;
private byte portDir;
private bool unusedPin0;
private bool unusedPin1;
@ -41,13 +42,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
cpu.WriteMemory = Write;
// configure data port defaults
portDir = 0x2F;
portDir = 0xEF;
SetPortData(0x37);
// todo: verify this value (I only know that unconnected bits fade after a number of cycles)
unusedPinTTLCycles = 40;
unusedPinTTL0 = 0;
unusedPinTTL1 = 0;
// NMI is high on startup (todo: verify)
pinNMILast = true;
}
public void HardReset()
@ -73,7 +77,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
// the 6502 core expects active high
// so we reverse the polarity here
cpu.NMI = !(chips.cia1.IRQ & chips.cartPort.NMI);
bool thisNMI = (chips.cia1.IRQ & chips.cartPort.NMI);
if (!thisNMI && pinNMILast)
cpu.NMI = true;
else
cpu.NMI = false;
pinNMILast = thisNMI;
cpu.IRQ = !(chips.vic.IRQ && chips.cia0.IRQ && chips.cartPort.IRQ);
cpu.ExecuteOne();
}
@ -105,7 +115,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void Poke(int addr, byte val)
{
if (addr == 0x0000)
portDir = val;
SetPortDir(val);
else if (addr == 0x0001)
SetPortData(val);
else
@ -182,7 +192,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
set
{
Console.WriteLine("CPU write DIR: val=" + C64Util.ToBinary(value, 8));
portDir = value;
SetPortDir(value);
}
}
@ -202,6 +212,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
unusedPinTTL1 = unusedPinTTLCycles;
}
private void SetPortDir(byte val)
{
portDir = val;
SetPortData((byte)(PortData | ((byte)~val & 0x1F)));
}
// ------------------------------------
}
}

View File

@ -61,6 +61,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private bool pinFlag;
private bool pinPC;
private byte sr;
private uint[] timerDelay;
private InMode[] timerInMode;
private OutMode[] timerOutMode;
private bool[] timerPortEnable;
@ -82,6 +83,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
chipRegion = region;
enableIntTimer = new bool[2];
intTimer = new bool[2];
timerDelay = new uint[2];
timerInMode = new InMode[2];
timerOutMode = new OutMode[2];
timerPortEnable = new bool[2];
@ -111,8 +113,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
if (timerPulse[1])
portData[1] &= PBOnMask[0];
if (timerDelay[0] == 0)
TimerRun(0);
else
timerDelay[0]--;
if (timerDelay[1] == 0)
TimerRun(1);
else
timerDelay[1]--;
intAlarm |= (
tod[0] == todAlarm[0] &&
tod[1] == todAlarm[1] &&
@ -149,8 +159,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
intTimer[0] = false;
intTimer[1] = false;
sr = 0;
timerPortEnable[0] = false;
timerPortEnable[1] = false;
timerDelay[0] = 0;
timerDelay[1] = 0;
timerInMode[0] = InMode.Phase2;
timerInMode[1] = InMode.Phase2;
timerOn[0] = false;
@ -402,6 +412,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
private byte ReadRegister(ushort addr)
{
byte val = 0x00; //unused pin value
uint timerVal;
switch (addr)
{
@ -418,16 +429,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
val = portDir[1];
break;
case 0x4:
val = (byte)(timer[0] & 0xFF);
timerVal = ReadTimerValue(0);
val = (byte)(timerVal & 0xFF);
break;
case 0x5:
val = (byte)(timer[0] >> 8);
timerVal = ReadTimerValue(0);
val = (byte)(timerVal >> 8);
break;
case 0x6:
val = (byte)(timer[1] & 0xFF);
timerVal = ReadTimerValue(1);
val = (byte)(timerVal & 0xFF);
break;
case 0x7:
val = (byte)(timer[1] >> 8);
timerVal = ReadTimerValue(1);
val = (byte)(timerVal >> 8);
break;
case 0x8:
val = tod[0];
@ -495,6 +510,21 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
return val;
}
private uint ReadTimerValue(uint index)
{
if (timerOn[index])
{
if (timer[index] == 0)
return timerLatch[index];
else
return timer[index];
}
else
{
return timer[index];
}
}
public void Write(ushort addr, byte val)
{
Write(addr, val, 0xFF);
@ -622,6 +652,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
enableIntFlag = intReg;
break;
case 0xE:
if ((val & 0x01) != 0 && !timerOn[0])
timerDelay[0] = 2;
timerOn[0] = ((val & 0x01) != 0);
timerPortEnable[0] = ((val & 0x02) != 0);
timerOutMode[0] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse;
@ -631,6 +663,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
todIn = ((val & 0x80) != 0);
break;
case 0xF:
if ((val & 0x01) != 0 && !timerOn[1])
timerDelay[1] = 2;
timerOn[1] = ((val & 0x01) != 0);
timerPortEnable[1] = ((val & 0x02) != 0);
timerOutMode[1] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse;