c64- VIC register class
This commit is contained in:
parent
9d83249eba
commit
821553cda8
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public Memory mem;
|
public Memory mem;
|
||||||
public Sid sid;
|
public Sid sid;
|
||||||
public VicII vic;
|
public VicII vic;
|
||||||
public VicSignals vicSignal;
|
public ChipSignals signal;
|
||||||
|
|
||||||
private void HardReset()
|
private void HardReset()
|
||||||
{
|
{
|
||||||
|
@ -35,8 +35,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
cia2 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort);
|
cia2 = new Cia(Cia.DummyReadPort, Cia.DummyReadPort, Cia.DummyWritePort, Cia.DummyWritePort);
|
||||||
|
|
||||||
// initialize vic
|
// initialize vic
|
||||||
vicSignal = new VicSignals();
|
signal = new ChipSignals();
|
||||||
vic = new VicII(vicSignal, VicIIMode.NTSC);
|
vic = new VicII(signal, VicIIMode.NTSC);
|
||||||
|
|
||||||
// initialize sid
|
// initialize sid
|
||||||
sid = new Sid();
|
sid = new Sid();
|
||||||
|
@ -88,4 +88,21 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
mem.Write(addr, value);
|
mem.Write(addr, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ChipSignals
|
||||||
|
{
|
||||||
|
private bool[] _CiaIRQOutput = new bool[2];
|
||||||
|
private bool _VicAECOutput;
|
||||||
|
private bool _VicBAOutput;
|
||||||
|
private bool _VicIRQOutput;
|
||||||
|
private bool _VicLPInput;
|
||||||
|
|
||||||
|
public bool CpuAEC { get { return _VicAECOutput; } }
|
||||||
|
public bool CpuIRQ { get { return _VicIRQOutput | _CiaIRQOutput[0] | _CiaIRQOutput[1]; } }
|
||||||
|
public bool CpuRDY { get { return _VicBAOutput; } }
|
||||||
|
public bool VicAEC { get { return _VicAECOutput; } set { _VicAECOutput = value; } }
|
||||||
|
public bool VicBA { get { return _VicBAOutput; } set { _VicBAOutput = value; } }
|
||||||
|
public bool VicIRQ { get { return _VicIRQOutput; } set { _VicIRQOutput = value; } }
|
||||||
|
public bool VicLP { get { return _VicLPInput; } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,11 +92,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
for (int i = 0; i < cyclesPerSecond; i++)
|
for (int i = 0; i < cyclesPerSecond; i++)
|
||||||
{
|
{
|
||||||
if (vicSignal.Interrupt || cia1.interrupt || cia2.interrupt)
|
if (signal.CpuIRQ)
|
||||||
{
|
{
|
||||||
cpu.IRQ = true;
|
cpu.IRQ = true;
|
||||||
}
|
}
|
||||||
if (vicSignal.AllowCpu)
|
if (signal.CpuRDY)
|
||||||
{
|
{
|
||||||
cpu.ExecuteOne();
|
cpu.ExecuteOne();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,429 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
PAL
|
PAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class VicIIRegs
|
||||||
|
{
|
||||||
|
public bool BMM;
|
||||||
|
public int[] BxC = new int[4];
|
||||||
|
public int CB;
|
||||||
|
public bool CSEL;
|
||||||
|
public bool DEN;
|
||||||
|
public int EC;
|
||||||
|
public bool ECM;
|
||||||
|
public bool ELP;
|
||||||
|
public bool EMBC;
|
||||||
|
public bool EMMC;
|
||||||
|
public bool ERST;
|
||||||
|
public bool ILP;
|
||||||
|
public bool IMBC;
|
||||||
|
public bool IMMC;
|
||||||
|
public bool IRQ;
|
||||||
|
public bool IRST;
|
||||||
|
public int LPX;
|
||||||
|
public int LPY;
|
||||||
|
public bool MCM;
|
||||||
|
public int[] MMx = new int[2];
|
||||||
|
public int[] MxC = new int[8];
|
||||||
|
public bool[] MxD = new bool[8];
|
||||||
|
public bool[] MxDP = new bool[8];
|
||||||
|
public bool[] MxE = new bool[8];
|
||||||
|
public bool[] MxM = new bool[8];
|
||||||
|
public bool[] MxMC = new bool[8];
|
||||||
|
public int[] MxX = new int[8];
|
||||||
|
public bool[] MxXE = new bool[8];
|
||||||
|
public int[] MxY = new int[8];
|
||||||
|
public bool[] MxYE = new bool[8];
|
||||||
|
public int RASTER;
|
||||||
|
public int RASTERX;
|
||||||
|
public int RC;
|
||||||
|
public bool RES;
|
||||||
|
public bool RSEL;
|
||||||
|
public int VC;
|
||||||
|
public int VCBASE;
|
||||||
|
public int VM;
|
||||||
|
public int VMLI;
|
||||||
|
public int XSCROLL;
|
||||||
|
public int YSCROLL;
|
||||||
|
|
||||||
|
public VicIIRegs()
|
||||||
|
{
|
||||||
|
// power on state
|
||||||
|
|
||||||
|
this[0x16] = 0xC0;
|
||||||
|
this[0x18] = 0x01;
|
||||||
|
this[0x19] = 0x71;
|
||||||
|
this[0x1A] = 0xF0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte this[int addr]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int result = 0xFF; // value for any open bits
|
||||||
|
addr &= 0x3F;
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
case 0x02:
|
||||||
|
case 0x04:
|
||||||
|
case 0x06:
|
||||||
|
case 0x08:
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0C:
|
||||||
|
case 0x0E:
|
||||||
|
result = MxX[addr >> 1];
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
case 0x03:
|
||||||
|
case 0x05:
|
||||||
|
case 0x07:
|
||||||
|
case 0x09:
|
||||||
|
case 0x0B:
|
||||||
|
case 0x0D:
|
||||||
|
case 0x0F:
|
||||||
|
result = MxY[addr >> 1];
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
result = ((MxX[0] & 0x100) != 0) ? 0x01 : 0x00;
|
||||||
|
result |= ((MxX[1] & 0x100) != 0) ? 0x02 : 0x00;
|
||||||
|
result |= ((MxX[2] & 0x100) != 0) ? 0x04 : 0x00;
|
||||||
|
result |= ((MxX[3] & 0x100) != 0) ? 0x08 : 0x00;
|
||||||
|
result |= ((MxX[4] & 0x100) != 0) ? 0x10 : 0x00;
|
||||||
|
result |= ((MxX[5] & 0x100) != 0) ? 0x20 : 0x00;
|
||||||
|
result |= ((MxX[6] & 0x100) != 0) ? 0x40 : 0x00;
|
||||||
|
result |= ((MxX[7] & 0x100) != 0) ? 0x80 : 0x00;
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
result = YSCROLL & 0x07;
|
||||||
|
result |= (RSEL ? 0x08 : 0x00);
|
||||||
|
result |= (DEN ? 0x10 : 0x00);
|
||||||
|
result |= (BMM ? 0x20 : 0x00);
|
||||||
|
result |= (ECM ? 0x40 : 0x00);
|
||||||
|
result |= ((RASTER & 0x100) >> 1);
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
result = RASTER & 0xFF;
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
result = LPX;
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
result = LPY;
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
result = (MxE[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxE[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxE[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxE[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxE[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxE[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxE[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxE[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x16:
|
||||||
|
result &= 0xBF;
|
||||||
|
result |= XSCROLL & 0x07;
|
||||||
|
result |= (CSEL ? 0x08 : 0x00);
|
||||||
|
result |= (MCM ? 0x10 : 0x00);
|
||||||
|
result |= (RES ? 0x20 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x17:
|
||||||
|
result = (MxYE[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxYE[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxYE[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxYE[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxYE[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxYE[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxYE[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxYE[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x18:
|
||||||
|
result &= 0x01;
|
||||||
|
result |= (CB & 0x07) << 1;
|
||||||
|
result |= (VM & 0x0F) << 4;
|
||||||
|
break;
|
||||||
|
case 0x19:
|
||||||
|
result &= 0x70;
|
||||||
|
result |= (IRST ? 0x01 : 0x00);
|
||||||
|
result |= (IMBC ? 0x02 : 0x00);
|
||||||
|
result |= (IMMC ? 0x04 : 0x00);
|
||||||
|
result |= (ILP ? 0x08 : 0x00);
|
||||||
|
result |= (IRQ ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1A:
|
||||||
|
result &= 0xF0;
|
||||||
|
result |= (ERST ? 0x01 : 0x00);
|
||||||
|
result |= (EMBC ? 0x02 : 0x00);
|
||||||
|
result |= (EMMC ? 0x04 : 0x00);
|
||||||
|
result |= (ELP ? 0x08 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1B:
|
||||||
|
result = (MxDP[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxDP[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxDP[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxDP[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxDP[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxDP[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxDP[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxDP[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1C:
|
||||||
|
result = (MxMC[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxMC[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxMC[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxMC[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxMC[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxMC[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxMC[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxMC[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1D:
|
||||||
|
result = (MxXE[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxXE[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxXE[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxXE[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxXE[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxXE[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxXE[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxXE[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1E:
|
||||||
|
result = (MxM[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxM[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxM[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxM[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxM[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxM[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxM[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxM[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
result = (MxD[0] ? 0x01 : 0x00);
|
||||||
|
result |= (MxD[1] ? 0x02 : 0x00);
|
||||||
|
result |= (MxD[2] ? 0x04 : 0x00);
|
||||||
|
result |= (MxD[3] ? 0x08 : 0x00);
|
||||||
|
result |= (MxD[4] ? 0x10 : 0x00);
|
||||||
|
result |= (MxD[5] ? 0x20 : 0x00);
|
||||||
|
result |= (MxD[6] ? 0x40 : 0x00);
|
||||||
|
result |= (MxD[7] ? 0x80 : 0x00);
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
result &= 0xF0;
|
||||||
|
result |= EC & 0x0F;
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
case 0x22:
|
||||||
|
case 0x23:
|
||||||
|
case 0x24:
|
||||||
|
result &= 0xF0;
|
||||||
|
result |= BxC[addr - 0x21] & 0x0F;
|
||||||
|
break;
|
||||||
|
case 0x25:
|
||||||
|
case 0x26:
|
||||||
|
result &= 0xF0;
|
||||||
|
result |= MMx[addr - 0x25] & 0x0F;
|
||||||
|
break;
|
||||||
|
case 0x27:
|
||||||
|
case 0x28:
|
||||||
|
case 0x29:
|
||||||
|
case 0x2A:
|
||||||
|
case 0x2B:
|
||||||
|
case 0x2C:
|
||||||
|
case 0x2D:
|
||||||
|
case 0x2E:
|
||||||
|
result &= 0xF0;
|
||||||
|
result |= MxC[addr - 0x27] & 0x0F;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte)(result);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int val = value;
|
||||||
|
addr &= 0x3F;
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
case 0x02:
|
||||||
|
case 0x04:
|
||||||
|
case 0x06:
|
||||||
|
case 0x08:
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0C:
|
||||||
|
case 0x0E:
|
||||||
|
index = addr >> 1;
|
||||||
|
MxX[index] &= 0x100;
|
||||||
|
MxX[index] |= (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
case 0x03:
|
||||||
|
case 0x05:
|
||||||
|
case 0x07:
|
||||||
|
case 0x09:
|
||||||
|
case 0x0B:
|
||||||
|
case 0x0D:
|
||||||
|
case 0x0F:
|
||||||
|
index = addr >> 1;
|
||||||
|
MxY[index] &= 0x100;
|
||||||
|
MxY[index] |= (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
MxX[0] = (MxX[0] & 0xFF) | ((val & 0x01) << 8);
|
||||||
|
MxX[1] = (MxX[1] & 0xFF) | ((val & 0x02) << 7);
|
||||||
|
MxX[2] = (MxX[2] & 0xFF) | ((val & 0x04) << 6);
|
||||||
|
MxX[3] = (MxX[3] & 0xFF) | ((val & 0x08) << 5);
|
||||||
|
MxX[4] = (MxX[4] & 0xFF) | ((val & 0x10) << 4);
|
||||||
|
MxX[5] = (MxX[5] & 0xFF) | ((val & 0x20) << 3);
|
||||||
|
MxX[6] = (MxX[6] & 0xFF) | ((val & 0x40) << 2);
|
||||||
|
MxX[7] = (MxX[7] & 0xFF) | ((val & 0x80) << 1);
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
YSCROLL = (val & 0x07);
|
||||||
|
RSEL = ((val & 0x08) != 0x00);
|
||||||
|
DEN = ((val & 0x10) != 0x00);
|
||||||
|
BMM = ((val & 0x20) != 0x00);
|
||||||
|
ECM = ((val & 0x40) != 0x00);
|
||||||
|
RASTER &= 0xFF;
|
||||||
|
RASTER |= ((val & 0x80) << 1);
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
RASTER &= 0x100;
|
||||||
|
RASTER |= (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
LPX = (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
LPY = (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
MxE[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxE[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxE[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxE[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxE[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxE[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxE[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxE[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x16:
|
||||||
|
XSCROLL = (val & 0x07);
|
||||||
|
CSEL = ((val & 0x08) != 0x00);
|
||||||
|
MCM = ((val & 0x10) != 0x00);
|
||||||
|
RES = ((val & 0x20) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x17:
|
||||||
|
MxYE[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxYE[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxYE[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxYE[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxYE[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxYE[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxYE[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxYE[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x18:
|
||||||
|
CB = (val & 0x0E) >> 1;
|
||||||
|
VM = (val & 0xF0) >> 4;
|
||||||
|
break;
|
||||||
|
case 0x19:
|
||||||
|
IRST = ((val & 0x01) != 0x00);
|
||||||
|
IMBC = ((val & 0x02) != 0x00);
|
||||||
|
IMMC = ((val & 0x04) != 0x00);
|
||||||
|
ILP = ((val & 0x08) != 0x00);
|
||||||
|
IRQ = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1A:
|
||||||
|
ERST = ((val & 0x01) != 0x00);
|
||||||
|
EMBC = ((val & 0x02) != 0x00);
|
||||||
|
EMMC = ((val & 0x04) != 0x00);
|
||||||
|
ELP = ((val & 0x08) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1B:
|
||||||
|
MxDP[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxDP[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxDP[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxDP[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxDP[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxDP[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxDP[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxDP[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1C:
|
||||||
|
MxMC[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxMC[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxMC[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxMC[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxMC[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxMC[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxMC[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxMC[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1D:
|
||||||
|
MxXE[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxXE[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxXE[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxXE[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxXE[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxXE[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxXE[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxXE[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1E:
|
||||||
|
MxM[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxM[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxM[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxM[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxM[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxM[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxM[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxM[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
MxD[0] = ((val & 0x01) != 0x00);
|
||||||
|
MxD[1] = ((val & 0x02) != 0x00);
|
||||||
|
MxD[2] = ((val & 0x04) != 0x00);
|
||||||
|
MxD[3] = ((val & 0x08) != 0x00);
|
||||||
|
MxD[4] = ((val & 0x10) != 0x00);
|
||||||
|
MxD[5] = ((val & 0x20) != 0x00);
|
||||||
|
MxD[6] = ((val & 0x40) != 0x00);
|
||||||
|
MxD[7] = ((val & 0x80) != 0x00);
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
EC = (val & 0x0F);
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
case 0x22:
|
||||||
|
case 0x23:
|
||||||
|
case 0x24:
|
||||||
|
BxC[addr - 0x21] = val & 0x0F;
|
||||||
|
break;
|
||||||
|
case 0x25:
|
||||||
|
case 0x26:
|
||||||
|
MMx[addr - 0x25] = val & 0x0F;
|
||||||
|
break;
|
||||||
|
case 0x27:
|
||||||
|
case 0x28:
|
||||||
|
case 0x29:
|
||||||
|
case 0x2A:
|
||||||
|
case 0x2B:
|
||||||
|
case 0x2C:
|
||||||
|
case 0x2D:
|
||||||
|
case 0x2E:
|
||||||
|
MxC[addr - 0x27] = val & 0x0F;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class VicII
|
public class VicII
|
||||||
{
|
{
|
||||||
// buffer
|
// buffer
|
||||||
|
@ -38,30 +461,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
Colors.ARGB(0x95, 0x95, 0x95)
|
Colors.ARGB(0x95, 0x95, 0x95)
|
||||||
};
|
};
|
||||||
|
|
||||||
// interrupts
|
|
||||||
public bool interrupt = true;
|
|
||||||
public bool lightPenInterrupt = true;
|
|
||||||
public bool lightPenInterruptEnabled;
|
|
||||||
public bool rasterInterrupt = true;
|
|
||||||
public bool rasterInterruptEnabled;
|
|
||||||
public bool spriteBackgroundInterrupt = true;
|
|
||||||
public bool spriteBackgroundInterruptEnabled;
|
|
||||||
public bool spriteSpriteInterrupt = true;
|
|
||||||
public bool spriteSpriteInterruptEnabled;
|
|
||||||
|
|
||||||
// memory
|
// memory
|
||||||
public bool characterFetch;
|
|
||||||
public int characterFetchOffset;
|
public int characterFetchOffset;
|
||||||
public int characterMemoryOffset;
|
|
||||||
public byte[] charBuffer;
|
|
||||||
public int charBufferOffset;
|
|
||||||
public bool fetching;
|
|
||||||
public int fetchOffsetX;
|
|
||||||
public int screenMemoryOffset;
|
|
||||||
|
|
||||||
// lightpen
|
|
||||||
public int lightPenX; // LPX
|
|
||||||
public int lightPenY; // LPY
|
|
||||||
|
|
||||||
// raster
|
// raster
|
||||||
public int[] backgroundColor; // B0C
|
public int[] backgroundColor; // B0C
|
||||||
|
@ -74,10 +475,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public bool borderOnVertical;
|
public bool borderOnVertical;
|
||||||
public int borderRight;
|
public int borderRight;
|
||||||
public int borderTop;
|
public int borderTop;
|
||||||
public bool extendHeight; // RSEL
|
|
||||||
public bool extendWidth; // CSEL
|
|
||||||
public int horizontalScroll; // XSCROLL
|
|
||||||
public bool multiColorMode; // MCM
|
|
||||||
public int rasterInterruptLine;
|
public int rasterInterruptLine;
|
||||||
public int rasterLineLeft;
|
public int rasterLineLeft;
|
||||||
public int rasterOffset;
|
public int rasterOffset;
|
||||||
|
@ -98,26 +495,13 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public int visibleTop;
|
public int visibleTop;
|
||||||
public int visibleWidth;
|
public int visibleWidth;
|
||||||
|
|
||||||
// sprites
|
public ChipSignals signal;
|
||||||
public bool[] spriteBackgroundCollision; // M0D
|
|
||||||
public bool[] spriteCollision; // M0M
|
|
||||||
public int[] spriteColor; // M0C
|
|
||||||
public bool[] spriteEnabled; // M0E
|
|
||||||
public int[] spriteExtraColor; // MM0
|
|
||||||
public bool[] spriteMultiColor; // M0MC
|
|
||||||
public bool[] spritePriority; // M0DP
|
|
||||||
public bool[] spriteStretchHorizontal; // M0XE
|
|
||||||
public bool[] spriteStretchVertical; // M0YE
|
|
||||||
public int[] spriteX; // M0X, M0X8
|
|
||||||
public int[] spriteY; // M0Y
|
|
||||||
|
|
||||||
public VicSignals cpuSignal;
|
|
||||||
public Memory mem;
|
public Memory mem;
|
||||||
public byte[] regs;
|
public VicIIRegs regs;
|
||||||
|
|
||||||
public VicII(VicSignals signals, VicIIMode videoMode)
|
public VicII(ChipSignals newSignal, VicIIMode videoMode)
|
||||||
{
|
{
|
||||||
cpuSignal = signals;
|
signal = newSignal;
|
||||||
|
|
||||||
switch (videoMode)
|
switch (videoMode)
|
||||||
{
|
{
|
||||||
|
@ -134,10 +518,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
visibleWidth = 418;
|
visibleWidth = 418;
|
||||||
visibleHeight = 217;
|
visibleHeight = 217;
|
||||||
renderOffset = 0;
|
renderOffset = 0;
|
||||||
borderLeft = 0x018;
|
|
||||||
borderRight = 0x158;
|
|
||||||
borderTop = 0x033;
|
|
||||||
borderBottom = 0x0FA;
|
|
||||||
characterFetchOffset = rasterWidth - 3;
|
characterFetchOffset = rasterWidth - 3;
|
||||||
break;
|
break;
|
||||||
case VicIIMode.PAL:
|
case VicIIMode.PAL:
|
||||||
|
@ -148,23 +528,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
// initialize raster
|
// initialize raster
|
||||||
backgroundColor = new int[4];
|
backgroundColor = new int[4];
|
||||||
charBuffer = new byte[40];
|
|
||||||
rasterOffsetX = rasterLineLeft;
|
rasterOffsetX = rasterLineLeft;
|
||||||
rasterOffsetY = 0;
|
rasterOffsetY = 0;
|
||||||
|
|
||||||
// initialize sprites
|
|
||||||
spriteBackgroundCollision = new bool[8];
|
|
||||||
spriteCollision = new bool[8];
|
|
||||||
spriteColor = new int[8];
|
|
||||||
spriteEnabled = new bool[8];
|
|
||||||
spriteExtraColor = new int[2];
|
|
||||||
spriteMultiColor = new bool[8];
|
|
||||||
spritePriority = new bool[8];
|
|
||||||
spriteStretchHorizontal = new bool[8];
|
|
||||||
spriteStretchVertical = new bool[8];
|
|
||||||
spriteX = new int[8];
|
|
||||||
spriteY = new int[8];
|
|
||||||
|
|
||||||
// initialize buffer
|
// initialize buffer
|
||||||
buffer = new int[rasterWidth * rasterTotalLines];
|
buffer = new int[rasterWidth * rasterTotalLines];
|
||||||
bufferSize = buffer.Length;
|
bufferSize = buffer.Length;
|
||||||
|
@ -175,331 +541,75 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
public void HardReset()
|
public void HardReset()
|
||||||
{
|
{
|
||||||
// power on state
|
regs = new VicIIRegs();
|
||||||
regs = new byte[0x40];
|
UpdateBorder();
|
||||||
Write(0x0016, 0xC0);
|
|
||||||
Write(0x0018, 0x01);
|
|
||||||
Write(0x0019, 0x71);
|
|
||||||
Write(0x001A, 0xF0);
|
|
||||||
for (ushort i = 0x0020; i <= 0x002E; i++)
|
|
||||||
Write(i, 0xF0);
|
|
||||||
|
|
||||||
// unused registers always return FF
|
|
||||||
for (int i = 0x2F; i <= 0x3F; i++)
|
|
||||||
regs[i] = 0xFF;
|
|
||||||
|
|
||||||
UpdateRegs();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LockBus()
|
|
||||||
{
|
|
||||||
cpuSignal.Lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PerformCycle()
|
public void PerformCycle()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (rasterOffsetX == visibleLeft)
|
|
||||||
visibleRenderX = true;
|
|
||||||
if (rasterOffsetX == visibleRight)
|
|
||||||
visibleRenderX = false;
|
|
||||||
if (rasterOffsetX == borderLeft)
|
|
||||||
borderOnHorizontal = false;
|
|
||||||
if (rasterOffsetX == borderRight)
|
|
||||||
borderOnHorizontal = true;
|
|
||||||
|
|
||||||
if ((rasterOffsetX == fetchOffsetX) && ((rasterOffsetY & 0x07) == verticalScroll))
|
|
||||||
{
|
|
||||||
cpuSignal.Lock();
|
|
||||||
fetching = true;
|
|
||||||
characterFetchOffset = (rasterOffsetY >> 3) * 40;
|
|
||||||
charBufferOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fetching)
|
|
||||||
{
|
|
||||||
if (charBufferOffset >= 0)
|
|
||||||
{
|
|
||||||
charBuffer[charBufferOffset] = mem.VicRead((ushort)(screenMemoryOffset + characterFetchOffset));
|
|
||||||
characterFetchOffset++;
|
|
||||||
}
|
|
||||||
charBufferOffset++;
|
|
||||||
if (charBufferOffset == 40)
|
|
||||||
{
|
|
||||||
fetching = false;
|
|
||||||
cpuSignal.Unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (borderOnVertical || borderOnHorizontal)
|
|
||||||
{
|
|
||||||
WritePixel(borderColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WritePixel(backgroundColor[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rasterOffsetX++;
|
|
||||||
if (rasterOffsetX == rasterWidth)
|
|
||||||
rasterOffsetX = 0;
|
|
||||||
|
|
||||||
if (rasterOffsetX == rasterLineLeft)
|
|
||||||
{
|
|
||||||
rasterOffsetY++;
|
|
||||||
|
|
||||||
if (rasterOffsetY == visibleTop)
|
|
||||||
visibleRenderY = true;
|
|
||||||
if (rasterOffsetY == visibleBottom)
|
|
||||||
visibleRenderY = false;
|
|
||||||
if (rasterOffsetY == borderTop)
|
|
||||||
borderOnVertical = false;
|
|
||||||
if (rasterOffsetY == borderBottom)
|
|
||||||
borderOnVertical = true;
|
|
||||||
if (rasterOffsetY == rasterTotalLines)
|
|
||||||
{
|
|
||||||
rasterOffsetY = 0;
|
|
||||||
renderOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rasterInterruptEnabled && (rasterOffsetY == rasterInterruptLine))
|
|
||||||
{
|
|
||||||
rasterInterrupt = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interrupt =
|
|
||||||
(rasterInterrupt & rasterInterruptEnabled) |
|
|
||||||
(spriteSpriteInterrupt & spriteSpriteInterruptEnabled) |
|
|
||||||
(spriteBackgroundInterrupt & spriteBackgroundInterruptEnabled) |
|
|
||||||
(lightPenInterrupt & lightPenInterruptEnabled);
|
|
||||||
|
|
||||||
cpuSignal.Interrupt = interrupt;
|
|
||||||
UpdateRegs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte Read(ushort addr)
|
public byte Read(ushort addr)
|
||||||
{
|
{
|
||||||
return regs[addr & 0x3F];
|
byte result = 0;
|
||||||
}
|
|
||||||
|
|
||||||
public void UnlockBus()
|
|
||||||
{
|
|
||||||
cpuSignal.Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateRegs()
|
|
||||||
{
|
|
||||||
// these registers update on their own
|
|
||||||
|
|
||||||
regs[0x11] = (byte)
|
|
||||||
((verticalScroll & 0x07) |
|
|
||||||
(extendHeight ? 0x08 : 0x00) |
|
|
||||||
(screenEnabled ? 0x10 : 0x00) |
|
|
||||||
(bitmapMode ? 0x20 : 0x00) |
|
|
||||||
(backgroundMode ? 0x40 : 0x00) |
|
|
||||||
((rasterOffsetY & 0x100) >> 1));
|
|
||||||
regs[0x12] = (byte)(rasterOffsetY & 0xFF);
|
|
||||||
regs[0x13] = (byte)(lightPenX >> 1);
|
|
||||||
regs[0x14] = (byte)(lightPenY);
|
|
||||||
regs[0x19] = (byte)
|
|
||||||
((rasterInterrupt ? 0x01 : 0x00) |
|
|
||||||
(spriteBackgroundInterrupt ? 0x02 : 0x00) |
|
|
||||||
(spriteSpriteInterrupt ? 0x04 : 0x00) |
|
|
||||||
(lightPenInterrupt ? 0x08 : 0x00) |
|
|
||||||
(interrupt ? 0x80 : 0x00));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(ushort addr, byte val)
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
bool allowWrite = true;
|
|
||||||
addr &= 0x3F;
|
addr &= 0x3F;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00:
|
|
||||||
case 0x02:
|
|
||||||
case 0x04:
|
|
||||||
case 0x06:
|
|
||||||
case 0x08:
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0C:
|
|
||||||
case 0x0E:
|
|
||||||
index = addr >> 1;
|
|
||||||
spriteX[index] &= 0xFF;
|
|
||||||
spriteX[index] |= val;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
case 0x03:
|
|
||||||
case 0x05:
|
|
||||||
case 0x07:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0B:
|
|
||||||
case 0x0D:
|
|
||||||
case 0x0F:
|
|
||||||
index = addr >> 1;
|
|
||||||
spriteY[index] &= 0xFF;
|
|
||||||
spriteY[index] |= val;
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
spriteX[0] = (spriteX[0] & 0xFF) | ((val & 0x01) << 8);
|
|
||||||
spriteX[1] = (spriteX[1] & 0xFF) | ((val & 0x02) << 7);
|
|
||||||
spriteX[2] = (spriteX[2] & 0xFF) | ((val & 0x04) << 6);
|
|
||||||
spriteX[3] = (spriteX[3] & 0xFF) | ((val & 0x08) << 5);
|
|
||||||
spriteX[4] = (spriteX[4] & 0xFF) | ((val & 0x10) << 4);
|
|
||||||
spriteX[5] = (spriteX[5] & 0xFF) | ((val & 0x20) << 3);
|
|
||||||
spriteX[6] = (spriteX[6] & 0xFF) | ((val & 0x40) << 2);
|
|
||||||
spriteX[7] = (spriteX[7] & 0xFF) | ((val & 0x80) << 1);
|
|
||||||
break;
|
|
||||||
case 0x11:
|
|
||||||
verticalScroll = val & 0x07;
|
|
||||||
extendHeight = ((val & 0x08) != 0x00);
|
|
||||||
screenEnabled = ((val & 0x10) != 0x00);
|
|
||||||
bitmapMode = ((val & 0x20) != 0x00);
|
|
||||||
backgroundMode = ((val & 0x40) != 0x00);
|
|
||||||
rasterInterruptLine = (rasterInterruptLine & 0xFF) | ((val & 0x80) << 1);
|
|
||||||
val = (byte)((val & 0x7F) | ((rasterOffsetY & 0x100) >> 1));
|
|
||||||
break;
|
|
||||||
case 0x12:
|
|
||||||
rasterInterruptLine = (rasterInterruptLine & 0x100) | val;
|
|
||||||
allowWrite = false;
|
|
||||||
break;
|
|
||||||
case 0x15:
|
|
||||||
spriteEnabled[0] = ((val & 0x01) != 0x00);
|
|
||||||
spriteEnabled[1] = ((val & 0x02) != 0x00);
|
|
||||||
spriteEnabled[2] = ((val & 0x04) != 0x00);
|
|
||||||
spriteEnabled[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteEnabled[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteEnabled[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteEnabled[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteEnabled[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x16:
|
|
||||||
horizontalScroll = val & 0x07;
|
|
||||||
extendWidth = ((val & 0x08) != 0x00);
|
|
||||||
multiColorMode = ((val & 0x10) != 0x00);
|
|
||||||
resetBit = ((val & 0x20) != 0x00);
|
|
||||||
val |= 0xC0;
|
|
||||||
break;
|
|
||||||
case 0x17:
|
|
||||||
spriteStretchVertical[0] = ((val & 0x01) != 0x00);
|
|
||||||
spriteStretchVertical[1] = ((val & 0x02) != 0x00);
|
|
||||||
spriteStretchVertical[2] = ((val & 0x04) != 0x00);
|
|
||||||
spriteStretchVertical[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteStretchVertical[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteStretchVertical[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteStretchVertical[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteStretchVertical[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x18:
|
|
||||||
characterMemoryOffset = (int)(val & 0x0E) << 10;
|
|
||||||
screenMemoryOffset = (int)(val & 0xF0) << 6;
|
|
||||||
break;
|
|
||||||
case 0x19:
|
|
||||||
rasterInterrupt = ((val & 0x01) != 0);
|
|
||||||
spriteSpriteInterrupt = ((val & 0x02) != 0);
|
|
||||||
spriteBackgroundInterrupt = ((val & 0x04) != 0);
|
|
||||||
lightPenInterrupt = ((val & 0x08) != 0);
|
|
||||||
allowWrite = false;
|
|
||||||
break;
|
|
||||||
case 0x1A:
|
|
||||||
rasterInterruptEnabled = ((val & 0x01) != 0);
|
|
||||||
spriteSpriteInterruptEnabled = ((val & 0x02) != 0);
|
|
||||||
spriteBackgroundInterruptEnabled = ((val & 0x04) != 0);
|
|
||||||
lightPenInterruptEnabled = ((val & 0x08) != 0);
|
|
||||||
break;
|
|
||||||
case 0x1B:
|
|
||||||
spritePriority[0] = ((val & 0x01) != 0x00);
|
|
||||||
spritePriority[1] = ((val & 0x02) != 0x00);
|
|
||||||
spritePriority[2] = ((val & 0x04) != 0x00);
|
|
||||||
spritePriority[3] = ((val & 0x08) != 0x00);
|
|
||||||
spritePriority[4] = ((val & 0x10) != 0x00);
|
|
||||||
spritePriority[5] = ((val & 0x20) != 0x00);
|
|
||||||
spritePriority[6] = ((val & 0x40) != 0x00);
|
|
||||||
spritePriority[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x1C:
|
|
||||||
spriteMultiColor[0] = ((val & 0x01) != 0x00);
|
|
||||||
spriteMultiColor[1] = ((val & 0x02) != 0x00);
|
|
||||||
spriteMultiColor[2] = ((val & 0x04) != 0x00);
|
|
||||||
spriteMultiColor[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteMultiColor[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteMultiColor[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteMultiColor[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteMultiColor[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x1D:
|
|
||||||
spriteStretchHorizontal[0] = ((val & 0x01) != 0x00);
|
|
||||||
spriteStretchHorizontal[1] = ((val & 0x02) != 0x00);
|
|
||||||
spriteStretchHorizontal[2] = ((val & 0x04) != 0x00);
|
|
||||||
spriteStretchHorizontal[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteStretchHorizontal[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteStretchHorizontal[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteStretchHorizontal[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteStretchHorizontal[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x1E:
|
case 0x1E:
|
||||||
spriteCollision[0] = ((val & 0x01) != 0x00);
|
|
||||||
spriteCollision[1] = ((val & 0x02) != 0x00);
|
|
||||||
spriteCollision[2] = ((val & 0x04) != 0x00);
|
|
||||||
spriteCollision[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteCollision[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteCollision[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteCollision[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteCollision[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x1F:
|
case 0x1F:
|
||||||
spriteBackgroundCollision[0] = ((val & 0x01) != 0x00);
|
// collision regs clear after read
|
||||||
spriteBackgroundCollision[1] = ((val & 0x02) != 0x00);
|
result = regs[addr];
|
||||||
spriteBackgroundCollision[2] = ((val & 0x04) != 0x00);
|
regs[addr] = 0x00;
|
||||||
spriteBackgroundCollision[3] = ((val & 0x08) != 0x00);
|
|
||||||
spriteBackgroundCollision[4] = ((val & 0x10) != 0x00);
|
|
||||||
spriteBackgroundCollision[5] = ((val & 0x20) != 0x00);
|
|
||||||
spriteBackgroundCollision[6] = ((val & 0x40) != 0x00);
|
|
||||||
spriteBackgroundCollision[7] = ((val & 0x80) != 0x00);
|
|
||||||
break;
|
|
||||||
case 0x20:
|
|
||||||
borderColor = val;
|
|
||||||
break;
|
|
||||||
case 0x21:
|
|
||||||
backgroundColor[0] = val;
|
|
||||||
break;
|
|
||||||
case 0x22:
|
|
||||||
backgroundColor[1] = val;
|
|
||||||
break;
|
|
||||||
case 0x23:
|
|
||||||
backgroundColor[2] = val;
|
|
||||||
break;
|
|
||||||
case 0x24:
|
|
||||||
backgroundColor[3] = val;
|
|
||||||
break;
|
|
||||||
case 0x25:
|
|
||||||
spriteExtraColor[0] = val;
|
|
||||||
break;
|
|
||||||
case 0x26:
|
|
||||||
spriteExtraColor[1] = val;
|
|
||||||
break;
|
|
||||||
case 0x27:
|
|
||||||
case 0x28:
|
|
||||||
case 0x29:
|
|
||||||
case 0x2A:
|
|
||||||
case 0x2B:
|
|
||||||
case 0x2C:
|
|
||||||
case 0x2D:
|
|
||||||
case 0x2E:
|
|
||||||
index = addr - 0x27;
|
|
||||||
spriteColor[index] = val;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
allowWrite = false;
|
result = regs[addr];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowWrite)
|
return result;
|
||||||
regs[addr] = val;
|
}
|
||||||
|
|
||||||
|
public void UpdateBorder()
|
||||||
|
{
|
||||||
|
borderTop = regs.RSEL ? 0x033 : 0x037;
|
||||||
|
borderBottom = regs.RSEL ? 0x0FA : 0x0F6;
|
||||||
|
borderLeft = regs.CSEL ? 0x018 : 0x01F;
|
||||||
|
borderRight = regs.CSEL ? 0x14E : 0x157;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(ushort addr, byte val)
|
||||||
|
{
|
||||||
|
addr &= 0x3F;
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x11:
|
||||||
|
rasterInterruptLine &= 0xFF;
|
||||||
|
rasterInterruptLine |= (val & 0x80) << 1;
|
||||||
|
// raster upper bit can't be changed, save and restore the value
|
||||||
|
val &= 0x7F;
|
||||||
|
val |= (byte)(regs[addr] & 0x80);
|
||||||
|
regs[addr] = val;
|
||||||
|
UpdateBorder();
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
// raster interrupt lower 8 bits
|
||||||
|
rasterInterruptLine &= 0x100;
|
||||||
|
rasterInterruptLine |= (val & 0xFF);
|
||||||
|
break;
|
||||||
|
case 0x16:
|
||||||
|
regs[addr] = val;
|
||||||
|
UpdateBorder();
|
||||||
|
break;
|
||||||
|
case 0x1E:
|
||||||
|
case 0x1F:
|
||||||
|
// can't write to these regs
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
regs[addr] = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WritePixel(int value)
|
private void WritePixel(int value)
|
||||||
|
@ -511,47 +621,4 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VicSignals
|
|
||||||
{
|
|
||||||
public bool AllowCpu;
|
|
||||||
public bool Interrupt;
|
|
||||||
public int LockCounter;
|
|
||||||
|
|
||||||
public VicSignals()
|
|
||||||
{
|
|
||||||
AllowCpu = true;
|
|
||||||
Interrupt = false;
|
|
||||||
LockCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Lock()
|
|
||||||
{
|
|
||||||
if (AllowCpu)
|
|
||||||
{
|
|
||||||
LockCounter = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PerformCycle()
|
|
||||||
{
|
|
||||||
if (AllowCpu)
|
|
||||||
{
|
|
||||||
if (LockCounter > 0)
|
|
||||||
{
|
|
||||||
LockCounter--;
|
|
||||||
if (LockCounter == 0)
|
|
||||||
{
|
|
||||||
AllowCpu = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Unlock()
|
|
||||||
{
|
|
||||||
AllowCpu = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue