summaryrefslogtreecommitdiff
path: root/Chip/Q1CpuAddressingModes.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Chip/Q1CpuAddressingModes.cs')
-rw-r--r--Chip/Q1CpuAddressingModes.cs150
1 files changed, 150 insertions, 0 deletions
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<u16, u16> 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