From 634681ce2bb36cd686943102a0f071cd6a09049f Mon Sep 17 00:00:00 2001 From: Melodi <62381002+Melodi17@users.noreply.github.com> Date: Wed, 27 Aug 2025 21:22:55 +1000 Subject: fixed bugs and revolutionized the universe --- Emulator/Chip/DebugDevice.cs | 13 ----------- Emulator/Chip/DisplayDevice.cs | 50 ++++++++++++++++++++++++++++-------------- Emulator/Chip/HIDDevice.cs | 36 ++++++++++++++++++++++++++++++ Emulator/Chip/Q1Cpu.cs | 4 ++-- 4 files changed, 72 insertions(+), 31 deletions(-) delete mode 100644 Emulator/Chip/DebugDevice.cs create mode 100644 Emulator/Chip/HIDDevice.cs (limited to 'Emulator/Chip') diff --git a/Emulator/Chip/DebugDevice.cs b/Emulator/Chip/DebugDevice.cs deleted file mode 100644 index 4e869bb..0000000 --- a/Emulator/Chip/DebugDevice.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Q1.Emulator.Chip; - -using System; - -public class DebugDevice(u16 addressPoint) - : BusDevice(addressPoint, (u16) (addressPoint + 2)) -{ - public override u8 Read(u16 address) => throw new Exception("DebugDevice.Read not permitted"); - public override void Write(u16 address, u8 value) - { - Console.WriteLine($"DebugDevice.Write: x{value:X4} b{value:b8}"); - } -} \ No newline at end of file diff --git a/Emulator/Chip/DisplayDevice.cs b/Emulator/Chip/DisplayDevice.cs index a18dbd4..c8889ba 100644 --- a/Emulator/Chip/DisplayDevice.cs +++ b/Emulator/Chip/DisplayDevice.cs @@ -6,31 +6,39 @@ using Microsoft.Xna.Framework.Graphics; public class DisplayDevice : RamDevice { - public Texture2D? OutputTexture; - private readonly u16 _paletteSize; - private readonly u16 _displayWidth; - private readonly u16 _displayHeight; - private Color[] textureData; + public Texture2D? OutputTexture; + + private readonly u16 _paletteSize; + private readonly u16 _displayWidth; + private readonly u16 _displayHeight; + + private Color[] textureData; + private Color[] palette; + private bool _paletteDirty; public DisplayDevice(u16 paletteSize, u16 displayWidth, u16 displayHeight, u16 addressableStart) - : base(addressableStart, DisplayDevice.DetermineSize(paletteSize, displayWidth, displayHeight)) + : base( + addressableStart, DisplayDevice.DetermineSize(paletteSize, displayWidth, displayHeight)) { - this._paletteSize = paletteSize; - this._displayWidth = displayWidth; + this._paletteSize = paletteSize; + this._displayWidth = displayWidth; this._displayHeight = displayHeight; - this.textureData = new Color[this._displayWidth * this._displayHeight]; + this.textureData = new Color[this._displayWidth * this._displayHeight]; } - private static u16 DetermineSize(u16 paletteSize, u16 displayWidth, u16 displayHeight) + public static u16 DetermineSize(u16 paletteSize, u16 displayWidth, u16 displayHeight) { return (u16) ((paletteSize * 3) + (displayWidth * displayHeight)); } public override void Clock() { - Color[] palette = this.ReadPalette(); - ref8 pixelData = this.Memory.AsSpan((u16) (this._paletteSize * 3), (u16) (this._displayWidth * this._displayHeight)); - // Console.WriteLine($"DisplayDevice.Clock: @{(this.AddressableStart + this._paletteSize * 3):X4} palette size={this._paletteSize} display size={this._displayWidth}x{this._displayHeight}"); + if (this._paletteDirty) + this.ReadPalette(); + + ref8 pixelData = this.Memory.AsSpan( + (u16) (this._paletteSize * 3), (u16) (this._displayWidth * this._displayHeight)); + for (u16 i = 0; i < this.textureData.Length; i++) { u8 pixelValue = pixelData[i]; @@ -41,7 +49,7 @@ public class DisplayDevice : RamDevice this.OutputTexture.SetData(this.textureData); } - private Color[] ReadPalette() + private void ReadPalette() { ref8 paletteData = this.Memory.AsSpan(0, (u16) (this._paletteSize * 3)); Color[] colors = new Color[this._paletteSize + 1]; @@ -56,7 +64,8 @@ public class DisplayDevice : RamDevice colors[(u16) (i + 1)] = new Color(r, g, b); } - return colors; + this._paletteDirty = false; + this.palette = colors; } public void SetPalette(Color[] palette) @@ -68,9 +77,18 @@ public class DisplayDevice : RamDevice for (u16 i = 0; i < this._paletteSize; i++) { u16 offset = (u16) (i * 3); - paletteData[offset] = palette[i].R; + paletteData[offset] = palette[i].R; paletteData[offset + 1] = palette[i].G; paletteData[offset + 2] = palette[i].B; } + + this._paletteDirty = true; + } + + public override u8 Read(u16 address) => base.Read(address); + public override void Write(u16 address, u8 value) + { + this._paletteDirty = true; + base.Write(address, value); } } \ No newline at end of file diff --git a/Emulator/Chip/HIDDevice.cs b/Emulator/Chip/HIDDevice.cs new file mode 100644 index 0000000..87bb2c3 --- /dev/null +++ b/Emulator/Chip/HIDDevice.cs @@ -0,0 +1,36 @@ +namespace Q1.Emulator.Chip; + +public class HIDDevice : RamDevice +{ + public HIDDevice(u16 start) : base(start, HIDDevice.CalculateSize()) { } + + public static u16 CalculateSize() + { + return 4 + 256; + } + + public void SetMouse(u16 positionalIndex, bool leftDown, bool rightDown, bool middleDown) + { + this.WriteWord(this.AddressableStart, positionalIndex); + u16 buttons = (u16) ((leftDown ? 1 : 0) + | ((rightDown ? 1 : 0) << 1) + | ((middleDown ? 1 : 0) << 2)); + this.WriteWord((u16) (this.AddressableStart + 2), buttons); + } + + public void SetKeyboard(u8 scanCode, bool pressed) + { + int index = scanCode >> 3; // keyCode / 8 + int bit = scanCode & 7; // keyCode % 8 + + ushort addr = (ushort) (4 + index); + u8 value = this.Read(addr); + + if (pressed) + value |= (u8) (1 << bit); + else + value &= (u8) ~(1 << bit); + + this.Write((u16) (this.AddressableStart + addr), value); + } +} \ No newline at end of file diff --git a/Emulator/Chip/Q1Cpu.cs b/Emulator/Chip/Q1Cpu.cs index 7f60ca6..81f9908 100644 --- a/Emulator/Chip/Q1Cpu.cs +++ b/Emulator/Chip/Q1Cpu.cs @@ -47,8 +47,8 @@ public partial class Q1Cpu } u16 instruction = this.FetchInstruction(out u8 op, out u8 m1, out u8 m2, out _); - if (instruction != 0x0101) - Console.WriteLine($"CPU.Clock: {pc:X4} | {Disassembler.ParseInstruction(instruction)}"); + // if (instruction != 0x0101) + // Console.WriteLine($"CPU.Clock: {pc:X4} | {Disassembler.ParseInstruction(instruction)}"); bool ex = m2 > 0; switch (m1, ex) -- cgit v1.3.1