From 16f3cb74564cf7c19da6e13666c98aca36094716 Mon Sep 17 00:00:00 2001 From: Melodi <62381002+Melodi17@users.noreply.github.com> Date: Tue, 5 Aug 2025 21:24:16 +1000 Subject: updates --- Chip/Bus.cs | 18 ---- Chip/BusDevice.cs | 18 ++-- Chip/DisplayDevice.cs | 21 +--- Chip/Q1Cpu.cs | 9 +- Chip/Q1CpuAddressingModes.cs | 238 +++++++++++++++++++------------------------ Chip/Q1CpuInstructions.cs | 133 +++++++++++++++--------- Chip/RamDevice.cs | 13 --- 7 files changed, 211 insertions(+), 239 deletions(-) (limited to 'Chip') diff --git a/Chip/Bus.cs b/Chip/Bus.cs index 951d23f..3578ad6 100644 --- a/Chip/Bus.cs +++ b/Chip/Bus.cs @@ -34,22 +34,4 @@ public class Bus : BusDevice device.Write(address, value); } - - public override ref8 ReadSeq(u16 address, u16 length) - { - BusDevice? device = this.GetDevice(address); - if (device == null) - return new u8[length]; - - return device.ReadSeq(address, length); - } - - public override void WriteSeq(u16 address, u16 length, ref8 value) - { - BusDevice? device = this.GetDevice(address); - if (device == null) - return; - - device.WriteSeq(address, length, value); - } } \ No newline at end of file diff --git a/Chip/BusDevice.cs b/Chip/BusDevice.cs index e1f559c..8b677c5 100644 --- a/Chip/BusDevice.cs +++ b/Chip/BusDevice.cs @@ -14,20 +14,26 @@ public abstract class BusDevice public abstract u8 Read(u16 address); public abstract void Write(u16 address, u8 value); - public abstract ref8 ReadSeq(u16 address, u16 length); - public abstract void WriteSeq(u16 address, u16 length, ref8 value); - public u16 ReadWord(u16 address) { - ref8 data = this.ReadSeq(address, 2); - u16 value = Make.u16(data); + u8 high = this.Read(address); + u8 low = this.Read((u16) (address + 1)); + u16 value = Make.u16(high, low); return value; } public void WriteWord(u16 address, u16 value) { ref8 data = Make.ref8(value); - this.WriteSeq(address, 2, data); + this.Write(address, data[0]); + this.Write((u16) (address + 1), data[1]); + } + + public i16 ReadSignedWord(u16 address) + { + u8 high = this.Read(address); + u8 low = this.Read((u16) (address + 1)); + return Make.i16(high, low); } public virtual void Clock() { } diff --git a/Chip/DisplayDevice.cs b/Chip/DisplayDevice.cs index 28bf4e0..1bf4f14 100644 --- a/Chip/DisplayDevice.cs +++ b/Chip/DisplayDevice.cs @@ -31,12 +31,12 @@ public class DisplayDevice : RamDevice public override void Clock() { Color[] palette = this.ReadPalette(); - ref8 pixelData = this.ReadSeq((u16) (this.AddressableStart + this._paletteSize * 3), (u16) (this._displayWidth * this._displayHeight)); - + 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}"); for (u16 i = 0; i < textureData.Length; i++) { u8 pixelValue = pixelData[i]; - textureData[i] = palette[pixelValue]; + textureData[i] = palette[pixelValue % this._paletteSize]; } if (this.OutputTexture != null) @@ -45,7 +45,7 @@ public class DisplayDevice : RamDevice private Color[] ReadPalette() { - ref8 paletteData = this.ReadSeq(this.AddressableStart, (u16) (this._paletteSize * 3)); + ref8 paletteData = this.Memory.AsSpan(0, (u16) (this._paletteSize * 3)); Color[] colors = new Color[this._paletteSize + 1]; colors[0] = Color.Transparent; @@ -66,7 +66,7 @@ public class DisplayDevice : RamDevice if (palette.Length != this._paletteSize) throw new ArgumentException($"Palette must have {this._paletteSize} colors."); - ref8 paletteData = this.ReadSeq(this.AddressableStart, (u16) (this._paletteSize * 3)); + ref8 paletteData = this.Memory.AsSpan(0, (u16) (this._paletteSize * 3)); for (u16 i = 0; i < this._paletteSize; i++) { u16 offset = (u16) (i * 3); @@ -75,15 +75,4 @@ public class DisplayDevice : RamDevice paletteData[offset + 2] = palette[i].B; } } - - public override void Write(u16 address, u8 value) - { - Console.WriteLine($"DisplayDevice.Write: {address:X4} = {value:X2}"); - base.Write(address, value); - } - public override void WriteSeq(u16 address, u16 length, ref8 value) - { - Console.WriteLine($"DisplayDevice.WriteSeq: {address:X4} length={length} value={Make.u16(value)}"); - base.WriteSeq(address, length, value); - } } \ No newline at end of file diff --git a/Chip/Q1Cpu.cs b/Chip/Q1Cpu.cs index 910ad64..eefc61c 100644 --- a/Chip/Q1Cpu.cs +++ b/Chip/Q1Cpu.cs @@ -7,7 +7,7 @@ using Assembler; public partial class Q1Cpu { - public const u16 StackStart = 0x30; + public const u16 StackStart = 0x2FFF; public const u16 StackLength = 16 * 2; // 16 16-bit values public Random Random; @@ -45,7 +45,8 @@ public partial class Q1Cpu { var pc = this.PC; u16 instruction = this.FetchInstruction(out u8 op, out u8 m1, out u8 m2, out _); - Console.WriteLine($"{pc:X4}: {Disassembler.ParseInstruction(instruction)}"); + Console.WriteLine($"CPU.Clock: {pc:X4} | {Disassembler.ParseInstruction(instruction)}"); + // Console.WriteLine($"{V[0]:X4} {V[1]:X4} {V[2]:X4} {V[3]:X4} {V[4]:X4} {V[5]:X4} {V[6]:X4} {V[7]:X4}"); bool ex = m2 > 0; switch (m1, ex) @@ -84,7 +85,7 @@ public partial class Q1Cpu if (this.SP + 2 >= StackStart + StackLength) throw new InvalidOperationException("Stack overflow"); - this.Bus.WriteSeq(this.SP, 2, Make.ref8(value)); + this.Bus.WriteWord(this.SP, value); this.SP += 2; } @@ -94,7 +95,7 @@ public partial class Q1Cpu throw new InvalidOperationException("Stack underflow"); this.SP -= 2; - return Make.u16(this.Bus.ReadSeq(this.SP, 2)); + return this.Bus.ReadWord(this.SP); } private u16 FetchRegister(u8 regIndex) diff --git a/Chip/Q1CpuAddressingModes.cs b/Chip/Q1CpuAddressingModes.cs index f809ff3..2b79db7 100644 --- a/Chip/Q1CpuAddressingModes.cs +++ b/Chip/Q1CpuAddressingModes.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; public partial class Q1Cpu { - public u16 FetchData(u8 mode) + public (Func read, Action write, Action writeByte) Address(u8 mode) { return mode switch { @@ -20,61 +20,8 @@ public partial class Q1Cpu _ => throw new InvalidOperationException($"Unknown addressing mode: {mode:X2}"), }; } - - public void StoreData(u8 mode, u16 value) - { - switch (mode) - { - case 0x0: - throw new InvalidOperationException("Cannot store data in implicit mode."); - case 0x1: - throw new InvalidOperationException("Cannot store data in immediate mode."); - case 0x2: - this.AddressingMode_Direct_Store(value); - break; - case 0x3: - this.AddressingMode_Indirect_Store(value); - break; - case 0x4: - this.AddressingMode_Relative_Store(value); - break; - case 0x5: - this.AddressingMode_Register_Store(value); - break; - case 0x6: - this.AddressingMode_RegisterIndirect_Store(value); - break; - case 0x7: - this.AddressingMode_RegisterIndirectOffset_Store(value); - break; - default: - throw new InvalidOperationException($"Unknown addressing mode: {mode:X2}"); - } - } - - public void TransformData(u8 mode, Func transform) - { - // if (mode != 0x05) - // { - // u16 address = this.FetchData(mode); - // u16 value = this.Bus.ReadWord(address); - // u16 transformedValue = transform(value); - // this.Bus.WriteWord(address, transformedValue); - // } - // else - // { - // u8 regIndex = this.Bus.Read(this.PC); - // this.PC += 1; - // - // u16 value = this.FetchRegister(regIndex); - // u16 transformedValue = transform(value); - // this.StoreRegister(regIndex, transformedValue); - // } - - throw new NotImplementedException("TransformData is not implemented yet."); - } - public u8 AddressingModeLength(u8 mode) + private u8 AddressingModeLength(u8 mode) { return mode switch { @@ -90,133 +37,152 @@ public partial class Q1Cpu }; } - public u16 AddressingMode_Implicit() + public (Func read, Action write, Action writeByte) AddressingMode_Implicit() { - return 0; + u16 Read() => throw new InvalidOperationException("Cannot read from implicit mode."); + void Write(u16 value) => throw new InvalidOperationException("Cannot write to implicit mode."); + void WriteByte(u8 value) => throw new InvalidOperationException("Cannot write byte to implicit mode."); + + return (Read, Write, WriteByte); } - public u16 AddressingMode_Immediate() + public (Func read, Action write, Action writeByte) AddressingMode_Immediate() { u16 value = this.Bus.ReadWord(this.PC); this.PC += 2; - return value; + u16 Read() => value; + void Write(u16 v) => throw new InvalidOperationException("Cannot write to immediate mode."); + void WriteByte(u8 v) => throw new InvalidOperationException("Cannot write byte to immediate mode."); + + return (Read, Write, WriteByte); } - public u16 AddressingMode_Direct() + public (Func read, Action write, Action writeByte) AddressingMode_Direct() { u16 address = this.Bus.ReadWord(this.PC); this.PC += 2; - - u16 value = this.Bus.ReadWord(address); - return value; + + u16 Read() => this.Bus.ReadWord(address); + void Write(u16 value) => this.Bus.WriteWord(address, value); + void WriteByte(u8 value) => this.Bus.Write(address, value); + + return (Read, Write, WriteByte); } - public u16 AddressingMode_Indirect() + public (Func read, Action write, Action writeByte) AddressingMode_Indirect() { u16 address = this.Bus.ReadWord(this.PC); this.PC += 2; + + u16 Read() + { + u16 indirectAddress = this.Bus.ReadWord(address); + u16 value = this.Bus.ReadWord(indirectAddress); + return value; + } - u16 indirectAddress = this.Bus.ReadWord(address); - u16 value = this.Bus.ReadWord(indirectAddress); - return value; + void Write(u16 value) + { + u16 indirectAddress = this.Bus.ReadWord(address); + this.Bus.WriteWord(indirectAddress, value); + } + + void WriteByte(u8 value) + { + u16 indirectAddress = this.Bus.ReadWord(address); + this.Bus.Write(indirectAddress, value); + } + + return (Read, Write, WriteByte); } - public u16 AddressingMode_Relative() + public (Func read, Action write, Action writeByte) AddressingMode_Relative() { u16 offset = this.Bus.ReadWord(this.PC); this.PC += 2; u16 address = (u16) (this.PC + offset); - return address; - } - - public u16 AddressingMode_Register() - { - u8 regIndex = this.Bus.Read(this.PC); - this.PC += 1; - - return this.FetchRegister(regIndex); - } - - public u16 AddressingMode_RegisterIndirect() - { - u8 regIndex = this.Bus.Read(this.PC); - this.PC += 1; - - u16 address = this.FetchRegister(regIndex); - u16 value = this.Bus.ReadWord(address); - Console.WriteLine($"Value at {address:X4}: {value:X4}"); - return value; - } - - public u16 AddressingMode_RegisterIndirectOffset() - { - u8 regIndex = this.Bus.Read(this.PC); - this.PC += 1; - - i16 offset = Make.i16(this.Bus.ReadSeq(this.PC, 2)); - Console.WriteLine("Offset: " + offset); - this.PC += 2; - u16 address = (u16) (this.FetchRegister(regIndex) + offset); - u16 value = this.Bus.ReadWord(address); - return value; - } - - public void AddressingMode_Direct_Store(u16 data) - { - u16 address = this.Bus.ReadWord(this.PC); - this.PC += 2; - - this.Bus.WriteWord(address, data); - } - - public void AddressingMode_Indirect_Store(u16 data) - { - u16 address = this.Bus.ReadWord(this.PC); - this.PC += 2; - - u16 indirectAddress = this.Bus.ReadWord(address); - this.Bus.WriteWord(indirectAddress, data); - } - - public void AddressingMode_Relative_Store(u16 data) - { - u16 offset = this.Bus.ReadWord(this.PC); - this.PC += 2; - - u16 address = (u16) (this.PC + offset); - this.Bus.WriteWord(address, data); + u16 Read() => address; + void Write(u16 value) => throw new InvalidOperationException("Cannot write to relative mode."); + void WriteByte(u8 value) => throw new InvalidOperationException("Cannot write byte to relative mode."); + + return (Read, Write, WriteByte); } - public void AddressingMode_Register_Store(u16 data) + public (Func read, Action write, Action writeByte) AddressingMode_Register() { u8 regIndex = this.Bus.Read(this.PC); this.PC += 1; - this.StoreRegister(regIndex, data); + u16 Read() => this.FetchRegister(regIndex); + void Write(u16 value) => this.StoreRegister(regIndex, value); + void WriteByte(u8 value) + { + u16 currentValue = this.FetchRegister(regIndex); + u16 newValue = (u16) ((currentValue & 0xFF00) | (value & 0x00FF)); // Update low byte + this.StoreRegister(regIndex, newValue); + } + + return (Read, Write, WriteByte); } - public void AddressingMode_RegisterIndirect_Store(u16 data) + public (Func read, Action write, Action writeByte) AddressingMode_RegisterIndirect() { u8 regIndex = this.Bus.Read(this.PC); this.PC += 1; - u16 address = this.FetchRegister(regIndex); - this.Bus.WriteWord(address, data); + u16 Read() + { + u16 address = this.FetchRegister(regIndex); + u16 value = this.Bus.ReadWord(address); + return value; + } + + void Write(u16 value) + { + u16 address = this.FetchRegister(regIndex); + this.Bus.WriteWord(address, value); + } + + void WriteByte(u8 value) + { + u16 address = this.FetchRegister(regIndex); + this.Bus.Write(address, value); + } + + return (Read, Write, WriteByte); } - public void AddressingMode_RegisterIndirectOffset_Store(u16 data) + public (Func read, Action write, Action writeByte) AddressingMode_RegisterIndirectOffset() { u8 regIndex = this.Bus.Read(this.PC); this.PC += 1; - i16 offset = Make.i16(this.Bus.ReadSeq(this.PC, 2)); + i16 offset = this.Bus.ReadSignedWord(this.PC); this.PC += 2; - u16 address = (u16) (this.FetchRegister(regIndex) + offset); - this.Bus.WriteWord(address, data); + u16 Read() + { + u16 address = (u16) (this.FetchRegister(regIndex) + offset); + u16 value = this.Bus.ReadWord(address); + return value; + } + + void Write(u16 value) + { + u16 address = (u16) (this.FetchRegister(regIndex) + offset); + this.Bus.WriteWord(address, value); + } + + void WriteByte(u8 value) + { + u16 address = (u16) (this.FetchRegister(regIndex) + offset); + this.Bus.Write(address, value); + } + + return (Read, Write, WriteByte); } } \ No newline at end of file diff --git a/Chip/Q1CpuInstructions.cs b/Chip/Q1CpuInstructions.cs index 8b79a1d..b31a102 100644 --- a/Chip/Q1CpuInstructions.cs +++ b/Chip/Q1CpuInstructions.cs @@ -5,56 +5,79 @@ using System.Collections.Generic; public partial class Q1Cpu { + public static Dictionary InstructionLookupStrings = new() + { + { 0x00, ["NOP", "JMP", "HALT", "MOV"] }, + { 0x01, ["RET", "CALL", "SUS", "MOVB"] }, + { 0x02, ["BZ", "BZ", "BR", "NOP"] }, + + { 0x10, ["INV", "INV", "NOP", "AND"] }, + { 0x11, ["SHL", "SHL", "NOP", "OR"] }, + { 0x12, ["SHR", "SHR", "NOP", "XOR"] }, + + { 0x20, ["NOT", "NOT", "NOP", "CMP"] }, + { 0x21, ["NOP", "NOP", "NOP", "LT"] }, + { 0x22, ["NOP", "NOP", "NOP", "GT"] }, + + { 0x30, ["INC_AX", "INC", "NOP", "ADD"] }, + { 0x31, ["DEC_AX", "DEC", "NOP", "SUB"] }, + { 0x32, ["NOP", "NOP", "NOP", "DIV"] }, + { 0x33, ["NOP", "NOP", "NOP", "MUL"] }, + { 0x34, ["NOP", "NOP", "NOP", "MOD"] }, + }; + public Dictionary, Action, Action)> InstructionLookup; private void LoadInstructionLookup() { this.InstructionLookup = new Dictionary, Action, Action)> { { 0x00, (this.Instruction_NOP, this.Instruction_JMP, this.Instruction_HALT, this.Instruction_MOV) }, - { 0x01, (this.Instruction_RET, this.Instruction_CALL, this.Instruction_SUS, this.Instruction_CMP) }, - { 0x02, (this.Instruction_BR, this.Instruction_BZ, this.Instruction_BZ_LX, this.Instruction_LT) }, - { 0x03, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_GT) }, + { 0x01, (this.Instruction_RET, this.Instruction_CALL, this.Instruction_SUS, this.Instruction_MOVB) }, + { 0x02, (this.Instruction_BZ_LX, this.Instruction_BZ, this.Instruction_BR, this.Instruction_NOP) }, - { 0x04, (this.Instruction_NOT_LX, this.Instruction_NOT, this.Instruction_NOP, this.Instruction_AND) }, - { 0x05, (this.Instruction_INV_DX, this.Instruction_INV, this.Instruction_NOP, this.Instruction_OR) }, - { 0x06, (this.Instruction_SHL_DX, this.Instruction_SHL, this.Instruction_NOP, this.Instruction_XOR) }, - { 0x07, (this.Instruction_SHR_DX, this.Instruction_SHR, this.Instruction_NOP, this.Instruction_NOP) }, + { 0x10, (this.Instruction_INV_DX, this.Instruction_INV, this.Instruction_NOP, this.Instruction_AND) }, + { 0x11, (this.Instruction_SHL_DX, this.Instruction_SHL, this.Instruction_NOP, this.Instruction_OR) }, + { 0x12, (this.Instruction_SHR_DX, this.Instruction_SHR, this.Instruction_NOP, this.Instruction_XOR) }, + + { 0x20, (this.Instruction_NOT_LX, this.Instruction_NOT, this.Instruction_NOP, this.Instruction_CMP) }, + { 0x21, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_LT) }, + { 0x22, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_GT) }, - { 0x08, (this.Instruction_INC_AX, this.Instruction_INC, this.Instruction_NOP, this.Instruction_ADD) }, - { 0x09, (this.Instruction_DEC_AX, this.Instruction_DEC, this.Instruction_NOP, this.Instruction_SUB) }, - { 0x0A, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_DIV) }, - { 0x0B, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_MUL) }, - { 0x0C, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_MOD) }, + { 0x30, (this.Instruction_INC_AX, this.Instruction_INC, this.Instruction_NOP, this.Instruction_ADD) }, + { 0x31, (this.Instruction_DEC_AX, this.Instruction_DEC, this.Instruction_NOP, this.Instruction_SUB) }, + { 0x32, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_DIV) }, + { 0x33, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_MUL) }, + { 0x34, (this.Instruction_NOP, this.Instruction_NOP, this.Instruction_NOP, this.Instruction_MOD) }, }; } private void Instruction_ADD(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16) (v1 + v2); this.AX = result; } private void Instruction_SUB(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16)(v1 - v2); this.AX = result; } private void Instruction_MUL(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16) (v1 * v2); this.AX = result; } private void Instruction_DIV(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); if (v2 == 0) throw new DivideByZeroException("Cannot perform division by zero."); @@ -63,8 +86,8 @@ public partial class Q1Cpu } private void Instruction_MOD(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); if (v2 == 0) throw new DivideByZeroException("Cannot perform modulo operation with divisor zero."); @@ -73,11 +96,15 @@ public partial class Q1Cpu } private void Instruction_INC(u8 obj) { - this.TransformData(obj, value => (u16)(value + 1)); + var address = this.Address(obj); + u16 value = address.read(); + address.write((u16)(value + 1)); } private void Instruction_DEC(u8 obj) { - this.TransformData(obj, value => (u16)(value - 1)); + var address = this.Address(obj); + u16 value = address.read(); + address.write((u16)(value - 1)); } private void Instruction_INC_AX() { @@ -89,11 +116,17 @@ public partial class Q1Cpu } private void Instruction_SHL(u8 obj) { - this.TransformData(obj, value => (u16)(value << 1)); + var address = this.Address(obj); + u16 value = address.read(); + u16 result = (u16)(value << 1); + address.write(result); } private void Instruction_SHR(u8 obj) { - this.TransformData(obj, value => (u16)(value >> 1)); + var address = this.Address(obj); + u16 value = address.read(); + u16 result = (u16)(value >> 1); + address.write(result); } private void Instruction_SHL_DX() { @@ -105,25 +138,26 @@ public partial class Q1Cpu } private void Instruction_XOR(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16)(v1 ^ v2); this.DX = result; } private void Instruction_OR(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16)(v1 | v2); this.DX = result; } private void Instruction_INV(u8 obj) { - u16 value = this.FetchData(obj); + var address = this.Address(obj); + u16 value = address.read(); u16 result = (u16)~value; - this.DX = result; + address.write(result); } private void Instruction_INV_DX() { @@ -131,15 +165,15 @@ public partial class Q1Cpu } private void Instruction_AND(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); u16 result = (u16)(v1 & v2); this.DX = result; } private void Instruction_NOT(u8 obj) { - u16 value = this.FetchData(obj); + u16 value = this.Address(obj).read(); u16 result = value == 0 ? (u16)1 : (u16)0; this.LX = result; } @@ -149,15 +183,15 @@ public partial class Q1Cpu } private void Instruction_GT(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); this.LX = (u16)(v1 > v2 ? 1 : 0); } private void Instruction_LT(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); this.LX = (u16)(v1 < v2 ? 1 : 0); } @@ -174,22 +208,29 @@ public partial class Q1Cpu } private void Instruction_BZ(u8 obj) { - u16 value = this.FetchData(obj); + u16 value = this.Address(obj).read(); if (value == 0) this.Instruction_BR(); } private void Instruction_CMP(u8 m1, u8 m2) { - u16 v1 = this.FetchData(m1); - u16 v2 = this.FetchData(m2); + u16 v1 = this.Address(m1).read(); + u16 v2 = this.Address(m2).read(); // Set LX based on comparison this.LX = (u16)(v1 == v2 ? 1 : 0); } private void Instruction_MOV(u8 m1, u8 m2) { - u16 value = this.FetchData(m1); - this.StoreData(m2, value); + u16 value = this.Address(m1).read(); + this.Address(m2).write(value); + } + + private void Instruction_MOVB(u8 m1, u8 m2) + { + u16 value = this.Address(m1).read(); + u8 low = Make.ref8(value)[1]; + this.Address(m2).writeByte(low); } public void Instruction_NOP() { } @@ -198,7 +239,7 @@ public partial class Q1Cpu public void Instruction_JMP(u8 m1) { - this.PC = this.FetchData(m1); + this.PC = this.Address(m1).read(); } public void Instruction_RET() @@ -208,7 +249,7 @@ public partial class Q1Cpu public void Instruction_CALL(u8 m1) { - u16 address = this.FetchData(m1); + u16 address = this.Address(m1).read(); this.PushStack(this.PC); this.PC = address; } diff --git a/Chip/RamDevice.cs b/Chip/RamDevice.cs index 6811d22..509a2df 100644 --- a/Chip/RamDevice.cs +++ b/Chip/RamDevice.cs @@ -33,17 +33,4 @@ public class RamDevice : BusDevice u16 relativeAddress = this.GetRelativeAddress(address); this.Memory[relativeAddress] = value; } - - public override ref8 ReadSeq(u16 address, u16 length) - { - u16 relativeAddress = this.GetRelativeAddress(address); - // Console.WriteLine($"{address:X4} {relativeAddress:X4} {length:X4}"); - return new ref8(this.Memory, relativeAddress, length); - } - - public override void WriteSeq(u16 address, u16 length, ref8 value) - { - ref8 destination = this.ReadSeq(address, length); - value.CopyTo(destination); - } } \ No newline at end of file -- cgit v1.3.1