From 7a8d2bcd75d88a5429937bf551878c55e1dcf0fd Mon Sep 17 00:00:00 2001 From: Melodi <62381002+Melodi17@users.noreply.github.com> Date: Wed, 6 Aug 2025 22:36:34 +1000 Subject: moved everything to seperate projects, and started compiler work + push and pop instructions added --- Emulator/Chip/Q1CpuAddressingModes.cs | 187 ++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 Emulator/Chip/Q1CpuAddressingModes.cs (limited to 'Emulator/Chip/Q1CpuAddressingModes.cs') diff --git a/Emulator/Chip/Q1CpuAddressingModes.cs b/Emulator/Chip/Q1CpuAddressingModes.cs new file mode 100644 index 0000000..40020f1 --- /dev/null +++ b/Emulator/Chip/Q1CpuAddressingModes.cs @@ -0,0 +1,187 @@ +namespace Q1.Emulator.Chip; + +using System; + +public partial class Q1Cpu +{ + public (Func read, Action write, Action writeByte) Address(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}"), + }; + } + + private 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 (Func read, Action write, Action writeByte) AddressingMode_Implicit() + { + 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 (Func read, Action write, Action writeByte) AddressingMode_Immediate() + { + u16 value = this.Bus.ReadWord(this.PC); + this.PC += 2; + + 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 (Func read, Action write, Action writeByte) AddressingMode_Direct() + { + u16 address = this.Bus.ReadWord(this.PC); + this.PC += 2; + + 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 (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; + } + + 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 (Func read, Action write, Action writeByte) AddressingMode_Relative() + { + u16 offset = this.Bus.ReadWord(this.PC); + this.PC += 2; + + u16 address = (u16) (this.PC + offset); + + 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 (Func read, Action write, Action writeByte) AddressingMode_Register() + { + u8 regIndex = this.Bus.Read(this.PC); + this.PC += 1; + + 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 (Func read, Action write, Action writeByte) AddressingMode_RegisterIndirect() + { + u8 regIndex = this.Bus.Read(this.PC); + this.PC += 1; + + 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 (Func read, Action write, Action writeByte) AddressingMode_RegisterIndirectOffset() + { + u8 regIndex = this.Bus.Read(this.PC); + this.PC += 1; + + u16 offset = this.Bus.ReadWord(this.PC); + this.PC += 2; + + 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 -- cgit v1.3.1