mirror of
https://github.com/ApfelTeeSaft/DotNesJit.git
synced 2026-08-26 19:23:35 +00:00
More vic-ii work
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user