diff options
Diffstat (limited to 'Chip/Q1CpuAddressingModes.cs')
| -rw-r--r-- | Chip/Q1CpuAddressingModes.cs | 150 |
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 |
