commodore64: more timer functionality added to VIA, memory domains added for VIA chips in 1541 drive
This commit is contained in:
parent
5b701a58e9
commit
fff3b623e8
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue