diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Interface.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Interface.cs index c2f33d5b5b..fe8822ac4e 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Interface.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Interface.cs @@ -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; } } diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs index 47111ff0f6..825e71d282 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Internal.cs @@ -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(); } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs index c6eb00d434..1a93520c9c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Registers.cs @@ -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); + } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Timing.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Timing.cs index b6577ec727..6326880ddc 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Timing.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.Timing.cs @@ -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 diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.VideoProvider.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.VideoProvider.cs index ee1b2457d1..b4c4dfb7f1 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.VideoProvider.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Vic.VideoProvider.cs @@ -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; diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Presets.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Presets.cs index 9052308c07..de6afacc62 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Presets.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Presets.cs @@ -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; } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Chip2114.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Chip2114.cs index 4479f1c9da..f95e60483c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Chip2114.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Chip2114.cs @@ -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); diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs index cdaed53c34..5b448d48bb 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Registers.cs @@ -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); diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs index 1ff0531618..a57d76211c 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.Render.cs @@ -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; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs index e7b75e4859..d97c08e836 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Vic.cs @@ -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; + } } }