commodore64: more timer functionality added to VIA, memory domains added for VIA chips in 1541 drive

This commit is contained in:
saxxonpike 2012-11-16 09:23:34 +00:00
parent 5b701a58e9
commit fff3b623e8
7 changed files with 228 additions and 27 deletions

View File

@ -73,6 +73,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
SetRPM(300.0);
// attach VIA/CIA
via0.Connect(cia.ConnectSerialPort(1));
// set VIA values
via0.Poke(0x0, 0x07);
@ -118,6 +119,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
return 0xFF;
}
public byte PeekVia0(int addr)
{
return via0.Peek(addr);
}
public byte PeekVia1(int addr)
{
return via1.Peek(addr);
}
public void PerformCycle()
{
cpu.IRQ = via0.IRQ | via1.IRQ;
@ -143,6 +154,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
}
public void PokeVia0(int addr, byte val)
{
via0.Poke(addr, val);
}
public void PokeVia1(int addr, byte val)
{
via1.Poke(addr, val);
}
public byte Read(ushort addr)
{
if (addr < 0x0800)

View File

@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public byte PeekColorRAM(int addr)
{
return (byte)((mem.colorRam[addr & 0x3FF] & 0xF) | mem.busData);
return (byte)(mem.colorRam[addr & 0x3FF] & 0xF);
}
public byte PeekDiskDrive(int addr)
@ -49,6 +49,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
return sid.regs[addr];
}
public byte PeekVia0(int addr)
{
if (diskDriveAttached)
return diskDrive.PeekVia0(addr);
return 0xFF;
}
public byte PeekVia1(int addr)
{
if (diskDriveAttached)
return diskDrive.PeekVia1(addr);
return 0xFF;
}
public byte PeekVic(int addr)
{
return vic.regs[addr];
@ -90,6 +104,18 @@ namespace BizHawk.Emulation.Computers.Commodore64
sid.Poke(addr, val);
}
public void PokeVia0(int addr, byte val)
{
if (diskDriveAttached)
diskDrive.PokeVia0(addr, val);
}
public void PokeVia1(int addr, byte val)
{
if (diskDriveAttached)
diskDrive.PokeVia1(addr, val);
}
public void PokeVic(int addr, byte val)
{
vic.Poke(addr, val);

View File

@ -125,6 +125,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
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)));
domains.Add(new MemoryDomain("DISKRAM", 0x10000, Endian.Little, new Func<int, byte>(PeekDiskDrive), new Action<int, byte>(PokeDiskDrive)));
domains.Add(new MemoryDomain("DISKVIA0", 0x10, Endian.Little, new Func<int, byte>(PeekVia0), new Action<int, byte>(PokeVia0)));
domains.Add(new MemoryDomain("DISKVIA1", 0x10, Endian.Little, new Func<int, byte>(PeekVia1), new Action<int, byte>(PokeVia1)));
memoryDomains = domains.AsReadOnly();
}

View File

@ -342,6 +342,14 @@ namespace BizHawk.Emulation.Computers.Commodore64
return regs.ports[index].Connect();
}
public DataPortConnector ConnectSerialPort(int index)
{
DataPortConnector result = regs.ports[index].Connect();
regs.ports[index].AttachInputConverter(result, new DataPortSerialInputConverter());
regs.ports[index].AttachOutputConverter(result, new DataPortSerialOutputConverter());
return result;
}
public void HardReset()
{
outputBitMask = new byte[] { 0x40, 0x80 };

View File

@ -25,8 +25,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
outputConverters[0] = new DataPortConverter();
outputConverters[1] = new DataPortConverter();
connectors = new DataPortConnector[2];
connectors[0] = new DataPortConnector(ReadData0, ReadDirection0, ReadRemoteData0, WriteData0, WriteDirection0);
connectors[1] = new DataPortConnector(ReadData1, ReadDirection1, ReadRemoteData1, WriteData1, WriteDirection1);
connectors[0] = new DataPortConnector(ReadData0, ReadDirection0, ReadLatch0, ReadRemoteLatch0, WriteData0, WriteDirection0);
connectors[1] = new DataPortConnector(ReadData1, ReadDirection1, ReadLatch1, ReadRemoteLatch1, WriteData1, WriteDirection1);
connected[0] = false;
connected[1] = false;
direction[0] = 0x00;
@ -168,12 +168,22 @@ namespace BizHawk.Emulation.Computers.Commodore64
return direction[1];
}
protected virtual byte ReadRemoteData0()
protected virtual byte ReadLatch0()
{
return latch[0];
}
protected virtual byte ReadLatch1()
{
return latch[1];
}
protected virtual byte ReadRemoteData1()
protected virtual byte ReadRemoteLatch0()
{
return latch[1];
}
protected virtual byte ReadRemoteLatch1()
{
return latch[0];
}
@ -213,24 +223,37 @@ namespace BizHawk.Emulation.Computers.Commodore64
{
private Func<byte> ReadData;
private Func<byte> ReadDirection;
private Func<byte> ReadRemoteData;
private Func<byte> ReadLatch;
private Func<byte> ReadRemoteLatch;
private Action<byte> WriteData;
private Action<byte> WriteDirection;
public DataPortConnector()
{
ReadData = ReadDataDummy;
ReadDirection = ReadDataDummy;
ReadLatch = ReadDataDummy;
ReadRemoteLatch = ReadDataDummy;
WriteData = WriteDataDummy;
WriteDirection = WriteDataDummy;
}
public DataPortConnector(DataPortConnector source)
{
ReadData = source.ReadData;
ReadDirection = source.ReadDirection;
ReadRemoteData = source.ReadRemoteData;
ReadLatch = source.ReadLatch;
ReadRemoteLatch = source.ReadRemoteLatch;
WriteData = source.WriteData;
WriteDirection = source.WriteDirection;
}
public DataPortConnector(Func<byte> newReadData, Func<byte> newReadDirection, Func<byte> newReadRemoteData, Action<byte> newWriteData, Action<byte> newWriteDirection)
public DataPortConnector(Func<byte> newReadData, Func<byte> newReadDirection, Func<byte> newReadLatch, Func<byte> newReadRemoteLatch, Action<byte> newWriteData, Action<byte> newWriteDirection)
{
ReadData = newReadData;
ReadDirection = newReadDirection;
ReadRemoteData = newReadRemoteData;
ReadLatch = newReadLatch;
ReadRemoteLatch = newReadRemoteLatch;
WriteData = newWriteData;
WriteDirection = newWriteDirection;
}
@ -259,18 +282,36 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
}
public byte Latch
{
get
{
return ReadLatch();
}
}
public DataPortListener Listener()
{
return new DataPortListener(ReadData, ReadDirection);
}
public byte RemoteData
private byte ReadDataDummy()
{
return 0x00;
}
public byte RemoteLatch
{
get
{
return ReadRemoteData();
return ReadRemoteLatch();
}
}
private void WriteDataDummy(byte val)
{
return;
}
}
public class DataPortConverter

View File

@ -65,8 +65,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
result |= controller[keyboardMatrix[row, 5]] ? (byte)0x00 : (byte)0x20;
result |= controller[keyboardMatrix[row, 6]] ? (byte)0x00 : (byte)0x40;
result |= controller[keyboardMatrix[row, 7]] ? (byte)0x00 : (byte)0x80;
if (result != 0xFF)
row = row;
return result;
}
@ -106,14 +104,14 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void WritePortA()
{
// keyboard matrix column select
keyboardColumnData = ports[0].RemoteData;
keyboardColumnData = ports[0].RemoteLatch;
UpdatePortData();
}
public void WritePortB()
{
// keyboard matrix row select
keyboardRowData = ports[1].RemoteData;
keyboardRowData = ports[1].RemoteLatch;
UpdatePortData();
}
}

View File

@ -30,23 +30,14 @@ namespace BizHawk.Emulation.Computers.Commodore64
public int[] TCONTROL = new int[2];
public int[] TL = new int[2];
public DataPortBus[] ports;
private DataPortConnector[] connectors;
public ViaRegs()
{
// power on state
ports = new DataPortBus[2];
ports[0] = new DataPortBus();
ports[1] = new DataPortBus();
connectors = new DataPortConnector[2];
connectors[0] = ports[0].Connect();
connectors[1] = ports[1].Connect();
connectors[0].Data = 0xFF;
connectors[1].Data = 0xFF;
connectors[0].Direction = 0xFF;
connectors[1].Direction = 0xFF;
connectors[0] = new DataPortConnector();
connectors[1] = new DataPortConnector();
}
public byte this[int addr]
@ -210,6 +201,36 @@ namespace BizHawk.Emulation.Computers.Commodore64
break;
}
}
}
public void Connect(DataPortConnector connector, int index)
{
connectors[index] = connector;
}
public bool PB6
{
get
{
return ((connectors[1].Latch & 0x40) != 0);
}
set
{
connectors[1].Data = (byte)((connectors[1].Latch & 0xBF) | (value ? 0x40 : 0x00));
}
}
public bool PB7
{
get
{
return ((connectors[1].Latch & 0x80) != 0);
}
set
{
connectors[1].Data = (byte)((connectors[1].Latch & 0x7F) | (value ? 0x80 : 0x00));
}
}
}
@ -239,6 +260,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
HardReset();
}
public void Connect(DataPortConnector connector)
{
regs.Connect(connector, 1);
}
public void HardReset()
{
regs = new ViaRegs();
@ -260,7 +286,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void PerformCycle()
{
// do stuff
Tick0();
Tick1();
UpdateInterrupts();
}
@ -277,6 +304,18 @@ namespace BizHawk.Emulation.Computers.Commodore64
addr &= 0xF;
switch (addr)
{
case 0x4:
result = regs[0x4];
regs.IT[0] = false;
break;
case 0x8:
result = (byte)(regs.TC[1] & 0xFF);
regs.IT[1] = false;
break;
case 0x9:
result = (byte)(regs.TC[1] >> 8);
regs.IT[1] = false;
break;
case 0xD:
// reading this clears it
result = regs[addr];
@ -290,6 +329,52 @@ namespace BizHawk.Emulation.Computers.Commodore64
return result;
}
private void Tick0()
{
bool underflow = false;
switch (regs.TCONTROL[0] & 0x1)
{
case 0:
if (regs.TC[0] > 0)
{
if (--regs.TC[0] <= 0)
{
regs.IT[0] = true;
underflow = true;
}
}
break;
case 1:
if (--regs.TC[0] <= 0)
{
regs.IT[0] = true;
regs.TC[0] = regs.TL[0];
underflow = true;
}
break;
}
if (underflow)
{
if ((regs.TCONTROL[0] & 0x2) != 0)
{
regs.PB7 = !regs.PB7;
}
}
}
private void Tick1()
{
switch (regs.TCONTROL[1])
{
case 0:
break;
case 1:
break;
}
}
private void UpdateInterrupts()
{
regs.IRQ =
@ -307,6 +392,26 @@ namespace BizHawk.Emulation.Computers.Commodore64
addr &= 0xF;
switch (addr)
{
case 0x4: // write low counter
regs[0x6] = val;
break;
case 0x5: // write high counter
regs[0x4] = regs[0x06];
regs[0x5] = val;
regs[0x7] = val;
regs.IT[0] = false;
break;
case 0x7:
regs[0x7] = val;
regs.IT[0] = false;
break;
case 0x8:
regs.TL[1] = val;
break;
case 0x9:
regs.TC[1] = ((int)val << 8) | regs.TL[1];
regs.IT[1] = false;
break;
default:
regs[addr] = val;
break;