Commodore64: Preparation to implement savestates once again.

This commit is contained in:
saxxonpike 2013-08-18 01:21:53 +00:00
parent 0b6bce0198
commit 4efe07378f
6 changed files with 413 additions and 489 deletions

View File

@ -156,6 +156,7 @@
<Compile Include="Computers\Commodore64\MOS\Vic.Registers.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.Render.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.Sprite.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.State.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.VideoProvider.cs" />
<Compile Include="Computers\Commodore64\Tape\VIC1530.cs" />
<Compile Include="Consoles\Atari\2600\Atari2600.cs" />

View File

@ -7,18 +7,33 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
public abstract partial class Vic
{
protected const int baResetCounter = 6;
protected const int pipelineUpdateVc = 1;
protected const int pipelineChkSprChunch = 2;
protected const int pipelineUpdateMcBase = 4;
protected const int pipelineChkBrdL1 = 8;
protected const int pipelineChkBrdL0 = 16;
protected const int pipelineChkSprDma = 32;
protected const int pipelineChkBrdR0 = 64;
protected const int pipelineChkSprExp = 128;
protected const int pipelineChkBrdR1 = 256;
protected const int pipelineChkSprDisp = 512;
protected const int pipelineUpdateRc = 1024;
protected const int rasterIrqLine0Cycle = 1;
protected const int rasterIrqLineXCycle = 0;
private int parseaddr;
private int parsecycleBAsprite0;
private int parsecycleBAsprite1;
private int parsecycleBAsprite2;
private int parsecycleFetchSpriteIndex;
private int parsefetch;
private int parsefetchType;
private int parseba;
private int parseact;
private void ParseCycle()
{
{
parseaddr = 0x3FFF;
parsefetch = pipeline[1][cycleIndex];
@ -29,15 +44,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
rasterX = pipeline[0][cycleIndex];
// perform fetch
switch (parsefetch & 0xFF00)
parsefetchType = parsefetch & 0xFF00;
if (parsefetchType == 0x100)
{
case 0x0100:
// fetch R
refreshCounter = (refreshCounter - 1) & 0xFF;
parseaddr = (0x3F00 | refreshCounter);
ReadMemory(parseaddr);
break;
case 0x0200:
}
else if (parsefetchType == 0x200)
{
// fetch C
if (!idle)
{
@ -58,8 +74,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
dataC = 0;
bufferC[vmli] = dataC;
}
break;
case 0x0300:
}
else if (parsefetchType == 0x300)
{
// fetch G
if (idle)
parseaddr = 0x3FFF;
@ -79,17 +96,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
vmli = (vmli + 1) & 0x3F;
vc = (vc + 1) & 0x3FF;
}
break;
case 0x0400:
}
else if (parsefetchType == 0x400)
{
// fetch I
parseaddr = (extraColorMode ? 0x39FF : 0x3FFF);
dataG = ReadMemory(parseaddr);
dataC = 0;
break;
case 0x0500:
// no fetch
break;
default:
}
else if (parsefetchType == 0x500)
{
// fetch none
}
else
{
parsecycleFetchSpriteIndex = (parsefetch & 0x7);
switch (parsefetch & 0xF0)
{
@ -113,7 +133,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
break;
}
break;
}
// perform BA flag manipulation

View File

@ -7,37 +7,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
public abstract partial class Vic
{
private int backgroundColor0;
private int backgroundColor1;
private int backgroundColor2;
private int backgroundColor3;
private bool bitmapMode;
private int borderColor;
private bool columnSelect;
private bool displayEnable;
private bool enableIntLightPen;
private bool enableIntRaster;
private bool enableIntSpriteCollision;
private bool enableIntSpriteDataCollision;
private bool extraColorMode;
private bool intLightPen;
private bool intRaster;
private bool intSpriteCollision;
private bool intSpriteDataCollision;
private int lightPenX;
private int lightPenY;
private bool multicolorMode;
private int pointerCB;
private int pointerVM;
private int rasterInterruptLine;
private int rasterLine;
private int rasterX;
private bool rowSelect;
private int spriteMulticolor0;
private int spriteMulticolor1;
private Sprite[] sprites;
private int xScroll;
private int yScroll;
public byte Peek(int addr)
{

View File

@ -7,6 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
public abstract partial class Vic
{
private int ecmPixel;
private int pixel;
private int[] pixelBackgroundBuffer;
private int pixelBackgroundBufferDelay;
private int pixelBackgroundBufferIndex;
private int[] pixelBuffer;
private int pixelBufferDelay;
private int pixelBufferIndex;
private int pixelData;
private void Render()
{
@ -80,12 +90,14 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
spr.sr <<= 1;
}
spr.xCrunch ^= spr.xExpand;
switch (sprData)
{
case 1: sprPixel = spriteMulticolor0; break;
case 2: sprPixel = spr.color; break;
case 3: sprPixel = spriteMulticolor1; break;
}
if (sprData == 1)
sprPixel = spriteMulticolor0;
else if (sprData == 2)
sprPixel = spr.color;
else if (sprData == 3)
sprPixel = spriteMulticolor1;
if (sprData != 0)
{
// sprite-sprite collision
@ -149,13 +161,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
pixelData = (sr & 0xC0) >> 6;
if ((bitmapColumn & 1) != 0)
sr <<= 2;
switch (pixelData)
{
case 0x00: pixel = backgroundColor0; break;
case 0x01: pixel = backgroundColor1; break;
case 0x02: pixel = backgroundColor2; break;
default: pixel = (displayC & 0x700) >> 8; break;
}
if (pixelData == 0)
pixel = backgroundColor0;
else if (pixelData == 1)
pixel = backgroundColor1;
else if (pixelData == 2)
pixel = backgroundColor2;
else
pixel = (displayC & 0x700) >> 8;
}
else
{
@ -178,13 +192,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
pixelData = (sr & 0xC0) >> 6;
if ((bitmapColumn & 1) != 0)
sr <<= 2;
switch (pixelData)
{
case 0x00: pixel = backgroundColor0; break;
case 0x01: pixel = (displayC >> 4) & 0xF; break;
case 0x02: pixel = displayC & 0xF; break;
default: pixel = (displayC >> 8) & 0xF; break;
}
if (pixelData == 0)
pixel = backgroundColor0;
else if (pixelData == 1)
pixel = (displayC >> 4) & 0xF;
else if (pixelData == 2)
pixel = displayC & 0xF;
else
pixel = (displayC >> 8) & 0xF;
}
else if (extraColorMode && !bitmapMode & !multicolorMode)
{
@ -197,13 +213,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
else
{
switch ((displayC >> 6) & 0x3)
{
case 0x00: pixel = backgroundColor0; break;
case 0x01: pixel = backgroundColor1; break;
case 0x02: pixel = backgroundColor2; break;
default: pixel = backgroundColor3; break;
}
ecmPixel = (displayC >> 6) & 0x3;
if (ecmPixel == 0)
pixel = backgroundColor0;
else if (ecmPixel == 1)
pixel = backgroundColor1;
else if (ecmPixel == 2)
pixel = backgroundColor2;
else
pixel = backgroundColor3;
}
}
else if (extraColorMode && !bitmapMode & multicolorMode)

View File

@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
public abstract partial class Vic
{
private int backgroundColor0;
private int backgroundColor1;
private int backgroundColor2;
private int backgroundColor3;
private int baCount;
private bool badline;
private bool badlineEnable;
private int bitmapColumn;
private bool bitmapMode;
private int borderB;
private bool borderCheckLEnable;
private bool borderCheckREnable;
private int borderColor;
private int borderL;
private bool borderOnMain;
private bool borderOnVertical;
private int borderR;
private int borderT;
private int[] bufferC;
private int[] bufferG;
private int cycle;
private int cycleIndex;
private bool columnSelect;
private int dataC;
private int dataG;
private bool debugScreen;
private bool displayEnable;
private int displayIndex;
private int displayC;
private bool enableIntLightPen;
private bool enableIntRaster;
private bool enableIntSpriteCollision;
private bool enableIntSpriteDataCollision;
private bool extraColorMode;
private bool idle;
private bool intLightPen;
private bool intRaster;
private bool intSpriteCollision;
private bool intSpriteDataCollision;
private int lastRasterLine;
private int lightPenX;
private int lightPenY;
private bool multicolorMode;
private bool pinAEC = true;
private bool pinBA = true;
private bool pinIRQ = true;
private int[] pixelDataBuffer;
private int pointerCB;
private int pointerVM;
private int rasterInterruptLine;
private int rasterLine;
private int rasterX;
private int rc;
private int refreshCounter;
private bool renderEnabled;
private bool rowSelect;
private int spriteMulticolor0;
private int spriteMulticolor1;
private Sprite[] sprites;
private int sr;
private int vc;
private int vcbase;
private int vmli;
private int xOffset;
private int xScroll;
private int yScroll;
public void HardReset()
{
pinAEC = true;
pinBA = true;
pinIRQ = true;
bufOffset = 0;
backgroundColor0 = 0;
backgroundColor1 = 0;
backgroundColor2 = 0;
backgroundColor3 = 0;
baCount = baResetCounter;
badline = false;
badlineEnable = false;
bitmapMode = false;
borderCheckLEnable = false;
borderCheckREnable = false;
borderColor = 0;
borderOnMain = true;
borderOnVertical = true;
columnSelect = false;
displayEnable = false;
displayIndex = 0;
enableIntLightPen = false;
enableIntRaster = false;
enableIntSpriteCollision = false;
enableIntSpriteDataCollision = false;
extraColorMode = false;
idle = true;
intLightPen = false;
intRaster = false;
intSpriteCollision = false;
intSpriteDataCollision = false;
lastRasterLine = 0;
lightPenX = 0;
lightPenY = 0;
multicolorMode = false;
pixelBufferIndex = 0;
pixelBackgroundBufferIndex = 0;
pointerCB = 0;
pointerVM = 0;
rasterInterruptLine = 0;
rasterLine = 0;
rasterX = 0;
rc = 7;
refreshCounter = 0xFF;
rowSelect = false;
spriteMulticolor0 = 0;
spriteMulticolor1 = 0;
sr = 0;
vc = 0;
vcbase = 0;
vmli = 0;
xOffset = 0;
xScroll = 0;
yScroll = 0;
// reset sprites
for (int i = 0; i < 8; i++)
sprites[i].HardReset();
// clear C buffer
for (int i = 0; i < 40; i++)
{
bufferC[i] = 0;
bufferG[i] = 0;
}
// clear pixel buffer
for (int i = 0; i < pixelBufferDelay; i++)
{
pixelBuffer[i] = 0;
pixelDataBuffer[i] = 0;
}
for (int i = 0; i < pixelBackgroundBufferDelay; i++)
pixelBackgroundBuffer[i] = 0;
UpdateBorder();
}
public void SyncState(Serializer ser)
{
}
}
}

View File

@ -5,65 +5,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
public abstract partial class Vic
{
// ------------------------------------
private int baCount;
private bool badline;
private bool badlineEnable;
private int bitmapColumn;
private int borderB;
private bool borderCheckLEnable;
private bool borderCheckREnable;
private int borderL;
private bool borderOnMain;
private bool borderOnVertical;
private int borderR;
private int borderT;
private int[] bufferC;
private int[] bufferG;
private int cycle;
private int cycleIndex;
private int dataC;
private int dataG;
private bool debugScreen;
private int displayC;
private int displayIndex;
private bool idle;
private int lastRasterLine;
private int pixel;
private int[] pixelBackgroundBuffer;
private int pixelBackgroundBufferDelay;
private int pixelBackgroundBufferIndex;
private int[] pixelBuffer;
private int pixelBufferDelay;
private int pixelBufferIndex;
private int pixelData;
private int[] pixelDataBuffer;
private int rc;
private int refreshCounter;
private bool renderEnabled;
private int sr;
private int vc;
private int vcbase;
private int vmli;
private int xOffset;
// ------------------------------------
private int cyclesPerSec;
private bool pinAEC = true;
private bool pinBA = true;
private bool pinIRQ = true;
private int[][] pipeline;
private int totalCycles;
private int totalLines;
// ------------------------------------
public Func<int, byte> ReadColorRam;
public Func<int, byte> ReadMemory;
// ------------------------------------
public bool ReadAECBuffer() { return pinAEC; }
public bool ReadBABuffer() { return pinBA; }
public bool ReadIRQBuffer() { return pinIRQ; }
private int cyclesPerSec;
private int[][] pipeline;
private int totalCycles;
private int totalLines;
public Vic(int newCycles, int newLines, int[][] newPipeline, int newCyclesPerSec)
{
@ -104,142 +56,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
}
public void HardReset()
public int CyclesPerFrame
{
pinAEC = true;
pinBA = true;
pinIRQ = true;
bufOffset = 0;
backgroundColor0 = 0;
backgroundColor1 = 0;
backgroundColor2 = 0;
backgroundColor3 = 0;
baCount = baResetCounter;
badline = false;
badlineEnable = false;
bitmapMode = false;
borderCheckLEnable = false;
borderCheckREnable = false;
borderColor = 0;
borderOnMain = true;
borderOnVertical = true;
columnSelect = false;
displayEnable = false;
displayIndex = 0;
enableIntLightPen = false;
enableIntRaster = false;
enableIntSpriteCollision = false;
enableIntSpriteDataCollision = false;
extraColorMode = false;
idle = true;
intLightPen = false;
intRaster = false;
intSpriteCollision = false;
intSpriteDataCollision = false;
lastRasterLine = 0;
lightPenX = 0;
lightPenY = 0;
multicolorMode = false;
pixelBufferIndex = 0;
pixelBackgroundBufferIndex = 0;
pointerCB = 0;
pointerVM = 0;
rasterInterruptLine = 0;
rasterLine = 0;
rasterX = 0;
rc = 7;
refreshCounter = 0xFF;
rowSelect = false;
spriteMulticolor0 = 0;
spriteMulticolor1 = 0;
sr = 0;
vc = 0;
vcbase = 0;
vmli = 0;
xOffset = 0;
xScroll = 0;
yScroll = 0;
// reset sprites
for (int i = 0; i < 8; i++)
sprites[i].HardReset();
// clear C buffer
for (int i = 0; i < 40; i++)
get
{
bufferC[i] = 0;
bufferG[i] = 0;
}
// clear pixel buffer
for (int i = 0; i < pixelBufferDelay; i++)
{
pixelBuffer[i] = 0;
pixelDataBuffer[i] = 0;
}
for (int i = 0; i < pixelBackgroundBufferDelay; i++)
pixelBackgroundBuffer[i] = 0;
UpdateBorder();
}
private void UpdateBA()
{
{
if (pinBA)
baCount = baResetCounter;
else if (baCount > 0)
baCount--;
return (totalCycles * totalLines);
}
}
private void UpdateBorder()
public int CyclesPerSecond
{
get
{
borderL = columnSelect ? 0x018 : 0x01F;
borderR = columnSelect ? 0x158 : 0x14F;
borderT = rowSelect ? 0x033 : 0x037;
borderB = rowSelect ? 0x0FB : 0x0F7;
return cyclesPerSec;
}
}
private void UpdatePins()
{
{
pinIRQ = !(
(enableIntRaster & intRaster) |
(enableIntSpriteDataCollision & intSpriteDataCollision) |
(enableIntSpriteCollision & intSpriteCollision) |
(enableIntLightPen & intLightPen));
}
}
// ------------------------------------
protected const int pipelineUpdateVc = 1;
protected const int pipelineChkSprChunch = 2;
protected const int pipelineUpdateMcBase = 4;
protected const int pipelineChkBrdL1 = 8;
protected const int pipelineChkBrdL0 = 16;
protected const int pipelineChkSprDma = 32;
protected const int pipelineChkBrdR0 = 64;
protected const int pipelineChkSprExp = 128;
protected const int pipelineChkBrdR1 = 256;
protected const int pipelineChkSprDisp = 512;
protected const int pipelineUpdateRc = 1024;
protected const int rasterIrqLine0Cycle = 1;
protected const int rasterIrqLineXCycle = 0;
protected const int baResetCounter = 6;
// ------------------------------------
public void ExecutePhase1()
{
@ -332,115 +164,38 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
}
}
// ------------------------------------
public bool ReadAECBuffer() { return pinAEC; }
public bool ReadBABuffer() { return pinBA; }
public bool ReadIRQBuffer() { return pinIRQ; }
// ------------------------------------
public int CyclesPerFrame
private void UpdateBA()
{
get
{
return (totalCycles * totalLines);
if (pinBA)
baCount = baResetCounter;
else if (baCount > 0)
baCount--;
}
}
public int CyclesPerSecond
private void UpdateBorder()
{
get
{
return cyclesPerSec;
borderL = columnSelect ? 0x018 : 0x01F;
borderR = columnSelect ? 0x158 : 0x14F;
borderT = rowSelect ? 0x033 : 0x037;
borderB = rowSelect ? 0x0FB : 0x0F7;
}
}
// ------------------------------------
// --------------------------
public void SyncState(Serializer ser)
private void UpdatePins()
{
for (int i = 0; i < 8; i++)
{
ser.BeginSection("sprite" + i.ToString());
sprites[i].SyncState(ser);
ser.EndSection();
}
ser.Sync("backgroundColor0", ref backgroundColor0);
ser.Sync("backgroundColor1", ref backgroundColor1);
ser.Sync("backgroundColor2", ref backgroundColor2);
ser.Sync("backgroundColor3", ref backgroundColor3);
ser.Sync("baCount", ref baCount);
ser.Sync("badline", ref badline);
ser.Sync("badlineEnable", ref badlineEnable);
ser.Sync("bitmapColumn", ref bitmapColumn);
ser.Sync("bitmapMode", ref bitmapMode);
ser.Sync("borderB", ref borderB);
ser.Sync("borderCheckLEnable", ref borderCheckLEnable);
ser.Sync("borderCheckREnable", ref borderCheckREnable);
ser.Sync("borderColor", ref borderColor);
ser.Sync("borderL", ref borderL);
ser.Sync("borderOnMain", ref borderOnMain);
ser.Sync("borderOnVertical", ref borderOnVertical);
ser.Sync("borderR", ref borderR);
ser.Sync("borderT", ref borderT);
ser.Sync("bufferC", ref bufferC, false);
ser.Sync("bufferG", ref bufferG, false);
ser.Sync("columnSelect", ref columnSelect);
ser.Sync("cycle", ref cycle);
ser.Sync("cycleIndex", ref cycleIndex);
ser.Sync("dataC", ref dataC);
ser.Sync("dataG", ref dataG);
ser.Sync("displayC", ref displayC);
ser.Sync("displayEnable", ref displayEnable);
ser.Sync("displayIndex", ref displayIndex);
ser.Sync("enableIntLightPen", ref enableIntLightPen);
ser.Sync("enableIntRaster", ref enableIntRaster);
ser.Sync("enableIntSpriteCollision", ref enableIntSpriteCollision);
ser.Sync("enableIntSpriteDataCollision", ref enableIntSpriteDataCollision);
ser.Sync("extraColorMode", ref extraColorMode);
ser.Sync("idle", ref idle);
ser.Sync("intLightPen", ref intLightPen);
ser.Sync("intRaster", ref intRaster);
ser.Sync("intSpriteCollision", ref intSpriteCollision);
ser.Sync("intSpriteDataCollision", ref intSpriteDataCollision);
ser.Sync("lastRasterLine", ref lastRasterLine);
ser.Sync("lightPenX", ref lightPenX);
ser.Sync("lightPenY", ref lightPenY);
ser.Sync("multicolorMode", ref multicolorMode);
ser.Sync("pixelBuffer", ref pixelBuffer, false);
ser.Sync("pixelBufferDelay", ref pixelBufferDelay);
ser.Sync("pixelBufferIndex", ref pixelBufferIndex);
ser.Sync("pixelBackgroundBuffer", ref pixelBackgroundBuffer, false);
ser.Sync("pixelBackgroundBufferDelay", ref pixelBackgroundBufferDelay);
ser.Sync("pixelBackgroundBufferIndex", ref pixelBackgroundBufferIndex);
ser.Sync("pixelDataBuffer", ref pixelDataBuffer, false);
ser.Sync("pointerCB", ref pointerCB);
ser.Sync("pointerVM", ref pointerVM);
ser.Sync("rasterInterruptLine", ref rasterInterruptLine);
ser.Sync("rasterLine", ref rasterLine);
ser.Sync("rasterX", ref rasterX);
ser.Sync("rc", ref rc);
ser.Sync("refreshCounter", ref refreshCounter);
ser.Sync("rowSelect", ref rowSelect);
ser.Sync("spriteMulticolor0", ref spriteMulticolor0);
ser.Sync("spriteMulticolor1", ref spriteMulticolor1);
ser.Sync("sr", ref sr);
ser.Sync("vc", ref vc);
ser.Sync("vcbase", ref vcbase);
ser.Sync("vmli", ref vmli);
ser.Sync("xOffset", ref xOffset);
ser.Sync("xScroll", ref xScroll);
ser.Sync("yScroll", ref yScroll);
ser.Sync("cyclesPerSec", ref cyclesPerSec);
ser.Sync("pinAEC", ref pinAEC);
ser.Sync("pinBA", ref pinBA);
ser.Sync("pinIRQ", ref pinIRQ);
ser.Sync("totalCycles", ref totalCycles);
ser.Sync("totalLines", ref totalLines);
{
pinIRQ = !(
(enableIntRaster & intRaster) |
(enableIntSpriteDataCollision & intSpriteDataCollision) |
(enableIntSpriteCollision & intSpriteCollision) |
(enableIntLightPen & intLightPen));
}
}
}
}