commodore64: implement more c64-disk communications, hook up drive LED
This commit is contained in:
parent
38adb50a10
commit
e4ff87e92a
|
@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
byte[] diskRom = File.ReadAllBytes(diskPath);
|
||||
|
||||
disk = new VIC1541(initRegion, diskRom);
|
||||
disk.Connect(board.serPort);
|
||||
}
|
||||
|
||||
private void InitMedia()
|
||||
|
@ -84,7 +85,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
string basicFile = "basic";
|
||||
string charFile = "chargen";
|
||||
string kernalFile = "kernal";
|
||||
string diskFile = "dos1541";
|
||||
|
||||
string basicPath = Path.Combine(sourceFolder, basicFile);
|
||||
string charPath = Path.Combine(sourceFolder, charFile);
|
||||
|
@ -109,7 +109,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
return (disk.PeekVia1(0x00) & 0x08) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,8 +151,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
cia1.ReadPortB = (() => { return cia1DataB; });
|
||||
cia1.WriteDirA = ((byte val) => { cia1DirA = val; });
|
||||
cia1.WriteDirB = ((byte val) => { cia1DirB = val; });
|
||||
cia1.WritePortA = ((byte val) => { cia1DataA = Port.CPUWrite(cia1DataA, val, cia1DirA); UpdateVicBank(); });
|
||||
cia1.WritePortB = ((byte val) => { cia1DataB = Port.CPUWrite(cia1DataB, val, cia1DirB); });
|
||||
cia1.WritePortA = ((byte val) => {
|
||||
cia1DataA = Port.CPUWrite(cia1DataA, val, cia1DirA);
|
||||
UpdateVicBank();
|
||||
serPort.SystemWriteAtn((cia1DataA & 0x08) == 0);
|
||||
serPort.SystemWriteClock((cia1DataA & 0x10) == 0);
|
||||
serPort.SystemWriteData((cia1DataA & 0x20) == 0);
|
||||
});
|
||||
cia1.WritePortB = ((byte val) => {
|
||||
cia1DataB = Port.CPUWrite(cia1DataB, val, cia1DirB);
|
||||
});
|
||||
|
||||
cpu.PeekMemory = pla.Peek;
|
||||
cpu.PokeMemory = pla.Poke;
|
||||
|
|
|
@ -79,14 +79,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.Disk
|
|||
public MOS6522 via0;
|
||||
public MOS6522 via1;
|
||||
|
||||
public byte via0dirA;
|
||||
public byte via0dirB;
|
||||
public byte via0portA;
|
||||
public byte via0portB;
|
||||
public byte via1dirA;
|
||||
public byte via1dirB;
|
||||
public byte via1portA;
|
||||
public byte via1portB;
|
||||
public bool via0CA0;
|
||||
public bool via0CA1;
|
||||
public bool via0CB0;
|
||||
public bool via0CB1;
|
||||
public byte via0DataA;
|
||||
public byte via0DataB;
|
||||
public byte via0DirA;
|
||||
public byte via0DirB;
|
||||
public bool via1CA0;
|
||||
public bool via1CA1;
|
||||
public bool via1CB0;
|
||||
public bool via1CB1;
|
||||
public byte via1DataA;
|
||||
public byte via1DataB;
|
||||
public byte via1DirA;
|
||||
public byte via1DirB;
|
||||
|
||||
public VIC1541Motherboard(Region initRegion, byte[] initRom)
|
||||
{
|
||||
|
@ -119,28 +127,97 @@ namespace BizHawk.Emulation.Computers.Commodore64.Disk
|
|||
pla.WriteVia0 = via0.Write;
|
||||
pla.WriteVia1 = via1.Write;
|
||||
|
||||
via0dirA = 0x00;
|
||||
via0dirB = 0x00;
|
||||
via0portA = 0xFF;
|
||||
via0portB = 0xFF;
|
||||
via1dirA = 0x00;
|
||||
via1dirB = 0x00;
|
||||
via1portA = 0xFF;
|
||||
via1portB = 0xFF;
|
||||
via0CA0 = false;
|
||||
via0CA1 = false;
|
||||
via0CB0 = false;
|
||||
via0CB1 = false;
|
||||
via0DirA = 0x00;
|
||||
via0DirB = 0x00;
|
||||
via0DataA = 0xFF;
|
||||
via0DataB = 0xFF;
|
||||
via1CA0 = false;
|
||||
via1CA1 = false;
|
||||
via1CB0 = false;
|
||||
via1CB1 = false;
|
||||
via1DirA = 0x00;
|
||||
via1DirB = 0x00;
|
||||
via1DataA = 0xFF;
|
||||
via1DataB = 0xFF;
|
||||
|
||||
via0.ReadCA0 = (() => { return via0CA0; });
|
||||
via0.ReadCA1 = (() => { return via0CA1; });
|
||||
via0.ReadCB0 = (() => { return via0CB0; });
|
||||
via0.ReadCB1 = (() => { return via0CB1; });
|
||||
via0.ReadDirA = (() => { return via0DirA; });
|
||||
via0.ReadDirB = (() => { return via0DirB; });
|
||||
via0.ReadPortA = (() => { return via0DataA; });
|
||||
via0.ReadPortB = (() => { return via0DataB; });
|
||||
via0.WriteCA0 = ((bool val) => { via0CA0 = val; });
|
||||
via0.WriteCA1 = ((bool val) => { via0CA1 = val; });
|
||||
via0.WriteCB0 = ((bool val) => { via0CB0 = val; });
|
||||
via0.WriteCB1 = ((bool val) => { via0CB1 = val; });
|
||||
via0.WriteDirA = ((byte val) => { via0DirA = val; });
|
||||
via0.WriteDirB = ((byte val) => { via0DirB = val; });
|
||||
via0.WritePortA = ((byte val) => {
|
||||
via0DataA = Port.CPUWrite(via0DataA, val, via0DirA);
|
||||
});
|
||||
via0.WritePortB = ((byte val) => {
|
||||
via0DataB = Port.CPUWrite(via0DataB, val, via0DirB);
|
||||
serPort.DeviceWriteAtn((via0DataB & 0x80) != 0);
|
||||
serPort.DeviceWriteClock((via0DataB & 0x08) != 0);
|
||||
serPort.DeviceWriteData((via0DataB & 0x02) != 0);
|
||||
});
|
||||
|
||||
via1.ReadCA0 = (() => { return via1CA0; });
|
||||
via1.ReadCA1 = (() => { return via1CA1; });
|
||||
via1.ReadCB0 = (() => { return via1CB0; });
|
||||
via1.ReadCB1 = (() => { return via1CB1; });
|
||||
via1.ReadDirA = (() => { return via1DirA; });
|
||||
via1.ReadDirB = (() => { return via1DirB; });
|
||||
via1.ReadPortA = (() => { return via1DataA; });
|
||||
via1.ReadPortB = (() => { return via1DataB; });
|
||||
via1.WriteCA0 = ((bool val) => { via1CA0 = val; });
|
||||
via1.WriteCA1 = ((bool val) => { via1CA1 = val; });
|
||||
via1.WriteCB0 = ((bool val) => { via1CB0 = val; });
|
||||
via1.WriteCB1 = ((bool val) => { via1CB1 = val; });
|
||||
via1.WriteDirA = ((byte val) => { via1DirA = val; });
|
||||
via1.WriteDirB = ((byte val) => { via1DirB = val; });
|
||||
via1.WritePortA = ((byte val) => { via1DataA = Port.CPUWrite(via1DataA, val, via1DirA); });
|
||||
via1.WritePortB = ((byte val) => { via1DataB = Port.CPUWrite(via1DataB, val, via1DirB); });
|
||||
}
|
||||
|
||||
public void Connect(SerialPort newSerPort)
|
||||
{
|
||||
// TODO: verify polarity
|
||||
serPort = newSerPort;
|
||||
serPort.SystemReadAtn = (() => { return true; });
|
||||
serPort.SystemReadClock = (() => { return ((via0portB & 0x8) != 0); }); // bit 3
|
||||
serPort.SystemReadData = (() => { return ((via0portB & 0x2) != 0); }); // bit 1
|
||||
serPort.SystemReadSrq = (() => { return true; });
|
||||
serPort.SystemWriteAtn = ((bool val) => { via0portB = Port.ExternalWrite(via0portB, (byte)((via0portB & 0x7F) | (val ? 0x80 : 0x00)), via0dirB); });
|
||||
serPort.SystemWriteClock = ((bool val) => { via0portB = Port.ExternalWrite(via0portB, (byte)((via0portB & 0xFB) | (val ? 0x04 : 0x00)), via0dirB); });
|
||||
serPort.SystemWriteData = ((bool val) => { via0portB = Port.ExternalWrite(via0portB, (byte)((via0portB & 0xFE) | (val ? 0x01 : 0x00)), via0dirB); });
|
||||
serPort.SystemReadAtn = (() => {
|
||||
return true;
|
||||
});
|
||||
serPort.SystemReadClock = (() => {
|
||||
return ((via0DataB & 0x08) != 0);
|
||||
}); // bit 3
|
||||
serPort.SystemReadData = (() => {
|
||||
return ((via0DataB & 0x02) != 0);
|
||||
}); // bit 1
|
||||
serPort.SystemReadSrq = (() => {
|
||||
return false;
|
||||
}); // device sensing
|
||||
serPort.SystemWriteAtn = ((bool val) => {
|
||||
via0DataB = Port.ExternalWrite(via0DataB, (byte)((via0DataB & 0x7F) | (val ? 0x80 : 0x00)), via0DataB);
|
||||
via0CA0 = val;
|
||||
// repeat to DATA OUT if bit 4 enabled on port B
|
||||
if ((via0DataB & 0x10) != 0)
|
||||
serPort.DeviceWriteData(val);
|
||||
});
|
||||
serPort.SystemWriteClock = ((bool val) => {
|
||||
via0DataB = Port.ExternalWrite(via0DataB, (byte)((via0DataB & 0xFB) | (val ? 0x04 : 0x00)), via0DataB);
|
||||
});
|
||||
serPort.SystemWriteData = ((bool val) => {
|
||||
via0DataB = Port.ExternalWrite(via0DataB, (byte)((via0DataB & 0xFE) | (val ? 0x01 : 0x00)), via0DataB);
|
||||
});
|
||||
serPort.SystemWriteReset = ((bool val) => { });
|
||||
|
||||
serPort.DeviceWriteSrq(false);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
|
@ -148,6 +225,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Disk
|
|||
via0.ExecutePhase1();
|
||||
via1.ExecutePhase1();
|
||||
|
||||
cpu.IRQ = !(via0.IRQ && via1.IRQ);
|
||||
cpu.ExecuteOne();
|
||||
via0.ExecutePhase2();
|
||||
via1.ExecutePhase2();
|
||||
|
@ -158,6 +236,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Disk
|
|||
for (uint i = 0; i < 0x7FF; i++)
|
||||
ram[i] = 0x00;
|
||||
cpu.PC = (ushort)(cpu.ReadMemory(0xFFFC) | ((ushort)cpu.ReadMemory(0xFFFD) << 8));
|
||||
via0.HardReset();
|
||||
via1.HardReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,18 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
private const uint pcrControlLow = 6;
|
||||
private const uint pcrControlHigh = 7;
|
||||
|
||||
private const uint tControlLoad = 0;
|
||||
private const uint tControlContinuous = 1;
|
||||
private const uint tControlLoadPB = 2;
|
||||
private const uint tControlContinuousPB = 3;
|
||||
private const uint tControlPulseCounter = 4;
|
||||
|
||||
private static byte[] portBit = new byte[] { 0x80, 0x40 };
|
||||
private static byte[] portMask = new byte[] { 0x7F, 0xBF };
|
||||
|
||||
private uint acrShiftMode;
|
||||
private bool caPulse;
|
||||
private bool cbPulse;
|
||||
private bool[] enableIrqCA;
|
||||
private bool[] enableIrqCB;
|
||||
private bool enableIrqSR;
|
||||
|
@ -35,18 +46,32 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
private bool[] irqCB;
|
||||
private bool irqSR;
|
||||
private bool[] irqT;
|
||||
private bool[] lastca;
|
||||
private bool[] lastcb;
|
||||
private byte lastpb;
|
||||
private byte paLatch;
|
||||
private byte pbLatch;
|
||||
private bool paLatchEnable;
|
||||
private bool pbLatchEnable;
|
||||
private byte paOut;
|
||||
private byte pbOut;
|
||||
private bool[] pbPulse;
|
||||
private uint[] pcrControlA;
|
||||
private uint[] pcrControlB;
|
||||
private byte sr;
|
||||
private uint srControl;
|
||||
private uint srCounter;
|
||||
private uint[] tControl;
|
||||
|
||||
public Func<bool> ReadCA0;
|
||||
public Func<bool> ReadCA1;
|
||||
public Func<bool> ReadCB0;
|
||||
public Func<bool> ReadCB1;
|
||||
public Action<bool> WriteCA0;
|
||||
public Action<bool> WriteCA1;
|
||||
public Action<bool> WriteCB0;
|
||||
public Action<bool> WriteCB1;
|
||||
|
||||
public MOS6522()
|
||||
{
|
||||
enableIrqCA = new bool[2];
|
||||
|
@ -55,6 +80,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
irqCA = new bool[2];
|
||||
irqCB = new bool[2];
|
||||
irqT = new bool[2];
|
||||
lastca = new bool[2];
|
||||
lastcb = new bool[2];
|
||||
pbPulse = new bool[2];
|
||||
pcrControlA = new uint[2];
|
||||
pcrControlB = new uint[2];
|
||||
tControl = new uint[2];
|
||||
|
@ -63,6 +91,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
public void HardReset()
|
||||
{
|
||||
acrShiftMode = 0;
|
||||
caPulse = false;
|
||||
cbPulse = false;
|
||||
enableIrqCA[0] = false;
|
||||
enableIrqCA[1] = false;
|
||||
enableIrqCB[0] = false;
|
||||
|
@ -77,12 +107,19 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
irqSR = false;
|
||||
irqT[0] = false;
|
||||
irqT[1] = false;
|
||||
lastca[0] = ReadCA0();
|
||||
lastca[1] = ReadCA1();
|
||||
lastcb[0] = ReadCB0();
|
||||
lastcb[1] = ReadCB1();
|
||||
pbPulse[0] = false;
|
||||
pbPulse[1] = false;
|
||||
pcrControlA[0] = 0;
|
||||
pcrControlA[1] = 0;
|
||||
pcrControlB[0] = 0;
|
||||
pcrControlB[1] = 0;
|
||||
tControl[0] = 0;
|
||||
tControl[1] = 0;
|
||||
HardResetInternal();
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
@ -93,10 +130,185 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
public void ExecutePhase2()
|
||||
{
|
||||
pinIRQ = !(irqCA[0] | irqCA[1] |
|
||||
irqCB[0] | irqCB[1] |
|
||||
irqSR | irqT[0] | irqT[1]
|
||||
bool ca0 = ReadCA0();
|
||||
bool ca1 = ReadCA1();
|
||||
bool cb0 = ReadCB0();
|
||||
bool cb1 = ReadCB1();
|
||||
bool ca0Trans = (lastca[0] != ca0);
|
||||
bool ca1Trans = (lastca[1] != ca1);
|
||||
bool cb0Trans = (lastcb[0] != cb0);
|
||||
bool cb1Trans = (lastcb[1] != cb1);
|
||||
|
||||
// edge triggered interrupts
|
||||
|
||||
switch (pcrControlA[0])
|
||||
{
|
||||
case pcrControlInNegative:
|
||||
if (lastca[0] && !ca0)
|
||||
irqCA[0] = true;
|
||||
break;
|
||||
case pcrControlInPositive:
|
||||
if (!lastca[0] && ca0)
|
||||
irqCA[0] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pcrControlB[0])
|
||||
{
|
||||
case pcrControlInNegative:
|
||||
if (lastcb[0] && !cb0)
|
||||
irqCB[0] = true;
|
||||
break;
|
||||
case pcrControlInPositive:
|
||||
if (!lastcb[0] && cb0)
|
||||
irqCB[0] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pcrControlA[1])
|
||||
{
|
||||
case pcrControlInNegative:
|
||||
case pcrControlInNegativeIndep:
|
||||
if (lastca[1] && !ca1)
|
||||
irqCA[1] = true;
|
||||
break;
|
||||
case pcrControlInPositive:
|
||||
case pcrControlInPositiveIndep:
|
||||
if (!lastca[1] && ca1)
|
||||
irqCA[1] = true;
|
||||
break;
|
||||
case pcrControlHandshake:
|
||||
if (lastca[0] != ca0)
|
||||
WriteCA1(true);
|
||||
break;
|
||||
case pcrControlPulse:
|
||||
if (caPulse)
|
||||
caPulse = false;
|
||||
else
|
||||
WriteCA1(true);
|
||||
break;
|
||||
case pcrControlLow:
|
||||
WriteCA1(false);
|
||||
break;
|
||||
case pcrControlHigh:
|
||||
WriteCA1(true);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pcrControlB[1])
|
||||
{
|
||||
case pcrControlInNegative:
|
||||
case pcrControlInNegativeIndep:
|
||||
if (lastcb[1] && !cb1)
|
||||
irqCB[1] = true;
|
||||
break;
|
||||
case pcrControlInPositive:
|
||||
case pcrControlInPositiveIndep:
|
||||
if (!lastcb[1] && cb1)
|
||||
irqCB[1] = true;
|
||||
break;
|
||||
case pcrControlHandshake:
|
||||
if (lastcb[0] != cb0)
|
||||
WriteCB1(true);
|
||||
break;
|
||||
case pcrControlPulse:
|
||||
if (cbPulse)
|
||||
cbPulse = false;
|
||||
else
|
||||
WriteCB1(true);
|
||||
break;
|
||||
case pcrControlLow:
|
||||
WriteCB1(false);
|
||||
break;
|
||||
case pcrControlHigh:
|
||||
WriteCB1(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// run timers
|
||||
for (uint i = 0; i < 2; i++)
|
||||
{
|
||||
switch (tControl[i])
|
||||
{
|
||||
case tControlLoad:
|
||||
if (timer[i] > 0)
|
||||
{
|
||||
timer[i]--;
|
||||
if (timer[i] == 0)
|
||||
irqT[i] = true;
|
||||
}
|
||||
break;
|
||||
case tControlContinuous:
|
||||
if (timer[i] > 0)
|
||||
{
|
||||
timer[i]--;
|
||||
if (timer[i] == 0)
|
||||
{
|
||||
irqT[i] = true;
|
||||
timer[i] = timerLatch[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tControlLoadPB:
|
||||
if (pbPulse[i])
|
||||
pbPulse[i] = false;
|
||||
else
|
||||
WritePortB((byte)(ReadPortB() & portMask[i]));
|
||||
|
||||
if (timer[i] > 0)
|
||||
{
|
||||
timer[i]--;
|
||||
if (timer[i] == 0)
|
||||
{
|
||||
irqT[i] = true;
|
||||
WritePortB((byte)(ReadPortB() | portBit[i]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tControlContinuousPB:
|
||||
if (timer[i] > 0)
|
||||
{
|
||||
timer[i]--;
|
||||
if (timer[i] == 0)
|
||||
{
|
||||
irqT[i] = true;
|
||||
timer[i] = timerLatch[i];
|
||||
WritePortB((byte)(ReadPortB() ^ portBit[i]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tControlPulseCounter:
|
||||
if ((lastpb & 0x40) != 0 && (ReadPortB() & 0x40) == 0)
|
||||
{
|
||||
if (timer[i] > 0)
|
||||
{
|
||||
timer[i]--;
|
||||
if (timer[i] == 0)
|
||||
{
|
||||
irqT[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastca[0] = ca0;
|
||||
lastca[1] = ca1;
|
||||
lastcb[0] = cb0;
|
||||
lastcb[1] = cb1;
|
||||
lastpb = ReadPortB();
|
||||
|
||||
pinIRQ = !((irqCA[0] & enableIrqCA[0]) |
|
||||
(irqCA[1] & enableIrqCA[1]) |
|
||||
(irqCB[0] & enableIrqCB[0]) |
|
||||
(irqCB[1] & enableIrqCB[1]) |
|
||||
(irqSR & enableIrqSR) |
|
||||
(irqT[0] & enableIrqT[0]) |
|
||||
(irqT[1] & enableIrqT[1])
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
@ -113,15 +325,26 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
public byte Read(ushort addr)
|
||||
{
|
||||
|
||||
//Console.WriteLine("via R: reg" + C64Util.ToHex(addr, 4));
|
||||
|
||||
addr &= 0xF;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x0:
|
||||
irqCB[0] = false;
|
||||
irqCB[1] = false;
|
||||
|
||||
if (pbLatchEnable)
|
||||
return Port.ExternalWrite(pbLatch, ReadPortB(), ReadDirB());
|
||||
else
|
||||
return ReadPortB();
|
||||
case 0x1:
|
||||
if (pcrControlA[0] != pcrControlInNegativeIndep && pcrControlA[0] != pcrControlInPositiveIndep)
|
||||
irqCA[0] = false;
|
||||
if (pcrControlA[1] != pcrControlInNegativeIndep && pcrControlA[1] != pcrControlInPositiveIndep)
|
||||
irqCA[1] = false;
|
||||
|
||||
if (paLatchEnable)
|
||||
return Port.ExternalWrite(paLatch, ReadPortA(), ReadDirA());
|
||||
else
|
||||
|
@ -168,7 +391,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
(paLatchEnable ? 0x01 : 0x00) |
|
||||
(pbLatchEnable ? 0x02 : 0x00) |
|
||||
(byte)((srControl & 0x7) << 2) |
|
||||
(byte)((tControl[1] & 0x1) << 5) |
|
||||
(byte)((tControl[1] & 0x4) << 3) |
|
||||
(byte)((tControl[0] & 0x3) << 6)
|
||||
);
|
||||
case 0xC:
|
||||
|
@ -207,14 +430,25 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
public void Write(ushort addr, byte val)
|
||||
{
|
||||
byte result;
|
||||
bool intEnable;
|
||||
|
||||
//Console.WriteLine("via W: reg" + C64Util.ToHex(addr, 4) + " val" + C64Util.ToHex(val, 2));
|
||||
|
||||
addr &= 0xF;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x0:
|
||||
irqCB[0] = false;
|
||||
irqCB[1] = false;
|
||||
pbOut = val;
|
||||
WritePortB(val);
|
||||
break;
|
||||
case 0x1:
|
||||
if (pcrControlA[0] != pcrControlInNegativeIndep && pcrControlA[0] != pcrControlInPositiveIndep)
|
||||
irqCA[0] = false;
|
||||
if (pcrControlA[1] != pcrControlInNegativeIndep && pcrControlA[1] != pcrControlInPositiveIndep)
|
||||
irqCA[1] = false;
|
||||
paOut = val;
|
||||
WritePortA(val);
|
||||
break;
|
||||
|
@ -240,6 +474,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
timer[1] = timerLatch[1];
|
||||
irqT[1] = false;
|
||||
break;
|
||||
case 0xE:
|
||||
intEnable = ((val & 0x80) != 0);
|
||||
result = ReadRegister(addr);
|
||||
if (intEnable)
|
||||
result |= val;
|
||||
else
|
||||
result &= (byte)(val ^ 0x7F);
|
||||
WriteRegister(0xE, result);
|
||||
break;
|
||||
default:
|
||||
WriteRegister(addr, val);
|
||||
break;
|
||||
|
@ -293,7 +536,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
paLatchEnable = ((val & 0x01) != 0);
|
||||
pbLatchEnable = ((val & 0x02) != 0);
|
||||
srControl = (((uint)val >> 2) & 0x7);
|
||||
tControl[1] = (((uint)val >> 5) & 0x1);
|
||||
tControl[1] = (((uint)val >> 3) & 0x4);
|
||||
tControl[0] = (((uint)val >> 6) & 0x3);
|
||||
break;
|
||||
case 0xC:
|
||||
|
|
|
@ -15,14 +15,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
protected bool[] timerOn;
|
||||
protected bool[] underflow;
|
||||
|
||||
public Func<byte> ReadDirA;
|
||||
public Func<byte> ReadDirB;
|
||||
public Func<byte> ReadPortA;
|
||||
public Func<byte> ReadPortB;
|
||||
public Action<byte> WriteDirA;
|
||||
public Action<byte> WriteDirB;
|
||||
public Action<byte> WritePortA;
|
||||
public Action<byte> WritePortB;
|
||||
public Func<byte> ReadDirA = (() => { return 0xFF; });
|
||||
public Func<byte> ReadDirB = (() => { return 0xFF; });
|
||||
public Func<byte> ReadPortA = (() => { return 0xFF; });
|
||||
public Func<byte> ReadPortB = (() => { return 0xFF; });
|
||||
public Action<byte> WriteDirA = ((byte val) => { });
|
||||
public Action<byte> WriteDirB = ((byte val) => { });
|
||||
public Action<byte> WritePortA = ((byte val) => { });
|
||||
public Action<byte> WritePortB = ((byte val) => { });
|
||||
|
||||
public Timer()
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
|
||||
protected void HardResetInternal()
|
||||
{
|
||||
WriteDirA(0x00);
|
||||
WriteDirB(0x00);
|
||||
timer[0] = 0xFFFF;
|
||||
timer[1] = 0xFFFF;
|
||||
timerLatch[0] = timer[0];
|
||||
|
|
Loading…
Reference in New Issue