Commodore64: More work on the experimental VIC. Some speedups in the current VIC from caching the video mode and removing unnecessary shifts from the inner loops of the background graphics generator.
This commit is contained in:
parent
31b9e37f86
commit
bde52b25bd
|
@ -24,6 +24,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
public int Address { get { return address; } }
|
||||
public int CharacterData { get { return characterData; } }
|
||||
public int ColorData { get { return colorData; } }
|
||||
public int CyclesPerFrame { get { return rasterCount * rasterWidth / 8; } }
|
||||
public int CyclesPerSecond { get { return frequency; } }
|
||||
public int Data { get { return data; } }
|
||||
public int DataPhi1 { get { return phi1Data; } }
|
||||
public int GraphicsData { get { return graphicsData; } }
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
sealed public partial class Vic
|
||||
{
|
||||
const int AEC_DELAY = 7;
|
||||
const int GRAPHICS_GENERATOR_DELAY = 12;
|
||||
const int BORDER_GENERATOR_DELAY = 8;
|
||||
const int BORDER_GENERATOR_DELAY_BIT = 1 << BORDER_GENERATOR_DELAY;
|
||||
const bool BORDER_ENABLE = false;
|
||||
|
||||
int address;
|
||||
bool aec;
|
||||
|
@ -29,8 +29,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
int graphicsGeneratorColor;
|
||||
int graphicsGeneratorData;
|
||||
bool graphicsGeneratorMulticolor;
|
||||
int graphicsGeneratorOutputData;
|
||||
int graphicsGeneratorPipeData;
|
||||
int graphicsGeneratorPipePixel0;
|
||||
int graphicsGeneratorPipePixel2;
|
||||
int graphicsGeneratorPixel;
|
||||
int graphicsGeneratorPixelData;
|
||||
bool graphicsGeneratorShiftToggle;
|
||||
bool idleState;
|
||||
bool mainBorder;
|
||||
|
@ -39,12 +42,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
bool phi0;
|
||||
int phi1Data;
|
||||
int pixel;
|
||||
int[] pixelDataBuffer;
|
||||
int rasterX;
|
||||
int refreshCounter;
|
||||
int rowCounter;
|
||||
Sprite spriteBuffer;
|
||||
int spriteGeneratorBackgroundData;
|
||||
int spriteGeneratorPixel;
|
||||
int spriteGeneratorPixelData;
|
||||
bool spriteGeneratorPixelEnabled;
|
||||
|
@ -59,39 +60,59 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
public Vic(VicSettings settings)
|
||||
{
|
||||
// initialize timing values
|
||||
InitTiming(settings.timing);
|
||||
timing = settings.timing;
|
||||
|
||||
// calculate visible screen dimensions
|
||||
screenWidth = screenXEnd - screenXStart;
|
||||
screenHeight = screenYEnd - screenYStart;
|
||||
if (screenXEnd < screenXStart)
|
||||
screenWidth += rasterWidth;
|
||||
if (screenYEnd < screenYStart)
|
||||
screenHeight += rasterCount;
|
||||
// reset registers
|
||||
Reset();
|
||||
|
||||
// calculate visible width
|
||||
screenWidth = 0;
|
||||
rasterX = screenXStart;
|
||||
while (rasterX != screenXEnd)
|
||||
{
|
||||
screenWidth++;
|
||||
rasterX++;
|
||||
if (rasterX == rasterWidth)
|
||||
rasterX = 0;
|
||||
}
|
||||
|
||||
// calculate visible height
|
||||
screenHeight = 0;
|
||||
rasterY = screenYStart;
|
||||
while (rasterY != screenYEnd)
|
||||
{
|
||||
screenHeight++;
|
||||
rasterY++;
|
||||
if (rasterY == rasterCount)
|
||||
rasterY = 0;
|
||||
}
|
||||
|
||||
// reset raster counters
|
||||
rasterX = 0;
|
||||
rasterY = 0;
|
||||
|
||||
// create video buffer
|
||||
videoBuffer = new int[screenWidth * screenHeight];
|
||||
|
||||
// reset registers
|
||||
pixelBufferLength = GRAPHICS_GENERATOR_DELAY;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Clock()
|
||||
{
|
||||
// these should be cached somewhere
|
||||
mainBorderStart = columnSelect ? 0x18 : 0x1F;
|
||||
mainBorderEnd = columnSelect ? 0x158 : 0x14F;
|
||||
verticalBorderStart = rowSelect ? 0x33 : 0x37;
|
||||
verticalBorderEnd = rowSelect ? 0xFB : 0xF7;
|
||||
mainBorderEnd = columnSelect ? 0x18 : 0x1F;
|
||||
mainBorderStart = columnSelect ? 0x158 : 0x14F;
|
||||
verticalBorderEnd = rowSelect ? 0x33 : 0x37;
|
||||
verticalBorderStart = rowSelect ? 0xFB : 0xF7;
|
||||
|
||||
// process badline enable & condition
|
||||
if (rasterY >= 0x30 && rasterY < 0xF8)
|
||||
if (!badLineCondition && rasterY >= 0x30 && rasterY < 0xF8)
|
||||
{
|
||||
if (rasterY == 0x30 && displayEnable)
|
||||
badLineEnable = true;
|
||||
if (badLineEnable && ((rasterY & 0x7) == yScroll))
|
||||
{
|
||||
badLineCondition = true;
|
||||
idleState = false;
|
||||
}
|
||||
}
|
||||
|
||||
// process sprites on phi1
|
||||
|
@ -208,6 +229,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
rasterX = 0;
|
||||
videoCounter = videoCounterBase;
|
||||
videoMatrixLineIndex = 0;
|
||||
if (badLineCondition)
|
||||
rowCounter = 0;
|
||||
if (rasterY == rasterYCompare)
|
||||
rasterInterrupt = true;
|
||||
}
|
||||
else if (rasterX == rasterAdvance)
|
||||
{
|
||||
|
@ -224,25 +249,36 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
videoBufferIndex = 0;
|
||||
badLineEnable = false;
|
||||
}
|
||||
badLineCondition = false;
|
||||
}
|
||||
|
||||
// determine BA and fetch state
|
||||
ba = true;
|
||||
|
||||
// None is used for when we don't assert control.
|
||||
fetchState = phi0 ? FetchState.Idle : FetchState.None;
|
||||
fetchState = phi0 ? FetchState.None : FetchState.Idle;
|
||||
|
||||
if (characterBA)
|
||||
if (!characterBA && badLineCondition && badLineEnable)
|
||||
{
|
||||
// covers badlines and display area fetches
|
||||
characterFetch = (badLineCondition && badLineEnable);
|
||||
ba = !characterFetch;
|
||||
fetchState = phi0 ? FetchState.Graphics : FetchState.Character;
|
||||
ba = false;
|
||||
}
|
||||
else if (refreshFetch)
|
||||
|
||||
if (graphicsFetch)
|
||||
{
|
||||
if (badLineCondition && badLineEnable)
|
||||
{
|
||||
fetchState = phi0 ? FetchState.Character : FetchState.Graphics;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetchState = phi0 ? FetchState.CharacterInternal : FetchState.Graphics;
|
||||
}
|
||||
}
|
||||
|
||||
if (refreshFetch)
|
||||
{
|
||||
// covers memory refresh fetches
|
||||
fetchState = phi0 ? FetchState.Refresh : FetchState.None;
|
||||
fetchState = phi0 ? FetchState.None : FetchState.Refresh;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -270,7 +306,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
{
|
||||
sprite.Fetch = true;
|
||||
fetchState = FetchState.Pointer;
|
||||
ba = !sprite.Fetch;
|
||||
ba = !sprite.DMA;
|
||||
break;
|
||||
}
|
||||
spriteIndex++;
|
||||
|
@ -302,17 +338,16 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
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.CharacterInternal:
|
||||
colorData = colorMatrix[videoMatrixLineIndex];
|
||||
characterData = characterMatrix[videoMatrixLineIndex];
|
||||
break;
|
||||
case FetchState.Graphics:
|
||||
address = (extraColorMode ? 0x39FF : 0x3FFF);
|
||||
if (!idleState)
|
||||
|
@ -322,7 +357,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
else
|
||||
address &= (rowCounter | (characterData << 3) | characterBitmap);
|
||||
videoMatrixLineIndex++;
|
||||
videoMatrixLineIndex &= 0x3F;
|
||||
videoCounter = ((videoCounter + 1) & 0x3FF);
|
||||
}
|
||||
data = ReadRam(address);
|
||||
graphicsData = data;
|
||||
|
@ -354,7 +389,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
|
||||
// render 4 pixels (there are 8 per cycle)
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
// initialize background pixel data generator
|
||||
if ((rasterX & 0x7) == xScroll)
|
||||
|
@ -366,39 +401,27 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
graphicsGeneratorShiftToggle = !graphicsGeneratorMulticolor;
|
||||
}
|
||||
|
||||
// extract graphics data
|
||||
graphicsGeneratorOutputData = (graphicsGeneratorData & (graphicsGeneratorMulticolor ? 0xC0 : 0x80));
|
||||
graphicsGeneratorPipeData <<= 2;
|
||||
graphicsGeneratorPipeData |= graphicsGeneratorOutputData;
|
||||
|
||||
// shift graphics data
|
||||
if (graphicsGeneratorShiftToggle)
|
||||
graphicsGeneratorPixelData >>= graphicsGeneratorMulticolor ? 2 : 1;
|
||||
graphicsGeneratorData <<= graphicsGeneratorMulticolor ? 2 : 1;
|
||||
graphicsGeneratorShiftToggle = !graphicsGeneratorShiftToggle || !graphicsGeneratorMulticolor;
|
||||
|
||||
// generate data and color for the pixelbuffer
|
||||
if (!verticalBorder)
|
||||
if (!verticalBorder || !BORDER_ENABLE)
|
||||
{
|
||||
// graphics generator
|
||||
if (extraColorMode)
|
||||
if (extraColorMode && !bitmapMode && !multiColorMode)
|
||||
{
|
||||
if (bitmapMode)
|
||||
{
|
||||
// ECM=1, BMM=1, MCM=1
|
||||
// ECM=1, BMM=1, MCM=0
|
||||
graphicsGeneratorPixel = 0;
|
||||
}
|
||||
// ECM=1, BMM=0, MCM=0
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = backgroundColor[characterData >> 6];
|
||||
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;
|
||||
}
|
||||
}
|
||||
graphicsGeneratorPixel = colorData;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -407,11 +430,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
if (multiColorMode)
|
||||
{
|
||||
// ECM=0, BMM=1, MCM=1
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else if (graphicsGeneratorPixelData == 0x1)
|
||||
else if (graphicsGeneratorOutputData == 0x40)
|
||||
graphicsGeneratorPixel = characterData >> 4;
|
||||
else if (graphicsGeneratorPixelData == 0x2)
|
||||
else if (graphicsGeneratorOutputData == 0x80)
|
||||
graphicsGeneratorPixel = (characterData & 0xF);
|
||||
else
|
||||
graphicsGeneratorPixel = colorData;
|
||||
|
@ -419,7 +442,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
else
|
||||
{
|
||||
// ECM=0, BMM=1, MCM=0
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = (characterData & 0xF);
|
||||
else
|
||||
graphicsGeneratorPixel = characterData >> 4;
|
||||
|
@ -432,18 +455,18 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
// ECM=0, BMM=0, MCM=1
|
||||
if ((colorData & 0x4) == 0)
|
||||
{
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else
|
||||
graphicsGeneratorPixel = (colorData & 0x7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else if (graphicsGeneratorPixelData == 0x1)
|
||||
else if (graphicsGeneratorOutputData == 0x40)
|
||||
graphicsGeneratorPixel = backgroundColor[1];
|
||||
else if (graphicsGeneratorPixelData == 0x2)
|
||||
else if (graphicsGeneratorOutputData == 0x80)
|
||||
graphicsGeneratorPixel = backgroundColor[2];
|
||||
else
|
||||
graphicsGeneratorPixel = (colorData & 0x7);
|
||||
|
@ -452,7 +475,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
else
|
||||
{
|
||||
// ECM=0, BMM=0, MCM=0
|
||||
if (graphicsGeneratorPixelData == 0x0)
|
||||
if (graphicsGeneratorOutputData == 0x00)
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
else
|
||||
graphicsGeneratorPixel = colorData;
|
||||
|
@ -464,11 +487,23 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
{
|
||||
// vertical border enabled, disable output
|
||||
graphicsGeneratorPixel = backgroundColor[0];
|
||||
graphicsGeneratorPixelData = 0x0;
|
||||
}
|
||||
|
||||
// shift color data
|
||||
if (phi0)
|
||||
{
|
||||
graphicsGeneratorPipePixel2 <<= 4;
|
||||
graphicsGeneratorPipePixel2 |= graphicsGeneratorPixel;
|
||||
graphicsGeneratorPixel = (graphicsGeneratorPipePixel2 & 0x00F00000) >> 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
graphicsGeneratorPipePixel0 <<= 4;
|
||||
graphicsGeneratorPipePixel0 |= graphicsGeneratorPixel;
|
||||
graphicsGeneratorPixel = (graphicsGeneratorPipePixel0 & 0x00F00000) >> 20;
|
||||
}
|
||||
|
||||
// sprite generator
|
||||
spriteGeneratorBackgroundData = pixelDataBuffer[pixelBufferIndex];
|
||||
spriteIndex = 0;
|
||||
spriteGeneratorPixelEnabled = false;
|
||||
foreach (Sprite sprite in sprites)
|
||||
|
@ -524,7 +559,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
|
||||
// determine sprite-background collision
|
||||
if ((spriteGeneratorBackgroundData & 0x2) != 0)
|
||||
if ((graphicsGeneratorData & 0x200000) != 0)
|
||||
sprite.DataCollision = true;
|
||||
}
|
||||
|
||||
|
@ -534,14 +569,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
|
||||
// combine the pixels
|
||||
if (spriteGeneratorPixelEnabled && (!spriteGeneratorPriority || ((spriteGeneratorBackgroundData & 0x2) == 0)))
|
||||
if (spriteGeneratorPixelEnabled && (!spriteGeneratorPriority || ((graphicsGeneratorPipeData & 0x80000) == 0)))
|
||||
pixel = spriteGeneratorPixel;
|
||||
else
|
||||
pixel = pixelBuffer[pixelBufferIndex];
|
||||
|
||||
// pixel generator data -> pixeldatabuffer
|
||||
pixelDataBuffer[pixelBufferIndex] = graphicsGeneratorPixelData;
|
||||
pixelBuffer[pixelBufferIndex] = graphicsGeneratorPixel;
|
||||
pixel = graphicsGeneratorPixel;
|
||||
|
||||
// border unit comparisons
|
||||
if (rasterX == verticalBorderStart)
|
||||
|
@ -560,7 +591,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
borderDelay <<= 1;
|
||||
if (mainBorder || verticalBorder)
|
||||
borderDelay |= 1;
|
||||
if ((borderDelay & BORDER_GENERATOR_DELAY_BIT) != 0)
|
||||
if (BORDER_ENABLE && (borderDelay & BORDER_GENERATOR_DELAY_BIT) != 0)
|
||||
pixel = borderColor;
|
||||
|
||||
// rendered pixel -> videobuffer
|
||||
|
@ -570,11 +601,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
videoBufferIndex++;
|
||||
}
|
||||
|
||||
// advance pixelbuffer
|
||||
pixelBufferIndex++;
|
||||
if (pixelBufferIndex == pixelBufferLength)
|
||||
pixelBufferIndex = 0;
|
||||
|
||||
// horizontal raster delay found in 6567R8
|
||||
if (rasterDelay > 0)
|
||||
rasterDelay--;
|
||||
|
@ -588,31 +614,40 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
phi0 = !phi0;
|
||||
} while (phi0);
|
||||
|
||||
// process irq
|
||||
irq = !(
|
||||
(rasterInterrupt && rasterInterruptEnable)
|
||||
);
|
||||
|
||||
// at the end, clock other devices if applicable
|
||||
ClockPhi0();
|
||||
if (ClockPhi0 != null)
|
||||
ClockPhi0();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// set up color arrays
|
||||
backgroundColor = new int[4];
|
||||
spriteMultiColor = new int[2];
|
||||
|
||||
// set up sprites
|
||||
sprites = new Sprite[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
sprites[i] = new Sprite();
|
||||
for (int i = 0; i < 0x40; i++)
|
||||
Poke(i, 0);
|
||||
|
||||
// set up pin state
|
||||
phi0 = false;
|
||||
irq = true;
|
||||
ba = true;
|
||||
aec = true;
|
||||
|
||||
// we set these so no video is displayed before
|
||||
// the first frame starts
|
||||
vBlank = true;
|
||||
hBlank = true;
|
||||
|
||||
// empty out the pixel buffer
|
||||
pixelBuffer = new int[pixelBufferLength];
|
||||
pixelDataBuffer = new int[pixelBufferLength];
|
||||
pixelBufferIndex = 0;
|
||||
|
||||
// internal screen row buffer
|
||||
colorMatrix = new int[40];
|
||||
characterMatrix = new int[40];
|
||||
|
@ -624,6 +659,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
// border unit
|
||||
mainBorder = true;
|
||||
verticalBorder = true;
|
||||
|
||||
// setup timing
|
||||
InitTiming();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
bool rasterInterrupt;
|
||||
bool rasterInterruptEnable;
|
||||
int rasterY;
|
||||
int rasterYCompare;
|
||||
bool reset;
|
||||
bool rowSelect;
|
||||
bool spriteCollisionInterrupt;
|
||||
|
@ -192,6 +193,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
}
|
||||
|
||||
public byte PeekByte(int addr)
|
||||
{
|
||||
return (byte)(Peek(addr) & 0xFF);
|
||||
}
|
||||
|
||||
public void Poke(int addr, int val)
|
||||
{
|
||||
switch (addr)
|
||||
|
@ -228,9 +234,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
displayEnable = ((val & 0x10) != 0);
|
||||
bitmapMode = ((val & 0x20) != 0);
|
||||
extraColorMode = ((val & 0x40) != 0);
|
||||
rasterY = (rasterY & 0xFF) | ((val & 0x80) << 1);
|
||||
rasterYCompare = (rasterYCompare & 0xFF) | ((val & 0x80) << 1);
|
||||
return;
|
||||
case 0x12: rasterY = (rasterY & 0x100) | val; return;
|
||||
case 0x12: rasterYCompare = (rasterYCompare & 0x100) | val; return;
|
||||
case 0x13: lightPenX = val; return;
|
||||
case 0x14: lightPenY = val; return;
|
||||
case 0x15:
|
||||
|
@ -246,8 +252,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
case 0x16:
|
||||
xScroll = (val & 0x07);
|
||||
columnSelect = ((val & 0x08) != 0);
|
||||
multiColorMode = ((val & 0x08) != 0);
|
||||
reset = ((val & 0x08) != 0);
|
||||
multiColorMode = ((val & 0x10) != 0);
|
||||
reset = ((val & 0x20) != 0);
|
||||
return;
|
||||
case 0x17:
|
||||
sprites[0].ExpandY = ((val & 0x01) != 0);
|
||||
|
@ -345,6 +351,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
}
|
||||
|
||||
public void PokeByte(int addr, byte val)
|
||||
{
|
||||
Poke(addr, val);
|
||||
}
|
||||
|
||||
public int Read(int addr)
|
||||
{
|
||||
int result;
|
||||
|
@ -362,6 +373,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
}
|
||||
}
|
||||
|
||||
public byte ReadByte(int addr)
|
||||
{
|
||||
return (byte)(Read(addr) & 0xFF);
|
||||
}
|
||||
|
||||
public void Write(int addr, int val)
|
||||
{
|
||||
addr &= 0x3F;
|
||||
|
@ -403,5 +419,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteByte(int addr, byte val)
|
||||
{
|
||||
Write(addr, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
Character,
|
||||
Refresh,
|
||||
Sprite,
|
||||
Pointer
|
||||
Pointer,
|
||||
CharacterInternal
|
||||
}
|
||||
FetchState fetchState;
|
||||
|
||||
|
@ -24,6 +25,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
int characterBAStart;
|
||||
bool characterFetch;
|
||||
int characterFetchStart;
|
||||
int frequency;
|
||||
bool graphicsFetch;
|
||||
bool hBlank;
|
||||
int hBlankDelay;
|
||||
|
@ -43,9 +45,10 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
int spriteDMADisableEnd;
|
||||
int spriteDMADisableStart;
|
||||
int spriteShiftDisableStart;
|
||||
VicTiming timing;
|
||||
bool vBlank;
|
||||
|
||||
void InitTiming(VicTiming timing)
|
||||
void InitTiming()
|
||||
{
|
||||
int spriteBAStart = timing.SpriteBAStart;
|
||||
|
||||
|
@ -54,6 +57,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
sprites[i].BAStart = spriteBAStart % timing.HSize;
|
||||
sprites[i].BAEnd = (spriteBAStart + 40) % timing.HSize;
|
||||
sprites[i].FetchStart = (spriteBAStart + 24) % timing.HSize;
|
||||
spriteBAStart = (spriteBAStart + 32) % timing.HSize;
|
||||
}
|
||||
|
||||
characterBAStart = timing.CharacterBAStart % timing.HSize;
|
||||
|
@ -66,6 +70,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
rasterWidth = timing.HSize;
|
||||
rasterAdvance = timing.LineStart;
|
||||
rasterCount = timing.VSize;
|
||||
frequency = timing.Frequency;
|
||||
spriteDMACheckStart = characterBAEnd;
|
||||
spriteDMACheckEnd = (spriteDMACheckStart + 8) % timing.HSize;
|
||||
spriteCounterCheckStart = (spriteDMACheckEnd + 16) % timing.HSize;
|
||||
|
@ -78,6 +83,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
sealed public class VicTiming
|
||||
{
|
||||
public int CharacterBAStart; //VMBA
|
||||
public int Frequency;
|
||||
public int HBlankDelay;
|
||||
public int HBlankEnd; //HBLANK
|
||||
public int HBlankStart; //HBLANK
|
||||
|
|
|
@ -7,9 +7,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
|
|||
{
|
||||
sealed public partial class Vic : IVideoProvider
|
||||
{
|
||||
int[] pixelBuffer;
|
||||
int pixelBufferIndex;
|
||||
int pixelBufferLength;
|
||||
int screenHeight;
|
||||
int screenWidth;
|
||||
int[] videoBuffer;
|
||||
|
|
|
@ -41,6 +41,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips
|
|||
static private VicSettings Settings6569()
|
||||
{
|
||||
VicSettings result = new VicSettings();
|
||||
|
||||
VicTiming timing = new VicTiming();
|
||||
timing.CharacterBAStart = 0x1EC;
|
||||
timing.Frequency = 17734472 / 18;
|
||||
timing.HBlankDelay = 0;
|
||||
timing.HBlankEnd = 0x1E0;
|
||||
timing.HBlankStart = 0x17C;
|
||||
timing.HSize = 0x1F8;
|
||||
timing.LineStart = 0x194;
|
||||
timing.RefreshStart = 0x1E4;
|
||||
timing.SpriteBAStart = 0x14C;
|
||||
timing.VBlankEnd = 0x010;
|
||||
timing.VBlankStart = 0x12C;
|
||||
timing.VSize = 0x138;
|
||||
|
||||
result.timing = timing;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
return ram[addr & 0x3FF];
|
||||
}
|
||||
|
||||
public int ReadInt(int addr)
|
||||
{
|
||||
return ram[addr & 0x3FF];
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
Sync.SyncObject(ser, this);
|
||||
|
|
|
@ -353,6 +353,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
rasterInterruptLine &= 0xFF;
|
||||
rasterInterruptLine |= (val & 0x80) << 1;
|
||||
UpdateBorder();
|
||||
UpdateVideoMode();
|
||||
break;
|
||||
case 0x12:
|
||||
rasterInterruptLine &= 0x100;
|
||||
|
@ -379,6 +380,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
columnSelect = ((val & 0x08) != 0);
|
||||
multicolorMode = ((val & 0x10) != 0);
|
||||
UpdateBorder();
|
||||
UpdateVideoMode();
|
||||
break;
|
||||
case 0x17:
|
||||
sprites[0].yExpand = ((val & 0x01) != 0);
|
||||
|
|
|
@ -16,6 +16,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
protected int pixelBufferDelay;
|
||||
protected int pixelBufferIndex;
|
||||
protected int pixelData;
|
||||
protected int pixelOwner;
|
||||
protected int sprData;
|
||||
protected int sprPixel;
|
||||
protected VicVideoMode videoMode;
|
||||
|
||||
protected enum VicVideoMode : int
|
||||
{
|
||||
Mode000,
|
||||
Mode001,
|
||||
Mode010,
|
||||
Mode011,
|
||||
Mode100,
|
||||
ModeBad
|
||||
}
|
||||
|
||||
private void Render()
|
||||
{
|
||||
|
@ -63,11 +77,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
pixel = pixelBackgroundBuffer[pixelBackgroundBufferIndex];
|
||||
|
||||
// render sprite
|
||||
int pixelOwner = 8;
|
||||
pixelOwner = 8;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
int sprData;
|
||||
int sprPixel = pixel;
|
||||
sprData = 0;
|
||||
sprPixel = pixel;
|
||||
|
||||
Sprite spr = sprites[j];
|
||||
|
||||
|
@ -78,28 +92,28 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
{
|
||||
if (spr.multicolor)
|
||||
{
|
||||
sprData = (spr.sr & 0xC00000) >> 22;
|
||||
sprData = (spr.sr & 0xC00000);
|
||||
if (spr.multicolorCrunch && spr.xCrunch)
|
||||
spr.sr <<= 2;
|
||||
spr.multicolorCrunch ^= spr.xCrunch;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprData = (spr.sr & 0x800000) >> 22;
|
||||
sprData = (spr.sr & 0x800000);
|
||||
if (spr.xCrunch)
|
||||
spr.sr <<= 1;
|
||||
}
|
||||
spr.xCrunch ^= spr.xExpand;
|
||||
|
||||
if (sprData == 1)
|
||||
sprPixel = spriteMulticolor0;
|
||||
else if (sprData == 2)
|
||||
sprPixel = spr.color;
|
||||
else if (sprData == 3)
|
||||
sprPixel = spriteMulticolor1;
|
||||
|
||||
if (sprData != 0)
|
||||
{
|
||||
if (sprData == 0x400000)
|
||||
sprPixel = spriteMulticolor0;
|
||||
else if (sprData == 0x800000)
|
||||
sprPixel = spr.color;
|
||||
else if (sprData == 0xC00000)
|
||||
sprPixel = spriteMulticolor1;
|
||||
|
||||
// sprite-sprite collision
|
||||
if (pixelOwner >= 8)
|
||||
{
|
||||
|
@ -117,7 +131,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
}
|
||||
|
||||
// sprite-data collision
|
||||
if (!borderOnVertical && (pixelDataBuffer[pixelBackgroundBufferIndex] >= 0x2))
|
||||
if (!borderOnVertical && (pixelDataBuffer[pixelBackgroundBufferIndex] == 0x80))
|
||||
{
|
||||
spr.collideData = true;
|
||||
}
|
||||
|
@ -145,10 +159,90 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
bitmapColumn = 0;
|
||||
}
|
||||
|
||||
#if true
|
||||
switch (videoMode)
|
||||
{
|
||||
case VicVideoMode.Mode000:
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? displayC >> 8 : backgroundColor0;
|
||||
break;
|
||||
case VicVideoMode.Mode001:
|
||||
if ((displayC & 0x800) != 0)
|
||||
{
|
||||
// multicolor 001
|
||||
pixelData = (sr & 0xC0);
|
||||
if ((bitmapColumn & 1) != 0)
|
||||
sr <<= 2;
|
||||
|
||||
if (pixelData == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (pixelData == 0x40)
|
||||
pixel = backgroundColor1;
|
||||
else if (pixelData == 0x80)
|
||||
pixel = backgroundColor2;
|
||||
else
|
||||
pixel = (displayC & 0x700) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// standard 001
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0;
|
||||
}
|
||||
break;
|
||||
case VicVideoMode.Mode010:
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? ((displayC >> 4) & 0xF) : (displayC & 0xF);
|
||||
break;
|
||||
case VicVideoMode.Mode011:
|
||||
pixelData = (sr & 0xC0);
|
||||
if ((bitmapColumn & 1) != 0)
|
||||
sr <<= 2;
|
||||
|
||||
if (pixelData == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (pixelData == 0x40)
|
||||
pixel = (displayC >> 4) & 0xF;
|
||||
else if (pixelData == 0x80)
|
||||
pixel = displayC & 0xF;
|
||||
else
|
||||
pixel = (displayC >> 8) & 0xF;
|
||||
break;
|
||||
case VicVideoMode.Mode100:
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
if (pixelData != 0)
|
||||
{
|
||||
pixel = displayC >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecmPixel = (displayC) & 0xC0;
|
||||
if (ecmPixel == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (ecmPixel == 0x40)
|
||||
pixel = backgroundColor1;
|
||||
else if (ecmPixel == 0x80)
|
||||
pixel = backgroundColor2;
|
||||
else
|
||||
pixel = backgroundColor3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pixelData = 0;
|
||||
pixel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (!extraColorMode && !bitmapMode & !multicolorMode)
|
||||
{
|
||||
// 000
|
||||
pixelData = (sr & 0x80) >> 6;
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? displayC >> 8 : backgroundColor0;
|
||||
}
|
||||
|
@ -158,15 +252,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
if ((displayC & 0x800) != 0)
|
||||
{
|
||||
// multicolor 001
|
||||
pixelData = (sr & 0xC0) >> 6;
|
||||
pixelData = (sr & 0xC0);
|
||||
if ((bitmapColumn & 1) != 0)
|
||||
sr <<= 2;
|
||||
|
||||
if (pixelData == 0)
|
||||
if (pixelData == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (pixelData == 1)
|
||||
else if (pixelData == 0x40)
|
||||
pixel = backgroundColor1;
|
||||
else if (pixelData == 2)
|
||||
else if (pixelData == 0x80)
|
||||
pixel = backgroundColor2;
|
||||
else
|
||||
pixel = (displayC & 0x700) >> 8;
|
||||
|
@ -174,7 +268,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
else
|
||||
{
|
||||
// standard 001
|
||||
pixelData = (sr & 0x80) >> 6;
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? (displayC >> 8) : backgroundColor0;
|
||||
}
|
||||
|
@ -182,22 +276,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
else if (!extraColorMode && bitmapMode & !multicolorMode)
|
||||
{
|
||||
// 010
|
||||
pixelData = (sr & 0x80) >> 6;
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
pixel = (pixelData != 0) ? ((displayC >> 4) & 0xF) : (displayC & 0xF);
|
||||
}
|
||||
else if (!extraColorMode && bitmapMode & multicolorMode)
|
||||
{
|
||||
// 011
|
||||
pixelData = (sr & 0xC0) >> 6;
|
||||
pixelData = (sr & 0xC0);
|
||||
if ((bitmapColumn & 1) != 0)
|
||||
sr <<= 2;
|
||||
|
||||
if (pixelData == 0)
|
||||
if (pixelData == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (pixelData == 1)
|
||||
else if (pixelData == 0x40)
|
||||
pixel = (displayC >> 4) & 0xF;
|
||||
else if (pixelData == 2)
|
||||
else if (pixelData == 0x80)
|
||||
pixel = displayC & 0xF;
|
||||
else
|
||||
pixel = (displayC >> 8) & 0xF;
|
||||
|
@ -205,7 +299,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
else if (extraColorMode && !bitmapMode & !multicolorMode)
|
||||
{
|
||||
// 100
|
||||
pixelData = (sr & 0x80) >> 6;
|
||||
pixelData = (sr & 0x80);
|
||||
sr <<= 1;
|
||||
if (pixelData != 0)
|
||||
{
|
||||
|
@ -213,12 +307,12 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
}
|
||||
else
|
||||
{
|
||||
ecmPixel = (displayC >> 6) & 0x3;
|
||||
if (ecmPixel == 0)
|
||||
ecmPixel = (displayC) & 0xC0;
|
||||
if (ecmPixel == 0x00)
|
||||
pixel = backgroundColor0;
|
||||
else if (ecmPixel == 1)
|
||||
else if (ecmPixel == 0x40)
|
||||
pixel = backgroundColor1;
|
||||
else if (ecmPixel == 2)
|
||||
else if (ecmPixel == 0x80)
|
||||
pixel = backgroundColor2;
|
||||
else
|
||||
pixel = backgroundColor3;
|
||||
|
@ -243,6 +337,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
pixel = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// put the rendered pixel into the background buffer
|
||||
pixelDataBuffer[pixelBackgroundBufferIndex] = pixelData;
|
||||
pixelBackgroundBuffer[pixelBackgroundBufferIndex] = pixel;
|
||||
|
|
|
@ -197,5 +197,35 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
|
|||
(enableIntLightPen & intLightPen));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVideoMode()
|
||||
{
|
||||
if (!extraColorMode && !bitmapMode && !multicolorMode)
|
||||
{
|
||||
videoMode = VicVideoMode.Mode000;
|
||||
return;
|
||||
}
|
||||
else if (!extraColorMode && !bitmapMode && multicolorMode)
|
||||
{
|
||||
videoMode = VicVideoMode.Mode001;
|
||||
return;
|
||||
}
|
||||
else if (!extraColorMode && bitmapMode && !multicolorMode)
|
||||
{
|
||||
videoMode = VicVideoMode.Mode010;
|
||||
return;
|
||||
}
|
||||
else if (!extraColorMode && bitmapMode && multicolorMode)
|
||||
{
|
||||
videoMode = VicVideoMode.Mode011;
|
||||
return;
|
||||
}
|
||||
else if (extraColorMode && !bitmapMode && !multicolorMode)
|
||||
{
|
||||
videoMode = VicVideoMode.Mode100;
|
||||
return;
|
||||
}
|
||||
videoMode = VicVideoMode.ModeBad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue