From 9a011b3c57a65208d0bdf65c8b77ec2ae2270489 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sat, 16 May 2026 21:10:23 +0100 Subject: [PATCH] Start implementing HD6309. Introduction of 32-bit operations has forced me to rename some of "Word" methods to better indicate size --- EightBit/BigEndianProcessor.cs | 8 +- EightBit/Bus.cs | 6 +- EightBit/Chip.cs | 14 +- EightBit/EightBit.UnitTest/ChipTests.cs | 2 +- EightBit/InputOutput.cs | 8 +- EightBit/IntelProcessor.cs | 14 +- EightBit/LittleEndianProcessor.cs | 8 +- EightBit/Processor.cs | 36 +- EightBit/Register16.cs | 19 +- Intel8080/Disassembler.cs | 8 +- Intel8080/Intel8080.Test/Board.cs | 8 +- Intel8080/Intel8080.cs | 20 +- LR35902/Bus.cs | 2 +- LR35902/Disassembler.cs | 6 +- LR35902/IoRegisters.cs | 6 +- LR35902/LR35902.BlarggTest/Board.cs | 4 +- LR35902/LR35902.FuseTest/TestRunner.cs | 24 +- LR35902/LR35902.cs | 28 +- LR35902/SM83.HarteTest/Checker.cs | 16 +- M6502/Core.cs | 30 +- M6502/Disassembler.cs | 2 +- M6502/M6502.HarteTest/Checker.cs | 10 +- M6502/M6502.Test/Board.cs | 6 +- M6502/MOS6502.cs | 2 +- M6502/Profiler.cs | 2 +- M6502/WDC65C02.cs | 10 +- MC6809/Disassembler.cs | 12 +- MC6809/HD6309.cs | 964 ++++++++++++++++++ MC6809/MC6809.Test/Board.cs | 12 +- MC6809/MC6809.UnitTest/AbxTests.cs | 28 +- MC6809/MC6809.UnitTest/AndTests.cs | 2 +- MC6809/MC6809.UnitTest/BgtTests.cs | 8 +- MC6809/MC6809.UnitTest/BleTests.cs | 2 +- MC6809/MC6809.UnitTest/CmpTests.cs | 62 +- MC6809/MC6809.UnitTest/ComTests.cs | 4 +- MC6809/MC6809.UnitTest/DaaTests.cs | 2 +- MC6809/MC6809.UnitTest/EorTests.cs | 6 +- MC6809/MC6809.UnitTest/ExgTests.cs | 18 +- MC6809/MC6809.UnitTest/JsrTests.cs | 22 +- MC6809/MC6809.UnitTest/LdTests.cs | 8 +- MC6809/MC6809.UnitTest/LeaTests.cs | 26 +- MC6809/MC6809.UnitTest/LsrTests.cs | 26 +- MC6809/MC6809.UnitTest/MulTests.cs | 8 +- MC6809/MC6809.UnitTest/NegTests.cs | 8 +- MC6809/MC6809.UnitTest/OrTests.cs | 2 +- MC6809/MC6809.UnitTest/PshTests.cs | 28 +- MC6809/MC6809.UnitTest/PulTests.cs | 58 +- MC6809/MC6809.UnitTest/RolTests.cs | 8 +- MC6809/MC6809.UnitTest/RorTests.cs | 4 +- MC6809/MC6809.UnitTest/RtsTests.cs | 10 +- .../SchwotzerArithmeticTests.cs | 8 +- .../SchwotzerCompareLoadTests.cs | 14 +- MC6809/MC6809.UnitTest/SubTests.cs | 2 +- MC6809/MC6809.UnitTest/TfrTests.cs | 34 +- MC6809/MC6809.UnitTest/TstTests.cs | 18 +- MC6809/MC6809.cs | 376 +++---- MC6809/Profiler.cs | 2 +- Z80/Disassembler.cs | 10 +- Z80/Z80.FuseTest/TestRunner.cs | 56 +- Z80/Z80.HarteTest/Checker.cs | 26 +- Z80/Z80.Test/Board.cs | 6 +- Z80/Z80.cs | 50 +- 62 files changed, 1620 insertions(+), 609 deletions(-) create mode 100644 MC6809/HD6309.cs diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index c38f9cc..0700c83 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -5,14 +5,14 @@ namespace EightBit { public abstract class BigEndianProcessor(Bus memory) : Processor(memory) { - public override Register16 PeekWord(ushort address) + public override Register16 PeekShort(ushort address) { this.Intermediate.High = this.Bus.Peek(address); this.Intermediate.Low = this.Bus.Peek(++address); return this.Intermediate; } - public override void PokeWord(ushort address, Register16 value) + public override void PokeShort(ushort address, Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.Bus.Poke(address, value.High); @@ -49,14 +49,14 @@ namespace EightBit into.Low = this.Pop(); } - protected override void PushWord(Register16 value) + protected override void PushShort(Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.Push(value.Low); this.Push(value.High); } - protected override void SetWord(Register16 value) + protected override void SetShort(Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.High); diff --git a/EightBit/Bus.cs b/EightBit/Bus.cs index 5043355..139ad5f 100644 --- a/EightBit/Bus.cs +++ b/EightBit/Bus.cs @@ -27,7 +27,7 @@ namespace EightBit public byte Peek(Register16 absolute) { ArgumentNullException.ThrowIfNull(absolute); - return this.Peek(absolute.Word); + return this.Peek(absolute.Joined); } public void Poke(byte value) => this.Reference() = value; @@ -37,7 +37,7 @@ namespace EightBit public void Poke(Register16 absolute, byte value) { ArgumentNullException.ThrowIfNull(absolute); - this.Poke(absolute.Word, value); + this.Poke(absolute.Joined, value); } public byte Read() @@ -80,7 +80,7 @@ namespace EightBit return ref mapped.Memory.Reference(offset); } - protected ref byte Reference() => ref this.Reference(this.Address.Word); + protected ref byte Reference() => ref this.Reference(this.Address.Joined); protected void LoadHexFile(string path) { diff --git a/EightBit/Chip.cs b/EightBit/Chip.cs index 9039f27..8dfebae 100644 --- a/EightBit/Chip.cs +++ b/EightBit/Chip.cs @@ -35,18 +35,27 @@ namespace EightBit [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte HighByte(int value) => (byte)(value >> 8); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort HighShort(uint value) => (ushort)(value >> 16); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte HighByte(ushort value) => HighByte((int)value); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte LowByte(int value) => (byte)(value & (int)Mask.Eight); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort LowShort(uint value) => (ushort)(value & (int)Mask.Sixteen); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte LowByte(ushort value) => LowByte((int)value); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort PromoteByte(byte value) => (ushort)(value << 8); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint PromoteShort(ushort value) => (uint)(value << 16); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte DemoteByte(ushort value) => HighByte(value); @@ -57,7 +66,10 @@ namespace EightBit public static byte LowerPart(ushort value) => LowByte(value); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort MakeWord(byte low, byte high) => (ushort)(PromoteByte(high) | low); + public static ushort MakeShort(byte low, byte high) => (ushort)(PromoteByte(high) | low); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint MakeInteger(ushort low, ushort high) => (uint)(PromoteShort(high) | low); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighNibble(byte value) => value >> 4; diff --git a/EightBit/EightBit.UnitTest/ChipTests.cs b/EightBit/EightBit.UnitTest/ChipTests.cs index 88e40c9..9c4c92f 100644 --- a/EightBit/EightBit.UnitTest/ChipTests.cs +++ b/EightBit/EightBit.UnitTest/ChipTests.cs @@ -61,7 +61,7 @@ namespace EightBit.UnitTest [TestMethod] public void MakeWord_CreatesCorrectWord() { - Assert.AreEqual(0x1234, Chip.MakeWord(0x34, 0x12)); + Assert.AreEqual(0x1234, Chip.MakeShort(0x34, 0x12)); } [TestMethod] diff --git a/EightBit/InputOutput.cs b/EightBit/InputOutput.cs index 675369d..8b73279 100644 --- a/EightBit/InputOutput.cs +++ b/EightBit/InputOutput.cs @@ -24,7 +24,7 @@ namespace EightBit { ArgumentNullException.ThrowIfNull(port); ReadingPort?.Invoke(this, new PortEventArgs(port)); - var value = this._input[port.Word]; + var value = this._input[port.Joined]; ReadPort?.Invoke(this, new PortEventArgs(port)); return value; } @@ -34,7 +34,7 @@ namespace EightBit public void WriteInputPort(Register16 port, byte value) { ArgumentNullException.ThrowIfNull(port); - this.WriteInputPort(port.Word, value); + this.WriteInputPort(port.Joined, value); } public void Write(Register16 port, byte value) => this.WriteOutputPort(port, value); @@ -43,7 +43,7 @@ namespace EightBit { ArgumentNullException.ThrowIfNull(port); WritingPort?.Invoke(this, new PortEventArgs(port)); - this._output[port.Word] = value; + this._output[port.Joined] = value; WrittenPort?.Invoke(this, new PortEventArgs(port)); } @@ -52,7 +52,7 @@ namespace EightBit public byte ReadOutputPort(Register16 port) { ArgumentNullException.ThrowIfNull(port); - return this.ReadOutputPort(port.Word); + return this.ReadOutputPort(port.Joined); } } } diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index 644a2ed..c897f37 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -118,12 +118,12 @@ namespace EightBit protected void ResetRegisterSet() { - this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Sixteen; + this.AF.Joined = this.BC.Joined = this.DE.Joined = this.HL.Joined = (ushort)Mask.Sixteen; } private void IntelProcessor_RaisedPOWER(object? sender, EventArgs e) { - this.PC.Word = this.SP.Word = (ushort)Mask.Sixteen; + this.PC.Joined = this.SP.Joined = (ushort)Mask.Sixteen; this.ResetRegisterSet(); this.RaiseHALT(); } @@ -155,15 +155,15 @@ namespace EightBit return this.Bus.Data; } - protected sealed override void GetWord() + protected sealed override void GetShort() { - base.GetWord(); + base.GetShort(); this.MEMPTR.Assign(this.Bus.Address); } - protected sealed override void SetWord(Register16 value) + protected sealed override void SetShort(Register16 value) { - base.SetWord(value); + base.SetShort(value); this.MEMPTR.Assign(this.Bus.Address); } @@ -263,7 +263,7 @@ namespace EightBit protected virtual void JumpRelative(sbyte offset) { - this.MEMPTR.Word = (ushort)(this.PC.Word + offset); + this.MEMPTR.Joined = (ushort)(this.PC.Joined + offset); this.Jump(); } diff --git a/EightBit/LittleEndianProcessor.cs b/EightBit/LittleEndianProcessor.cs index 573784f..12c9ddd 100644 --- a/EightBit/LittleEndianProcessor.cs +++ b/EightBit/LittleEndianProcessor.cs @@ -6,14 +6,14 @@ namespace EightBit { public abstract class LittleEndianProcessor(Bus memory) : Processor(memory) { - public override Register16 PeekWord(ushort address) + public override Register16 PeekShort(ushort address) { this.Intermediate.Low = this.Bus.Peek(address); this.Intermediate.High = this.Bus.Peek(++address); return this.Intermediate; } - public override void PokeWord(ushort address, Register16 value) + public override void PokeShort(ushort address, Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.Bus.Poke(address, value.Low); @@ -50,14 +50,14 @@ namespace EightBit into.High = this.Pop(); } - protected override void PushWord(Register16 value) + protected override void PushShort(Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.Push(value.High); this.Push(value.Low); } - protected override void SetWord(Register16 value) + protected override void SetShort(Register16 value) { //ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.Low); diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index d3bb3b9..08ca55d 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -100,11 +100,11 @@ namespace EightBit this.Execute(); } - public abstract Register16 PeekWord(ushort address); + public abstract Register16 PeekShort(ushort address); - public abstract void PokeWord(ushort address, Register16 value); + public abstract void PokeShort(ushort address, Register16 value); - public void PokeWord(ushort address, ushort value) => this.PokeWord(address, new Register16(value)); + public void PokeShort(ushort address, ushort value) => this.PokeShort(address, new Register16(value)); [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseRESET() @@ -216,18 +216,18 @@ namespace EightBit protected abstract void GetInto(Register16 into); - protected virtual void GetWord() => this.GetInto(this.Intermediate); + protected virtual void GetShort() => this.GetInto(this.Intermediate); - protected abstract void SetWord(Register16 value); + protected abstract void SetShort(Register16 value); protected abstract void GetPagedInto(Register16 into); - protected virtual void GetWordPaged() => this.GetPagedInto(this.Intermediate); + protected virtual void GetShortPaged() => this.GetPagedInto(this.Intermediate); - protected void GetWordPaged(byte page, byte offset) + protected void GetShortPaged(byte page, byte offset) { this.Bus.Address.Assign(offset, page); - this.GetWordPaged(); + this.GetShortPaged(); } protected void GetPagedInto(byte page, byte offset, Register16 into) @@ -253,11 +253,11 @@ namespace EightBit protected abstract void FetchInto(Register16 into); - protected void FetchWord() => this.FetchInto(this.Intermediate); + protected void FetchShort() => this.FetchInto(this.Intermediate); - protected void FetchWordAddress() + protected void FetchShortAddress() { - this.FetchWord(); + this.FetchShort(); this.Bus.Address.Assign(this.Intermediate); } @@ -265,30 +265,30 @@ namespace EightBit protected abstract byte Pop(); - protected abstract void PushWord(Register16 value); + protected abstract void PushShort(Register16 value); protected abstract void PopInto(Register16 into); - protected void GetWord(Register16 address) + protected void GetShort(Register16 address) { this.Bus.Address.Assign(address); - this.GetWord(); + this.GetShort(); } - protected void SetWord(Register16 address, Register16 value) + protected void SetShort(Register16 address, Register16 value) { this.Bus.Address.Assign(address); - this.SetWord(value); + this.SetShort(value); } - protected void Jump(ushort destination) => this.PC.Word = destination; + protected void Jump(ushort destination) => this.PC.Joined = destination; protected void Jump(Register16 destination) => this.PC.Assign(destination); [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Not using VB.NET")] protected virtual void Call(Register16 destination) { - this.PushWord(this.PC); + this.PushShort(this.PC); this.Jump(destination); } diff --git a/EightBit/Register16.cs b/EightBit/Register16.cs index d239ba0..2eafc81 100644 --- a/EightBit/Register16.cs +++ b/EightBit/Register16.cs @@ -15,10 +15,7 @@ namespace EightBit this.High = high; } - public Register16(ushort value) - { - this.Word = value; - } + public Register16(ushort value) => this.Joined = value; public Register16() { @@ -46,9 +43,9 @@ namespace EightBit this.High = rhs.High; } - public ushort Word + public ushort Joined { - get => Chip.MakeWord(this._low, this._high); + get => Chip.MakeShort(this._low, this._high); set { this._low = Chip.LowByte(value); @@ -66,9 +63,13 @@ namespace EightBit return left.Equals(right); } + public bool Zero => this.Joined == 0; + + public bool NonZero => !this.Zero; + public static bool operator !=(Register16 left, Register16 right) => !(left == right); - public override int GetHashCode() => this.Word; + public override int GetHashCode() => this.Joined; public override bool Equals(object? obj) => this.Equals(obj as Register16); @@ -87,8 +88,8 @@ namespace EightBit this.High = from.High; } - public void Increment() => ++this.Word; + public void Increment() => ++this.Joined; - public void Decrement() => --this.Word; + public void Decrement() => --this.Joined; } } diff --git a/Intel8080/Disassembler.cs b/Intel8080/Disassembler.cs index b755148..52caa2c 100644 --- a/Intel8080/Disassembler.cs +++ b/Intel8080/Disassembler.cs @@ -27,8 +27,8 @@ namespace Intel8080 { ArgumentNullException.ThrowIfNull(cpu); - var pc = cpu.PC.Word; - var sp = cpu.SP.Word; + var pc = cpu.PC.Joined; + var sp = cpu.SP.Joined; var a = cpu.A; var f = cpu.F; @@ -53,7 +53,7 @@ namespace Intel8080 public string Disassemble(Intel8080 cpu) { ArgumentNullException.ThrowIfNull(cpu); - return this.Disassemble(cpu, cpu.PC.Word); + return this.Disassemble(cpu, cpu.PC.Joined); } private static string CC(int flag) => flag switch @@ -426,7 +426,7 @@ namespace Intel8080 var q = decoded.Q; var immediate = this.Bus.Peek((ushort)(pc + 1)); - var absolute = cpu.PeekWord((ushort)(pc + 1)).Word; + var absolute = cpu.PeekShort((ushort)(pc + 1)).Joined; var displacement = (sbyte)immediate; var relative = pc + displacement + 2; var indexedImmediate = this.Bus.Peek((ushort)(pc + 1)); diff --git a/Intel8080/Intel8080.Test/Board.cs b/Intel8080/Intel8080.Test/Board.cs index 86a4b94..4f0edda 100644 --- a/Intel8080/Intel8080.Test/Board.cs +++ b/Intel8080/Intel8080.Test/Board.cs @@ -46,7 +46,7 @@ namespace Intel8080.Test { var programPath = this.configuration.RomDirectory + "/" + this.configuration.Program; var loadAddress = this.configuration.LoadAddress; - this.ram.Load(programPath, loadAddress.Word); + this.ram.Load(programPath, loadAddress.Joined); this.CPU.LoweredHALT += this.CPU_LoweredHALT; this.CPU.ExecutingInstruction += this.CPU_ExecutingInstruction_CPM; @@ -57,7 +57,7 @@ namespace Intel8080.Test } this.Poke(0, 0xc3); // JMP - this.CPU.PokeWord(1, this.configuration.StartAddress); + this.CPU.PokeShort(1, this.configuration.StartAddress); this.Poke(5, 0xc9); // ret } @@ -71,7 +71,7 @@ namespace Intel8080.Test System.Console.Out.Write((char)this.CPU.E); break; case 0x9: - for (var i = this.CPU.DE.Word; this.Peek(i) != '$'; ++i) + for (var i = this.CPU.DE.Joined; this.Peek(i) != '$'; ++i) { System.Console.Out.Write((char)this.Peek(i)); } @@ -82,7 +82,7 @@ namespace Intel8080.Test private void CPU_ExecutingInstruction_CPM(object? sender, System.EventArgs e) { - switch (this.CPU.PC.Word) + switch (this.CPU.PC.Joined) { case 0x0: // CP/M warm start if (++this.warmstartCount == 2) diff --git a/Intel8080/Intel8080.cs b/Intel8080/Intel8080.cs index bc3a2e5..b8ca85d 100644 --- a/Intel8080/Intel8080.cs +++ b/Intel8080/Intel8080.cs @@ -127,7 +127,7 @@ namespace Intel8080 { base.HandleRESET(); this.DisableInterrupts(); - this.SP.Word = this.AF.Word = (ushort)Mask.Sixteen; + this.SP.Joined = this.AF.Joined = (ushort)Mask.Sixteen; } private byte ReadDataUnderInterrupt() @@ -340,8 +340,8 @@ namespace Intel8080 this.WriteMemoryIndirect(this.DE, this.A); break; case 2: // LD (nn),HL - this.FetchWordAddress(); - this.SetWord(this.HL); + this.FetchShortAddress(); + this.SetShort(this.HL); break; case 3: // LD (nn),A this.FetchInto(this.MEMPTR); @@ -362,7 +362,7 @@ namespace Intel8080 this.A = this.ReadMemoryIndirect(this.DE); break; case 2: // LD HL,(nn) - this.FetchWordAddress(); + this.FetchShortAddress(); this.GetInto(this.HL); break; case 3: // LD A,(nn) @@ -566,7 +566,7 @@ namespace Intel8080 { case 0: // PUSH rp2[p] this.Tick(); - this.PushWord(this.RP2(p)); + this.PushShort(this.RP2(p)); break; case 1: switch (p) @@ -677,8 +677,8 @@ namespace Intel8080 private Register16 Add(Register16 operand, Register16 value) { - var addition = operand.Word + value.Word; - this.Intermediate.Word = (ushort)addition; + var addition = operand.Joined + value.Joined; + this.Intermediate.Joined = (ushort)addition; SetBit(StatusBits.CF, addition & (int)Bits.Bit16); @@ -687,7 +687,7 @@ namespace Intel8080 private byte Add(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand + value + carry); + this.Intermediate.Joined = (ushort)(operand + value + carry); var result = this.Intermediate.Low; AdjustAuxiliaryCarryAdd(operand, value, result); @@ -702,10 +702,10 @@ namespace Intel8080 private byte Subtract(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand - value - carry); + this.Intermediate.Joined = (ushort)(operand - value - carry); var result = this.Intermediate.Low; - AdjustAuxiliaryCarrySub(operand, value, this.Intermediate.Word); + AdjustAuxiliaryCarrySub(operand, value, this.Intermediate.Joined); SetBit(StatusBits.CF, CarryTest(this.Intermediate.High)); AdjustSZP(result); diff --git a/LR35902/Bus.cs b/LR35902/Bus.cs index c7886e3..d8a9032 100644 --- a/LR35902/Bus.cs +++ b/LR35902/Bus.cs @@ -176,7 +176,7 @@ namespace LR35902 private void Bus_WrittenByte(object? sender, EventArgs e) { - var address = this.Address.Word; + var address = this.Address.Joined; var value = this.Data; switch (address & 0xe000) diff --git a/LR35902/Disassembler.cs b/LR35902/Disassembler.cs index 4fef25f..d16d09c 100644 --- a/LR35902/Disassembler.cs +++ b/LR35902/Disassembler.cs @@ -71,7 +71,7 @@ namespace LR35902 var masked = cpu.MaskedInterrupts; return - $"PC={pc.Word:x4} SP={sp.Word:x4} " + $"PC={pc.Joined:x4} SP={sp.Joined:x4} " + $"A={a:x2} F={AsFlags(f)} " + $"B={b:x2} C={c:x2} " + $"D={d:x2} E={e:x2} " @@ -83,7 +83,7 @@ namespace LR35902 { ArgumentNullException.ThrowIfNull(cpu); this.prefixCB = false; - return this.Disassemble(cpu, cpu.PC.Word); + return this.Disassemble(cpu, cpu.PC.Joined); } private static string RP(int rp) => rp switch @@ -279,7 +279,7 @@ namespace LR35902 var q = decoded.Q; var immediate = this.Bus.Peek((ushort)(pc + 1)); - var absolute = cpu.PeekWord((ushort)(pc + 1)).Word; + var absolute = cpu.PeekShort((ushort)(pc + 1)).Joined; var displacement = (sbyte)immediate; var relative = pc + displacement + 2; var indexedImmediate = this.Bus.Peek((ushort)(pc + 1)); diff --git a/LR35902/IoRegisters.cs b/LR35902/IoRegisters.cs index d199643..7ff8c79 100644 --- a/LR35902/IoRegisters.cs +++ b/LR35902/IoRegisters.cs @@ -130,7 +130,7 @@ namespace LR35902 { this.Poke(NR52, 0xf1); this.Poke(LCDC, (byte)(LcdcControls.BG_EN | LcdcControls.TILE_SEL | LcdcControls.LCD_EN)); - this.divCounter.Word = 0xabcc; + this.divCounter.Joined = 0xabcc; this.timerCounter = 0; } @@ -309,7 +309,7 @@ namespace LR35902 case DIV: // R/W this.Poke(port, 0); - this.timerCounter = this.divCounter.Word = 0; + this.timerCounter = this.divCounter.Joined = 0; break; case TIMA: // R/W break; @@ -328,7 +328,7 @@ namespace LR35902 case SCX: break; case DMA: - this.dmaAddress.Word = Chip.PromoteByte(value); + this.dmaAddress.Joined = Chip.PromoteByte(value); this.dmaTransferActive = true; break; case LY: // R/O diff --git a/LR35902/LR35902.BlarggTest/Board.cs b/LR35902/LR35902.BlarggTest/Board.cs index 185b30f..f252891 100644 --- a/LR35902/LR35902.BlarggTest/Board.cs +++ b/LR35902/LR35902.BlarggTest/Board.cs @@ -72,8 +72,8 @@ namespace LR35902.BlarggTest var e = this.CPU.E; var h = this.CPU.H; var l = this.CPU.L; - var sp = this.CPU.SP.Word; - var pc = this.CPU.PC.Word; + var sp = this.CPU.SP.Joined; + var pc = this.CPU.PC.Joined; var aa = this.Peek(pc); var bb = this.Peek((ushort)(pc + 1)); var cc = this.Peek((ushort)(pc + 2)); diff --git a/LR35902/LR35902.FuseTest/TestRunner.cs b/LR35902/LR35902.FuseTest/TestRunner.cs index 13d644d..7101267 100644 --- a/LR35902/LR35902.FuseTest/TestRunner.cs +++ b/LR35902/LR35902.FuseTest/TestRunner.cs @@ -94,13 +94,13 @@ namespace LR35902.FuseTest var testState = this.test.RegisterState; var inputRegisters = testState.Registers; - this.CPU.AF.Word = inputRegisters[(int)Register.AF].Word; - this.CPU.BC.Word = inputRegisters[(int)Register.BC].Word; - this.CPU.DE.Word = inputRegisters[(int)Register.DE].Word; - this.CPU.HL.Word = inputRegisters[(int)Register.HL].Word; + this.CPU.AF.Joined = inputRegisters[(int)Register.AF].Joined; + this.CPU.BC.Joined = inputRegisters[(int)Register.BC].Joined; + this.CPU.DE.Joined = inputRegisters[(int)Register.DE].Joined; + this.CPU.HL.Joined = inputRegisters[(int)Register.HL].Joined; - this.CPU.SP.Word = inputRegisters[(int)Register.SP].Word; - this.CPU.PC.Word = inputRegisters[(int)Register.PC].Word; + this.CPU.SP.Joined = inputRegisters[(int)Register.SP].Joined; + this.CPU.PC.Joined = inputRegisters[(int)Register.PC].Joined; } private void InitialiseMemory() @@ -126,13 +126,13 @@ namespace LR35902.FuseTest var expectedState = this.result.RegisterState; var expectedRegisters = expectedState.Registers; - var af = this.CPU.AF.Word == expectedRegisters[(int)Register.AF].Word; - var bc = this.CPU.BC.Word == expectedRegisters[(int)Register.BC].Word; - var de = this.CPU.DE.Word == expectedRegisters[(int)Register.DE].Word; - var hl = this.CPU.HL.Word == expectedRegisters[(int)Register.HL].Word; + var af = this.CPU.AF.Joined == expectedRegisters[(int)Register.AF].Joined; + var bc = this.CPU.BC.Joined == expectedRegisters[(int)Register.BC].Joined; + var de = this.CPU.DE.Joined == expectedRegisters[(int)Register.DE].Joined; + var hl = this.CPU.HL.Joined == expectedRegisters[(int)Register.HL].Joined; - var sp = this.CPU.SP.Word == expectedRegisters[(int)Register.SP].Word; - var pc = this.CPU.PC.Word == expectedRegisters[(int)Register.PC].Word; + var sp = this.CPU.SP.Joined == expectedRegisters[(int)Register.SP].Joined; + var pc = this.CPU.PC.Joined == expectedRegisters[(int)Register.PC].Joined; var success = af && bc && de && hl && sp && pc; if (!success) diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index 02f9e64..7a20e0e 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -249,7 +249,7 @@ namespace LR35902 protected override void HandleRESET() { base.HandleRESET(); - this.SP.Word = (ushort)(Mask.Sixteen - 1); + this.SP.Joined = (ushort)(Mask.Sixteen - 1); this.TickMachine(4); } @@ -368,10 +368,10 @@ namespace LR35902 return this.Bus.Data; } - protected override void PushWord(Register16 value) + protected override void PushShort(Register16 value) { this.TickMachine(); - base.PushWord(value); + base.PushShort(value); } protected override void JumpRelative(sbyte offset) @@ -533,9 +533,9 @@ namespace LR35902 case 0: // NOP break; case 1: // GB: LD (nn),SP - this.FetchWord(); + this.FetchShort(); this.Bus.Address.Assign(this.Intermediate); - this.SetWord(this.SP); + this.SetShort(this.SP); break; case 2: // GB: STOP this.Stop(); @@ -766,11 +766,11 @@ namespace LR35902 case 5: { // GB: ADD SP,dd - var before = this.SP.Word; + var before = this.SP.Joined; var value = (sbyte)this.FetchByte(); this.TickMachine(2); var result = before + value; - this.SP.Word = (ushort)result; + this.SP.Joined = (ushort)result; var carried = before ^ value ^ (result & (int)Mask.Sixteen); this.ClearBit(StatusBits.ZF | StatusBits.NF); this.SetBit(StatusBits.CF, carried & (int)Bits.Bit8); @@ -784,11 +784,11 @@ namespace LR35902 case 7: { // GB: LD HL,SP + dd - var before = this.SP.Word; + var before = this.SP.Joined; var value = (sbyte)this.FetchByte(); this.TickMachine(); var result = before + value; - this.HL.Word = (ushort)result; + this.HL.Joined = (ushort)result; var carried = before ^ value ^ (result & (int)Mask.Sixteen); this.ClearBit(StatusBits.ZF | StatusBits.NF); this.SetBit(StatusBits.CF, carried & (int)Bits.Bit8); @@ -892,7 +892,7 @@ namespace LR35902 switch (q) { case 0: // PUSH rp2[p] - this.PushWord(this.RP2(p)); + this.PushShort(this.RP2(p)); break; case 1: @@ -992,8 +992,8 @@ namespace LR35902 private void Add(Register16 value) { this.Intermediate.Assign(this.HL); - var result = this.HL.Word + value.Word; - this.HL.Word = (ushort)result; + var result = this.HL.Joined + value.Joined; + this.HL.Joined = (ushort)result; this.ClearBit(StatusBits.NF); this.SetBit(StatusBits.CF, result & (int)Bits.Bit16); this.AdjustHalfCarryAdd(this.Intermediate.High, value.High, this.HL.High); @@ -1001,7 +1001,7 @@ namespace LR35902 private byte Add(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand + value + carry); + this.Intermediate.Joined = (ushort)(operand + value + carry); var result = this.Intermediate.Low; this.AdjustHalfCarryAdd(operand, value, result); @@ -1017,7 +1017,7 @@ namespace LR35902 private byte Subtract(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand - value - carry); + this.Intermediate.Joined = (ushort)(operand - value - carry); var result = this.Intermediate.Low; this.AdjustHalfCarrySub(operand, value, result); diff --git a/LR35902/SM83.HarteTest/Checker.cs b/LR35902/SM83.HarteTest/Checker.cs index 32e83fb..67b18db 100644 --- a/LR35902/SM83.HarteTest/Checker.cs +++ b/LR35902/SM83.HarteTest/Checker.cs @@ -38,7 +38,7 @@ this.Runner.RaisePOWER(); this.InitialiseState(test); - var pc = cpu.PC.Word; + var pc = cpu.PC.Joined; this.Cycles = cpu.Step(); this.Runner.LowerPOWER(); @@ -58,8 +58,8 @@ var final = test.Final ?? throw new InvalidOperationException("Final test state cannot be null"); - this.Raise("PC", final.PC, cpu.PC.Word); - this.Raise("SP", final.SP, cpu.SP.Word); + this.Raise("PC", final.PC, cpu.PC.Joined); + this.Raise("SP", final.SP, cpu.SP.Joined); this.Raise("A", final.A, cpu.A); this.Raise("F", final.F, cpu.F); this.Raise("B", final.B, cpu.B); @@ -205,8 +205,8 @@ } var final = test.Final ?? throw new InvalidOperationException("Final state cannot be null"); - var pc_good = this.Check("PC", final.PC, cpu.PC.Word); - var sp_good = this.Check("SP", final.SP, cpu.SP.Word); + var pc_good = this.Check("PC", final.PC, cpu.PC.Joined); + var sp_good = this.Check("SP", final.SP, cpu.SP.Joined); var a_good = this.Check("A", final.A, cpu.A); var f_good = this.Check("F", final.F, cpu.F); var b_good = this.Check("B", final.B, cpu.B); @@ -298,8 +298,8 @@ var runner = this.Runner; var cpu = runner.CPU; - cpu.PC.Word = state.PC; - cpu.SP.Word = state.SP; + cpu.PC.Joined = state.PC; + cpu.SP.Joined = state.SP; cpu.A = state.A; cpu.F = state.F; cpu.B = state.B; @@ -335,7 +335,7 @@ private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "-wm"); - private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action); + private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Joined, value, action); private void AddActualCycle(ushort address, byte value, string action) => this.ActualCycles.Add(new Cycle(address, value, action)); diff --git a/M6502/Core.cs b/M6502/Core.cs index 6bdde2c..2a23d91 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -211,7 +211,7 @@ namespace M6502 } else { - this.PushWord(this.PC); + this.PushShort(this.PC); this.Push((byte)(this.P | (source == InterruptSource.hardware ? 0 : (byte)StatusBits.BF))); } this.SEI(); // Disable IRQ @@ -654,18 +654,18 @@ namespace M6502 protected void NoteFixedAddress(ushort address) { this.UnfixedPage = this.Bus.Address.High; - this.Intermediate.Word = address; + this.Intermediate.Joined = address; this.FixedPage = this.Intermediate.High; this.Bus.Address.Low = this.Intermediate.Low; } protected void GetAddressPaged() { - this.GetWordPaged(); + this.GetShortPaged(); this.Bus.Address.Assign(this.Intermediate); } - protected void AbsoluteAddress() => this.FetchWordAddress(); + protected void AbsoluteAddress() => this.FetchShortAddress(); protected void ZeroPageAddress() => this.Bus.Address.Assign(this.FetchByte()); @@ -690,7 +690,7 @@ namespace M6502 private void AbsoluteWithIndexAddress(byte index) { this.AbsoluteAddress(); - this.NoteFixedAddress(this.Bus.Address.Word + index); + this.NoteFixedAddress(this.Bus.Address.Joined + index); } protected void AbsoluteXAddress() => this.AbsoluteWithIndexAddress(this.X); @@ -706,7 +706,7 @@ namespace M6502 protected void IndirectIndexedYAddress() { this.ZeroPageIndirectAddress(); - this.NoteFixedAddress(this.Bus.Address.Word + this.Y); + this.NoteFixedAddress(this.Bus.Address.Joined + this.Y); } #endregion @@ -928,7 +928,7 @@ namespace M6502 protected virtual byte BinarySUB(byte operand, int borrow = 0) { var data = this.Bus.Data; - this.Intermediate.Word = (ushort)(operand - data - borrow); + this.Intermediate.Joined = (ushort)(operand - data - borrow); return this.Intermediate.Low; } @@ -978,7 +978,7 @@ namespace M6502 protected virtual byte BinaryADC(byte data) { var operand = this.A; - this.Intermediate.Word = (ushort)(operand + data + this.Carry); + this.Intermediate.Joined = (ushort)(operand + data + this.Carry); this.AdjustOverflowAdd(operand); this.SetFlag(StatusBits.CF, CarryTest(this.Intermediate.High)); @@ -991,22 +991,22 @@ namespace M6502 var operand = this.A; var low = (ushort)(LowerNibble(operand) + LowerNibble(data) + this.Carry); - this.Intermediate.Word = (ushort)(HigherNibble(operand) + HigherNibble(data)); + this.Intermediate.Joined = (ushort)(HigherNibble(operand) + HigherNibble(data)); - this.AdjustZero(LowByte((ushort)(low + this.Intermediate.Word))); + this.AdjustZero(LowByte((ushort)(low + this.Intermediate.Joined))); if (low > 0x09) { - this.Intermediate.Word += 0x10; + this.Intermediate.Joined += 0x10; low += 0x06; } this.AdjustNegative(this.Intermediate.Low); this.AdjustOverflowAdd(operand); - if (this.Intermediate.Word > 0x90) + if (this.Intermediate.Joined > 0x90) { - this.Intermediate.Word += 0x60; + this.Intermediate.Joined += 0x60; } this.SetFlag(StatusBits.CF, this.Intermediate.High); @@ -1056,7 +1056,7 @@ namespace M6502 protected void CMP(byte first, byte second) { - this.Intermediate.Word = (ushort)(first - second); + this.Intermediate.Joined = (ushort)(first - second); this.AdjustNZ(this.Intermediate.Low); this.ResetFlag(StatusBits.CF, this.Intermediate.High); } @@ -1089,7 +1089,7 @@ namespace M6502 { var low = this.FetchByte(); this.SwallowPop(); - this.PushWord(this.PC); + this.PushShort(this.PC); var high = this.FetchByte(); this.PC.Assign(low, high); } diff --git a/M6502/Disassembler.cs b/M6502/Disassembler.cs index 7877271..fb4fddb 100644 --- a/M6502/Disassembler.cs +++ b/M6502/Disassembler.cs @@ -548,7 +548,7 @@ namespace M6502 private byte GetByte(ushort absolute) => this.bus.Peek(absolute); - private ushort GetWord(ushort absolute) => this.processor.PeekWord(absolute).Word; + private ushort GetWord(ushort absolute) => this.processor.PeekShort(absolute).Joined; private string Dump_Byte(ushort absolute) => DumpByteValue(this.GetByte(absolute)); diff --git a/M6502/M6502.HarteTest/Checker.cs b/M6502/M6502.HarteTest/Checker.cs index 64df67b..e1db043 100644 --- a/M6502/M6502.HarteTest/Checker.cs +++ b/M6502/M6502.HarteTest/Checker.cs @@ -40,7 +40,7 @@ this.Runner.RaisePOWER(); this.InitialiseState(test); - var pc = cpu.PC.Word; + var pc = cpu.PC.Joined; this.Cycles = cpu.Step(); this.Runner.LowerPOWER(); @@ -60,7 +60,7 @@ var final = test.Final ?? throw new InvalidOperationException("Final test state cannot be null"); - this.Raise("PC", final.PC, cpu.PC.Word); + this.Raise("PC", final.PC, cpu.PC.Joined); this.Raise("S", final.S, cpu.S); this.Raise("A", final.A, cpu.A); this.Raise("X", final.X, cpu.X); @@ -195,7 +195,7 @@ } var final = test.Final ?? throw new InvalidOperationException("Final state cannot be null"); - var pc_good = this.Check("PC", final.PC, cpu.PC.Word); + var pc_good = this.Check("PC", final.PC, cpu.PC.Joined); var s_good = this.Check("S", final.S, cpu.S); var a_good = this.Check("A", final.A, cpu.A); var x_good = this.Check("X", final.X, cpu.X); @@ -260,7 +260,7 @@ var cpu = this.Runner.CPU; var ram = this.Runner.RAM; - cpu.PC.Word = state.PC; + cpu.PC.Joined = state.PC; cpu.S = state.S; cpu.A = state.A; cpu.X = state.X; @@ -286,7 +286,7 @@ private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "write"); - private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action); + private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Joined, value, action); private void AddActualCycle(ushort address, byte value, string action) => this.ActualCycles.Add(new Cycle(address, value, action)); diff --git a/M6502/M6502.Test/Board.cs b/M6502/M6502.Test/Board.cs index 00e0c2e..f85af37 100644 --- a/M6502/M6502.Test/Board.cs +++ b/M6502/M6502.Test/Board.cs @@ -71,7 +71,7 @@ namespace M6502.Test var programPath = this.configuration.RomDirectory + "/" + this.configuration.Program; var loadAddress = this.configuration.LoadAddress; - this.ram.Load(programPath, loadAddress.Word); + this.ram.Load(programPath, loadAddress.Joined); if (this.configuration.DebugMode) { @@ -104,7 +104,7 @@ namespace M6502.Test } this.Poke(0x00, 0x4c); - this.CPU.PokeWord(0x01, this.configuration.StartAddress); + this.CPU.PokeShort(0x01, this.configuration.StartAddress); symbolsParserTask?.Wait(); } @@ -192,7 +192,7 @@ namespace M6502.Test private void CPU_ExecutingInstruction_Debugging(object? sender, EventArgs e) { - var address = this.CPU.PC.Word; + var address = this.CPU.PC.Joined; var output = new StringBuilder(); diff --git a/M6502/MOS6502.cs b/M6502/MOS6502.cs index ebfe62f..e60d5be 100644 --- a/M6502/MOS6502.cs +++ b/M6502/MOS6502.cs @@ -173,7 +173,7 @@ namespace M6502 protected override void FixupBranch(sbyte relative) { - this.NoteFixedAddress(this.PC.Word + relative); + this.NoteFixedAddress(this.PC.Joined + relative); this.MaybeFixup(); } diff --git a/M6502/Profiler.cs b/M6502/Profiler.cs index 6d117db..c25ff4c 100644 --- a/M6502/Profiler.cs +++ b/M6502/Profiler.cs @@ -168,7 +168,7 @@ private void Processor_RaisingSYNC(object? sender, EventArgs e) { - this.executingAddress = this.processor.Bus.Address.Word; + this.executingAddress = this.processor.Bus.Address.Joined; ++this.instructionCounts[this.executingInstruction = this.processor.Bus.Data]; } diff --git a/M6502/WDC65C02.cs b/M6502/WDC65C02.cs index 8b800f5..be4c9d5 100644 --- a/M6502/WDC65C02.cs +++ b/M6502/WDC65C02.cs @@ -220,7 +220,7 @@ namespace M6502 // Not used by BBR/BBS, but used by other branch instructions protected override void FixupBranch(sbyte relative) { - this.NoteFixedAddress(this.PC.Word + relative); + this.NoteFixedAddress(this.PC.Joined + relative); this.lastFetchAddress.Assign(this.Bus.Address); // Effectively negate the use of "lastFetchAddress" for branch fixup usages this.MaybeFixup(); } @@ -231,7 +231,7 @@ namespace M6502 protected void GetAddress() { - this.GetWordPaged(); + this.GetShortPaged(); if (this.Bus.Address.Low == 0) { @@ -249,9 +249,9 @@ namespace M6502 private void AbsoluteXIndirectAddress() { - var current = this.PC.Word; + var current = this.PC.Joined; this.AbsoluteXAddress(); - this.Bus.Address.Word = current; + this.Bus.Address.Joined = current; this.SwallowSpin(); this.Bus.Address.Assign(this.Intermediate); this.GetInto(this.Intermediate); @@ -425,7 +425,7 @@ namespace M6502 { var relative = (sbyte)this.Bus.Data; this.SwallowRead(); - this.NoteFixedAddress(this.PC.Word + relative); + this.NoteFixedAddress(this.PC.Joined + relative); if (this.Bus.Address.High != this.FixedPage) { this.SwallowRead(); diff --git a/MC6809/Disassembler.cs b/MC6809/Disassembler.cs index cceab3c..551b986 100644 --- a/MC6809/Disassembler.cs +++ b/MC6809/Disassembler.cs @@ -31,17 +31,17 @@ namespace MC6809 var a = this.CPU.A; var b = this.CPU.B; var dp = this.CPU.DP; - var x = this.CPU.X.Word; - var y = this.CPU.Y.Word; - var u = this.CPU.U.Word; - var s = this.CPU.S.Word; + var x = this.CPU.X.Joined; + var y = this.CPU.Y.Joined; + var u = this.CPU.U.Joined; + var s = this.CPU.S.Joined; return $"{current:x4}|{disassembled}\t\tcc={cc:x2} a={a:x2} b={b:x2} dp={dp:x2} x={x:x4} y={y:x4} u={u:x4} s={s:x4}"; } public string Trace(Register16 current) { ArgumentNullException.ThrowIfNull(current, nameof(current)); - return this.Trace(current.Word); + return this.Trace(current.Joined); } public string Trace() => this.Trace(this.CPU.PC); @@ -828,6 +828,6 @@ namespace MC6809 private byte GetByte(ushort absolute) => this.BUS.Peek(absolute); - private ushort GetWord(ushort absolute) => this.CPU.PeekWord(absolute).Word; + private ushort GetWord(ushort absolute) => this.CPU.PeekShort(absolute).Joined; } } diff --git a/MC6809/HD6309.cs b/MC6809/HD6309.cs new file mode 100644 index 0000000..4b3a942 --- /dev/null +++ b/MC6809/HD6309.cs @@ -0,0 +1,964 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// +namespace MC6809 +{ + using EightBit; + using System.Diagnostics; + + // HD6309 - Hitachi CMOS implementation of the MC6809 + // References: + // https://colorcomputerarchive.com/repo/Documents/Books/Motorola%206809%20and%20Hitachi%206309%20Programming%20Reference%20(Darren%20Atkinson).pdf + // http://www.6809.org.uk/dragon/hd6309.shtml + + public sealed class HD6309(Bus bus) : MC6809(bus) + { + // MD register bits + private const byte MD_NATIVE = 0x01; // Native mode (vs 6809 emulation) + private const byte MD_FIRQ = 0x02; // FIRQ uses entire register save + private const byte MD_ILL = 0x40; // Illegal instruction flag + private const byte MD_DIV0 = 0x80; // Division by zero flag + + private byte _md; + + #region Registers + + public Register16 W { get; } = new(); + + public ref byte E => ref this.W.High; + + public ref byte F => ref this.W.Low; + + public Register16 V { get; } = new(); + + public ref byte MD => ref this._md; + + public uint Q + { + get => Chip.MakeInteger(this.W.Joined, this.D.Joined); + set + { + this.D.Joined = Chip.HighShort(value); + this.W.Joined = Chip.LowShort(value); + } + } + + public bool NativeMode => (this._md & MD_NATIVE) != 0; + + #endregion + + #region Register transfer extensions + + protected override Register16 ReferenceTransfer16(int specifier) + { + return specifier switch + { + 0b0110 => this.W, + 0b0111 => this.V, + _ => base.ReferenceTransfer16(specifier), + }; + } + + protected override ref byte ReferenceTransfer8(int specifier) + { + switch (specifier) + { + case 0b1110: + return ref this.E; + case 0b1111: + return ref this.F; + default: + return ref base.ReferenceTransfer8(specifier); + } + } + + #endregion + + #region Instruction dispatch overrides + + protected override void ExecuteUnprefixed() + { + switch (this.OpCode) + { + // OIM (OR immediate with memory) + case 0x01: this.OIM_Direct(); break; // OIM direct + case 0x61: this.OIM_Indexed(); break; // OIM indexed + case 0x71: this.OIM_Extended(); break; // OIM extended + + // AIM (AND immediate with memory) + case 0x02: this.AIM_Direct(); break; // AIM direct + case 0x62: this.AIM_Indexed(); break; // AIM indexed + case 0x72: this.AIM_Extended(); break; // AIM extended + + // EIM (EOR immediate with memory) + case 0x05: this.EIM_Direct(); break; // EIM direct + case 0x65: this.EIM_Indexed(); break; // EIM indexed + case 0x75: this.EIM_Extended(); break; // EIM extended + + // TIM (test immediate with memory, no write-back) + case 0x0B: this.TIM_Direct(); break; // TIM direct + case 0x6B: this.TIM_Indexed(); break; // TIM indexed + case 0x7B: this.TIM_Extended(); break; // TIM extended + + default: + base.ExecuteUnprefixed(); + break; + } + } + + protected override void Execute10() + { + switch (this.OpCode) + { + // Register-to-register operations (postbyte encodes source:destination) + case 0x30: this.ImmediateByte(); this.ADDR(); Debug.Assert(this.Cycles == 4); break; // ADDR + case 0x31: this.ImmediateByte(); this.ADCR(); Debug.Assert(this.Cycles == 4); break; // ADCR + case 0x32: this.ImmediateByte(); this.SUBR(); Debug.Assert(this.Cycles == 4); break; // SUBR + case 0x33: this.ImmediateByte(); this.SBCR(); Debug.Assert(this.Cycles == 4); break; // SBCR + case 0x34: this.ImmediateByte(); this.ANDR(); Debug.Assert(this.Cycles == 4); break; // ANDR + case 0x35: this.ImmediateByte(); this.ORR(); Debug.Assert(this.Cycles == 4); break; // ORR + case 0x36: this.ImmediateByte(); this.EORR(); Debug.Assert(this.Cycles == 4); break; // EORR + case 0x37: this.ImmediateByte(); this.CMPR(); Debug.Assert(this.Cycles == 4); break; // CMPR + + // W register stack operations + case 0x38: this.SwallowCurrent(); this.PSHSW(); Debug.Assert(this.Cycles == 6); break; // PSHSW + case 0x39: this.SwallowCurrent(); this.PULSW(); Debug.Assert(this.Cycles == 6); break; // PULSW + case 0x3A: this.SwallowCurrent(); this.PSHUW(); Debug.Assert(this.Cycles == 6); break; // PSHUW + case 0x3B: this.SwallowCurrent(); this.PULUW(); Debug.Assert(this.Cycles == 6); break; // PULUW + + // E register operations (inherent) + case 0x40: this.SwallowCurrent(); this.NEGE(); Debug.Assert(this.Cycles == 3); break; + case 0x43: this.SwallowCurrent(); this.COME(); Debug.Assert(this.Cycles == 3); break; + case 0x44: this.SwallowCurrent(); this.LSRE(); Debug.Assert(this.Cycles == 3); break; + case 0x46: this.SwallowCurrent(); this.RORE(); Debug.Assert(this.Cycles == 3); break; + case 0x47: this.SwallowCurrent(); this.ASRE(); Debug.Assert(this.Cycles == 3); break; + case 0x48: this.SwallowCurrent(); this.ASLE(); Debug.Assert(this.Cycles == 3); break; + case 0x49: this.SwallowCurrent(); this.ROLE(); Debug.Assert(this.Cycles == 3); break; + case 0x4A: this.SwallowCurrent(); this.DECE(); Debug.Assert(this.Cycles == 3); break; + case 0x4C: this.SwallowCurrent(); this.INCE(); Debug.Assert(this.Cycles == 3); break; + case 0x4D: this.SwallowCurrent(); this.TSTE(); Debug.Assert(this.Cycles == 3); break; + case 0x4F: this.SwallowCurrent(); this.CLRE(); Debug.Assert(this.Cycles == 3); break; + + // F register operations (inherent) + case 0x50: this.SwallowCurrent(); this.NEGF(); Debug.Assert(this.Cycles == 3); break; + case 0x53: this.SwallowCurrent(); this.COMF(); Debug.Assert(this.Cycles == 3); break; + case 0x54: this.SwallowCurrent(); this.LSRF(); Debug.Assert(this.Cycles == 3); break; + case 0x56: this.SwallowCurrent(); this.RORF(); Debug.Assert(this.Cycles == 3); break; + case 0x57: this.SwallowCurrent(); this.ASRF(); Debug.Assert(this.Cycles == 3); break; + case 0x58: this.SwallowCurrent(); this.ASLF(); Debug.Assert(this.Cycles == 3); break; + case 0x59: this.SwallowCurrent(); this.ROLF(); Debug.Assert(this.Cycles == 3); break; + case 0x5A: this.SwallowCurrent(); this.DECF(); Debug.Assert(this.Cycles == 3); break; + case 0x5C: this.SwallowCurrent(); this.INCF(); Debug.Assert(this.Cycles == 3); break; + case 0x5D: this.SwallowCurrent(); this.TSTF(); Debug.Assert(this.Cycles == 3); break; + case 0x5F: this.SwallowCurrent(); this.CLRF(); Debug.Assert(this.Cycles == 3); break; + + // W register load/store/arithmetic + case 0x80: this.ImmediateShort(); this.SUBW(); Debug.Assert(this.Cycles == 5); break; // SUBW immediate + case 0x81: this.ImmediateShort(); this.CMPW(); Debug.Assert(this.Cycles == 5); break; // CMPW immediate + case 0x86: this.ImmediateShort(); this.LDW(); Debug.Assert(this.Cycles == 4); break; // LDW immediate + case 0x8B: this.ImmediateShort(); this.ADDW(); Debug.Assert(this.Cycles == 5); break; // ADDW immediate + + case 0x90: this.DirectShort(); this.SUBW(); Debug.Assert(this.Cycles == 7); break; // SUBW direct + case 0x91: this.DirectShort(); this.CMPW(); Debug.Assert(this.Cycles == 7); break; // CMPW direct + case 0x96: this.DirectShort(); this.LDW(); Debug.Assert(this.Cycles == 6); break; // LDW direct + case 0x97: this.DirectAddress(); this.STW(); Debug.Assert(this.Cycles == 6); break; // STW direct + case 0x9B: this.DirectShort(); this.ADDW(); Debug.Assert(this.Cycles == 7); break; // ADDW direct + + case 0xA0: this.IndexedShort(); this.SUBW(); Debug.Assert(this.Cycles >= 7); break; // SUBW indexed + case 0xA1: this.IndexedShort(); this.CMPW(); Debug.Assert(this.Cycles >= 7); break; // CMPW indexed + case 0xA6: this.IndexedShort(); this.LDW(); Debug.Assert(this.Cycles >= 6); break; // LDW indexed + case 0xA7: this.IndexedAddress(); this.STW(); Debug.Assert(this.Cycles >= 6); break; // STW indexed + case 0xAB: this.IndexedShort(); this.ADDW(); Debug.Assert(this.Cycles >= 7); break; // ADDW indexed + + case 0xB0: this.ExtendedShort(); this.SUBW(); Debug.Assert(this.Cycles == 8); break; // SUBW extended + case 0xB1: this.ExtendedShort(); this.CMPW(); Debug.Assert(this.Cycles == 8); break; // CMPW extended + case 0xB6: this.ExtendedShort(); this.LDW(); Debug.Assert(this.Cycles == 7); break; // LDW extended + case 0xB7: this.ExtendedAddress(); this.STW(); Debug.Assert(this.Cycles == 7); break; // STW extended + case 0xBB: this.ExtendedShort(); this.ADDW(); Debug.Assert(this.Cycles == 8); break; // ADDW extended + + // Q register load/store + case 0xCD: this.LDQ_Immediate(); break; // LDQ immediate + case 0xDC: this.DirectShort(); this.LDQ_Lower(); break; // LDQ direct + case 0xEC: this.IndexedShort(); this.LDQ_Lower(); break; // LDQ indexed + case 0xFC: this.ExtendedShort(); this.LDQ_Lower(); break; // LDQ extended + + case 0xDD: this.DirectAddress(); this.STQ(); break; // STQ direct + case 0xED: this.IndexedAddress(); this.STQ(); break; // STQ indexed + case 0xFD: this.ExtendedAddress(); this.STQ(); break; // STQ extended + + default: + base.Execute10(); + break; + } + } + + protected override void Execute11() + { + switch (this.OpCode) + { + // Block transfers (TFM) — $11,38-$11,3B + case 0x38: this.ImmediateByte(); this.TFM_IncrBoth(); break; // TFM R0+,R1+ + case 0x39: this.ImmediateByte(); this.TFM_DecrBoth(); break; // TFM R0-,R1- + case 0x3A: this.ImmediateByte(); this.TFM_IncrSrc(); break; // TFM R0+,R1 + case 0x3B: this.ImmediateByte(); this.TFM_IncrDst(); break; // TFM R0,R1+ + + // LDMD — $11,3D immediate + case 0x3D: this.ImmediateByte(); this.LDMD(); break; // LDMD immediate + + // Bit manipulation instructions — $11,30-$11,37 + case 0x30: this.ImmediateByte(); this.BAND(); break; // BAND + case 0x31: this.ImmediateByte(); this.BIAND(); break; // BIAND + case 0x32: this.ImmediateByte(); this.BOR(); break; // BOR + case 0x33: this.ImmediateByte(); this.BIOR(); break; // BIOR + case 0x34: this.ImmediateByte(); this.BEOR(); break; // BEOR + case 0x35: this.ImmediateByte(); this.BIEOR(); break; // BIEOR + case 0x36: this.ImmediateByte(); this.LDBT(); break; // LDBT + case 0x37: this.ImmediateByte(); this.STBT(); break; // STBT + + // E register operations + case 0x80: this.ImmediateByte(); this.SUBE(); Debug.Assert(this.Cycles == 3); break; // SUBE immediate + case 0x81: this.ImmediateByte(); this.CMPE(); Debug.Assert(this.Cycles == 3); break; // CMPE immediate + case 0x86: this.ImmediateByte(); this.LDE(); Debug.Assert(this.Cycles == 2); break; // LDE immediate + case 0x8B: this.ImmediateByte(); this.ADDE(); Debug.Assert(this.Cycles == 3); break; // ADDE immediate + + case 0x90: this.DirectByte(); this.SUBE(); Debug.Assert(this.Cycles == 5); break; // SUBE direct + case 0x91: this.DirectByte(); this.CMPE(); Debug.Assert(this.Cycles == 5); break; // CMPE direct + case 0x96: this.DirectByte(); this.LDE(); Debug.Assert(this.Cycles == 4); break; // LDE direct + case 0x97: this.DirectAddress(); this.STE(); Debug.Assert(this.Cycles == 4); break; // STE direct + case 0x9B: this.DirectByte(); this.ADDE(); Debug.Assert(this.Cycles == 5); break; // ADDE direct + + case 0xA0: this.IndexedByte(); this.SUBE(); Debug.Assert(this.Cycles >= 5); break; // SUBE indexed + case 0xA1: this.IndexedByte(); this.CMPE(); Debug.Assert(this.Cycles >= 5); break; // CMPE indexed + case 0xA6: this.IndexedByte(); this.LDE(); Debug.Assert(this.Cycles >= 4); break; // LDE indexed + case 0xA7: this.IndexedAddress(); this.STE(); Debug.Assert(this.Cycles >= 4); break; // STE indexed + case 0xAB: this.IndexedByte(); this.ADDE(); Debug.Assert(this.Cycles >= 5); break; // ADDE indexed + + case 0xB0: this.ExtendedByte(); this.SUBE(); Debug.Assert(this.Cycles == 6); break; // SUBE extended + case 0xB1: this.ExtendedByte(); this.CMPE(); Debug.Assert(this.Cycles == 6); break; // CMPE extended + case 0xB6: this.ExtendedByte(); this.LDE(); Debug.Assert(this.Cycles == 5); break; // LDE extended + case 0xB7: this.ExtendedAddress(); this.STE(); Debug.Assert(this.Cycles == 5); break; // STE extended + case 0xBB: this.ExtendedByte(); this.ADDE(); Debug.Assert(this.Cycles == 6); break; // ADDE extended + + // F register operations + case 0xC0: this.ImmediateByte(); this.SUBF(); Debug.Assert(this.Cycles == 3); break; // SUBF immediate + case 0xC1: this.ImmediateByte(); this.CMPF(); Debug.Assert(this.Cycles == 3); break; // CMPF immediate + case 0xC6: this.ImmediateByte(); this.LDF(); Debug.Assert(this.Cycles == 2); break; // LDF immediate + case 0xCB: this.ImmediateByte(); this.ADDF(); Debug.Assert(this.Cycles == 3); break; // ADDF immediate + + case 0xD0: this.DirectByte(); this.SUBF(); Debug.Assert(this.Cycles == 5); break; // SUBF direct + case 0xD1: this.DirectByte(); this.CMPF(); Debug.Assert(this.Cycles == 5); break; // CMPF direct + case 0xD6: this.DirectByte(); this.LDF(); Debug.Assert(this.Cycles == 4); break; // LDF direct + case 0xD7: this.DirectAddress(); this.STF(); Debug.Assert(this.Cycles == 4); break; // STF direct + case 0xDB: this.DirectByte(); this.ADDF(); Debug.Assert(this.Cycles == 5); break; // ADDF direct + + case 0xE0: this.IndexedByte(); this.SUBF(); Debug.Assert(this.Cycles >= 5); break; // SUBF indexed + case 0xE1: this.IndexedByte(); this.CMPF(); Debug.Assert(this.Cycles >= 5); break; // CMPF indexed + case 0xE6: this.IndexedByte(); this.LDF(); Debug.Assert(this.Cycles >= 4); break; // LDF indexed + case 0xE7: this.IndexedAddress(); this.STF(); Debug.Assert(this.Cycles >= 4); break; // STF indexed + case 0xEB: this.IndexedByte(); this.ADDF(); Debug.Assert(this.Cycles >= 5); break; // ADDF indexed + + case 0xF0: this.ExtendedByte(); this.SUBF(); Debug.Assert(this.Cycles == 6); break; // SUBF extended + case 0xF1: this.ExtendedByte(); this.CMPF(); Debug.Assert(this.Cycles == 6); break; // CMPF extended + case 0xF6: this.ExtendedByte(); this.LDF(); Debug.Assert(this.Cycles == 5); break; // LDF extended + case 0xF7: this.ExtendedAddress(); this.STF(); Debug.Assert(this.Cycles == 5); break; // STF extended + case 0xFB: this.ExtendedByte(); this.ADDF(); Debug.Assert(this.Cycles == 6); break; // ADDF extended + + // Extended arithmetic + + case 0x8D: this.ImmediateByte(); this.DIVD(); break; // DIVD immediate + case 0x9D: this.DirectByte(); this.DIVD(); break; // DIVD direct + case 0xAD: this.IndexedByte(); this.DIVD(); break; // DIVD indexed + case 0xBD: this.ExtendedByte(); this.DIVD(); break; // DIVD extended + + case 0x8E: this.ImmediateShort(); this.MULD(); break; // MULD immediate + case 0x9E: this.DirectShort(); this.MULD(); break; // MULD direct + case 0xAE: this.IndexedShort(); this.MULD(); break; // MULD indexed + case 0xBE: this.ExtendedShort(); this.MULD(); break; // MULD extended + + default: + base.Execute11(); + break; + } + } + + #endregion + + #region OIM / AIM / EIM / TIM - immediate-with-memory operations + + private void OIM_Direct() + { + var mask = this.FetchByte(); + this.DirectByte(); + this.MemoryWrite(this.EA, this.Or(mask)); + } + + private void OIM_Indexed() + { + var mask = this.FetchByte(); + this.IndexedByte(); + this.MemoryWrite(this.EA, this.Or(mask)); + } + + private void OIM_Extended() + { + var mask = this.FetchByte(); + this.ExtendedByte(); + this.MemoryWrite(this.EA, this.Or(mask)); + } + + private void AIM_Direct() + { + var mask = this.FetchByte(); + this.DirectByte(); + this.MemoryWrite(this.EA, this.And(mask)); + } + + private void AIM_Indexed() + { + var mask = this.FetchByte(); + this.IndexedByte(); + this.MemoryWrite(this.EA, this.And(mask)); + } + + private void AIM_Extended() + { + var mask = this.FetchByte(); + this.ExtendedByte(); + this.MemoryWrite(this.EA, this.And(mask)); + } + + private void EIM_Direct() + { + var mask = this.FetchByte(); + this.DirectByte(); + this.MemoryWrite(this.EA, this.ExclusiveOr(mask)); + } + + private void EIM_Indexed() + { + var mask = this.FetchByte(); + this.IndexedByte(); + this.MemoryWrite(this.EA, this.ExclusiveOr(mask)); + } + + private void EIM_Extended() + { + var mask = this.FetchByte(); + this.ExtendedByte(); + this.MemoryWrite(this.EA, this.ExclusiveOr(mask)); + } + + private void TIM_Direct() + { + var mask = this.FetchByte(); + this.DirectByte(); + this.And(mask); + this.SwallowRead(2); + } + + private void TIM_Indexed() + { + var mask = this.FetchByte(); + this.IndexedByte(); + this.And(mask); + this.SwallowRead(2); + } + + private void TIM_Extended() + { + var mask = this.FetchByte(); + this.ExtendedByte(); + this.And(mask); + this.SwallowRead(2); + } + + #endregion + + #region Register-to-register operations + + private void ADDR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Add(destination, source, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.Add(destination, source); + } + } + + private void ADCR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Add(destination, source, this.CarryFlag, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.Add(destination, source, this.CarryFlag); + } + } + + private void SUBR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Subtract(destination, source, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.Subtract(destination, source); + } + } + + private void SBCR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Subtract(destination, source, this.CarryFlag, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.Subtract(destination, source, this.CarryFlag); + } + } + + private void ANDR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.And(destination, source, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.And(destination, source); + } + } + + private void ORR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Or(destination, source, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.Or(destination, source); + } + } + + private void EORR() + { + var post = this.Bus.Data; + var sourceSpecification = HighNibble(post); + var destinationSpecification = LowNibble(post); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.ExclusiveOr(destination, source, destination); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + destination = this.ExclusiveOr(destination, source); + } + } + + private void CMPR() + { + var immediate = this.Bus.Data; + var sourceSpecification = HighNibble(immediate); + var destinationSpecification = LowNibble(immediate); + this.SwallowRead(2); + var sourceType = sourceSpecification & 0x8; + var destinationType = destinationSpecification & 0x8; + if (sourceType == 0 && destinationType == 0) + { + var source = this.ReferenceTransfer16(sourceSpecification); + var destination = this.ReferenceTransfer16(destinationSpecification); + this.Compare(destination, source); + } + else if (sourceType != 0 && destinationType != 0) + { + ref var source = ref this.ReferenceTransfer8(sourceSpecification); + ref var destination = ref this.ReferenceTransfer8(destinationSpecification); + this.Compare(destination, source); + } + } + + #endregion + + #region W register stack operations + + private void PSHSW() + { + this.SwallowRead(3); + this.Push(this.S, this.W); + } + + private void PULSW() + { + this.SwallowRead(3); + this.W.Assign(this.PopWord(this.S)); + } + + private void PSHUW() + { + this.SwallowRead(3); + this.Push(this.U, this.W); + } + + private void PULUW() + { + this.SwallowRead(3); + this.W.Assign(this.PopWord(this.U)); + } + + #endregion + + #region E register operations + + private void NEGE() => this.E = this.Negate(this.E); + private void NEGF() => this.F = this.Negate(this.F); + private void COME() => this.E = this.Complement(this.E); + private void LSRE() => this.E = this.LogicalShiftRight(this.E); + private void RORE() => this.E = this.RotateRight(this.E); + private void ASRE() => this.E = this.ArithmeticShiftRight(this.E); + private void ASLE() => this.E = this.ArithmeticShiftLeft(this.E); + private void ROLE() => this.E = this.RotateLeft(this.E); + private void DECE() => this.E = this.Decrement(this.E); + private void INCE() => this.E = this.Increment(this.E); + private void TSTE() => this.Through(this.E); + private void CLRE() => this.E = this.Clear(); + + private void LDE() => this.E = this.Through(this.Bus.Data); + private void STE() => this.MemoryWrite(this.EA, this.Through(this.E)); + private void ADDE() => this.E = this.Add(this.E, this.Bus.Data); + private void SUBE() => this.E = this.Subtract(this.E, this.Bus.Data); + private void CMPE() => this.Compare(this.E, this.Bus.Data); + + #endregion + + #region F register operations + + private void COMF() => this.F = this.Complement(this.F); + private void LSRF() => this.F = this.LogicalShiftRight(this.F); + private void RORF() => this.F = this.RotateRight(this.F); + private void ASRF() => this.F = this.ArithmeticShiftRight(this.F); + private void ASLF() => this.F = this.ArithmeticShiftLeft(this.F); + private void ROLF() => this.F = this.RotateLeft(this.F); + private void DECF() => this.F = this.Decrement(this.F); + private void INCF() => this.F = this.Increment(this.F); + private void TSTF() => this.Through(this.F); + private void CLRF() => this.F = this.Clear(); + + private void LDF() => this.F = this.Through(this.Bus.Data); + private void STF() => this.MemoryWrite(this.EA, this.Through(this.F)); + private void ADDF() => this.F = this.Add(this.F, this.Bus.Data); + private void SUBF() => this.F = this.Subtract(this.F, this.Bus.Data); + private void CMPF() => this.Compare(this.F, this.Bus.Data); + + #endregion + + #region W register operations + + private void LDW() + { + this.W.Assign(this.Through(this.Intermediate)); + } + + private void STW() + { + this.SetShort(this.EA, this.Through(this.W)); + } + + private void CMPW() + { + this.Subtract(this.W, this.Intermediate, this.Intermediate); + } + + private void ADDW() + { + this.Add(this.W, this.Intermediate, this.W); + } + + private void SUBW() + { + this.Subtract(this.W, this.Intermediate, this.W); + } + + #endregion + + #region Q register operations + + private void LDQ_Immediate() + { + this.FetchInto(this.D); + this.FetchInto(this.W); + this.Through(this.Q != 0 ? (byte)1 : (byte)0); + } + + private void LDQ_Lower() + { + // Intermediate holds upper word (D); read the lower word (W) from the next address + this.D.Assign(this.Intermediate); + this.Bus.Address.Joined += 2; + this.GetInto(this.W); + this.Through(this.Q != 0 ? (byte)1 : (byte)0); + } + + private void STQ() + { + // Write D then W to consecutive memory locations + this.SetShort(this.EA, this.D); + this.Bus.Address.Joined += 2; + this.SetShort(this.W); + this.Through(this.D.NonZero || this.W.NonZero ? (byte)1 : (byte)0); + } + + #endregion + + #region Bit manipulation instructions + + // postbyte: bits 7:6 = register (CC=00, A=01, B=10), bits 5:3 = destination bit, bits 2:0 = source bit + // followed by a direct-page address + + private void BAND() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d & s)); + this.ApplyBitTransfer(immediate, result); + } + + private void BIAND() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d & ~s)); + this.ApplyBitTransfer(immediate, result); + } + + private void BOR() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d | s)); + this.ApplyBitTransfer(immediate, result); + } + + private void BIOR() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d | ~s)); + this.ApplyBitTransfer(immediate, result); + } + + private void BEOR() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d ^ s)); + this.ApplyBitTransfer(immediate, result); + } + + private void BIEOR() + { + var immediate = this.Bus.Data; + this.DirectByte(); + var result = this.BitTransfer(immediate, this.Bus.Data, (s, d) => (byte)(d ^ ~s)); + this.ApplyBitTransfer(immediate, result); + } + + private void LDBT() + { + // Load a single bit from memory into a register bit + var immediate = this.Bus.Data; + this.DirectByte(); + var memBit = (immediate >> 0) & 0x07; + var regBit = (immediate >> 3) & 0x07; + var regSelect = (immediate >> 6) & 0x03; + var memVal = (this.Bus.Data >> memBit) & 1; + ref byte reg = ref this.BitRegister(regSelect); + if (memVal != 0) + reg |= (byte)(1 << regBit); + else + reg &= (byte)~(1 << regBit); + } + + private void STBT() + { + // Store a single register bit into a memory bit + var immediate = this.Bus.Data; + this.DirectAddress(); + var memBit = (immediate >> 0) & 0x07; + var regBit = (immediate >> 3) & 0x07; + var regSelect = (immediate >> 6) & 0x03; + ref byte reg = ref this.BitRegister(regSelect); + var regVal = (reg >> regBit) & 1; + this.MemoryRead(this.EA); + byte mem = this.Bus.Data; + if (regVal != 0) + mem |= (byte)(1 << memBit); + else + mem &= (byte)~(1 << memBit); + this.MemoryWrite(this.EA, mem); + } + + private ref byte BitRegister(int sel) + { + switch (sel) + { + case 1: return ref this.A; + case 2: return ref this.B; + default: return ref this.CC; + } + } + + // Returns the new value of the destination bit in position 0 + private byte BitTransfer(byte postbyte, byte memByte, Func op) + { + var srcBit = (postbyte >> 0) & 0x07; + var dstBit = (postbyte >> 3) & 0x07; + var regSelect = (postbyte >> 6) & 0x03; + ref byte reg = ref this.BitRegister(regSelect); + var s = (byte)((memByte >> srcBit) & 1); + var d = (byte)((reg >> dstBit) & 1); + return op(s, d); + } + + private void ApplyBitTransfer(byte postbyte, byte bitValue) + { + var dstBit = (postbyte >> 3) & 0x07; + var regSelect = (postbyte >> 6) & 0x03; + ref byte reg = ref this.BitRegister(regSelect); + if ((bitValue & 1) != 0) + reg |= (byte)(1 << dstBit); + else + reg &= (byte)~(1 << dstBit); + } + + #endregion + + #region Block transfer (TFM) + + // TFM register specifiers: D=0, X=1, Y=2, U=3, S=4 + private Register16 TFMRegister(int spec) + { + return spec switch + { + 0x0000 => this.D, + 0x0001 => this.X, + 0x0010 => this.Y, + 0x0011 => this.U, + 0x0100 => this.S, + _ => throw new ArgumentOutOfRangeException(nameof(spec), spec, "Invalid TFM register specifier"), + }; + } + + // TFM R0+,R1+: transfer bytes from R0 to R1, incrementing both + private void TFM_IncrBoth() + { + var immediate = this.Bus.Data; + + this.SwallowRead(6); + while (this.W.NonZero) + { + var sourceSpecifier = HighNibble(immediate); + var source = this.TFMRegister(sourceSpecifier); + this.MemoryRead(source); + source.Increment(); + + var destinationSpecifier = LowNibble(immediate); + var destination = this.TFMRegister(destinationSpecifier); + this.MemoryWrite(destination, this.Bus.Data); + destination.Increment(); + + this.W.Decrement(); + + this.SwallowRead(3); + } + } + + // TFM R0-,R1-: transfer bytes from R0 to R1, decrementing both + private void TFM_DecrBoth() + { + var immediate = this.Bus.Data; + + this.SwallowRead(6); + while (this.W.NonZero) + { + var sourceSpecifier = HighNibble(immediate); + var source = this.TFMRegister(sourceSpecifier); + this.MemoryRead(source); + source.Decrement(); + + var destinationSpecifier = LowNibble(immediate); + var destination = this.TFMRegister(destinationSpecifier); + this.MemoryWrite(destination, this.Bus.Data); + destination.Decrement(); + + this.W.Decrement(); + + this.SwallowRead(3); + } + } + + // TFM R0+,R1: transfer from incrementing R0 to fixed R1 + private void TFM_IncrSrc() + { + var immediate = this.Bus.Data; + + this.SwallowRead(6); + while (this.W.NonZero) + { + var sourceSpecifier = HighNibble(immediate); + var source = this.TFMRegister(sourceSpecifier); + this.MemoryRead(source); + source.Increment(); + + var destinationSpecifier = LowNibble(immediate); + var destination = this.TFMRegister(destinationSpecifier); + this.MemoryWrite(destination, this.Bus.Data); + + this.W.Decrement(); + + this.SwallowRead(3); + } + } + + // TFM R0,R1+: transfer from fixed R0 to incrementing R1 + private void TFM_IncrDst() + { + var immediate = this.Bus.Data; + + this.SwallowRead(6); + while (this.W.NonZero) + { + var sourceSpecifier = HighNibble(immediate); + var source = this.TFMRegister(sourceSpecifier); + this.MemoryRead(source); + + var destinationSpecifier = LowNibble(immediate); + var destination = this.TFMRegister(destinationSpecifier); + this.MemoryWrite(destination, this.Bus.Data); + destination.Increment(); + + this.W.Decrement(); + + this.SwallowRead(3); + } + } + + #endregion + + #region Extended arithmetic (MULD, DIVD) + + private void MULD() + { + // Q = D * operand (signed 16x16 → 32-bit) + this.SwallowRead(26); + this.Q = (uint)((short)this.D.Joined * (short)this.Intermediate.Joined); + this.Through(this.D); + this.CC = ClearBit(this.CC, (byte)StatusBits.CF); + } + + private void DIVD() + { + // D / operand (byte): B = quotient, A = remainder + this.SwallowRead(22); + var divisor = (sbyte)this.Bus.Data; + if (divisor == 0) + { + this._md |= MD_DIV0; + return; + } + var dividend = (short)this.D.Joined; + var quotient = dividend / divisor; + var remainder = dividend % divisor; + if (quotient > 127 || quotient < -128) + { + this.CC = SetBit(this.CC, (byte)StatusBits.VF); + return; + } + this.B = this.Through((byte)quotient); + this.A = (byte)remainder; + this.CC = SetBit(this.CC, (byte)StatusBits.CF, this.B & (byte)Bits.Bit0); + } + + #endregion + + #region Mode register + + private void LDMD() => this._md = this.Bus.Data; + + #endregion + } +} diff --git a/MC6809/MC6809.Test/Board.cs b/MC6809/MC6809.Test/Board.cs index 6527cea..19f8362 100644 --- a/MC6809/MC6809.Test/Board.cs +++ b/MC6809/MC6809.Test/Board.cs @@ -79,7 +79,7 @@ namespace MC6809.Test this.CPU.RaiseHALT(); // Get the ACIA ready for action - Address.Word = 0b1010000000000000; + Address.Joined = 0b1010000000000000; Data = (byte)(MC6850.ControlRegister.CR0 | MC6850.ControlRegister.CR1); // Master reset this.ACIA.CTS.Lower(); this.ACIA.RW.Lower(); @@ -181,7 +181,7 @@ namespace MC6809.Test private void CPU_ExecutingInstruction(object? sender, EventArgs e) { - this._disassembleAt = this.CPU.PC.Word; + this._disassembleAt = this.CPU.PC.Joined; this._ignoreDisassembly = this._disassembler.Ignore || this._disassembler.Pause; } @@ -215,10 +215,10 @@ namespace MC6809.Test private void UpdateAciaPins() { this.ACIA.DATA = this.Data; - this.ACIA.RS.Match(this.Address.Word & (ushort)Bits.Bit0); - this.ACIA.CS0.Match(this.Address.Word & (ushort)Bits.Bit15); - this.ACIA.CS1.Match(this.Address.Word & (ushort)Bits.Bit13); - this.ACIA.CS2.Match(this.Address.Word & (ushort)Bits.Bit14); + this.ACIA.RS.Match(this.Address.Joined & (ushort)Bits.Bit0); + this.ACIA.CS0.Match(this.Address.Joined & (ushort)Bits.Bit15); + this.ACIA.CS1.Match(this.Address.Joined & (ushort)Bits.Bit13); + this.ACIA.CS2.Match(this.Address.Joined & (ushort)Bits.Bit14); } private bool AccessAcia() diff --git a/MC6809/MC6809.UnitTest/AbxTests.cs b/MC6809/MC6809.UnitTest/AbxTests.cs index e2e037d..dd4a137 100644 --- a/MC6809/MC6809.UnitTest/AbxTests.cs +++ b/MC6809/MC6809.UnitTest/AbxTests.cs @@ -31,9 +31,9 @@ namespace MC6809.UnitTest public void TestInherent() { this.cpu.B = 0x84; - this.cpu.X.Word = 0x1097; + this.cpu.X.Joined = 0x1097; this.cpu.Step(); - Assert.AreEqual(0x111b, this.cpu.X.Word); + Assert.AreEqual(0x111b, this.cpu.X.Joined); Assert.AreEqual(3, this.cpu.Cycles); } @@ -42,16 +42,16 @@ namespace MC6809.UnitTest { this.cpu.A = 0; this.cpu.B = 0xce; - this.cpu.X.Word = 0x8006; - this.cpu.Y.Word = 0; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0x8006; + this.cpu.Y.Joined = 0; + this.cpu.U.Joined = 0; this.cpu.CC = 0; this.cpu.Step(); Assert.AreEqual(0, this.cpu.A); Assert.AreEqual(0xce, this.cpu.B); - Assert.AreEqual(0x80d4, this.cpu.X.Word); - Assert.AreEqual(0, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0x80d4, this.cpu.X.Joined); + Assert.AreEqual(0, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsFalse(this.cpu.Carry); Assert.IsFalse(this.cpu.Overflow); Assert.IsFalse(this.cpu.Zero); @@ -65,16 +65,16 @@ namespace MC6809.UnitTest { this.cpu.A = 0; this.cpu.B = 0xd6; - this.cpu.X.Word = 0x7ffe; - this.cpu.Y.Word = 0; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0x7ffe; + this.cpu.Y.Joined = 0; + this.cpu.U.Joined = 0; this.cpu.CC = (byte)(StatusBits.CF | StatusBits.VF | StatusBits.ZF); this.cpu.Step(); Assert.AreEqual(0, this.cpu.A); Assert.AreEqual(0xd6, this.cpu.B); - Assert.AreEqual(0x80d4, this.cpu.X.Word); - Assert.AreEqual(0, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0x80d4, this.cpu.X.Joined); + Assert.AreEqual(0, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsTrue(this.cpu.Carry); Assert.IsTrue(this.cpu.Overflow); Assert.IsTrue(this.cpu.Zero); diff --git a/MC6809/MC6809.UnitTest/AndTests.cs b/MC6809/MC6809.UnitTest/AndTests.cs index cc270b5..6c60738 100644 --- a/MC6809/MC6809.UnitTest/AndTests.cs +++ b/MC6809/MC6809.UnitTest/AndTests.cs @@ -45,7 +45,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x1c); this.board.Poke(0xb01, 0xaf); this.cpu.CC = 0x79; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/BgtTests.cs b/MC6809/MC6809.UnitTest/BgtTests.cs index 5334f24..46d4b3a 100644 --- a/MC6809/MC6809.UnitTest/BgtTests.cs +++ b/MC6809/MC6809.UnitTest/BgtTests.cs @@ -48,7 +48,7 @@ namespace MC6809.UnitTest [TestMethod] public void TestBGT2() { - Assert.AreEqual(0, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.PC.Joined); this.cpu.CC = 0; this.cpu.Step(); this.cpu.Step(); @@ -58,7 +58,7 @@ namespace MC6809.UnitTest [TestMethod] public void TestBGT3() { - Assert.AreEqual(0, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.PC.Joined); this.cpu.CC = (byte)StatusBits.NF; this.cpu.Step(); this.cpu.Step(); @@ -68,7 +68,7 @@ namespace MC6809.UnitTest [TestMethod] public void TestBGT4() { - Assert.AreEqual(0, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.PC.Joined); this.cpu.CC = (byte)(StatusBits.NF | StatusBits.VF); this.cpu.Step(); this.cpu.Step(); @@ -78,7 +78,7 @@ namespace MC6809.UnitTest [TestMethod] public void TestBGT5() { - Assert.AreEqual(0, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.PC.Joined); this.cpu.CC = (byte)(StatusBits.ZF | StatusBits.NF); this.cpu.Step(); this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/BleTests.cs b/MC6809/MC6809.UnitTest/BleTests.cs index 48ad8ab..860eef5 100644 --- a/MC6809/MC6809.UnitTest/BleTests.cs +++ b/MC6809/MC6809.UnitTest/BleTests.cs @@ -38,7 +38,7 @@ namespace MC6809.UnitTest [TestMethod] public void TestBLE1() { - Assert.AreEqual(0, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.PC.Joined); this.cpu.CC = (byte)StatusBits.ZF; this.cpu.Step(); this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/CmpTests.cs b/MC6809/MC6809.UnitTest/CmpTests.cs index cf82b8e..6bd85f1 100644 --- a/MC6809/MC6809.UnitTest/CmpTests.cs +++ b/MC6809/MC6809.UnitTest/CmpTests.cs @@ -48,15 +48,15 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0xff; this.cpu.B = 0; - this.cpu.X.Word = 0; - this.cpu.Y.Word = 0x205; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0; + this.cpu.Y.Joined = 0x205; + this.cpu.U.Joined = 0; this.cpu.Step(); Assert.AreEqual(0xff, this.cpu.A); Assert.AreEqual(0, this.cpu.B); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0x206, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0x206, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsTrue(this.cpu.Zero); Assert.AreEqual(6, this.cpu.Cycles); } @@ -71,15 +71,15 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0xff; this.cpu.B = 0; - this.cpu.X.Word = 0; - this.cpu.Y.Word = 0x205; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0; + this.cpu.Y.Joined = 0x205; + this.cpu.U.Joined = 0; this.cpu.Step(); Assert.AreEqual(0xff, this.cpu.A); Assert.AreEqual(0, this.cpu.B); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0x207, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0x207, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsTrue(this.cpu.Zero); Assert.AreEqual(7, this.cpu.Cycles); } @@ -94,15 +94,15 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0xff; this.cpu.B = 0; - this.cpu.X.Word = 0; - this.cpu.Y.Word = 0x205; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0; + this.cpu.Y.Joined = 0x205; + this.cpu.U.Joined = 0; this.cpu.Step(); Assert.AreEqual(0xff, this.cpu.A); Assert.AreEqual(0, this.cpu.B); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0x204, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0x204, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsTrue(this.cpu.Zero); Assert.AreEqual(6, this.cpu.Cycles); } @@ -117,15 +117,15 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0xff; this.cpu.B = 0; - this.cpu.X.Word = 0; - this.cpu.Y.Word = 0x205; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0; + this.cpu.Y.Joined = 0x205; + this.cpu.U.Joined = 0; this.cpu.Step(); Assert.AreEqual(0xff, this.cpu.A); Assert.AreEqual(0, this.cpu.B); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0x203, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0x203, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.IsTrue(this.cpu.Zero); Assert.AreEqual(7, this.cpu.Cycles); } @@ -167,12 +167,12 @@ namespace MC6809.UnitTest public void TestCMP16() { this.cpu.CC = (byte)(StatusBits.HF | StatusBits.VF | StatusBits.CF); - this.cpu.X.Word = 0x5410; - this.cpu.PokeWord(0x33, 0x5410); + this.cpu.X.Joined = 0x5410; + this.cpu.PokeShort(0x33, 0x5410); this.board.Poke(0, 0xbc); - this.cpu.PokeWord(1, 0x33); + this.cpu.PokeShort(1, 0x33); this.cpu.Step(); - Assert.AreEqual(0x5410, this.cpu.X.Word); + Assert.AreEqual(0x5410, this.cpu.X.Joined); Assert.IsFalse(this.cpu.Carry); Assert.IsFalse(this.cpu.Overflow); Assert.IsTrue(this.cpu.Zero); @@ -184,10 +184,10 @@ namespace MC6809.UnitTest public void TestImmediateWord() { this.board.Poke(0, 0x8c); - this.cpu.PokeWord(1, 0x1bb0); - this.cpu.X.Word = 0x1ab0; + this.cpu.PokeShort(1, 0x1bb0); + this.cpu.X.Joined = 0x1ab0; this.cpu.Step(); - Assert.AreEqual(0x1ab0, this.cpu.X.Word); + Assert.AreEqual(0x1ab0, this.cpu.X.Joined); Assert.IsFalse(this.cpu.Zero); Assert.IsFalse(this.cpu.Overflow); Assert.IsTrue(this.cpu.Negative); diff --git a/MC6809/MC6809.UnitTest/ComTests.cs b/MC6809/MC6809.UnitTest/ComTests.cs index 6119f53..696cba2 100644 --- a/MC6809/MC6809.UnitTest/ComTests.cs +++ b/MC6809/MC6809.UnitTest/ComTests.cs @@ -31,7 +31,7 @@ namespace MC6809.UnitTest this.board.Poke(0x0200, 0x07); this.cpu.CC = 0; this.cpu.DP = 2; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -48,7 +48,7 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0x74; this.board.Poke(0xb00, 0x43); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/DaaTests.cs b/MC6809/MC6809.UnitTest/DaaTests.cs index 1739c07..fc15dec 100644 --- a/MC6809/MC6809.UnitTest/DaaTests.cs +++ b/MC6809/MC6809.UnitTest/DaaTests.cs @@ -35,7 +35,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x19); this.cpu.CC = 0; this.cpu.A = 0x7f; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/EorTests.cs b/MC6809/MC6809.UnitTest/EorTests.cs index 0bf8876..de86985 100644 --- a/MC6809/MC6809.UnitTest/EorTests.cs +++ b/MC6809/MC6809.UnitTest/EorTests.cs @@ -31,18 +31,18 @@ namespace MC6809.UnitTest [TestMethod] public void TestEOR_indexed() { - this.cpu.Y.Word = 0x12f0; + this.cpu.Y.Joined = 0x12f0; this.cpu.A = 0xf2; this.cpu.CC = 0x03; this.board.Poke(0x12f8, 0x98); this.board.Poke(0xb00, 0xa8); this.board.Poke(0xb01, 0x28); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); Assert.AreEqual(0x98, this.board.Peek(0x12f8)); Assert.AreEqual(0x6a, this.cpu.A); Assert.AreEqual(0x01, this.cpu.CC); - Assert.AreEqual(0x12f0, this.cpu.Y.Word); + Assert.AreEqual(0x12f0, this.cpu.Y.Joined); } } } \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/ExgTests.cs b/MC6809/MC6809.UnitTest/ExgTests.cs index 3aa8329..3e30562 100644 --- a/MC6809/MC6809.UnitTest/ExgTests.cs +++ b/MC6809/MC6809.UnitTest/ExgTests.cs @@ -31,7 +31,7 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.A = 0x7f; this.cpu.DP = 0xf6; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -45,14 +45,14 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x1e); this.board.Poke(0xb01, 0x01); this.cpu.CC = 0; - this.cpu.D.Word = 0x117f; - this.cpu.X.Word = 0xff16; - this.cpu.PC.Word = 0xb00; + this.cpu.D.Joined = 0x117f; + this.cpu.X.Joined = 0xff16; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0xff16, this.cpu.D.Word); - Assert.AreEqual(0x117f, this.cpu.X.Word); + Assert.AreEqual(0xff16, this.cpu.D.Joined); + Assert.AreEqual(0x117f, this.cpu.X.Joined); } [TestMethod] @@ -62,13 +62,13 @@ namespace MC6809.UnitTest this.board.Poke(0xb01, 0x81); this.cpu.CC = 0; this.cpu.A = 0x56; - this.cpu.X.Word = 0x1234; - this.cpu.PC.Word = 0xb00; + this.cpu.X.Joined = 0x1234; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); Assert.AreEqual(0x34, this.cpu.A); - Assert.AreEqual(0xff56, this.cpu.X.Word); + Assert.AreEqual(0xff56, this.cpu.X.Joined); } } } diff --git a/MC6809/MC6809.UnitTest/JsrTests.cs b/MC6809/MC6809.UnitTest/JsrTests.cs index 1bfc657..73a32e6 100644 --- a/MC6809/MC6809.UnitTest/JsrTests.cs +++ b/MC6809/MC6809.UnitTest/JsrTests.cs @@ -35,16 +35,16 @@ namespace MC6809.UnitTest public void TestJsr() { // Set up a word to test at address 0x205 - this.cpu.PokeWord(0x205, 0x03ff); + this.cpu.PokeShort(0x205, 0x03ff); // Set register D - this.cpu.D.Word = 0x105; + this.cpu.D.Joined = 0x105; // Set register Y to point to that location minus 5 - this.cpu.Y.Word = 0x200; + this.cpu.Y.Joined = 0x200; // Set register S to point to 0x915 - this.cpu.S.Word = 0x915; + this.cpu.S.Joined = 0x915; // Two bytes of instruction this.board.Poke(0xB00, 0xAD); @@ -52,7 +52,7 @@ namespace MC6809.UnitTest this.board.Poke(0xB02, 0x11); // Junk this.board.Poke(0xB03, 0x22); // Junk - this.cpu.PC.Word = 0xB00; + this.cpu.PC.Joined = 0xB00; this.cpu.CC = 0; this.cpu.Step(); @@ -61,12 +61,12 @@ namespace MC6809.UnitTest Assert.AreEqual(0x01, this.cpu.A); Assert.AreEqual(0x05, this.cpu.B); Assert.AreEqual(0, this.cpu.DP); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0x200, this.cpu.Y.Word); - Assert.AreEqual(0x105, this.cpu.D.Word); - Assert.AreEqual(0x913, this.cpu.S.Word); - Assert.AreEqual(0, this.cpu.U.Word); - Assert.AreEqual(0x305, this.cpu.PC.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0x200, this.cpu.Y.Joined); + Assert.AreEqual(0x105, this.cpu.D.Joined); + Assert.AreEqual(0x913, this.cpu.S.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); + Assert.AreEqual(0x305, this.cpu.PC.Joined); Assert.AreEqual(2, this.board.Peek(0x914)); Assert.AreEqual(0xb, this.board.Peek(0x913)); diff --git a/MC6809/MC6809.UnitTest/LdTests.cs b/MC6809/MC6809.UnitTest/LdTests.cs index 0cf892b..07d9a81 100644 --- a/MC6809/MC6809.UnitTest/LdTests.cs +++ b/MC6809/MC6809.UnitTest/LdTests.cs @@ -30,7 +30,7 @@ namespace MC6809.UnitTest this.board.Poke(1, 0x86); this.cpu.A = 0x2b; this.cpu.B = 0x00; - this.cpu.X.Word = 0xc300; + this.cpu.X.Joined = 0xc300; this.board.Poke(0xc32b, 0x4e); this.cpu.Step(); Assert.AreEqual(0x4e, this.cpu.B); @@ -43,7 +43,7 @@ namespace MC6809.UnitTest this.board.Poke(1, 0x85); this.cpu.A = 0x00; this.cpu.B = 0x2b; - this.cpu.X.Word = 0xc300; + this.cpu.X.Joined = 0xc300; this.board.Poke(0xc32b, 0x4e); this.cpu.Step(); Assert.AreEqual(0x4e, this.cpu.A); @@ -56,8 +56,8 @@ namespace MC6809.UnitTest this.board.Poke(1, 0x95); this.cpu.A = 0x00; this.cpu.B = 0x2b; - this.cpu.X.Word = 0xc300; - this.cpu.PokeWord(0xc32b, 0x1234); + this.cpu.X.Joined = 0xc300; + this.cpu.PokeShort(0xc32b, 0x1234); this.board.Poke(0x1234, 0x56); this.cpu.Step(); Assert.AreEqual(0x56, this.cpu.A); diff --git a/MC6809/MC6809.UnitTest/LeaTests.cs b/MC6809/MC6809.UnitTest/LeaTests.cs index b2e0d12..93c0451 100644 --- a/MC6809/MC6809.UnitTest/LeaTests.cs +++ b/MC6809/MC6809.UnitTest/LeaTests.cs @@ -31,14 +31,14 @@ namespace MC6809.UnitTest //// LEAX n,PCR (16-bit) this.board.Poke(location, 0x30); this.board.Poke((ushort)(location + 1), 0x8d); - this.cpu.PokeWord((ushort)(location + 2), 0xfe49); - this.cpu.PC.Word = location; + this.cpu.PokeShort((ushort)(location + 2), 0xfe49); + this.cpu.PC.Joined = location; this.cpu.Step(); var offset = 0x10000 - 0xfe49; - Assert.AreEqual(location + 4 - offset, this.cpu.X.Word); - Assert.AreEqual(location + 4, this.cpu.PC.Word); + Assert.AreEqual(location + 4 - offset, this.cpu.X.Joined); + Assert.AreEqual(location + 4, this.cpu.PC.Joined); } [TestMethod] @@ -50,13 +50,13 @@ namespace MC6809.UnitTest this.board.Poke(location, 0x30); this.board.Poke((ushort)(location + 1), 0x8c); this.board.Poke((ushort)(location + 2), 0xf1); - this.cpu.PC.Word = location; + this.cpu.PC.Joined = location; this.cpu.Step(); var offset = 0x100 - 0xf1; - Assert.AreEqual(location + 3 - offset, this.cpu.X.Word); - Assert.AreEqual(location + 3, this.cpu.PC.Word); + Assert.AreEqual(location + 3 - offset, this.cpu.X.Joined); + Assert.AreEqual(location + 3, this.cpu.PC.Joined); } [TestMethod] @@ -65,14 +65,14 @@ namespace MC6809.UnitTest this.board.Poke(0, 0x30); this.board.Poke(1, 0xab); this.cpu.CC = 0; - this.cpu.X.Word = 0xabcd; - this.cpu.Y.Word = 0x804f; + this.cpu.X.Joined = 0xabcd; + this.cpu.Y.Joined = 0x804f; this.cpu.A = 0x80; this.cpu.B = 0x01; this.cpu.Step(); - Assert.AreEqual(0x50, this.cpu.X.Word); + Assert.AreEqual(0x50, this.cpu.X.Joined); Assert.IsFalse(this.cpu.Zero); } @@ -82,14 +82,14 @@ namespace MC6809.UnitTest this.board.Poke(0, 0x30); this.board.Poke(1, 0xab); this.cpu.CC = 0x28; - this.cpu.X.Word = 0xefa; - this.cpu.Y.Word = 0xef8; + this.cpu.X.Joined = 0xefa; + this.cpu.Y.Joined = 0xef8; this.cpu.A = 0xff; this.cpu.B = 0x82; this.cpu.Step(); - Assert.AreEqual(0xe7a, this.cpu.X.Word); + Assert.AreEqual(0xe7a, this.cpu.X.Joined); Assert.IsFalse(this.cpu.Zero); } } diff --git a/MC6809/MC6809.UnitTest/LsrTests.cs b/MC6809/MC6809.UnitTest/LsrTests.cs index 8b6d12e..55718b3 100644 --- a/MC6809/MC6809.UnitTest/LsrTests.cs +++ b/MC6809/MC6809.UnitTest/LsrTests.cs @@ -31,7 +31,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x44); this.cpu.CC = 0xf; this.cpu.A = 0x3e; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -50,7 +50,7 @@ namespace MC6809.UnitTest this.cpu.CC = Chip.SetBit(this.cpu.CC, (byte)StatusBits.VF); this.cpu.CC = Chip.SetBit(this.cpu.CC, (byte)StatusBits.NF); this.cpu.A = 1; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -68,7 +68,7 @@ namespace MC6809.UnitTest this.cpu.CC = Chip.ClearBit(this.cpu.CC, (byte)StatusBits.CF); this.cpu.CC = Chip.ClearBit(this.cpu.CC, (byte)StatusBits.VF); this.cpu.A = 0xb8; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -83,28 +83,28 @@ namespace MC6809.UnitTest { this.board.Poke(0xb00, 0x4); this.board.Poke(0xb01, 0x2); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.CC = 0; this.cpu.A = 0; this.cpu.B = 0; this.cpu.DP = 4; - this.cpu.X.Word = 0; - this.cpu.Y.Word = 0; - this.cpu.S.Word = 0; - this.cpu.U.Word = 0; + this.cpu.X.Joined = 0; + this.cpu.Y.Joined = 0; + this.cpu.S.Joined = 0; + this.cpu.U.Joined = 0; this.board.Poke(0x0402, 0xf1); this.cpu.Step(); - Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(0xb02, this.cpu.PC.Joined); Assert.AreEqual(1, this.cpu.CC); Assert.AreEqual(0, this.cpu.A); Assert.AreEqual(0, this.cpu.B); Assert.AreEqual(4, this.cpu.DP); - Assert.AreEqual(0, this.cpu.X.Word); - Assert.AreEqual(0, this.cpu.Y.Word); - Assert.AreEqual(0, this.cpu.S.Word); - Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.X.Joined); + Assert.AreEqual(0, this.cpu.Y.Joined); + Assert.AreEqual(0, this.cpu.S.Joined); + Assert.AreEqual(0, this.cpu.U.Joined); Assert.AreEqual(0x78, this.board.Peek(0x402)); } } diff --git a/MC6809/MC6809.UnitTest/MulTests.cs b/MC6809/MC6809.UnitTest/MulTests.cs index 43d0601..de09a84 100644 --- a/MC6809/MC6809.UnitTest/MulTests.cs +++ b/MC6809/MC6809.UnitTest/MulTests.cs @@ -35,11 +35,11 @@ namespace MC6809.UnitTest this.cpu.CC |= (byte)StatusBits.ZF; this.cpu.A = 0xc; this.cpu.B = 0x64; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0x4b0, this.cpu.D.Word); + Assert.AreEqual(0x4b0, this.cpu.D.Joined); Assert.AreEqual(0x4, this.cpu.A); Assert.AreEqual(0xb0, this.cpu.B); Assert.IsFalse(this.cpu.Zero); @@ -58,11 +58,11 @@ namespace MC6809.UnitTest this.cpu.CC = Chip.SetBit(this.cpu.CC, (byte)StatusBits.ZF); this.cpu.A = 0xc; this.cpu.B = 0x00; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0, this.cpu.D.Word); + Assert.AreEqual(0, this.cpu.D.Joined); Assert.AreEqual(0, this.cpu.A); Assert.AreEqual(0, this.cpu.B); Assert.IsTrue(this.cpu.Zero); diff --git a/MC6809/MC6809.UnitTest/NegTests.cs b/MC6809/MC6809.UnitTest/NegTests.cs index 587383c..4ff1f9c 100644 --- a/MC6809/MC6809.UnitTest/NegTests.cs +++ b/MC6809/MC6809.UnitTest/NegTests.cs @@ -28,7 +28,7 @@ namespace MC6809.UnitTest { this.board.Poke(0xb00, 0x40); this.cpu.A = 0; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -41,7 +41,7 @@ namespace MC6809.UnitTest { this.board.Poke(0xb00, 0x40); this.cpu.A = 1; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -54,7 +54,7 @@ namespace MC6809.UnitTest { this.board.Poke(0xb00, 0x40); this.cpu.A = 2; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -68,7 +68,7 @@ namespace MC6809.UnitTest { this.board.Poke(0xb00, 0x40); this.cpu.A = 0x80; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/OrTests.cs b/MC6809/MC6809.UnitTest/OrTests.cs index 91d6975..3772718 100644 --- a/MC6809/MC6809.UnitTest/OrTests.cs +++ b/MC6809/MC6809.UnitTest/OrTests.cs @@ -30,7 +30,7 @@ namespace MC6809.UnitTest this.cpu.A = 0xda; this.board.Poke(0xb00, 0x8a); this.board.Poke(0xb01, 0x0f); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/PshTests.cs b/MC6809/MC6809.UnitTest/PshTests.cs index 3ea8e69..ab276f1 100644 --- a/MC6809/MC6809.UnitTest/PshTests.cs +++ b/MC6809/MC6809.UnitTest/PshTests.cs @@ -26,25 +26,25 @@ namespace MC6809.UnitTest [TestMethod] public void TestPSHS_all() { - this.cpu.S.Word = 517; + this.cpu.S.Joined = 517; this.cpu.CC = 0xf; this.cpu.A = 1; this.cpu.B = 2; this.cpu.DP = 3; - this.cpu.X.Word = 0x405; - this.cpu.Y.Word = 0x607; - this.cpu.U.Word = 0x809; - this.cpu.PC.Word = 0xb00; + this.cpu.X.Joined = 0x405; + this.cpu.Y.Joined = 0x607; + this.cpu.U.Joined = 0x809; + this.cpu.PC.Joined = 0xb00; this.board.Poke(0xb00, 0x34); this.board.Poke(0xb01, 0xff); this.cpu.Step(); - Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(0xb02, this.cpu.PC.Joined); Assert.AreEqual(0xf, this.cpu.CC); Assert.AreEqual(1, this.cpu.A); Assert.AreEqual(2, this.cpu.B); - Assert.AreEqual(517 - 12, this.cpu.S.Word); + Assert.AreEqual(517 - 12, this.cpu.S.Joined); Assert.AreEqual(0x02, this.board.Peek(517 - 1)); Assert.AreEqual(0x0b, this.board.Peek(517 - 2)); Assert.AreEqual(0x09, this.board.Peek(517 - 3)); @@ -62,25 +62,25 @@ namespace MC6809.UnitTest [TestMethod] public void TestPSHU_all() { - this.cpu.U.Word = 517; + this.cpu.U.Joined = 517; this.cpu.CC = 0xf; this.cpu.A = 1; this.cpu.B = 2; this.cpu.DP = 3; - this.cpu.X.Word = 0x405; - this.cpu.Y.Word = 0x607; - this.cpu.S.Word = 0x809; - this.cpu.PC.Word = 0xb00; + this.cpu.X.Joined = 0x405; + this.cpu.Y.Joined = 0x607; + this.cpu.S.Joined = 0x809; + this.cpu.PC.Joined = 0xb00; this.board.Poke(0xb00, 0x36); this.board.Poke(0xb01, 0xff); this.cpu.Step(); - Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(0xb02, this.cpu.PC.Joined); Assert.AreEqual(0xf, this.cpu.CC); Assert.AreEqual(1, this.cpu.A); Assert.AreEqual(2, this.cpu.B); - Assert.AreEqual(517 - 12, this.cpu.U.Word); + Assert.AreEqual(517 - 12, this.cpu.U.Joined); Assert.AreEqual(0x02, this.board.Peek(517 - 1)); Assert.AreEqual(0x0b, this.board.Peek(517 - 2)); Assert.AreEqual(0x09, this.board.Peek(517 - 3)); diff --git a/MC6809/MC6809.UnitTest/PulTests.cs b/MC6809/MC6809.UnitTest/PulTests.cs index 7a35917..49a8caa 100644 --- a/MC6809/MC6809.UnitTest/PulTests.cs +++ b/MC6809/MC6809.UnitTest/PulTests.cs @@ -30,16 +30,16 @@ namespace MC6809.UnitTest this.board.Poke(512 - 11, 0x11); this.board.Poke(512 - 10, 0x12); this.board.Poke(512 - 9, 0x13); - this.cpu.PokeWord(512 - 8, 0x9141); - this.cpu.PokeWord(512 - 6, 0xa142); - this.cpu.PokeWord(512 - 4, 0xb140); - this.cpu.PokeWord(512 - 2, 0x04ff); - this.cpu.Y.Word = 0x1115; - this.cpu.S.Word = 500; + this.cpu.PokeShort(512 - 8, 0x9141); + this.cpu.PokeShort(512 - 6, 0xa142); + this.cpu.PokeShort(512 - 4, 0xb140); + this.cpu.PokeShort(512 - 2, 0x04ff); + this.cpu.Y.Joined = 0x1115; + this.cpu.S.Joined = 500; this.cpu.CC = 0xf; this.board.Poke(0xb00, 0x35); this.board.Poke(0xb01, 0xff); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -47,10 +47,10 @@ namespace MC6809.UnitTest Assert.AreEqual(0x11, this.cpu.A); Assert.AreEqual(0x12, this.cpu.B); Assert.AreEqual(0x13, this.cpu.DP); - Assert.AreEqual(0x9141, this.cpu.X.Word); - Assert.AreEqual(0xa142, this.cpu.Y.Word); - Assert.AreEqual(0xb140, this.cpu.U.Word); - Assert.AreEqual(0x4ff, this.cpu.PC.Word); + Assert.AreEqual(0x9141, this.cpu.X.Joined); + Assert.AreEqual(0xa142, this.cpu.Y.Joined); + Assert.AreEqual(0xb140, this.cpu.U.Joined); + Assert.AreEqual(0x4ff, this.cpu.PC.Joined); } [TestMethod] @@ -60,16 +60,16 @@ namespace MC6809.UnitTest this.board.Poke(512 - 11, 0x11); this.board.Poke(512 - 10, 0x12); this.board.Poke(512 - 9, 0x13); - this.cpu.PokeWord(512 - 8, 0x9141); - this.cpu.PokeWord(512 - 6, 0xa142); - this.cpu.PokeWord(512 - 4, 0xb140); - this.cpu.PokeWord(512 - 2, 0x04ff); - this.cpu.Y.Word = 0x1115; - this.cpu.U.Word = 500; + this.cpu.PokeShort(512 - 8, 0x9141); + this.cpu.PokeShort(512 - 6, 0xa142); + this.cpu.PokeShort(512 - 4, 0xb140); + this.cpu.PokeShort(512 - 2, 0x04ff); + this.cpu.Y.Joined = 0x1115; + this.cpu.U.Joined = 500; this.cpu.CC = 0xf; this.board.Poke(0xb00, 0x37); this.board.Poke(0xb01, 0xff); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -77,28 +77,28 @@ namespace MC6809.UnitTest Assert.AreEqual(0x11, this.cpu.A); Assert.AreEqual(0x12, this.cpu.B); Assert.AreEqual(0x13, this.cpu.DP); - Assert.AreEqual(0x9141, this.cpu.X.Word); - Assert.AreEqual(0xa142, this.cpu.Y.Word); - Assert.AreEqual(0xb140, this.cpu.S.Word); - Assert.AreEqual(0x4ff, this.cpu.PC.Word); + Assert.AreEqual(0x9141, this.cpu.X.Joined); + Assert.AreEqual(0xa142, this.cpu.Y.Joined); + Assert.AreEqual(0xb140, this.cpu.S.Joined); + Assert.AreEqual(0x4ff, this.cpu.PC.Joined); } [TestMethod] public void TestPULS_y() { - this.cpu.PokeWord(0x205, 0xb140); - this.cpu.PokeWord(0x207, 0x04ff); - this.cpu.Y.Word = 0x1115; - this.cpu.S.Word = 0x205; + this.cpu.PokeShort(0x205, 0xb140); + this.cpu.PokeShort(0x207, 0x04ff); + this.cpu.Y.Joined = 0x1115; + this.cpu.S.Joined = 0x205; this.cpu.CC = 0xf; this.board.Poke(0xb00, 0x35); this.board.Poke(0xb01, 0xa0); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0xb140, this.cpu.Y.Word); - Assert.AreEqual(0x4ff, this.cpu.PC.Word); + Assert.AreEqual(0xb140, this.cpu.Y.Joined); + Assert.AreEqual(0x4ff, this.cpu.PC.Joined); Assert.AreEqual(0xf, this.cpu.CC); } } diff --git a/MC6809/MC6809.UnitTest/RolTests.cs b/MC6809/MC6809.UnitTest/RolTests.cs index 79d7462..4267836 100644 --- a/MC6809/MC6809.UnitTest/RolTests.cs +++ b/MC6809/MC6809.UnitTest/RolTests.cs @@ -31,11 +31,11 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.CC |= (byte)StatusBits.NF; this.cpu.CC |= (byte)StatusBits.CF; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0xb01, this.cpu.PC.Word); + Assert.AreEqual(0xb01, this.cpu.PC.Joined); Assert.AreEqual(0x13, this.cpu.B); Assert.AreEqual(0x3, this.cpu.CC); Assert.IsTrue(this.cpu.Carry); @@ -49,7 +49,7 @@ namespace MC6809.UnitTest this.cpu.CC |= (byte)StatusBits.CF; this.cpu.CC |= (byte)StatusBits.VF; this.cpu.B = 1; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -63,7 +63,7 @@ namespace MC6809.UnitTest this.board.Poke(0xB00, 0x59); this.cpu.CC = 0; this.cpu.B = 0xd8; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/RorTests.cs b/MC6809/MC6809.UnitTest/RorTests.cs index baed50d..5cd4af8 100644 --- a/MC6809/MC6809.UnitTest/RorTests.cs +++ b/MC6809/MC6809.UnitTest/RorTests.cs @@ -31,7 +31,7 @@ namespace MC6809.UnitTest this.cpu.B = 0x89; this.cpu.CC = 0; this.cpu.CC |= (byte)StatusBits.CF; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -48,7 +48,7 @@ namespace MC6809.UnitTest this.cpu.B = 0x89; this.cpu.CC = 0; this.cpu.CC = Chip.ClearBit(this.cpu.CC, (byte)StatusBits.CF); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.UnitTest/RtsTests.cs b/MC6809/MC6809.UnitTest/RtsTests.cs index 7f3c3c2..a7b70a7 100644 --- a/MC6809/MC6809.UnitTest/RtsTests.cs +++ b/MC6809/MC6809.UnitTest/RtsTests.cs @@ -32,17 +32,17 @@ namespace MC6809.UnitTest [TestMethod] public void TestRts() { - this.cpu.S.Word = 0x300; + this.cpu.S.Joined = 0x300; - this.cpu.PokeWord(0x300, 0x102C); // Write return address + this.cpu.PokeShort(0x300, 0x102C); // Write return address this.board.Poke(0xB00, 0x39); // RTS - this.cpu.PC.Word = 0xB00; + this.cpu.PC.Joined = 0xB00; this.cpu.Step(); - Assert.AreEqual(0x102C, this.cpu.PC.Word); - Assert.AreEqual(0x302, this.cpu.S.Word); + Assert.AreEqual(0x102C, this.cpu.PC.Joined); + Assert.AreEqual(0x302, this.cpu.S.Joined); Assert.AreEqual(5, this.cpu.Cycles); } } diff --git a/MC6809/MC6809.UnitTest/SchwotzerArithmeticTests.cs b/MC6809/MC6809.UnitTest/SchwotzerArithmeticTests.cs index 92ade1e..d14e7a0 100644 --- a/MC6809/MC6809.UnitTest/SchwotzerArithmeticTests.cs +++ b/MC6809/MC6809.UnitTest/SchwotzerArithmeticTests.cs @@ -71,9 +71,9 @@ namespace MC6809.UnitTest this.board.Poke(1, (byte)(data >> 8)); this.board.Poke(2, (byte)(data & 0xFF)); this.cpu.CC = 0; - this.cpu.D.Word = (ushort)operand; + this.cpu.D.Joined = (ushort)operand; this.cpu.Step(); - Assert.AreEqual((ushort)expected, this.cpu.D.Word); + Assert.AreEqual((ushort)expected, this.cpu.D.Joined); Assert.AreEqual((byte)flags, (byte)(this.cpu.CC & 0x0F)); } @@ -193,9 +193,9 @@ namespace MC6809.UnitTest this.board.Poke(1, (byte)(data >> 8)); this.board.Poke(2, (byte)(data & 0xFF)); this.cpu.CC = 0; - this.cpu.D.Word = (ushort)operand; + this.cpu.D.Joined = (ushort)operand; this.cpu.Step(); - Assert.AreEqual((ushort)expected, this.cpu.D.Word); + Assert.AreEqual((ushort)expected, this.cpu.D.Joined); Assert.AreEqual((byte)flags, (byte)(this.cpu.CC & 0x0F)); } diff --git a/MC6809/MC6809.UnitTest/SchwotzerCompareLoadTests.cs b/MC6809/MC6809.UnitTest/SchwotzerCompareLoadTests.cs index 0895f3b..e318b84 100644 --- a/MC6809/MC6809.UnitTest/SchwotzerCompareLoadTests.cs +++ b/MC6809/MC6809.UnitTest/SchwotzerCompareLoadTests.cs @@ -95,9 +95,9 @@ namespace MC6809.UnitTest this.board.Poke(2, (byte)(data >> 8)); this.board.Poke(3, (byte)(data & 0xFF)); this.cpu.CC = 0; - this.cpu.D.Word = (ushort)operand; + this.cpu.D.Joined = (ushort)operand; this.cpu.Step(); - Assert.AreEqual((ushort)operand, this.cpu.D.Word); // D must not be modified + Assert.AreEqual((ushort)operand, this.cpu.D.Joined); // D must not be modified Assert.AreEqual((byte)flags, (byte)(this.cpu.CC & 0x0F)); } @@ -138,9 +138,9 @@ namespace MC6809.UnitTest this.board.Poke(1, (byte)(data >> 8)); this.board.Poke(2, (byte)(data & 0xFF)); this.cpu.CC = 0; - this.cpu.D.Word = 0x1234; // pre-load a different value + this.cpu.D.Joined = 0x1234; // pre-load a different value this.cpu.Step(); - Assert.AreEqual((ushort)data, this.cpu.D.Word); + Assert.AreEqual((ushort)data, this.cpu.D.Joined); Assert.AreEqual((byte)flags, (byte)(this.cpu.CC & 0x0E)); } @@ -184,7 +184,7 @@ namespace MC6809.UnitTest this.board.Poke(1, 0x01); this.board.Poke(2, 0x00); this.cpu.CC = 0; - this.cpu.D.Word = (ushort)data; + this.cpu.D.Joined = (ushort)data; this.cpu.Step(); var stored = (ushort)((this.board.Peek(0x0100) << 8) | this.board.Peek(0x0101)); Assert.AreEqual((ushort)data, stored); @@ -205,9 +205,9 @@ namespace MC6809.UnitTest this.board.Poke(0, 0x31); this.board.Poke(1, 0xA4); // ,Y (no offset, indirect=0) this.cpu.CC = 0; - this.cpu.Y.Word = (ushort)yValue; + this.cpu.Y.Joined = (ushort)yValue; this.cpu.Step(); - Assert.AreEqual((ushort)yValue, this.cpu.Y.Word); + Assert.AreEqual((ushort)yValue, this.cpu.Y.Joined); Assert.AreEqual((byte)flags, (byte)(this.cpu.CC & 0x04)); } diff --git a/MC6809/MC6809.UnitTest/SubTests.cs b/MC6809/MC6809.UnitTest/SubTests.cs index 436ada5..48b3566 100644 --- a/MC6809/MC6809.UnitTest/SubTests.cs +++ b/MC6809/MC6809.UnitTest/SubTests.cs @@ -116,7 +116,7 @@ namespace MC6809.UnitTest this.board.Poke(0x21, 0x21); this.cpu.CC = (byte)StatusBits.ZF; this.cpu.B = 3; - this.cpu.Y.Word = 0x21; + this.cpu.Y.Joined = 0x21; this.cpu.Step(); Assert.AreEqual(0xe2, this.cpu.B); Assert.IsTrue(this.cpu.Negative); diff --git a/MC6809/MC6809.UnitTest/TfrTests.cs b/MC6809/MC6809.UnitTest/TfrTests.cs index 8a8d549..3d55d36 100644 --- a/MC6809/MC6809.UnitTest/TfrTests.cs +++ b/MC6809/MC6809.UnitTest/TfrTests.cs @@ -29,15 +29,15 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x1f); this.board.Poke(0xb01, 0x02); this.cpu.CC = 0; - this.cpu.D.Word = 0xabba; - this.cpu.Y.Word = 0x101; - this.cpu.PC.Word = 0xb00; + this.cpu.D.Joined = 0xabba; + this.cpu.Y.Joined = 0x101; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0xb02, this.cpu.PC.Word); - Assert.AreEqual(0xabba, this.cpu.D.Word); - Assert.AreEqual(0xabba, this.cpu.Y.Word); + Assert.AreEqual(0xb02, this.cpu.PC.Joined); + Assert.AreEqual(0xabba, this.cpu.D.Joined); + Assert.AreEqual(0xabba, this.cpu.Y.Joined); Assert.IsFalse(this.cpu.Negative); Assert.IsFalse(this.cpu.Zero); Assert.IsFalse(this.cpu.Overflow); @@ -49,14 +49,14 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x1f); this.board.Poke(0xb01, 0x45); this.cpu.CC = 0; - this.cpu.S.Word = 0x1bb1; - this.cpu.Y.Word = 0x101; - this.cpu.PC.Word = 0xb00; + this.cpu.S.Joined = 0x1bb1; + this.cpu.Y.Joined = 0x101; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); - Assert.AreEqual(0x1bb1, this.cpu.PC.Word); - Assert.AreEqual(0x1bb1, this.cpu.S.Word); + Assert.AreEqual(0x1bb1, this.cpu.PC.Joined); + Assert.AreEqual(0x1bb1, this.cpu.S.Joined); Assert.IsFalse(this.cpu.Negative); Assert.IsFalse(this.cpu.Zero); Assert.IsFalse(this.cpu.Overflow); @@ -69,7 +69,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb01, 0xba); this.cpu.CC = 0; this.cpu.DP = 0x1b; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -91,12 +91,12 @@ namespace MC6809.UnitTest this.board.Poke(0xb01, 0x81); this.cpu.A = 0x56; this.cpu.B = 0x78; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); Assert.AreEqual(0x56, this.cpu.A); - Assert.AreEqual(0xff56, this.cpu.X.Word); + Assert.AreEqual(0xff56, this.cpu.X.Joined); } [TestMethod] @@ -105,14 +105,14 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x1f); this.board.Poke(0xb01, 0x19); this.cpu.CC = 0; - this.cpu.X.Word = 0x6541; + this.cpu.X.Joined = 0x6541; this.cpu.B = 0x78; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); Assert.AreEqual(0x41, this.cpu.B); - Assert.AreEqual(0x6541, this.cpu.X.Word); + Assert.AreEqual(0x6541, this.cpu.X.Joined); } } } \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/TstTests.cs b/MC6809/MC6809.UnitTest/TstTests.cs index 0f1bf0e..04d83a2 100644 --- a/MC6809/MC6809.UnitTest/TstTests.cs +++ b/MC6809/MC6809.UnitTest/TstTests.cs @@ -29,7 +29,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x4D); this.cpu.CC = 0; this.cpu.A = 0xff; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -46,7 +46,7 @@ namespace MC6809.UnitTest this.cpu.CC = 0; this.cpu.CC |= (byte)StatusBits.VF; this.cpu.A = 0x01; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -60,7 +60,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x4D); this.cpu.CC = 0; this.cpu.A = 0; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -73,10 +73,10 @@ namespace MC6809.UnitTest public void TestTSTA_indirect() { this.board.Poke(0x205, 0xff); - this.cpu.Y.Word = 0x205; + this.cpu.Y.Joined = 0x205; this.board.Poke(0xb00, 0x6d); this.board.Poke(0xb01, 0xa4); - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -92,7 +92,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x4D); this.cpu.CC = (byte)StatusBits.CF; this.cpu.A = 0x01; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -108,7 +108,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x4D); this.cpu.CC = (byte)StatusBits.VF; // V set, C clear this.cpu.A = 0x01; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -122,7 +122,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb00, 0x5D); this.cpu.CC = (byte)StatusBits.CF; this.cpu.B = 0x80; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); @@ -140,7 +140,7 @@ namespace MC6809.UnitTest this.board.Poke(0xb01, 0x03); this.board.Poke(0xb02, 0x00); this.cpu.CC = (byte)StatusBits.CF; - this.cpu.PC.Word = 0xb00; + this.cpu.PC.Joined = 0xb00; this.cpu.Step(); diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index 0c0ee52..b9c2f90 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -25,7 +25,7 @@ namespace MC6809 |-------|-------|-----------------------------------| */ - public sealed class MC6809 : BigEndianProcessor + public class MC6809 : BigEndianProcessor { private const byte RESET_vector = 0xfe; // RESET vector private const byte NMI_vector = 0xfc; // NMI vector @@ -352,7 +352,7 @@ namespace MC6809 public Register16 S { get; } = new(); - private Register16 EA { get; } = new(); + protected Register16 EA { get; } = new(); public ref byte DP => ref this._dp; @@ -366,7 +366,7 @@ namespace MC6809 public bool EntireRegisterSet => this.EntireRegisterSetFlag != 0; - public bool E => this.EntireRegisterSet; + public bool EntireFlag => this.EntireRegisterSet; public int FastInterruptMaskedFlag => this.CC & (byte)StatusBits.FF; @@ -418,53 +418,53 @@ namespace MC6809 private static byte ClearBit(byte f, StatusBits flag, int condition) => ClearBit(f, (byte)flag, condition); - private byte AdjustZero(byte datum) => ClearBit(this.CC, StatusBits.ZF, datum); + protected byte AdjustZero(byte datum) => ClearBit(this.CC, StatusBits.ZF, datum); - private byte AdjustZero(ushort datum) => ClearBit(this.CC, StatusBits.ZF, datum); + protected byte AdjustZero(ushort datum) => ClearBit(this.CC, StatusBits.ZF, datum); - private byte AdjustZero(Register16 datum) => this.AdjustZero(datum.Word); + protected byte AdjustZero(Register16 datum) => this.AdjustZero(datum.Joined); - private byte AdjustNegative(byte datum) => SetBit(this.CC, StatusBits.NF, datum & (byte)Bits.Bit7); + protected byte AdjustNegative(byte datum) => SetBit(this.CC, StatusBits.NF, datum & (byte)Bits.Bit7); - private byte AdjustNegative(ushort datum) => SetBit(this.CC, StatusBits.NF, datum & (ushort)Bits.Bit15); + protected byte AdjustNegative(ushort datum) => SetBit(this.CC, StatusBits.NF, datum & (ushort)Bits.Bit15); - private byte AdjustNZ(byte datum) + protected byte AdjustNZ(byte datum) { this.CC = this.AdjustZero(datum); return this.AdjustNegative(datum); } - private byte AdjustNZ(ushort datum) + protected byte AdjustNZ(ushort datum) { this.CC = this.AdjustZero(datum); return this.AdjustNegative(datum); } - private byte AdjustNZ(Register16 datum) => this.AdjustNZ(datum.Word); + protected byte AdjustNZ(Register16 datum) => this.AdjustNZ(datum.Joined); - private byte AdjustCarry(ushort datum) => SetBit(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit addition + protected byte AdjustCarry(ushort datum) => SetBit(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit addition - private byte AdjustCarry(uint datum) => SetBit(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit addition + protected byte AdjustCarry(uint datum) => SetBit(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit addition - private byte AdjustCarry(Register16 datum) => this.AdjustCarry(datum.Word); + protected byte AdjustCarry(Register16 datum) => this.AdjustCarry(datum.Joined); - private byte AdjustOverflow(byte before, byte data, Register16 after) + protected byte AdjustOverflow(byte before, byte data, Register16 after) { var lowAfter = after.Low; var highAfter = after.High; return SetBit(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ highAfter << 7) & (int)Bits.Bit7); } - private byte AdjustOverflow(ushort before, ushort data, uint after) + protected byte AdjustOverflow(ushort before, ushort data, uint after) { var lowAfter = (ushort)(after & (uint)Mask.Sixteen); var highAfter = (ushort)(after >> 16); return SetBit(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ highAfter << 15) & (int)Bits.Bit15); } - private byte AdjustHalfCarry(byte before, byte data, byte after) => SetBit(this.CC, StatusBits.HF, (before ^ data ^ after) & (int)Bits.Bit4); + protected byte AdjustHalfCarry(byte before, byte data, byte after) => SetBit(this.CC, StatusBits.HF, (before ^ data ^ after) & (int)Bits.Bit4); - private byte AdjustAddition(byte before, byte data, Register16 after) + protected byte AdjustAddition(byte before, byte data, Register16 after) { var result = after.Low; this.CC = this.AdjustNZ(result); @@ -473,17 +473,17 @@ namespace MC6809 return this.AdjustHalfCarry(before, data, result); } - private byte AdjustAddition(ushort before, ushort data, uint after) + protected byte AdjustAddition(ushort before, ushort data, uint after) { - this.Intermediate.Word = (ushort)after; - this.CC = this.AdjustNZ(this.Intermediate.Word); + this.Intermediate.Joined = (ushort)after; + this.CC = this.AdjustNZ(this.Intermediate.Joined); this.CC = this.AdjustCarry(after); return this.AdjustOverflow(before, data, after); } - private byte AdjustAddition(Register16 before, Register16 data, uint after) => this.AdjustAddition(before.Word, data.Word, after); + protected byte AdjustAddition(Register16 before, Register16 data, uint after) => this.AdjustAddition(before.Joined, data.Joined, after); - private byte AdjustSubtraction(byte before, byte data, Register16 after) + protected byte AdjustSubtraction(byte before, byte data, Register16 after) { var result = after.Low; this.CC = this.AdjustNZ(result); @@ -491,15 +491,15 @@ namespace MC6809 return this.AdjustOverflow(before, data, after); } - private byte AdjustSubtraction(ushort before, ushort data, uint after) + protected byte AdjustSubtraction(ushort before, ushort data, uint after) { - this.Intermediate.Word = (ushort)after; - this.CC = this.AdjustNZ(this.Intermediate.Word); + this.Intermediate.Joined = (ushort)after; + this.CC = this.AdjustNZ(this.Intermediate.Joined); this.CC = this.AdjustCarry(after); return this.AdjustOverflow(before, data, after); } - private byte AdjustSubtraction(Register16 before, Register16 data, uint after) => this.AdjustSubtraction(before.Word, data.Word, after); + protected byte AdjustSubtraction(Register16 before, Register16 data, uint after) => this.AdjustSubtraction(before.Joined, data.Joined, after); #endregion @@ -598,7 +598,7 @@ namespace MC6809 protected override void Push(byte value) => this.PushS(value); - private void Push(Register16 stack, byte value) + protected void Push(Register16 stack, byte value) { stack.Decrement(); this.MemoryWrite(stack, value); @@ -606,13 +606,13 @@ namespace MC6809 private void PushS(byte value) => this.Push(this.S, value); - private void Push(Register16 stack, Register16 value) + protected void Push(Register16 stack, Register16 value) { this.Push(stack, value.Low); this.Push(stack, value.High); } - private byte Pop(Register16 stack) + protected byte Pop(Register16 stack) { this.MemoryRead(stack); stack.Increment(); @@ -621,7 +621,7 @@ namespace MC6809 private byte PopS() => this.Pop(this.S); - private Register16 PopWord(Register16 stack) + protected Register16 PopWord(Register16 stack) { this.Intermediate.High = this.Pop(stack); this.Intermediate.Low = this.Pop(stack); @@ -638,33 +638,33 @@ namespace MC6809 this.IncrementPC(); } - private void RelativeByteAddress() + protected void RelativeByteAddress() { var offset = (sbyte)this.FetchByte(); - this.EA.Word = (ushort)(this.PC.Word + offset); + this.EA.Joined = (ushort)(this.PC.Joined + offset); } - private void RelativeWordAddress() + protected void RelativeWordAddress() { - this.FetchWord(); - var offset = (short)this.Intermediate.Word; - this.EA.Word = (ushort)(this.PC.Word + offset); + this.FetchShort(); + var offset = (short)this.Intermediate.Joined; + this.EA.Joined = (ushort)(this.PC.Joined + offset); } - private void DirectAddress() + protected void DirectAddress() { this.EA.Assign(this.FetchByte(), this.DP); this.SwallowRead(); } - private void ExtendedAddress() + protected void ExtendedAddress() { this.FetchInto(this.Intermediate); this.EA.Assign(this.Intermediate); this.SwallowRead(); } - private Register16 RR(int which) + protected Register16 RR(int which) { return which switch { @@ -676,7 +676,7 @@ namespace MC6809 }; } - private void IndexedAddress() + protected void IndexedAddress() { var type = this.FetchByte(); var r = this.RR((type & (byte)(Bits.Bit6 | Bits.Bit5)) >> 5); @@ -687,24 +687,24 @@ namespace MC6809 { case 0b0000: // ,R+ this.EA.Assign(r); - r.Word++; + r.Joined++; this.SwallowCurrent(); this.SwallowRead(2); break; case 0b0001: // ,R++ this.EA.Assign(r); - r.Word += 2; + r.Joined += 2; this.SwallowCurrent(); this.SwallowRead(3); break; case 0b0010: // ,-R - --r.Word; + --r.Joined; this.EA.Assign(r); this.SwallowCurrent(); this.SwallowRead(2); break; case 0b0011: // ,--R - r.Word -= 2; + r.Joined -= 2; this.EA.Assign(r); this.SwallowCurrent(); this.SwallowRead(3); @@ -714,29 +714,29 @@ namespace MC6809 this.SwallowCurrent(); break; case 0b0101: // B,R - this.EA.Word = (ushort)(r.Word + (sbyte)this.B); + this.EA.Joined = (ushort)(r.Joined + (sbyte)this.B); this.SwallowCurrent(); this.SwallowRead(); break; case 0b0110: // A,R - this.EA.Word = (ushort)(r.Word + (sbyte)this.A); + this.EA.Joined = (ushort)(r.Joined + (sbyte)this.A); this.SwallowCurrent(); this.SwallowRead(); break; case 0b1000: // n,R (eight-bit) this.FetchByte(); - this.EA.Word = (ushort)(r.Word + (sbyte)this.Bus.Data); + this.EA.Joined = (ushort)(r.Joined + (sbyte)this.Bus.Data); this.SwallowRead(); break; case 0b1001: // n,R (sixteen-bit) this.FetchInto(this.Intermediate); this.EA.Assign(this.Intermediate); - this.EA.Word += r.Word; + this.EA.Joined += r.Joined; this.SwallowCurrent(); this.SwallowRead(2); break; case 0b1011: // D,R - this.EA.Word = (ushort)(r.Word + this.D.Word); + this.EA.Joined = (ushort)(r.Joined + this.D.Joined); this.SwallowCurrent(3); this.SwallowRead(2); break; @@ -769,13 +769,13 @@ namespace MC6809 else { // EA = ,R + 5-bit offset - this.EA.Word = (ushort)(r.Word + SignExtend(5, (byte)(type & (byte)Mask.Five))); + this.EA.Joined = (ushort)(r.Joined + SignExtend(5, (byte)(type & (byte)Mask.Five))); this.SwallowCurrent(); this.SwallowRead(); } } - private void ImmediateByte() + protected void ImmediateByte() { this.ImmediateAddress(); this.MemoryRead(this.EA); @@ -787,42 +787,42 @@ namespace MC6809 return this.Bus.Data; } - private void DirectByte() + protected void DirectByte() { this.DirectAddress(); this.MemoryRead(this.EA); } - private void IndexedByte() + protected void IndexedByte() { this.IndexedAddress(); this.MemoryRead(this.EA); } - private void ExtendedByte() + protected void ExtendedByte() { this.ExtendedAddress(); this.MemoryRead(this.EA); } - private void ImmediateWord() => this.FetchWord(); + protected void ImmediateShort() => this.FetchShort(); - private void DirectWord() + protected void DirectShort() { this.DirectAddress(); - this.GetWord(this.EA); + this.GetShort(this.EA); } - private void IndexedWord() + protected void IndexedShort() { this.IndexedAddress(); - this.GetWord(this.EA); + this.GetShort(this.EA); } - private void ExtendedWord() + protected void ExtendedShort() { this.ExtendedAddress(); - this.GetWord(this.EA); + this.GetShort(this.EA); } #endregion @@ -834,7 +834,7 @@ namespace MC6809 private void Assign(ref byte destination) => destination = this.Through(this.Bus.Data); - private byte Through(byte data) + protected byte Through(byte data) { this.CC = ClearBit(this.CC, StatusBits.VF); this.CC = this.AdjustNZ(data); @@ -849,13 +849,19 @@ namespace MC6809 private void Assign(Register16 destination) => destination.Assign(this.Through(this.Intermediate)); - private Register16 Through(Register16 data) + protected ushort Through(ushort data) { this.CC = ClearBit(this.CC, StatusBits.VF); this.CC = this.AdjustNZ(data); return data; } + protected Register16 Through(Register16 data) + { + this.Through(data.Joined); + return data; + } + private void STA() => this.Store(this.A); private void STB() => this.Store(this.B); @@ -867,7 +873,7 @@ namespace MC6809 private void STX() => this.Store(this.X); private void STY() => this.Store(this.Y); - private void Store(Register16 data) => this.SetWord(this.EA, this.Through(data)); + private void Store(Register16 data) => this.SetShort(this.EA, this.Through(data)); #endregion @@ -959,12 +965,12 @@ namespace MC6809 private void SaveRegisterState() { this.SwallowRead(); - this.PSH(this.S, this.E ? (byte)Mask.Eight : (byte)0b10000001); + this.PSH(this.S, this.EntireFlag ? (byte)Mask.Eight : (byte)0b10000001); } private void RestoreRegisterState() { - this.PUL(this.S, this.E ? (byte)Mask.Eight : (byte)0b10000001); + this.PUL(this.S, this.EntireFlag ? (byte)Mask.Eight : (byte)0b10000001); } private void PSHS() => this.PSH(this.S); @@ -978,7 +984,7 @@ namespace MC6809 this.PSH(stack, control); } - private void PSH(Register16 stack, byte control) + protected void PSH(Register16 stack, byte control) { // Reverse order of PUL @@ -1039,7 +1045,7 @@ namespace MC6809 this.SwallowPop(stack); } - private void PUL(Register16 stack, byte control) + protected void PUL(Register16 stack, byte control) { // Reverse order of PSH @@ -1093,7 +1099,7 @@ namespace MC6809 #region 8-bit register transfers - private ref byte ReferenceTransfer8(int specifier) + protected virtual ref byte ReferenceTransfer8(int specifier) { switch (specifier) { @@ -1110,7 +1116,7 @@ namespace MC6809 } } - private Register16 ReferenceTransfer16(int specifier) + protected virtual Register16 ReferenceTransfer16(int specifier) { return specifier switch { @@ -1126,12 +1132,12 @@ namespace MC6809 private void EXG() { - var data = this.Bus.Data; + var immediate = this.Bus.Data; - var leftSpecifier = HighNibble(data); + var leftSpecifier = HighNibble(immediate); var leftType = leftSpecifier & (int)Bits.Bit3; - var rightSpecifier = LowNibble(data); + var rightSpecifier = LowNibble(immediate); var rightType = rightSpecifier & (int)Bits.Bit3; if (leftType == 0) @@ -1140,7 +1146,7 @@ namespace MC6809 if (rightType == 0) { var rightRegister = this.ReferenceTransfer16(rightSpecifier); - (leftRegister.Word, rightRegister.Word) = (rightRegister.Word, leftRegister.Word); + (leftRegister.Joined, rightRegister.Joined) = (rightRegister.Joined, leftRegister.Joined); } else { @@ -1170,12 +1176,12 @@ namespace MC6809 private void TFR() { - var data = this.Bus.Data; + var immediate = this.Bus.Data; - var sourceSpecifier = HighNibble(data); + var sourceSpecifier = HighNibble(immediate); var sourceType = sourceSpecifier & (int)Bits.Bit3; - var destinationSpecifier = LowNibble(data); + var destinationSpecifier = LowNibble(immediate); var destinationType = destinationSpecifier & (int)Bits.Bit3; if (sourceType == 0) @@ -1210,7 +1216,7 @@ namespace MC6809 #region Cycle wastage - private void SwallowRead(int ticks = 1) + protected void SwallowRead(int ticks = 1) { for (int i = 0; i < ticks; i++) { @@ -1218,7 +1224,7 @@ namespace MC6809 } } - private void SwallowCurrent(int ticks = 1) + protected void SwallowCurrent(int ticks = 1) { for (int i = 0; i < ticks; i++) { @@ -1226,11 +1232,11 @@ namespace MC6809 } } - private void SwallowPop(Register16 stack) => this.MemoryRead(stack); + protected void SwallowPop(Register16 stack) => this.MemoryRead(stack); - private void SwallowEffectiveAddress() => this.MemoryRead(this.EA); + protected void SwallowEffectiveAddress() => this.MemoryRead(this.EA); - private void SwallowSpin(int ticks = 1) + protected void SwallowSpin(int ticks = 1) { for (int i = 0; i < ticks; i++) { @@ -1293,7 +1299,7 @@ namespace MC6809 #region Instruction dispatching - private void ExecuteUnprefixed() + protected virtual void ExecuteUnprefixed() { switch (this.OpCode) { @@ -1325,10 +1331,10 @@ namespace MC6809 case 0xeb: this.IndexedByte(); this.ADDB(); Debug.Assert(this.Cycles >= 4); break; // ADD (ADDB indexed) case 0xfb: this.ExtendedByte(); this.ADDB(); Debug.Assert(this.Cycles == 5); break; // ADD (ADDB extended) - case 0xc3: this.ImmediateWord(); this.ADDD(); Debug.Assert(this.Cycles == 4); break; // ADD (ADDD immediate) - case 0xd3: this.DirectWord(); this.ADDD(); Debug.Assert(this.Cycles == 6); break; // ADD (ADDD direct) - case 0xe3: this.IndexedWord(); this.ADDD(); Debug.Assert(this.Cycles >= 6); break; // ADD (ADDD indexed) - case 0xf3: this.ExtendedWord(); this.ADDD(); Debug.Assert(this.Cycles == 7); break; // ADD (ADDD extended) + case 0xc3: this.ImmediateShort(); this.ADDD(); Debug.Assert(this.Cycles == 4); break; // ADD (ADDD immediate) + case 0xd3: this.DirectShort(); this.ADDD(); Debug.Assert(this.Cycles == 6); break; // ADD (ADDD direct) + case 0xe3: this.IndexedShort(); this.ADDD(); Debug.Assert(this.Cycles >= 6); break; // ADD (ADDD indexed) + case 0xf3: this.ExtendedShort(); this.ADDD(); Debug.Assert(this.Cycles == 7); break; // ADD (ADDD extended) // AND case 0x84: this.ImmediateByte(); this.ANDA(); Debug.Assert(this.Cycles == 2); break; // AND (ANDA immediate) @@ -1390,10 +1396,10 @@ namespace MC6809 case 0xf1: this.ExtendedByte(); this.CMPB(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPB, extended) // CMPX - case 0x8c: this.ImmediateWord(); this.CMPX(); Debug.Assert(this.Cycles == 4); break; // CMP (CMPX, immediate) - case 0x9c: this.DirectWord(); this.CMPX(); Debug.Assert(this.Cycles == 6); break; // CMP (CMPX, direct) - case 0xac: this.IndexedWord(); this.CMPX(); Debug.Assert(this.Cycles >= 6); break; // CMP (CMPX, indexed) - case 0xbc: this.ExtendedWord(); this.CMPX(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPX, extended) + case 0x8c: this.ImmediateShort(); this.CMPX(); Debug.Assert(this.Cycles == 4); break; // CMP (CMPX, immediate) + case 0x9c: this.DirectShort(); this.CMPX(); Debug.Assert(this.Cycles == 6); break; // CMP (CMPX, direct) + case 0xac: this.IndexedShort(); this.CMPX(); Debug.Assert(this.Cycles >= 6); break; // CMP (CMPX, indexed) + case 0xbc: this.ExtendedShort(); this.CMPX(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPX, extended) // COM case 0x03: this.DirectByte(); this.COM(); Debug.Assert(this.Cycles == 6); break; // COM (direct) @@ -1464,22 +1470,22 @@ namespace MC6809 case 0xf6: this.ExtendedByte(); this.LDB(); Debug.Assert(this.Cycles == 5); break; // LD (LDB extended) // LDD - case 0xcc: this.ImmediateWord(); this.LDD(); Debug.Assert(this.Cycles == 3); break; // LD (LDD immediate) - case 0xdc: this.DirectWord(); this.LDD(); Debug.Assert(this.Cycles == 5); break; // LD (LDD direct) - case 0xec: this.IndexedWord(); this.LDD(); Debug.Assert(this.Cycles >= 5); break; // LD (LDD indexed) - case 0xfc: this.ExtendedWord(); this.LDD(); Debug.Assert(this.Cycles == 6); break; // LD (LDD extended) + case 0xcc: this.ImmediateShort(); this.LDD(); Debug.Assert(this.Cycles == 3); break; // LD (LDD immediate) + case 0xdc: this.DirectShort(); this.LDD(); Debug.Assert(this.Cycles == 5); break; // LD (LDD direct) + case 0xec: this.IndexedShort(); this.LDD(); Debug.Assert(this.Cycles >= 5); break; // LD (LDD indexed) + case 0xfc: this.ExtendedShort(); this.LDD(); Debug.Assert(this.Cycles == 6); break; // LD (LDD extended) // LDU - case 0xce: this.ImmediateWord(); this.LDU(); Debug.Assert(this.Cycles == 3); break; // LD (LDU immediate) - case 0xde: this.DirectWord(); this.LDU(); Debug.Assert(this.Cycles == 5); break; // LD (LDU direct) - case 0xee: this.IndexedWord(); this.LDU(); Debug.Assert(this.Cycles >= 5); break; // LD (LDU indexed) - case 0xfe: this.ExtendedWord(); this.LDU(); Debug.Assert(this.Cycles == 6); break; // LD (LDU extended) + case 0xce: this.ImmediateShort(); this.LDU(); Debug.Assert(this.Cycles == 3); break; // LD (LDU immediate) + case 0xde: this.DirectShort(); this.LDU(); Debug.Assert(this.Cycles == 5); break; // LD (LDU direct) + case 0xee: this.IndexedShort(); this.LDU(); Debug.Assert(this.Cycles >= 5); break; // LD (LDU indexed) + case 0xfe: this.ExtendedShort(); this.LDU(); Debug.Assert(this.Cycles == 6); break; // LD (LDU extended) // LDX - case 0x8e: this.ImmediateWord(); this.LDX(); Debug.Assert(this.Cycles == 3); break; // LD (LDX immediate) - case 0x9e: this.DirectWord(); this.LDX(); Debug.Assert(this.Cycles == 5); break; // LD (LDX direct) - case 0xae: this.IndexedWord(); this.LDX(); Debug.Assert(this.Cycles >= 5); break; // LD (LDX indexed) - case 0xbe: this.ExtendedWord(); this.LDX(); Debug.Assert(this.Cycles == 6); break; // LD (LDX extended) + case 0x8e: this.ImmediateShort(); this.LDX(); Debug.Assert(this.Cycles == 3); break; // LD (LDX immediate) + case 0x9e: this.DirectShort(); this.LDX(); Debug.Assert(this.Cycles == 5); break; // LD (LDX direct) + case 0xae: this.IndexedShort(); this.LDX(); Debug.Assert(this.Cycles >= 5); break; // LD (LDX indexed) + case 0xbe: this.ExtendedShort(); this.LDX(); Debug.Assert(this.Cycles == 6); break; // LD (LDX extended) // LEA case 0x30: this.IndexedAddress(); this.LEAX(); Debug.Assert(this.Cycles >= 4); break; // LEA (LEAX indexed) @@ -1547,7 +1553,7 @@ namespace MC6809 case 0x76: this.ExtendedByte(); this.ROR(); Debug.Assert(this.Cycles == 7); break; // ROR (extended) // RTI - case 0x3B: this.SwallowCurrent(); this.RTI(); Debug.Assert(this.Cycles == (this.E ? 15 : 6)); break; // RTI (inherent) + case 0x3B: this.SwallowCurrent(); this.RTI(); Debug.Assert(this.Cycles == (this.EntireFlag ? 15 : 6)); break; // RTI (inherent) // RTS case 0x39: this.SwallowCurrent(); this.RTS(); Debug.Assert(this.Cycles == 5); break; // RTS (inherent) @@ -1611,10 +1617,10 @@ namespace MC6809 case 0xf0: this.ExtendedByte(); this.SUBB(); Debug.Assert(this.Cycles == 5); break; // SUB (SUBB extended) // SUBD - case 0x83: this.ImmediateWord(); this.SUBD(); Debug.Assert(this.Cycles == 4); break; // SUB (SUBD immediate) - case 0x93: this.DirectWord(); this.SUBD(); Debug.Assert(this.Cycles == 6); break; // SUB (SUBD direct) - case 0xa3: this.IndexedWord(); this.SUBD(); Debug.Assert(this.Cycles >= 6); break; // SUB (SUBD indexed) - case 0xb3: this.ExtendedWord(); this.SUBD(); Debug.Assert(this.Cycles == 7); break; // SUB (SUBD extended) + case 0x83: this.ImmediateShort(); this.SUBD(); Debug.Assert(this.Cycles == 4); break; // SUB (SUBD immediate) + case 0x93: this.DirectShort(); this.SUBD(); Debug.Assert(this.Cycles == 6); break; // SUB (SUBD direct) + case 0xa3: this.IndexedShort(); this.SUBD(); Debug.Assert(this.Cycles >= 6); break; // SUB (SUBD indexed) + case 0xb3: this.ExtendedShort(); this.SUBD(); Debug.Assert(this.Cycles == 7); break; // SUB (SUBD extended) // SWI case 0x3f: this.SwallowCurrent(); this.SWI(); Debug.Assert(this.Cycles == 19); break; // SWI (inherent) @@ -1659,37 +1665,37 @@ namespace MC6809 } } - private void Execute10() + protected virtual void Execute10() { switch (this.OpCode) { // CMP // CMPD - case 0x83: this.ImmediateWord(); this.CMPD(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPD, immediate) - case 0x93: this.DirectWord(); this.CMPD(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPD, direct) - case 0xa3: this.IndexedWord(); this.CMPD(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPD, indexed) - case 0xb3: this.ExtendedWord(); this.CMPD(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPD, extended) + case 0x83: this.ImmediateShort(); this.CMPD(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPD, immediate) + case 0x93: this.DirectShort(); this.CMPD(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPD, direct) + case 0xa3: this.IndexedShort(); this.CMPD(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPD, indexed) + case 0xb3: this.ExtendedShort(); this.CMPD(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPD, extended) // CMPY - case 0x8c: this.ImmediateWord(); this.CMPY(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPY, immediate) - case 0x9c: this.DirectWord(); this.CMPY(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPY, direct) - case 0xac: this.IndexedWord(); this.CMPY(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPY, indexed) - case 0xbc: this.ExtendedWord(); this.CMPY(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPY, extended) + case 0x8c: this.ImmediateShort(); this.CMPY(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPY, immediate) + case 0x9c: this.DirectShort(); this.CMPY(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPY, direct) + case 0xac: this.IndexedShort(); this.CMPY(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPY, indexed) + case 0xbc: this.ExtendedShort(); this.CMPY(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPY, extended) // LD // LDS - case 0xce: this.ImmediateWord(); this.LDS(); Debug.Assert(this.Cycles == 4); break; // LD (LDS immediate) - case 0xde: this.DirectWord(); this.LDS(); Debug.Assert(this.Cycles == 6); break; // LD (LDS direct) - case 0xee: this.IndexedWord(); this.LDS(); Debug.Assert(this.Cycles >= 6); break; // LD (LDS indexed) - case 0xfe: this.ExtendedWord(); this.LDS(); Debug.Assert(this.Cycles == 7); break; // LD (LDS extended) + case 0xce: this.ImmediateShort(); this.LDS(); Debug.Assert(this.Cycles == 4); break; // LD (LDS immediate) + case 0xde: this.DirectShort(); this.LDS(); Debug.Assert(this.Cycles == 6); break; // LD (LDS direct) + case 0xee: this.IndexedShort(); this.LDS(); Debug.Assert(this.Cycles >= 6); break; // LD (LDS indexed) + case 0xfe: this.ExtendedShort(); this.LDS(); Debug.Assert(this.Cycles == 7); break; // LD (LDS extended) // LDY - case 0x8e: this.ImmediateWord(); this.LDY(); Debug.Assert(this.Cycles == 4); break; // LD (LDY immediate) - case 0x9e: this.DirectWord(); this.LDY(); Debug.Assert(this.Cycles == 6); break; // LD (LDY direct) - case 0xae: this.IndexedWord(); this.LDY(); Debug.Assert(this.Cycles >= 6); break; // LD (LDY indexed) - case 0xbe: this.ExtendedWord(); this.LDY(); Debug.Assert(this.Cycles == 7); break; // LD (LDY extended) + case 0x8e: this.ImmediateShort(); this.LDY(); Debug.Assert(this.Cycles == 4); break; // LD (LDY immediate) + case 0x9e: this.DirectShort(); this.LDY(); Debug.Assert(this.Cycles == 6); break; // LD (LDY direct) + case 0xae: this.IndexedShort(); this.LDY(); Debug.Assert(this.Cycles >= 6); break; // LD (LDY indexed) + case 0xbe: this.ExtendedShort(); this.LDY(); Debug.Assert(this.Cycles == 7); break; // LD (LDY extended) // Branching case 0x21: this.RelativeWordAddress(); this.LBRN(); Debug.Assert(this.Cycles == 5); break; // BRN (LBRN relative) @@ -1726,23 +1732,23 @@ namespace MC6809 } } - private void Execute11() + protected virtual void Execute11() { switch (this.OpCode) { // CMP // CMPU - case 0x83: this.ImmediateWord(); this.CMPU(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPU, immediate) - case 0x93: this.DirectWord(); this.CMPU(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPU, direct) - case 0xa3: this.IndexedWord(); this.CMPU(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPU, indexed) - case 0xb3: this.ExtendedWord(); this.CMPU(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPU, extended) + case 0x83: this.ImmediateShort(); this.CMPU(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPU, immediate) + case 0x93: this.DirectShort(); this.CMPU(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPU, direct) + case 0xa3: this.IndexedShort(); this.CMPU(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPU, indexed) + case 0xb3: this.ExtendedShort(); this.CMPU(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPU, extended) // CMPS - case 0x8c: this.ImmediateWord(); this.CMPS(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPS, immediate) - case 0x9c: this.DirectWord(); this.CMPS(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPS, direct) - case 0xac: this.IndexedWord(); this.CMPS(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPS, indexed) - case 0xbc: this.ExtendedWord(); this.CMPS(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPS, extended) + case 0x8c: this.ImmediateShort(); this.CMPS(); Debug.Assert(this.Cycles == 5); break; // CMP (CMPS, immediate) + case 0x9c: this.DirectShort(); this.CMPS(); Debug.Assert(this.Cycles == 7); break; // CMP (CMPS, direct) + case 0xac: this.IndexedShort(); this.CMPS(); Debug.Assert(this.Cycles >= 7); break; // CMP (CMPS, indexed) + case 0xbc: this.ExtendedShort(); this.CMPS(); Debug.Assert(this.Cycles == 8); break; // CMP (CMPS, extended) // SWI case 0x3f: this.SwallowCurrent(); this.SWI3(); Debug.Assert(this.Cycles == 20); break; // SWI (SWI3 inherent) @@ -1771,33 +1777,41 @@ namespace MC6809 private byte Add(byte operand) => this.Add(operand, this.Bus.Data); - private byte Add(byte operand, byte data, byte carry = 0) + protected byte Add(byte operand, byte data, int carry = 0) { - this.Intermediate.Word = (ushort)(operand + data + carry); + this.Intermediate.Joined = (ushort)(operand + data + carry); this.CC = this.AdjustAddition(operand, data, this.Intermediate); return this.Intermediate.Low; } private void ADDD() => this.Add(this.D, this.Intermediate, this.D); - private void Add(Register16 operand, Register16 data, Register16 result) + protected void Add(Register16 operand, Register16 data, int carry, Register16 result) { - var addition = operand.Word + data.Word; + var addition = operand.Joined + data.Joined + carry; this.CC = this.AdjustAddition(operand, data, (uint)addition); - result.Word = (ushort)addition; + result.Joined = (ushort)addition; this.SwallowRead(); } + protected void Add(Register16 operand, Register16 data, Register16 result) => this.Add(operand, data, 0, result); + private void ANDCC() { this.CC &= this.Bus.Data; this.SwallowRead(); } - private void ANDA() => this.A = this.And(this.A, this.Bus.Data); - private void ANDB() => this.B = this.And(this.B, this.Bus.Data); + private void ANDA() => this.A = this.And(this.A); + private void ANDB() => this.B = this.And(this.B); - private byte And(byte operand, byte data) => this.Through((byte)(operand & data)); + protected ushort And(ushort operand, ushort data) => this.Through((ushort)(operand & data)); + + protected void And(Register16 operand, Register16 data, Register16 destination) => destination.Joined = this.And(operand.Joined, data.Joined); + + protected byte And(byte operand, byte data) => this.Through((byte)(operand & data)); + + protected byte And(byte operand) => this.And(operand, this.Bus.Data); private void ASLA() => this.A = this.ArithmeticShiftLeft(this.A); @@ -1810,7 +1824,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte ArithmeticShiftLeft(byte operand) + protected byte ArithmeticShiftLeft(byte operand) { this.CC = SetBit(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); this.CC = this.AdjustNZ(operand <<= 1); @@ -1830,7 +1844,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte ArithmeticShiftRight(byte operand) + protected byte ArithmeticShiftRight(byte operand) { this.CC = SetBit(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); var result = (byte)(operand >> 1 | (operand & (byte)Bits.Bit7)); @@ -1855,7 +1869,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte Clear() + protected byte Clear() { this.CC = ClearBit(this.CC, StatusBits.CF); return this.Through((byte)0U); @@ -1864,7 +1878,11 @@ namespace MC6809 private void CMPA() => this.Compare(this.A, this.Bus.Data); private void CMPB() => this.Compare(this.B, this.Bus.Data); - private void Compare(byte operand, byte data) => this.Subtract(operand, data); + protected void Compare(ushort operand, ushort data) => this.Subtract(operand, data); + + protected void Compare(Register16 operand, Register16 data) => this.Compare(operand.Joined, data.Joined); + + protected void Compare(byte operand, byte data) => this.Subtract(operand, data); private void CMPU() => this.Compare(this.U); private void CMPS() => this.Compare(this.S); @@ -1872,7 +1890,7 @@ namespace MC6809 private void CMPX() => this.Compare(this.X); private void CMPY() => this.Compare(this.Y); - private void Compare(Register16 operand) => this.Subtract(operand, this.Intermediate, this.Intermediate); + protected void Compare(Register16 operand) => this.Subtract(operand, this.Intermediate, this.Intermediate); private void COMA() => this.A = this.Complement(this.A); @@ -1885,7 +1903,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte Complement(byte operand) + protected byte Complement(byte operand) { this.CC = SetBit(this.CC, StatusBits.CF); return this.Through((byte)~operand); @@ -1928,10 +1946,16 @@ namespace MC6809 this.CC = SetBit(this.CC, StatusBits.CF, newCarry); } - private void EORA() => this.A = this.ExclusiveOr(this.A, this.Bus.Data); - private void EORB() => this.B = this.ExclusiveOr(this.B, this.Bus.Data); + private void EORA() => this.A = this.ExclusiveOr(this.A); + private void EORB() => this.B = this.ExclusiveOr(this.B); - private byte ExclusiveOr(byte operand, byte data) => this.Through((byte)(operand ^ data)); + protected ushort ExclusiveOr(ushort operand, ushort data) => this.Through((ushort)(operand ^ data)); + + protected void ExclusiveOr(Register16 operand, Register16 data, Register16 destination) => destination.Joined = this.ExclusiveOr(operand.Joined, data.Joined); + + protected byte ExclusiveOr(byte operand, byte data) => this.Through((byte)(operand ^ data)); + + protected byte ExclusiveOr(byte operand) => this.ExclusiveOr(operand, this.Bus.Data); private void DECA() => this.A = this.Decrement(this.A); @@ -1944,9 +1968,9 @@ namespace MC6809 this.MemoryWrite(result); } - private byte Decrement(byte operand) + protected byte Decrement(byte operand) { - this.Intermediate.Word = (ushort)(operand - 1); + this.Intermediate.Joined = (ushort)(operand - 1); var result = this.Intermediate.Low; this.CC = this.AdjustNZ(result); this.CC = this.AdjustOverflow(operand, 1, this.Intermediate); @@ -1964,9 +1988,9 @@ namespace MC6809 this.MemoryWrite(result); } - private byte Increment(byte operand) + protected byte Increment(byte operand) { - this.Intermediate.Word = (ushort)(operand + 1); + this.Intermediate.Joined = (ushort)(operand + 1); var result = this.Intermediate.Low; this.CC = this.AdjustNZ(result); this.CC = this.AdjustOverflow(operand, 1, this.Intermediate); @@ -1993,7 +2017,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte LogicalShiftRight(byte operand) + protected byte LogicalShiftRight(byte operand) { this.CC = SetBit(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); this.CC = this.AdjustNZ(operand >>= 1); @@ -2003,7 +2027,7 @@ namespace MC6809 private void MUL() { this.SwallowRead(9); - this.D.Word = (ushort)(this.A * this.B); + this.D.Joined = (ushort)(this.A * this.B); this.CC = this.AdjustZero(this.D); this.CC = SetBit(this.CC, StatusBits.CF, this.D.Low & (byte)Bits.Bit7); } @@ -2019,10 +2043,10 @@ namespace MC6809 this.MemoryWrite(result); } - private byte Negate(byte operand) + protected byte Negate(byte operand) { this.CC = SetBit(this.CC, StatusBits.VF, operand == (byte)Bits.Bit7); - this.Intermediate.Word = (ushort)(~operand + 1); + this.Intermediate.Joined = (ushort)(~operand + 1); operand = this.Intermediate.Low; this.CC = this.AdjustNZ(operand); this.CC = this.AdjustCarry(this.Intermediate); @@ -2038,7 +2062,13 @@ namespace MC6809 private void ORA() => this.A = this.Or(this.A); private void ORB() => this.B = this.Or(this.B); - private byte Or(byte operand) => this.Through((byte)(operand | this.Bus.Data)); + protected ushort Or(ushort operand, ushort data) => this.Through((ushort)(operand | data)); + + protected void Or(Register16 operand, Register16 data, Register16 destination) => destination.Joined = this.Or(operand.Joined, data.Joined); + + protected byte Or(byte operand, byte data) => this.Through((byte)(operand | data)); + + protected byte Or(byte operand) => this.Or(operand, this.Bus.Data); private void ROLA() => this.A = this.RotateLeft(this.A); @@ -2051,7 +2081,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte RotateLeft(byte operand) + protected byte RotateLeft(byte operand) { var carryIn = this.CarryFlag; this.CC = SetBit(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); @@ -2072,7 +2102,7 @@ namespace MC6809 this.MemoryWrite(result); } - private byte RotateRight(byte operand) + protected byte RotateRight(byte operand) { var carryIn = this.CarryFlag; this.CC = SetBit(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); @@ -2096,30 +2126,34 @@ namespace MC6809 private void SBCA() => this.A = this.SubtractWithCarry(this.A); private void SBCB() => this.B = this.SubtractWithCarry(this.B); - private byte SubtractWithCarry(byte operand) => this.Subtract(operand, this.Bus.Data, (byte)this.CarryFlag); + private byte SubtractWithCarry(byte operand) => this.Subtract(operand, this.Bus.Data, this.CarryFlag); private void SUBA() => this.A = this.Subtract(this.A); private void SUBB() => this.B = this.Subtract(this.B); private byte Subtract(byte operand) => this.Subtract(operand, this.Bus.Data); - private byte Subtract(byte operand, byte data, byte carry = 0) + protected byte Subtract(byte operand, byte data, int carry = 0) { - this.Intermediate.Word = (ushort)(operand - data - carry); + this.Intermediate.Joined = (ushort)(operand - data - carry); this.CC = this.AdjustSubtraction(operand, data, this.Intermediate); return this.Intermediate.Low; } private void SUBD() => this.Subtract(this.D, this.Intermediate, this.D); - private void Subtract(Register16 operand, Register16 data, Register16 result) + protected ushort Subtract(ushort operand, ushort data, int carry = 0) { - var subtraction = operand.Word - data.Word; + var subtraction = operand - data - carry; this.CC = this.AdjustSubtraction(operand, data, (uint)subtraction); - result.Word = (ushort)subtraction; this.SwallowRead(); + return (ushort)subtraction; } + protected void Subtract(Register16 operand, Register16 data, int carry, Register16 result) => result.Joined = this.Subtract(operand.Joined, data.Joined, carry); + + protected void Subtract(Register16 operand, Register16 data, Register16 result) => this.Subtract(operand, data, 0, result); + private void SEX() => this.A = this.SEX(this.B); private byte SEX(byte from) @@ -2196,11 +2230,11 @@ namespace MC6809 this.SwallowRead(); } - private void LEA(Register16 register) => register.Assign(this.EA); + protected void LEA(Register16 register) => register.Assign(this.EA); private void ABX() { - this.X.Word += this.B; + this.X.Joined += this.B; this.SwallowRead(); } diff --git a/MC6809/Profiler.cs b/MC6809/Profiler.cs index 5a116b7..fac85ef 100644 --- a/MC6809/Profiler.cs +++ b/MC6809/Profiler.cs @@ -73,7 +73,7 @@ namespace MC6809 } } - private void Processor_ExecutingInstruction(object? sender, EventArgs e) => this.address = this.processor.PC.Word; + private void Processor_ExecutingInstruction(object? sender, EventArgs e) => this.address = this.processor.PC.Joined; private void Processor_ExecutedInstruction(object? sender, EventArgs e) { diff --git a/Z80/Disassembler.cs b/Z80/Disassembler.cs index 71e1a5e..dbddbea 100644 --- a/Z80/Disassembler.cs +++ b/Z80/Disassembler.cs @@ -53,13 +53,13 @@ namespace Z80 var im = cpu.IM; return - $"PC={pc.Word:x4} SP={sp.Word:x4} " + $"PC={pc.Joined:x4} SP={sp.Joined:x4} " + $"A={a:x2} F={AsFlags(f)} " + $"B={b:x2} C={c:x2} " + $"D={d:x2} E={e:x2} " + $"H={h:x2} L={l:x2} " - + $"IX={cpu.IX.Word:x4} " - + $"IY={cpu.IY.Word:x4} " + + $"IX={cpu.IX.Joined:x4} " + + $"IY={cpu.IY.Joined:x4} " + $"I={i:x2} R={(byte)r:x2} " + $"IM={im} " + $"IFF1={(cpu.IFF1 ? 1 : 0)} " @@ -73,7 +73,7 @@ namespace Z80 { ArgumentNullException.ThrowIfNull(cpu); this._prefixCB = this._prefixDD = this._prefixED = this._prefixFD = false; - return this.Disassemble(cpu, cpu.PC.Word); + return this.Disassemble(cpu, cpu.PC.Joined); } private static string CC(int flag) => flag switch @@ -118,7 +118,7 @@ namespace Z80 var q = decoded.Q; var immediate = this.Bus.Peek((ushort)(pc + 1)); - var absolute = cpu.PeekWord((ushort)(pc + 1)).Word; + var absolute = cpu.PeekShort((ushort)(pc + 1)).Joined; var displacement = (sbyte)immediate; var relative = pc + displacement + 2; var indexedImmediate = this.Bus.Peek((ushort)(pc + 1)); diff --git a/Z80/Z80.FuseTest/TestRunner.cs b/Z80/Z80.FuseTest/TestRunner.cs index a3f25be..2a3e04a 100644 --- a/Z80/Z80.FuseTest/TestRunner.cs +++ b/Z80/Z80.FuseTest/TestRunner.cs @@ -112,7 +112,7 @@ namespace Z80.FuseTest private void AddActualEvent(string specifier) { - var address = this.Address.Word; + var address = this.Address.Joined; var cycles = this.totalCycles + this.cpu.Cycles; if (specifier.EndsWith('C')) { @@ -161,24 +161,24 @@ namespace Z80.FuseTest var testState = this.test.RegisterState; var inputRegisters = testState.Registers; - this.cpu.AF.Word = inputRegisters[(int)Register.AF_].Word; - this.cpu.BC.Word = inputRegisters[(int)Register.BC_].Word; - this.cpu.DE.Word = inputRegisters[(int)Register.DE_].Word; - this.cpu.HL.Word = inputRegisters[(int)Register.HL_].Word; + this.cpu.AF.Joined = inputRegisters[(int)Register.AF_].Joined; + this.cpu.BC.Joined = inputRegisters[(int)Register.BC_].Joined; + this.cpu.DE.Joined = inputRegisters[(int)Register.DE_].Joined; + this.cpu.HL.Joined = inputRegisters[(int)Register.HL_].Joined; this.cpu.Exx(); this.cpu.ExxAF(); - this.cpu.AF.Word = inputRegisters[(int)Register.AF].Word; - this.cpu.BC.Word = inputRegisters[(int)Register.BC].Word; - this.cpu.DE.Word = inputRegisters[(int)Register.DE].Word; - this.cpu.HL.Word = inputRegisters[(int)Register.HL].Word; + this.cpu.AF.Joined = inputRegisters[(int)Register.AF].Joined; + this.cpu.BC.Joined = inputRegisters[(int)Register.BC].Joined; + this.cpu.DE.Joined = inputRegisters[(int)Register.DE].Joined; + this.cpu.HL.Joined = inputRegisters[(int)Register.HL].Joined; - this.cpu.IX.Word = inputRegisters[(int)Register.IX].Word; - this.cpu.IY.Word = inputRegisters[(int)Register.IY].Word; + this.cpu.IX.Joined = inputRegisters[(int)Register.IX].Joined; + this.cpu.IY.Joined = inputRegisters[(int)Register.IY].Joined; - this.cpu.SP.Word = inputRegisters[(int)Register.SP].Word; - this.cpu.PC.Word = inputRegisters[(int)Register.PC].Word; + this.cpu.SP.Joined = inputRegisters[(int)Register.SP].Joined; + this.cpu.PC.Joined = inputRegisters[(int)Register.PC].Joined; - this.cpu.MEMPTR.Word = inputRegisters[(int)Register.MEMPTR].Word; + this.cpu.MEMPTR.Joined = inputRegisters[(int)Register.MEMPTR].Joined; this.cpu.IV = (byte)testState.I; this.cpu.REFRESH = (byte)testState.R; @@ -211,26 +211,26 @@ namespace Z80.FuseTest var expectedState = this.result.RegisterState; var expectedRegisters = expectedState.Registers; - var af = this.cpu.AF.Word == expectedRegisters[(int)Register.AF].Word; - var bc = this.cpu.BC.Word == expectedRegisters[(int)Register.BC].Word; - var de = this.cpu.DE.Word == expectedRegisters[(int)Register.DE].Word; - var hl = this.cpu.HL.Word == expectedRegisters[(int)Register.HL].Word; + var af = this.cpu.AF.Joined == expectedRegisters[(int)Register.AF].Joined; + var bc = this.cpu.BC.Joined == expectedRegisters[(int)Register.BC].Joined; + var de = this.cpu.DE.Joined == expectedRegisters[(int)Register.DE].Joined; + var hl = this.cpu.HL.Joined == expectedRegisters[(int)Register.HL].Joined; this.cpu.Exx(); this.cpu.ExxAF(); - var af_ = this.cpu.AF.Word == expectedRegisters[(int)Register.AF_].Word; - var bc_ = this.cpu.BC.Word == expectedRegisters[(int)Register.BC_].Word; - var de_ = this.cpu.DE.Word == expectedRegisters[(int)Register.DE_].Word; - var hl_ = this.cpu.HL.Word == expectedRegisters[(int)Register.HL_].Word; + var af_ = this.cpu.AF.Joined == expectedRegisters[(int)Register.AF_].Joined; + var bc_ = this.cpu.BC.Joined == expectedRegisters[(int)Register.BC_].Joined; + var de_ = this.cpu.DE.Joined == expectedRegisters[(int)Register.DE_].Joined; + var hl_ = this.cpu.HL.Joined == expectedRegisters[(int)Register.HL_].Joined; - var ix = this.cpu.IX.Word == expectedRegisters[(int)Register.IX].Word; - var iy = this.cpu.IY.Word == expectedRegisters[(int)Register.IY].Word; + var ix = this.cpu.IX.Joined == expectedRegisters[(int)Register.IX].Joined; + var iy = this.cpu.IY.Joined == expectedRegisters[(int)Register.IY].Joined; - var sp = this.cpu.SP.Word == expectedRegisters[(int)Register.SP].Word; - var pc = this.cpu.PC.Word == expectedRegisters[(int)Register.PC].Word; + var sp = this.cpu.SP.Joined == expectedRegisters[(int)Register.SP].Joined; + var pc = this.cpu.PC.Joined == expectedRegisters[(int)Register.PC].Joined; - var memptr = this.cpu.MEMPTR.Word == expectedRegisters[(int)Register.MEMPTR].Word; + var memptr = this.cpu.MEMPTR.Joined == expectedRegisters[(int)Register.MEMPTR].Joined; var iv = this.cpu.IV == expectedState.I; var refresh = this.cpu.REFRESH == expectedState.R; @@ -403,7 +403,7 @@ namespace Z80.FuseTest Console.Error.WriteLine(output); } - this.cpu.PC.Word = this.test.RegisterState.Registers[(int)Register.PC].Word; + this.cpu.PC.Joined = this.test.RegisterState.Registers[(int)Register.PC].Joined; var disassembled = this.disassembler.Disassemble(this.cpu); Console.Error.WriteLine(disassembled); } diff --git a/Z80/Z80.HarteTest/Checker.cs b/Z80/Z80.HarteTest/Checker.cs index d2e77da..9ad2a5a 100644 --- a/Z80/Z80.HarteTest/Checker.cs +++ b/Z80/Z80.HarteTest/Checker.cs @@ -40,7 +40,7 @@ this.Runner.RaisePOWER(); this.InitialiseState(test); - var pc = cpu.PC.Word; + var pc = cpu.PC.Joined; this.Cycles = cpu.Step(); this.Runner.LowerPOWER(); @@ -116,7 +116,7 @@ this.Valid = false; } - private bool Check(string what, ushort expected, Register16 actual) => this.Check(what, expected, actual.Word); + private bool Check(string what, ushort expected, Register16 actual) => this.Check(what, expected, actual.Joined); private bool Check(string what, ushort expected, ushort actual) { @@ -318,7 +318,7 @@ private void RaiseFlags(string what, byte expected, byte actual) => this.Messages.Add($"{what}: expected: {Disassembler.AsFlags(expected)}, actual: {Disassembler.AsFlags(actual)}"); - private void Raise(string what, ushort expected, Register16 actual) => this.Raise(what, expected, actual.Word); + private void Raise(string what, ushort expected, Register16 actual) => this.Raise(what, expected, actual.Joined); private void Raise(string what, ushort expected, ushort actual) => this.Messages.Add($"{what}: expected: {expected:X4}, actual: {actual:X4}"); @@ -346,13 +346,13 @@ var runner = this.Runner; var cpu = runner.CPU; - cpu.PC.Word = state.PC; - cpu.SP.Word = state.SP; + cpu.PC.Joined = state.PC; + cpu.SP.Joined = state.SP; - cpu.AF.Word = state.AF_; - cpu.BC.Word = state.BC_; - cpu.DE.Word = state.DE_; - cpu.HL.Word = state.HL_; + cpu.AF.Joined = state.AF_; + cpu.BC.Joined = state.BC_; + cpu.DE.Joined = state.DE_; + cpu.HL.Joined = state.HL_; cpu.Exx(); cpu.ExxAF(); @@ -372,10 +372,10 @@ cpu.IFF1 = state.IFF1 != 0; cpu.IFF2 = state.IFF2 != 0; - cpu.MEMPTR.Word = state.WZ; + cpu.MEMPTR.Joined = state.WZ; - cpu.IX.Word = state.IX; - cpu.IY.Word = state.IY; + cpu.IX.Joined = state.IX; + cpu.IY.Joined = state.IY; var initialRAM = state.RAM ?? throw new InvalidOperationException("Initial test state cannot have invalid RAM"); foreach (var entry in initialRAM) @@ -408,7 +408,7 @@ } } - private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action); + private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Joined, value, action); private void AddActualCycle(ushort address, byte value, string action) => this.ActualCycles.Add(new Cycle(address, value, action)); diff --git a/Z80/Z80.Test/Board.cs b/Z80/Z80.Test/Board.cs index 2dae096..b1ab8df 100644 --- a/Z80/Z80.Test/Board.cs +++ b/Z80/Z80.Test/Board.cs @@ -48,7 +48,7 @@ namespace Z80.Test { var programPath = this.configuration.RomDirectory + "/" + this.configuration.Program; var loadAddress = this.configuration.LoadAddress; - this.ram.Load(programPath, loadAddress.Word); + this.ram.Load(programPath, loadAddress.Joined); this.CPU.LoweredHALT += this.CPU_LoweredHALT; this.CPU.ExecutingInstruction += this.CPU_ExecutingInstruction_CPM; @@ -59,7 +59,7 @@ namespace Z80.Test } this.Poke(0, 0xc3); // JMP - this.CPU.PokeWord(1, this.configuration.StartAddress); + this.CPU.PokeShort(1, this.configuration.StartAddress); this.Poke(5, 0xc9); // ret } @@ -73,7 +73,7 @@ namespace Z80.Test System.Console.Out.Write(this.CPU.E.ToString(CultureInfo.InvariantCulture)); break; case 0x9: - for (var i = this.CPU.DE.Word; this.Peek(i) != '$'; ++i) + for (var i = this.CPU.DE.Joined; this.Peek(i) != '$'; ++i) { System.Console.Out.Write((char)this.Peek(i)); } diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 5978b97..4806b64 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -88,8 +88,8 @@ namespace Z80 private void DisplaceAddress() { - var displacement = (this._prefixDD ? this.IX : this.IY).Word + this._displacement; - this.MEMPTR.Word = (ushort)displacement; + var displacement = (this._prefixDD ? this.IX : this.IY).Joined + this._displacement; + this.MEMPTR.Joined = (ushort)displacement; this.Bus.Address.Assign(this.MEMPTR); } @@ -183,7 +183,7 @@ namespace Z80 this.REFRESH = 0; this.IV = (byte)Mask.Eight; - this.IX.Word = this.IY.Word = (ushort)Mask.Sixteen; + this.IX.Joined = this.IY.Joined = (ushort)Mask.Sixteen; // One of the register sets has been initialised // (by the IntelProcessor base class) @@ -543,7 +543,7 @@ namespace Z80 this.DisableInterrupts(); this.IM = 0; this.IV = this.REFRESH = 0; - this.SP.Word = this.AF.Word = (ushort)Mask.Sixteen; + this.SP.Joined = this.AF.Joined = (ushort)Mask.Sixteen; } private byte ReadDataUnderInterrupt() @@ -956,14 +956,14 @@ namespace Z80 this.Tick(7); break; case 3: // Retrieve/store register pair from/to immediate address - this.FetchWordAddress(); + this.FetchShortAddress(); switch (q) { case 0: // LD (nn), rp[p] - this.SetWord(this.RP(p)); + this.SetShort(this.RP(p)); break; case 1: // LD rp[p], (nn) - this.GetWord(); + this.GetShort(); this.RP(p).Assign(this.Intermediate); break; default: @@ -1193,8 +1193,8 @@ namespace Z80 WriteMemoryIndirect(this.DE, this.A); break; case 2: // LD (nn),HL - this.FetchWordAddress(); - this.SetWord(this.HL2()); + this.FetchShortAddress(); + this.SetShort(this.HL2()); break; case 3: // LD (nn),A this.FetchInto(this.MEMPTR); @@ -1215,8 +1215,8 @@ namespace Z80 this.A = this.ReadMemoryIndirect(this.DE); break; case 2: // LD HL,(nn) - this.FetchWordAddress(); - this.GetWord(); + this.FetchShortAddress(); + this.GetShort(); this.HL2().Assign(this.Intermediate); break; case 3: // LD A,(nn) @@ -1595,7 +1595,7 @@ namespace Z80 private void PushRegisterPair(int p) { this.Tick(); - this.PushWord(this.RP2(p)); + this.PushShort(this.RP2(p)); } private void PopRegisterPair(int p) @@ -1675,7 +1675,7 @@ namespace Z80 private byte Subtract(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand - value - carry); + this.Intermediate.Joined = (ushort)(operand - value - carry); var result = this.Intermediate.Low; this.AdjustHalfCarrySub(operand, value, result); @@ -1737,11 +1737,11 @@ namespace Z80 private Register16 SBC(Register16 operand, Register16 value) { - var subtraction = operand.Word - value.Word - this.Carry(); - this.Intermediate.Word = (ushort)subtraction; + var subtraction = operand.Joined - value.Joined - this.Carry(); + this.Intermediate.Joined = (ushort)subtraction; this.SetBit(StatusBits.NF); - this.ClearBit(StatusBits.ZF, this.Intermediate.Word); + this.ClearBit(StatusBits.ZF, this.Intermediate.Joined); this.SetBit(StatusBits.CF, subtraction & (int)Bits.Bit16); this.AdjustHalfCarrySub(operand.High, value.High, this.Intermediate.High); this.AdjustXY(this.Intermediate.High); @@ -1753,7 +1753,7 @@ namespace Z80 this.SetBit(StatusBits.SF, afterNegative); this.AdjustOverflowSub(beforeNegative, valueNegative, afterNegative); - this.MEMPTR.Word = (ushort)(operand.Word + 1); + this.MEMPTR.Joined = (ushort)(operand.Joined + 1); return this.Intermediate; } @@ -1761,7 +1761,7 @@ namespace Z80 private Register16 ADC(Register16 operand, Register16 value) { this.Add(operand, value, this.Carry()); - this.ClearBit(StatusBits.ZF, this.Intermediate.Word); + this.ClearBit(StatusBits.ZF, this.Intermediate.Joined); var beforeNegative = SignTest(operand.High); var valueNegative = SignTest(value.High); @@ -1775,22 +1775,22 @@ namespace Z80 private Register16 Add(Register16 operand, Register16 value, int carry = 0) { - var addition = operand.Word + value.Word + carry; - this.Intermediate.Word = (ushort)addition; + var addition = operand.Joined + value.Joined + carry; + this.Intermediate.Joined = (ushort)addition; this.ClearBit(StatusBits.NF); this.SetBit(StatusBits.CF, addition & (int)Bits.Bit16); this.AdjustHalfCarryAdd(operand.High, value.High, this.Intermediate.High); this.AdjustXY(this.Intermediate.High); - this.MEMPTR.Word = (ushort)(operand.Word + 1); + this.MEMPTR.Joined = (ushort)(operand.Joined + 1); return this.Intermediate; } private byte Add(byte operand, byte value, int carry = 0) { - this.Intermediate.Word = (ushort)(operand + value + carry); + this.Intermediate.Joined = (ushort)(operand + value + carry); var result = this.Intermediate.Low; this.AdjustHalfCarryAdd(operand, value, result); @@ -2017,7 +2017,7 @@ namespace Z80 this.MemoryRead(this.HL); var result = (byte)(this.A - this.Bus.Data); - this.SetBit(StatusBits.PF, --this.BC.Word); + this.SetBit(StatusBits.PF, --this.BC.Joined); this.AdjustSZ(result); this.AdjustHalfCarrySub(this.A, this.Bus.Data, result); @@ -2071,7 +2071,7 @@ namespace Z80 } else { - this.MEMPTR.Word = (ushort)(this.PC.Word - 2); + this.MEMPTR.Joined = (ushort)(this.PC.Joined - 2); this.Tick(2); } } @@ -2092,7 +2092,7 @@ namespace Z80 this.SetBit(StatusBits.XF, xy & (int)Bits.Bit3); this.SetBit(StatusBits.YF, xy & (int)Bits.Bit1); this.ClearBit(StatusBits.NF | StatusBits.HC); - this.SetBit(StatusBits.PF, --this.BC.Word); + this.SetBit(StatusBits.PF, --this.BC.Joined); } #region Block load single