From 86452af2d48e2d1883dbfd67316e371f2a593bfe Mon Sep 17 00:00:00 2001 From: Melodi <62381002+Melodi17@users.noreply.github.com> Date: Mon, 4 Aug 2025 00:58:48 +1000 Subject: Initial commit --- Chip/Q1CpuAddressingModes.cs | 150 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 Chip/Q1CpuAddressingModes.cs (limited to 'Chip/Q1CpuAddressingModes.cs') diff --git a/Chip/Q1CpuAddressingModes.cs b/Chip/Q1CpuAddressingModes.cs new file mode 100644 index 0000000..0d664f7 --- /dev/null +++ b/Chip/Q1CpuAddressingModes.cs @@ -0,0 +1,150 @@ +namespace Q1Emu.Chip; + +using System; +using System.Collections.Generic; + +public partial class Q1Cpu +{ + public u16 FetchData(u8 mode) + { + return mode switch + { + 0x0 => this.AddressingMode_Implicit(), + 0x1 => this.AddressingMode_Immediate(), + 0x2 => this.AddressingMode_Direct(), + 0x3 => this.AddressingMode_Indirect(), + 0x4 => this.AddressingMode_Relative(), + 0x5 => this.AddressingMode_Register(), + 0x6 => this.AddressingMode_RegisterIndirect(), + 0x7 => this.AddressingMode_RegisterIndirectOffset(), + _ => throw new InvalidOperationException($"Unknown addressing mode: {mode:X2}"), + }; + } + + public void StoreData(u8 mode, u16 value) + { + Console.WriteLine($"StoreData: mode={mode:X8}, value={value:X16}"); + if (mode != 0x05) + { + u16 address = this.FetchData(mode); + Console.WriteLine($"StoreData: address={address:X16}"); + this.Bus.WriteWord(address, value); + } + else + { + u8 regIndex = this.Bus.Read(this.PC); + this.PC += 1; + + this.StoreRegister(regIndex, value); + } + } + + 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); + } + } + + public u8 AddressingModeLength(u8 mode) + { + return mode switch + { + 0x0 => 0, // Implicit + 0x1 => 2, // Immediate + 0x2 => 2, // Direct + 0x3 => 2, // Indirect + 0x4 => 2, // Relative + 0x5 => 1, // Register + 0x6 => 1, // Register indirect + 0x7 => 3, // Register indirect with offset + _ => throw new InvalidOperationException($"Unknown addressing mode: {mode:X2}"), + }; + } + + public u16 AddressingMode_Implicit() + { + return 0; + } + + + public u16 AddressingMode_Immediate() + { + u16 value = this.Bus.ReadWord(this.PC); + this.PC += 2; + + return value; + } + + public u16 AddressingMode_Direct() + { + u16 address = this.Bus.ReadWord(this.PC); + this.PC += 2; + + u16 value = this.Bus.ReadWord(address); + return value; + } + + public u16 AddressingMode_Indirect() + { + u16 address = this.Bus.ReadWord(this.PC); + this.PC += 2; + + u16 indirectAddress = this.Bus.ReadWord(address); + u16 value = this.Bus.ReadWord(indirectAddress); + return value; + } + + public u16 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); + return value; + } + + public u16 AddressingMode_RegisterIndirectOffset() + { + u8 regIndex = this.Bus.Read(this.PC); + this.PC += 1; + + u16 offset = this.Bus.ReadWord(this.PC); + this.PC += 2; + + u16 address = (u16) (this.FetchRegister(regIndex) + offset); + u16 value = this.Bus.ReadWord(address); + return value; + } +} \ No newline at end of file -- cgit v1.3.1