More vic-ii work

This commit is contained in:
KallDrexx
2026-01-03 20:41:49 -05:00
parent 8e41f54cda
commit 224590167d
4 changed files with 73 additions and 15 deletions
+51 -3
View File
@@ -8,18 +8,30 @@ namespace Dotnet6502.C64.Hardware;
public class Vic2
{
// Reference: https://zimmers.net/cbmpics/cbm/c64/vic-ii.txt
public enum GraphicsMode
{
StandardTextMode,
MulticolorTextMode,
StandardBitmapMode,
MulticolorBitmapMode,
EcmTextMode,
Invalid,
}
private const int DotsPerCpuCycle = 8;
private const int DotsPerScanline = 520;
private const int VisibleDotsPerScanLine = 418;
public const int VisibleDotsPerScanLine = 418;
private const int TotalScanlines = 263;
private const int FirstVisibleScanline = 28;
private const int LastVisibleScanLine = 262;
private const int FirstDisplayWindowScanLine = 51;
private const int LastDisplayWindowScanLine = 250;
private const int VisibleScanLines = LastVisibleScanLine - FirstVisibleScanline + 1;
public const int VisibleScanLines = LastVisibleScanLine - FirstVisibleScanline + 1;
private readonly IC64Display _c64Display;
private readonly Memory<byte> _vic2Registers;
// private readonly Memory<byte> _colorRam;
private readonly ReadOnlyMemory<byte> _screenRam;
private readonly RgbColor[] _frameBuffer = new RgbColor[VisibleDotsPerScanLine * VisibleScanLines];
private readonly RgbColor[] _palette = new RgbColor[16];
private int _lineCycleCount;
@@ -48,10 +60,12 @@ public class Vic2
/// </summary>
private ushort _videoMatrixLineIndex;
public Vic2(IC64Display c64Display, IoMemoryArea ioMemoryArea)
public Vic2(IC64Display c64Display, IoMemoryArea ioMemoryArea, ReadOnlyMemory<byte> screenRam)
{
_c64Display = c64Display;
_screenRam = screenRam;
_vic2Registers = ioMemoryArea.Vic2Registers;
// _colorRam = ioMemoryArea.ColorRam;
// Fill in the palette values based on the Colodore Palette
_palette[0] = new RgbColor(0, 0, 0); // Black
@@ -182,6 +196,13 @@ public class Vic2
var firstBorderBottomLine = rsel ? 247 : 251;
var borderColor = registerData.BorderColor;
// var colorRam = _colorRam.Span;
var screenRam = _screenRam.Span;
var row = (_currentScanLine - FirstVisibleScanline) / 8;
var rowInChar = (_currentScanLine - FirstVisibleScanline) % 8;
var column = _lineCycleCount - 17;
// Write the next 8 dots
for (var x = 0; x < DotsPerCpuCycle; x++)
{
@@ -195,6 +216,11 @@ public class Vic2
_frameBuffer[pixelIndex] = _palette[borderColor];
continue;
}
// Standard text only mode atm
var columnInChar = x;
var charCode = screenRam[row * 40 + column];
// var color = colorRam[row * 40 + column];
}
}
@@ -210,4 +236,26 @@ public class Vic2
_currentScanLine <= 247 &&
(_currentScanLine & 0b111) == registerData.YScroll;
}
/// <summary>
/// Gets the current graphics mode based on the current register set
/// </summary>
/// <param name="registerData"></param>
/// <returns></returns>
private GraphicsMode GetGraphicsMode(Vic2RegisterData registerData)
{
var ecm = registerData.Ecm;
var bmm = registerData.Bmm;
var mcm = registerData.Mcm;
return (ecm, bmm, mcm) switch
{
(false, false, false) => GraphicsMode.StandardTextMode,
(false, false, true) => GraphicsMode.MulticolorTextMode,
(false, true, false) => GraphicsMode.StandardBitmapMode,
(false, true, true) => GraphicsMode.MulticolorBitmapMode,
(true, false, false) => GraphicsMode.EcmTextMode,
_ => GraphicsMode.Invalid,
};
}
}
@@ -49,6 +49,12 @@ public readonly ref struct Vic2RegisterData
/// </summary>
public byte CharacterMapPointer => (byte)((_registerBytes[VmCb] & 0xF) >> 1);
public bool Ecm => (_registerBytes[ControlRegister1] & 0b0100_0000) > 0;
public bool Bmm => (_registerBytes[ControlRegister1] & 0b0010_0000) > 0;
public bool Mcm => (_registerBytes[ControlRegister2] & 0b00010000) > 0;
/// <summary>
/// - 7 = Raster bit 8
/// - 6 = ECM
@@ -1,5 +1,6 @@
using System.Diagnostics;
using Dotnet6502.C64.Emulation;
using Dotnet6502.C64.Hardware;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
@@ -8,8 +9,8 @@ namespace Dotnet6502.C64.Integration;
public class MonogameApp : Game, IC64Display
{
private const int Width = 464;
private const int Height = 247;
private const int Width = Vic2.VisibleDotsPerScanLine;
private const int Height = Vic2.VisibleScanLines;
private readonly GraphicsDeviceManager _graphicsDeviceManager;
private readonly object _synchronizationLock = new();
+13 -10
View File
@@ -11,9 +11,9 @@ var cliArgs = CommandLineHandler.Parse(args);
Console.WriteLine("Starting Dotnet6502 Commodore64 emulator");
var ioMemoryArea = new IoMemoryArea();
var pla = await SetupPla(cliArgs);
var memoryBus = SetupMemoryBus();
var (memoryBus, screenRam) = SetupMemoryBus();
var app = new MonogameApp(false);
var vic2 = new Vic2(app, ioMemoryArea);
var vic2 = new Vic2(app, ioMemoryArea, screenRam);
var hal = new C64Hal(memoryBus, cancellationTokenSource.Token, vic2);
var jitCustomizer = new C64JitCustomizer();
var jitCompiler = new JitCompiler(hal, jitCustomizer, memoryBus);
@@ -66,19 +66,22 @@ async Task<ProgrammableLogicArray> SetupPla(CommandLineHandler.Values values)
return programmableLogicArray;
}
MemoryBus SetupMemoryBus()
(MemoryBus, ReadOnlyMemory<byte> screenRam) SetupMemoryBus()
{
var memoryBus1 = new MemoryBus();
memoryBus1.Attach(pla, 0x0000);
pla.AttachToBus(memoryBus1);
var bus = new MemoryBus();
bus.Attach(pla, 0x0000);
pla.AttachToBus(bus);
// fill in the rest with ram
memoryBus1.Attach(new BasicRamMemoryDevice(0x7fff - 0x0002 + 1), 0x0002);
memoryBus1.Attach(new BasicRamMemoryDevice(0xcfff - 0xc000 + 1), 0xc000);
var screenRamArea = new BasicRamMemoryDevice(0x07ff - 0x0400 + 1);
bus.Attach(new BasicRamMemoryDevice(0x03ff - 0x0002 + 1), 0x0002);
bus.Attach(screenRamArea, 0x0400);
bus.Attach(new BasicRamMemoryDevice(0x7fff - 0x0800 + 1), 0x0800);
bus.Attach(new BasicRamMemoryDevice(0xcfff - 0xc000 + 1), 0xc000);
// TODO: Add cartridge rom low swapping to this region
memoryBus1.Attach(new BasicRamMemoryDevice(0x9fff - 0x8000 + 1), 0x8000);
return memoryBus1;
bus.Attach(new BasicRamMemoryDevice(0x9fff - 0x8000 + 1), 0x8000);
return (bus, screenRamArea.RawBlockFromZero!.Value);
}
async Task RunSystem()