Commodore64: Experimental Vic implementation nearly complete.
This commit is contained in:
parent
c827d42f2d
commit
cfc2b141bf
|
@ -14,17 +14,30 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
bool badLineCondition;
|
||||
bool badLineEnable;
|
||||
int characterData;
|
||||
int[] characterMatrix;
|
||||
int colorData;
|
||||
int[] colorMatrix;
|
||||
int data;
|
||||
int graphicsData;
|
||||
int graphicsGeneratorCharacter;
|
||||
int graphicsGeneratorColor;
|
||||
int graphicsGeneratorData;
|
||||
int graphicsGeneratorPixel;
|
||||
int graphicsGeneratorPixelData;
|
||||
bool idleState;
|
||||
bool mainBorder;
|
||||
int mainBorderEnd;
|
||||
int mainBorderStart;
|
||||
bool phi0;
|
||||
int phi1Data;
|
||||
int pixel;
|
||||
int[] pixelDataBuffer;
|
||||
int rasterX;
|
||||
int refreshCounter;
|
||||
int rowCounter;
|
||||
bool verticalBorder;
|
||||
int verticalBorderEnd;
|
||||
int verticalBorderStart;
|
||||
int videoCounter;
|
||||
int videoCounterBase;
|
||||
int videoMatrixLineIndex;
|
||||
|
@ -42,6 +55,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
if (screenYEnd < screenYStart)
|
||||
screenHeight += rasterCount;
|
||||
|
||||
// create video buffer
|
||||
videoBuffer = new int[screenWidth * screenHeight];
|
||||
|
||||
// reset registers
|
||||
pixelBufferLength = 12;
|
||||
Reset();
|
||||
|
@ -49,16 +65,39 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
|
||||
public void Clock()
|
||||
{
|
||||
// these should be cached somewhere
|
||||
mainBorderStart = columnSelect ? 0x18 : 0x1F;
|
||||
mainBorderEnd = columnSelect ? 0x158 : 0x14F;
|
||||
verticalBorderStart = rowSelect ? 0x33 : 0x37;
|
||||
verticalBorderEnd = rowSelect ? 0xFB : 0xF7;
|
||||
|
||||
do
|
||||
{
|
||||
// process horizontal triggers
|
||||
// process hblank trigger
|
||||
if (rasterX == screenXStart)
|
||||
hBlank = false;
|
||||
else if (rasterX == screenXEnd)
|
||||
else if (rasterX == screenXEnd && !hBlank)
|
||||
{
|
||||
hBlank = true;
|
||||
rasterDelay = hBlankDelay;
|
||||
|
||||
// process row counter
|
||||
if (rowCounter == 7)
|
||||
{
|
||||
idleState = true;
|
||||
videoCounterBase = videoCounter;
|
||||
}
|
||||
else if (!idleState)
|
||||
rowCounter++;
|
||||
|
||||
// process vertical border flipflop
|
||||
if (rasterY == mainBorderEnd)
|
||||
verticalBorder = true;
|
||||
if (rasterY == mainBorderStart && displayEnable)
|
||||
verticalBorder = false;
|
||||
}
|
||||
|
||||
// process character BA trigger
|
||||
if (rasterX == characterBAStart)
|
||||
characterBA = false;
|
||||
else if (rasterX == characterBAEnd)
|
||||
|
@ -66,13 +105,21 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
characterBA = true;
|
||||
graphicsFetch = false;
|
||||
}
|
||||
|
||||
// process character fetch trigger
|
||||
if (rasterX == characterFetchStart)
|
||||
{
|
||||
graphicsFetch = true;
|
||||
refreshFetch = false;
|
||||
}
|
||||
|
||||
// process new line/raster triggers
|
||||
if (rasterX == rasterWidth)
|
||||
{
|
||||
rasterX = 0;
|
||||
videoCounter = videoCounterBase;
|
||||
videoMatrixLineIndex = 0;
|
||||
}
|
||||
else if (rasterX == rasterAdvance)
|
||||
{
|
||||
// process vertical triggers
|
||||
|
@ -81,20 +128,26 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
vBlank = false;
|
||||
else if (rasterY == screenYEnd)
|
||||
vBlank = true;
|
||||
else if (rasterY == rasterCount)
|
||||
{
|
||||
rasterY = 0;
|
||||
videoCounterBase = 0;
|
||||
videoBufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// determine BA and fetch state
|
||||
ba = true;
|
||||
|
||||
// None is used for when we don't assert control.
|
||||
fetchState = phi0 ? FetchState.Idle : FetchState.None;
|
||||
|
||||
// determine BA state
|
||||
ba = true;
|
||||
|
||||
if (characterBA)
|
||||
{
|
||||
// covers badlines and display area fetches
|
||||
characterFetch = (badLineCondition && badLineEnable);
|
||||
ba = !characterFetch;
|
||||
fetchState = phi0 ? FetchState.Graphics : (characterFetch ? FetchState.Character : FetchState.None);
|
||||
fetchState = phi0 ? FetchState.Graphics : FetchState.Character;
|
||||
}
|
||||
else if (refreshFetch)
|
||||
{
|
||||
|
@ -104,6 +157,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
else
|
||||
{
|
||||
// covers sprite pointer and data fetches
|
||||
spriteIndex = 0;
|
||||
foreach (Sprite sprite in sprites)
|
||||
{
|
||||
if (rasterX == sprite.BAStart)
|
||||
|
@ -113,18 +167,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
sprite.BA = true;
|
||||
sprite.Fetch = false;
|
||||
}
|
||||
if (!sprite.BA && sprite.Enabled)
|
||||
if (sprite.Fetch)
|
||||
{
|
||||
fetchState = FetchState.Sprite;
|
||||
ba = false;
|
||||
break;
|
||||
}
|
||||
if (rasterX == sprite.FetchStart)
|
||||
else if (rasterX == sprite.FetchStart)
|
||||
{
|
||||
sprite.Fetch = true;
|
||||
sprite.Fetch = sprite.Enabled;
|
||||
fetchState = FetchState.Pointer;
|
||||
ba = !sprite.Fetch;
|
||||
break;
|
||||
}
|
||||
spriteIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,17 +203,34 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
switch (fetchState)
|
||||
{
|
||||
case FetchState.Character:
|
||||
address = videoCounter | videoMemory;
|
||||
colorData = ReadColorRam(address);
|
||||
characterData = ReadRam(address);
|
||||
data = characterData;
|
||||
if (badLineCondition)
|
||||
{
|
||||
address = videoCounter | videoMemory;
|
||||
colorMatrix[videoMatrixLineIndex] = colorData = ReadColorRam(address);
|
||||
characterMatrix[videoMatrixLineIndex] = characterData = data = ReadRam(address);
|
||||
}
|
||||
else if (!idleState)
|
||||
{
|
||||
colorData = colorMatrix[videoMatrixLineIndex];
|
||||
characterData = characterMatrix[videoMatrixLineIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
colorData = 0;
|
||||
characterData = 0;
|
||||
}
|
||||
break;
|
||||
case FetchState.Graphics:
|
||||
address = (extraColorMode ? 0x39FF : 0x3FFF);
|
||||
if (bitmapMode)
|
||||
address &= (rowCounter | (videoCounter << 3) | (characterBitmap & 0x2000));
|
||||
else
|
||||
address &= (rowCounter | (data << 3) | characterBitmap);
|
||||
if (!idleState)
|
||||
{
|
||||
if (bitmapMode)
|
||||
address &= (rowCounter | (videoCounter << 3) | (characterBitmap & 0x2000));
|
||||
else
|
||||
address &= (rowCounter | (characterData << 3) | characterBitmap);
|
||||
videoMatrixLineIndex++;
|
||||
videoMatrixLineIndex &= 0x3F;
|
||||
}
|
||||
data = ReadRam(address);
|
||||
graphicsData = data;
|
||||
break;
|
||||
|
@ -172,6 +245,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
case FetchState.Refresh:
|
||||
address = refreshCounter | 0x3F00;
|
||||
data = ReadRam(address);
|
||||
refreshCounter--;
|
||||
refreshCounter &= 0xFF;
|
||||
break;
|
||||
case FetchState.Sprite:
|
||||
address = data | sprites[spriteIndex].Counter;
|
||||
|
@ -182,20 +257,169 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
// render 4 pixels
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// pixelbuffer -> videobuffer
|
||||
if (!hBlank && !vBlank)
|
||||
{
|
||||
videoBuffer[videoBufferIndex] = palette[pixelBuffer[pixelBufferIndex]];
|
||||
videoBufferIndex++;
|
||||
}
|
||||
|
||||
// graphics generator
|
||||
if ((rasterX & 0x7) == xScroll)
|
||||
{
|
||||
graphicsGeneratorCharacter = characterData;
|
||||
graphicsGeneratorColor = colorData;
|
||||
graphicsGeneratorData = graphicsData;
|
||||
}
|
||||
|
||||
// shift graphics data
|
||||
if (!multiColorMode || (!bitmapMode && ((colorData & 0x4) == 0)))
|
||||
{
|
||||
graphicsGeneratorPixelData = graphicsData & 0x01;
|
||||
graphicsData >>= 1;
|
||||
}
|
||||
else if ((rasterX & 0x7) == xScroll)
|
||||
{
|
||||
graphicsGeneratorPixelData = graphicsData & 0x03;
|
||||
graphicsData >>= 2;
|
||||
}
|
||||
|
||||
// generate pixel
|
||||
if (!verticalBorder)
|
||||
{
|
||||
if (extraColorMode)
|
||||
{
|
||||
if (bitmapMode)
|
||||
{
|
||||
// ECM=1, BMM=1, MCM=1
|
||||
// ECM=1, BMM=1, MCM=0
|
||||
graphicsGeneratorPixel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (multiColorMode)
|
||||
{
|
||||
// ECM=1, BMM=0, MCM=1
|
||||
graphicsGeneratorPixel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ECM=1, BMM=0, MCM=0
|
||||
if (graphicsGeneratorPixelData == 0)
|
||||
graphicsGeneratorPixel = backgroundColor[characterData >> 6];
|
||||
else
|
||||
graphicsGeneratorPixel = colorData;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitmapMode)
|
||||
{
|
||||
if (multiColorMode)
|
||||
{
|
||||
// ECM=0, BMM=1, MCM=1
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else if (graphicsGeneratorPixelData == 0x1)
|
||||
graphicsGeneratorPixel = characterData >> 4;
|
||||
else if (graphicsGeneratorPixelData == 0x2)
|
||||
graphicsGeneratorPixel = (characterData & 0xF);
|
||||
else
|
||||
graphicsGeneratorPixel = colorData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ECM=0, BMM=1, MCM=0
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
graphicsGeneratorPixel = (characterData & 0xF);
|
||||
else
|
||||
graphicsGeneratorPixel = characterData >> 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (multiColorMode)
|
||||
{
|
||||
// ECM=0, BMM=0, MCM=1
|
||||
if ((colorData & 0x4) == 0)
|
||||
{
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else
|
||||
graphicsGeneratorPixel = (colorData & 0x7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else if (graphicsGeneratorPixelData == 0x1)
|
||||
graphicsGeneratorPixel = backgroundColor[1];
|
||||
else if (graphicsGeneratorPixelData == 0x2)
|
||||
graphicsGeneratorPixel = backgroundColor[2];
|
||||
else
|
||||
graphicsGeneratorPixel = (colorData & 0x7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ECM=0, BMM=0, MCM=0
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else
|
||||
graphicsGeneratorPixel = colorData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// vertical border enabled, disable output
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
graphicsGeneratorPixelData = 0x0;
|
||||
}
|
||||
|
||||
// pixel generator -> pixelbuffer
|
||||
pixelBuffer[pixelBufferIndex] = graphicsGeneratorPixel;
|
||||
|
||||
// border unit comparisons
|
||||
if (rasterX == verticalBorderStart)
|
||||
mainBorder = true;
|
||||
else if (rasterX == verticalBorderEnd)
|
||||
{
|
||||
if (rasterY == mainBorderStart)
|
||||
verticalBorder = true;
|
||||
if (rasterY == mainBorderEnd && displayEnable)
|
||||
verticalBorder = false;
|
||||
if (!verticalBorder)
|
||||
mainBorder = false;
|
||||
}
|
||||
|
||||
// border unit -> pixelbuffer
|
||||
if (mainBorder || verticalBorder)
|
||||
pixelBuffer[borderPixelBufferIndex] = borderColor;
|
||||
|
||||
// advance pixelbuffer
|
||||
pixelBufferIndex++;
|
||||
if (pixelBufferIndex == pixelBufferLength)
|
||||
pixelBufferIndex = 0;
|
||||
borderPixelBufferIndex++;
|
||||
if (borderPixelBufferIndex == pixelBufferLength)
|
||||
borderPixelBufferIndex = 0;
|
||||
|
||||
// horizontal raster delay found in 6567R8
|
||||
if (rasterDelay > 0)
|
||||
rasterDelay--;
|
||||
else
|
||||
rasterX++;
|
||||
}
|
||||
|
||||
if (!phi0)
|
||||
phi1Data = data;
|
||||
|
||||
phi0 = !phi0;
|
||||
} while (phi0);
|
||||
|
||||
|
||||
// at the end, clock other devices if applicable
|
||||
ClockPhi0();
|
||||
}
|
||||
|
@ -218,8 +442,21 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
|
||||
// empty out the pixel buffer
|
||||
pixelBuffer = new int[pixelBufferLength];
|
||||
pixelDataBuffer = new int[pixelBufferLength];
|
||||
pixelBufferIndex = 0;
|
||||
borderPixelBufferIndex = 8;
|
||||
|
||||
// internal screen row buffer
|
||||
colorMatrix = new int[40];
|
||||
characterMatrix = new int[40];
|
||||
rowCounter = 0;
|
||||
videoCounter = 0;
|
||||
videoCounterBase = 0;
|
||||
videoMatrixLineIndex = 0;
|
||||
|
||||
// border unit
|
||||
mainBorder = true;
|
||||
verticalBorder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue