c64 - more CIA timer regs, VIC border and background rendering
This commit is contained in:
parent
81f33754e0
commit
59bb49ae20
|
@ -49,7 +49,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
Cartridge cart = new Cartridge(inputFile);
|
Cartridge cart = new Cartridge(inputFile);
|
||||||
if (cart.valid)
|
if (cart.valid)
|
||||||
{
|
{
|
||||||
mem.ApplyCartridge(cart);
|
//mem.ApplyCartridge(cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize cpu (hard reset vector)
|
// initialize cpu (hard reset vector)
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
for (int i = 0; i < cyclesPerSecond; i++)
|
for (int i = 0; i < cyclesPerSecond; i++)
|
||||||
{
|
{
|
||||||
if (vicSignal.Interrupt)
|
if (vicSignal.Interrupt || cia1.interrupt || cia2.interrupt)
|
||||||
{
|
{
|
||||||
cpu.IRQ = true;
|
cpu.IRQ = true;
|
||||||
}
|
}
|
||||||
|
@ -131,11 +131,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
{
|
{
|
||||||
this.vic = vic;
|
this.vic = vic;
|
||||||
|
|
||||||
buffer = new int[vic.rasterWidth * vic.rasterTotalLines];
|
buffer = new int[vic.visibleWidth * vic.visibleHeight];
|
||||||
top = 0;
|
top = 0;
|
||||||
bottom = vic.rasterTotalLines-1;
|
bottom = vic.visibleHeight - 1;
|
||||||
left = 0;
|
left = 0;
|
||||||
right = vic.rasterWidth-1;
|
right = vic.visibleWidth - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] buffer;
|
int[] buffer;
|
||||||
|
|
|
@ -7,22 +7,33 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
{
|
{
|
||||||
public class Cia
|
public class Cia
|
||||||
{
|
{
|
||||||
|
public int alarmTime;
|
||||||
|
public bool alarmWriteEnabled;
|
||||||
public int cycles;
|
public int cycles;
|
||||||
public bool flagPin;
|
public bool flagPin;
|
||||||
|
public bool flagPinInterrupt;
|
||||||
|
public bool flagPinInterruptEnabled;
|
||||||
|
public bool[] generatePositiveEdgeOnUnderflow = new bool[2];
|
||||||
public bool interrupt;
|
public bool interrupt;
|
||||||
|
public bool[] loadStartValue = new bool[2];
|
||||||
|
public bool palMode;
|
||||||
public byte[] regs;
|
public byte[] regs;
|
||||||
public bool serialData;
|
|
||||||
public bool serialReady;
|
|
||||||
public int shiftRegisterCycles;
|
public int shiftRegisterCycles;
|
||||||
public bool shiftRegisterInterrupt;
|
public bool shiftRegisterInterrupt;
|
||||||
public bool shiftRegisterInterruptEnabled;
|
public bool shiftRegisterInterruptEnabled;
|
||||||
public bool shiftRegisterIsOutput;
|
public bool shiftRegisterIsOutput;
|
||||||
|
public bool[] stopOnUnderflow = new bool[2];
|
||||||
|
public int timeOfDay;
|
||||||
public bool timeOfDayAlarmInterrupt;
|
public bool timeOfDayAlarmInterrupt;
|
||||||
public bool timeOfDayAlarmInterruptEnabled;
|
public bool timeOfDayAlarmInterruptEnabled;
|
||||||
public bool underflowTimerAInterrupt;
|
public int[] timerConfig = new int[2];
|
||||||
public bool underflowTimerAInterruptEnabled;
|
public bool[] timerEnabled = new bool[2];
|
||||||
public bool underflowTimerBInterrupt;
|
public bool[] timerInterruptEnabled = new bool[2];
|
||||||
public bool underflowTimerBInterruptEnabled;
|
public ushort[] timerLatch = new ushort[2];
|
||||||
|
public bool[] timerUnderflowMonitor = new bool[2];
|
||||||
|
public ushort[] timerValue = new ushort[2];
|
||||||
|
public bool[] underflowTimerInterrupt = new bool[2];
|
||||||
|
public bool[] underflowTimerInterruptEnabled = new bool[2];
|
||||||
|
|
||||||
public Func<byte> ReadPortA;
|
public Func<byte> ReadPortA;
|
||||||
public Func<byte> ReadPortB;
|
public Func<byte> ReadPortB;
|
||||||
|
@ -31,12 +42,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
public Cia(Func<byte> funcReadPortA, Func<byte> funcReadPortB, Action<byte, byte> actWritePortA, Action<byte, byte> actWritePortB)
|
public Cia(Func<byte> funcReadPortA, Func<byte> funcReadPortB, Action<byte, byte> actWritePortA, Action<byte, byte> actWritePortB)
|
||||||
{
|
{
|
||||||
regs = new byte[0x10];
|
ReadPortA = funcReadPortA;
|
||||||
|
ReadPortB = funcReadPortB;
|
||||||
|
WritePortA = actWritePortA;
|
||||||
|
WritePortB = actWritePortB;
|
||||||
|
HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public byte DummyReadPort()
|
static public byte DummyReadPort()
|
||||||
{
|
{
|
||||||
return 0xFF;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void DummyWritePort(byte val, byte direction)
|
static public void DummyWritePort(byte val, byte direction)
|
||||||
|
@ -44,33 +59,84 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HardReset()
|
||||||
|
{
|
||||||
|
regs = new byte[0x10];
|
||||||
|
Write(0x0004, 0xFF);
|
||||||
|
Write(0x0005, 0xFF);
|
||||||
|
Write(0x0006, 0xFF);
|
||||||
|
Write(0x0007, 0xFF);
|
||||||
|
Write(0x000B, 0x01);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void PerformCycle()
|
public void PerformCycle()
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
cycles++;
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (timerConfig[i] == 0)
|
||||||
|
TimerTick(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regs[0x04] = (byte)(timerValue[0] & 0xFF);
|
||||||
|
regs[0x05] = (byte)(timerValue[0] >> 8);
|
||||||
|
regs[0x06] = (byte)(timerValue[1] & 0xFF);
|
||||||
|
regs[0x07] = (byte)(timerValue[1] >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PollSerial(ref bool bit)
|
||||||
|
{
|
||||||
|
// this has the same effect as raising CNT
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
switch (timerConfig[i])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
TimerTick(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shiftRegisterIsOutput)
|
||||||
|
{
|
||||||
|
bit = ((regs[0x0C] & 0x01) != 0x00);
|
||||||
|
regs[0x0C] >>= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regs[0x0C] >>= 1;
|
||||||
|
if (bit)
|
||||||
|
regs[0x0C] |= 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte Read(ushort addr)
|
public byte Read(ushort addr)
|
||||||
{
|
{
|
||||||
byte result = 0;
|
byte result = 0;
|
||||||
|
addr &= 0x0F;
|
||||||
|
|
||||||
switch (addr & 0x0F)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
result = ReadPortA();
|
result = ReadPortA();
|
||||||
|
regs[addr] = result;
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
result = ReadPortB();
|
result = ReadPortB();
|
||||||
|
regs[addr] = result;
|
||||||
break;
|
break;
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
result = regs[addr];
|
result = regs[addr];
|
||||||
shiftRegisterInterrupt = false;
|
shiftRegisterInterrupt = false;
|
||||||
timeOfDayAlarmInterrupt = false;
|
timeOfDayAlarmInterrupt = false;
|
||||||
underflowTimerAInterrupt = false;
|
underflowTimerInterrupt[0] = false;
|
||||||
underflowTimerBInterrupt = false;
|
underflowTimerInterrupt[1] = false;
|
||||||
interrupt = false;
|
interrupt = false;
|
||||||
|
UpdateInterruptReg();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = regs[addr];
|
result = regs[addr];
|
||||||
|
@ -80,47 +146,118 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TimerTick(int index)
|
||||||
|
{
|
||||||
|
if (timerEnabled[index])
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
timerValue[index]--;
|
||||||
|
}
|
||||||
|
if (timerValue[index] == 0xFFFF)
|
||||||
|
{
|
||||||
|
if (underflowTimerInterruptEnabled[index])
|
||||||
|
{
|
||||||
|
underflowTimerInterrupt[index] = true;
|
||||||
|
interrupt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// timer B can count on timer A's underflows
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
switch (timerConfig[1])
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
TimerTick(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateInterruptReg()
|
||||||
|
{
|
||||||
|
byte result;
|
||||||
|
result = (byte)(shiftRegisterInterrupt ? 0x01 : 0x00);
|
||||||
|
result |= (byte)(timeOfDayAlarmInterrupt ? 0x02 : 0x00);
|
||||||
|
result |= (byte)(underflowTimerInterrupt[0] ? 0x04 : 0x00);
|
||||||
|
result |= (byte)(underflowTimerInterrupt[1] ? 0x08 : 0x00);
|
||||||
|
result |= (byte)(flagPinInterrupt ? 0x10 : 0x00);
|
||||||
|
result |= (byte)(interrupt ? 0x80 : 0x00);
|
||||||
|
regs[0x0D] = result;
|
||||||
|
}
|
||||||
|
|
||||||
public void Write(ushort addr, byte val)
|
public void Write(ushort addr, byte val)
|
||||||
{
|
{
|
||||||
switch (addr & 0x0F)
|
bool allowWrite = true;
|
||||||
|
addr &= 0x0F;
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
WritePortA(val, regs[0x02]);
|
WritePortA(val, regs[0x02]);
|
||||||
|
allowWrite = false;
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
WritePortB(val, regs[0x03]);
|
WritePortB(val, regs[0x03]);
|
||||||
break;
|
allowWrite = false;
|
||||||
case 0x02:
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
|
timerValue[0] &= 0xFF00;
|
||||||
|
timerValue[0] |= val;
|
||||||
break;
|
break;
|
||||||
case 0x05:
|
case 0x05:
|
||||||
|
timerValue[0] &= 0xFF;
|
||||||
|
timerValue[0] |= (ushort)(val << 8);
|
||||||
break;
|
break;
|
||||||
case 0x06:
|
case 0x06:
|
||||||
|
timerValue[1] &= 0xFF00;
|
||||||
|
timerValue[1] |= val;
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07:
|
||||||
break;
|
timerValue[1] &= 0xFF;
|
||||||
case 0x08:
|
timerValue[1] |= (ushort)(val << 8);
|
||||||
break;
|
|
||||||
case 0x09:
|
|
||||||
break;
|
|
||||||
case 0x0A:
|
|
||||||
break;
|
|
||||||
case 0x0B:
|
|
||||||
break;
|
|
||||||
case 0x0C:
|
|
||||||
break;
|
break;
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
|
if ((val & 0x01) != 0x00)
|
||||||
|
timerInterruptEnabled[0] = ((val & 0x80) != 0x00);
|
||||||
|
if ((val & 0x02) != 0x00)
|
||||||
|
timerInterruptEnabled[1] = ((val & 0x80) != 0x00);
|
||||||
|
if ((val & 0x04) != 0x00)
|
||||||
|
timeOfDayAlarmInterruptEnabled = ((val & 0x80) != 0x00);
|
||||||
|
if ((val & 0x08) != 0x00)
|
||||||
|
shiftRegisterInterruptEnabled = ((val & 0x80) != 0x00);
|
||||||
|
if ((val & 0x10) != 0x00)
|
||||||
|
flagPinInterruptEnabled = ((val & 0x80) != 0x00);
|
||||||
|
allowWrite = false;
|
||||||
break;
|
break;
|
||||||
case 0x0E:
|
case 0x0E:
|
||||||
|
timerEnabled[0] = ((val & 0x01) != 0x00);
|
||||||
|
timerUnderflowMonitor[0] = ((val & 0x02) != 0x00);
|
||||||
|
generatePositiveEdgeOnUnderflow[0] = ((val & 0x04) != 0x00);
|
||||||
|
stopOnUnderflow[0] = ((val & 0x08) != 0x00);
|
||||||
|
loadStartValue[0] = ((val & 0x10) != 0x00);
|
||||||
|
timerConfig[0] = ((val & 0x20) >> 5);
|
||||||
|
shiftRegisterIsOutput = ((val & 0x40) != 0x00);
|
||||||
|
palMode = ((val & 0x80) != 0x00);
|
||||||
break;
|
break;
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
|
timerEnabled[1] = ((val & 0x01) != 0x00);
|
||||||
|
timerUnderflowMonitor[1] = ((val & 0x02) != 0x00);
|
||||||
|
generatePositiveEdgeOnUnderflow[1] = ((val & 0x04) != 0x00);
|
||||||
|
stopOnUnderflow[1] = ((val & 0x08) != 0x00);
|
||||||
|
loadStartValue[1] = ((val & 0x10) != 0x00);
|
||||||
|
timerConfig[1] = ((val & 0x60) >> 5);
|
||||||
|
alarmWriteEnabled = ((val & 0x80) != 0x00);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowWrite)
|
||||||
|
regs[addr] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,19 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
};
|
};
|
||||||
|
|
||||||
// interrupts
|
// interrupts
|
||||||
public bool interrupt;
|
public bool interrupt = true;
|
||||||
public bool lightPenInterrupt;
|
public bool lightPenInterrupt = true;
|
||||||
public bool lightPenInterruptEnabled;
|
public bool lightPenInterruptEnabled;
|
||||||
public bool rasterInterrupt;
|
public bool rasterInterrupt = true;
|
||||||
public bool rasterInterruptEnabled;
|
public bool rasterInterruptEnabled;
|
||||||
public bool spriteBackgroundInterrupt;
|
public bool spriteBackgroundInterrupt = true;
|
||||||
public bool spriteBackgroundInterruptEnabled;
|
public bool spriteBackgroundInterruptEnabled;
|
||||||
public bool spriteSpriteInterrupt;
|
public bool spriteSpriteInterrupt = true;
|
||||||
public bool spriteSpriteInterruptEnabled;
|
public bool spriteSpriteInterruptEnabled;
|
||||||
|
|
||||||
// memory
|
// memory
|
||||||
|
public bool characterFetch;
|
||||||
|
public int characterFetchOffset;
|
||||||
public int characterMemoryOffset;
|
public int characterMemoryOffset;
|
||||||
public int screenMemoryOffset;
|
public int screenMemoryOffset;
|
||||||
|
|
||||||
|
@ -61,22 +63,35 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public int[] backgroundColor;
|
public int[] backgroundColor;
|
||||||
public bool backgroundMode;
|
public bool backgroundMode;
|
||||||
public bool bitmapMode;
|
public bool bitmapMode;
|
||||||
|
public int borderBottom;
|
||||||
public int borderColor;
|
public int borderColor;
|
||||||
public bool borderOn;
|
public int borderLeft;
|
||||||
|
public bool borderOnHorizontal;
|
||||||
|
public bool borderOnVertical;
|
||||||
|
public int borderRight;
|
||||||
|
public int borderTop;
|
||||||
public byte[] charBuffer;
|
public byte[] charBuffer;
|
||||||
public bool extendHeight;
|
public bool extendHeight;
|
||||||
public bool extendWidth;
|
public bool extendWidth;
|
||||||
public int horizontalScroll;
|
public int horizontalScroll;
|
||||||
public bool multiColorMode;
|
public bool multiColorMode;
|
||||||
public int rasterInterruptLine;
|
public int rasterInterruptLine;
|
||||||
|
public int rasterLineLeft;
|
||||||
public int rasterOffset;
|
public int rasterOffset;
|
||||||
public int rasterOffsetX;
|
public int rasterOffsetX;
|
||||||
public int rasterOffsetY;
|
public int rasterOffsetY;
|
||||||
public int rasterTotalLines;
|
public int rasterTotalLines;
|
||||||
public int rasterWidth;
|
public int rasterWidth;
|
||||||
|
public int renderOffset;
|
||||||
public bool screenEnabled;
|
public bool screenEnabled;
|
||||||
public int verticalScroll;
|
public int verticalScroll;
|
||||||
|
public int visibleBottom;
|
||||||
public int visibleHeight;
|
public int visibleHeight;
|
||||||
|
public int visibleLeft;
|
||||||
|
public bool visibleRenderX;
|
||||||
|
public bool visibleRenderY;
|
||||||
|
public int visibleRight;
|
||||||
|
public int visibleTop;
|
||||||
public int visibleWidth;
|
public int visibleWidth;
|
||||||
|
|
||||||
// sprites
|
// sprites
|
||||||
|
@ -104,8 +119,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
case VicIIMode.NTSC:
|
case VicIIMode.NTSC:
|
||||||
rasterWidth = 512;
|
rasterWidth = 512;
|
||||||
rasterTotalLines = 263;
|
rasterTotalLines = 263;
|
||||||
visibleWidth = 368;
|
rasterLineLeft = 0x19C;
|
||||||
visibleHeight = 235;
|
visibleLeft = 0x1E9;
|
||||||
|
visibleRight = 0x18B;
|
||||||
|
visibleTop = 0x41;
|
||||||
|
visibleBottom = 0x13;
|
||||||
|
visibleRenderX = false;
|
||||||
|
visibleRenderY = true;
|
||||||
|
visibleWidth = 418;
|
||||||
|
visibleHeight = 217;
|
||||||
|
renderOffset = 0;
|
||||||
|
borderLeft = 0x018;
|
||||||
|
borderRight = 0x158;
|
||||||
|
borderTop = 0x033;
|
||||||
|
borderBottom = 0x0FA;
|
||||||
break;
|
break;
|
||||||
case VicIIMode.PAL:
|
case VicIIMode.PAL:
|
||||||
break;
|
break;
|
||||||
|
@ -116,6 +143,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
// initialize raster
|
// initialize raster
|
||||||
backgroundColor = new int[4];
|
backgroundColor = new int[4];
|
||||||
charBuffer = new byte[40];
|
charBuffer = new byte[40];
|
||||||
|
rasterOffsetX = rasterLineLeft;
|
||||||
|
rasterOffsetY = 0;
|
||||||
|
|
||||||
// initialize sprites
|
// initialize sprites
|
||||||
spriteBackgroundCollision = new bool[8];
|
spriteBackgroundCollision = new bool[8];
|
||||||
|
@ -135,9 +164,24 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
bufferSize = buffer.Length;
|
bufferSize = buffer.Length;
|
||||||
|
|
||||||
// initialize registers
|
// initialize registers
|
||||||
|
HardReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HardReset()
|
||||||
|
{
|
||||||
|
// power on state
|
||||||
regs = new byte[0x40];
|
regs = new byte[0x40];
|
||||||
|
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++)
|
for (int i = 0x2F; i <= 0x3F; i++)
|
||||||
regs[i] = 0xFF;
|
regs[i] = 0xFF;
|
||||||
|
|
||||||
UpdateRegs();
|
UpdateRegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +193,54 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public void PerformCycle()
|
public void PerformCycle()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
WritePixel(borderColor);
|
{
|
||||||
|
if (rasterOffsetX == visibleLeft)
|
||||||
|
visibleRenderX = true;
|
||||||
|
if (rasterOffsetX == visibleRight)
|
||||||
|
visibleRenderX = false;
|
||||||
|
if (rasterOffsetX == borderLeft)
|
||||||
|
borderOnHorizontal = false;
|
||||||
|
if (rasterOffsetX == borderRight)
|
||||||
|
borderOnHorizontal = true;
|
||||||
|
|
||||||
if (rasterInterruptEnabled && (rasterOffsetY == rasterInterruptLine) && (rasterOffsetX == 0))
|
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;
|
rasterInterrupt = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
interrupt =
|
interrupt =
|
||||||
(rasterInterrupt & rasterInterruptEnabled) |
|
(rasterInterrupt & rasterInterruptEnabled) |
|
||||||
|
@ -204,7 +290,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
bool allowWrite = true;
|
bool allowWrite = true;
|
||||||
addr &= 0x3F;
|
addr &= 0x3F;
|
||||||
|
|
||||||
switch (addr & 0x3F)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
case 0x02:
|
case 0x02:
|
||||||
|
@ -390,13 +476,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
private void WritePixel(int value)
|
private void WritePixel(int value)
|
||||||
{
|
{
|
||||||
buffer[rasterOffset] = palette[value];
|
if (visibleRenderX && visibleRenderY)
|
||||||
rasterOffset++;
|
{
|
||||||
if (rasterOffset >= bufferSize)
|
value &= 0x0F;
|
||||||
rasterOffset = 0;
|
buffer[renderOffset++] = palette[value];
|
||||||
|
}
|
||||||
rasterOffsetX = (rasterOffset & 0x1FF);
|
|
||||||
rasterOffsetY = (rasterOffset >> 9);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue