summaryrefslogtreecommitdiff
path: root/Q1.core/Arch/AddressingModes.cs
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2026-03-17 20:49:22 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2026-03-17 20:49:22 +1000
commit18868128e18d38b706e7df14e8e683e1a9739c17 (patch)
tree6f0e0e5eee646f10cbad9c0c89c24d330bc58cc6 /Q1.core/Arch/AddressingModes.cs
parentd87ab8af4c86a3fc6ee237444e372d87e536e3ef (diff)
chore: Initial commit
Diffstat (limited to 'Q1.core/Arch/AddressingModes.cs')
-rw-r--r--Q1.core/Arch/AddressingModes.cs331
1 files changed, 331 insertions, 0 deletions
diff --git a/Q1.core/Arch/AddressingModes.cs b/Q1.core/Arch/AddressingModes.cs
new file mode 100644
index 0000000..206ee4f
--- /dev/null
+++ b/Q1.core/Arch/AddressingModes.cs
@@ -0,0 +1,331 @@
+namespace Q1.core.Arch;
+
+public static class AddressingModes
+{
+ public static AddressingMode[] Lookup = new AddressingMode[8];
+
+ static AddressingModes()
+ {
+ AddressingModes.Lookup[0x00] = new AddressingMode
+ {
+ Name = "Implicit",
+ SizeB = 0,
+ SizeW = 0,
+ LoadByte = AddressingModes.ImplicitLoadByte,
+ LoadWord = AddressingModes.ImplicitLoadWord,
+ StoreByte = AddressingModes.ImplicitStoreByte,
+ StoreWord = AddressingModes.ImplicitStoreWord
+ };
+
+ AddressingModes.Lookup[0x01] = new AddressingMode
+ {
+ Name = "Immediate",
+ SizeB = 1,
+ SizeW = 2,
+ LoadByte = AddressingModes.ImmediateLoadByte,
+ LoadWord = AddressingModes.ImmediateLoadWord,
+ StoreByte = AddressingModes.ImmediateStoreByte,
+ StoreWord = AddressingModes.ImmediateStoreWord
+ };
+
+ AddressingModes.Lookup[0x02] = new AddressingMode
+ {
+ Name = "Direct",
+ SizeB = 2,
+ SizeW = 2,
+ LoadByte = AddressingModes.DirectLoadByte,
+ LoadWord = AddressingModes.DirectLoadWord,
+ StoreByte = AddressingModes.DirectStoreByte,
+ StoreWord = AddressingModes.DirectStoreWord
+ };
+
+ AddressingModes.Lookup[0x03] = new AddressingMode
+ {
+ Name = "Indirect",
+ SizeB = 2,
+ SizeW = 2,
+ LoadByte = AddressingModes.IndirectLoadByte,
+ LoadWord = AddressingModes.IndirectLoadWord,
+ StoreByte = AddressingModes.IndirectStoreByte,
+ StoreWord = AddressingModes.IndirectStoreWord
+ };
+
+ AddressingModes.Lookup[0x04] = new AddressingMode
+ {
+ Name = "Relative",
+ SizeB = 2,
+ SizeW = 2,
+ LoadByte = AddressingModes.RelativeLoadByte,
+ LoadWord = AddressingModes.RelativeLoadWord,
+ StoreByte = AddressingModes.RelativeStoreByte,
+ StoreWord = AddressingModes.RelativeStoreWord
+ };
+
+ AddressingModes.Lookup[0x05] = new AddressingMode
+ {
+ Name = "Register",
+ SizeB = 1,
+ SizeW = 1,
+ LoadByte = AddressingModes.RegisterLoadByte,
+ LoadWord = AddressingModes.RegisterLoadWord,
+ StoreByte = AddressingModes.RegisterStoreByte,
+ StoreWord = AddressingModes.RegisterStoreWord
+ };
+
+ AddressingModes.Lookup[0x06] = new AddressingMode
+ {
+ Name = "Register Indirect",
+ SizeB = 1,
+ SizeW = 1,
+ LoadByte = AddressingModes.RegisterIndirectLoadByte,
+ LoadWord = AddressingModes.RegisterIndirectLoadWord,
+ StoreByte = AddressingModes.RegisterIndirectStoreByte,
+ StoreWord = AddressingModes.RegisterIndirectStoreWord
+ };
+
+ AddressingModes.Lookup[0x07] = new AddressingMode
+ {
+ Name = "Register Indirect with Offset",
+ SizeB = 3,
+ SizeW = 3,
+ LoadByte = AddressingModes.RegisterIndirectOffsetLoadByte,
+ LoadWord = AddressingModes.RegisterIndirectOffsetLoadWord,
+ StoreByte = AddressingModes.RegisterIndirectOffsetStoreByte,
+ StoreWord = AddressingModes.RegisterIndirectOffsetStoreWord
+ };
+ }
+
+ private static u8 ImplicitLoadByte(Chip chip)
+ => throw new InvalidOperationException("Cannot load from an implicit value");
+ private static u16 ImplicitLoadWord(Chip chip)
+ => throw new InvalidOperationException("Cannot load from an implicit value");
+ private static void ImplicitStoreByte(Chip chip, u8 value)
+ => throw new InvalidOperationException("Cannot store to an implicit value");
+ private static void ImplicitStoreWord(Chip chip, u16 value)
+ => throw new InvalidOperationException("Cannot store to an implicit value");
+
+
+ private static u8 ImmediateLoadByte(Chip chip)
+ {
+ u8 value = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+ return value;
+ }
+ private static u16 ImmediateLoadWord(Chip chip)
+ {
+ u16 value = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+ return value;
+ }
+ private static void ImmediateStoreByte(Chip chip, u8 value)
+ => throw new InvalidOperationException("Cannot store to an immediate value");
+ private static void ImmediateStoreWord(Chip chip, u16 value)
+ => throw new InvalidOperationException("Cannot store to an immediate value");
+
+
+ private static u8 DirectLoadByte(Chip chip)
+ {
+ u16 address = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ return chip.Bus.Read(address);
+ }
+ private static u16 DirectLoadWord(Chip chip)
+ {
+ u16 address = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ return chip.Bus.ReadWord(address);
+ }
+ private static void DirectStoreByte(Chip chip, u8 value)
+ {
+ u16 address = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ chip.Bus.Write(address, value);
+ }
+ private static void DirectStoreWord(Chip chip, u16 value)
+ {
+ u16 address = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ chip.Bus.WriteWord(address, value);
+ }
+
+
+ private static u8 IndirectLoadByte(Chip chip)
+ {
+ u16 pointer = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = chip.Bus.ReadWord(pointer);
+ return chip.Bus.Read(address);
+ }
+ private static u16 IndirectLoadWord(Chip chip)
+ {
+ u16 pointer = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = chip.Bus.ReadWord(pointer);
+ return chip.Bus.ReadWord(address);
+ }
+ private static void IndirectStoreByte(Chip chip, u8 value)
+ {
+ u16 pointer = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = chip.Bus.ReadWord(pointer);
+ chip.Bus.Write(address, value);
+ }
+ private static void IndirectStoreWord(Chip chip, u16 value)
+ {
+ u16 pointer = chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = chip.Bus.ReadWord(pointer);
+ chip.Bus.WriteWord(address, value);
+ }
+
+
+ private static u8 RelativeLoadByte(Chip chip)
+ {
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16) (chip.Pc + offset);
+ return chip.Bus.Read(address);
+ }
+ private static u16 RelativeLoadWord(Chip chip)
+ {
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16) (chip.Pc + offset);
+ return chip.Bus.ReadWord(address);
+ }
+ private static void RelativeStoreByte(Chip chip, u8 value)
+ {
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16) (chip.Pc + offset);
+ chip.Bus.Write(address, value);
+ }
+ private static void RelativeStoreWord(Chip chip, u16 value)
+ {
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16) (chip.Pc + offset);
+ chip.Bus.WriteWord(address, value);
+ }
+
+ private static u8 RegisterLoadByte(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ return (u8) (chip.GetRegister(regIndex) & 0xFF);
+ }
+ private static u16 RegisterLoadWord(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ return chip.GetRegister(regIndex);
+ }
+ private static void RegisterStoreByte(Chip chip, u8 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ u16 current = chip.GetRegister(regIndex);
+ u16 newValue = (u16)((current & 0xFF00) | value);
+ chip.SetRegister(regIndex, newValue);
+ }
+ private static void RegisterStoreWord(Chip chip, u16 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ chip.SetRegister(regIndex, value);
+ }
+
+ private static u8 RegisterIndirectLoadByte(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ u16 address = chip.GetRegister(regIndex);
+ return chip.Bus.Read(address);
+ }
+ private static u16 RegisterIndirectLoadWord(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ u16 address = chip.GetRegister(regIndex);
+ return chip.Bus.ReadWord(address);
+ }
+ private static void RegisterIndirectStoreByte(Chip chip, u8 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ u16 address = chip.GetRegister(regIndex);
+ chip.Bus.Write(address, value);
+ }
+ private static void RegisterIndirectStoreWord(Chip chip, u16 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ u16 address = chip.GetRegister(regIndex);
+ chip.Bus.WriteWord(address, value);
+ }
+
+ private static u8 RegisterIndirectOffsetLoadByte(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16)(chip.GetRegister(regIndex) + offset);
+ return chip.Bus.Read(address);
+ }
+ private static u16 RegisterIndirectOffsetLoadWord(Chip chip)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16)(chip.GetRegister(regIndex) + offset);
+ return chip.Bus.ReadWord(address);
+ }
+ private static void RegisterIndirectOffsetStoreByte(Chip chip, u8 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16)(chip.GetRegister(regIndex) + offset);
+ chip.Bus.Write(address, value);
+ }
+ private static void RegisterIndirectOffsetStoreWord(Chip chip, u16 value)
+ {
+ u8 regIndex = chip.Bus.Read(chip.Pc);
+ chip.Pc += 1;
+
+ i16 offset = (i16) chip.Bus.ReadWord(chip.Pc);
+ chip.Pc += 2;
+
+ u16 address = (u16)(chip.GetRegister(regIndex) + offset);
+ chip.Bus.WriteWord(address, value);
+ }
+} \ No newline at end of file