From 515c679e683f4807fd6ddab98c955790f0c69f73 Mon Sep 17 00:00:00 2001 From: Adrian Conlon <98398945+AdrianConlon@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:20:29 +0100 Subject: [PATCH] Apply .net 9 analysis --- M6502/Core.cs | 891 +++++++++--------- M6502/Disassembler.cs | 430 ++++----- M6502/M6502.HarteTest/Checker.cs | 155 +-- M6502/M6502.HarteTest/Cycle.cs | 14 +- M6502/M6502.HarteTest/OpcodeTestSuite.cs | 13 +- M6502/M6502.HarteTest/ProcessorTestSuite.cs | 2 +- M6502/M6502.HarteTest/Program.cs | 6 +- M6502/M6502.HarteTest/State.cs | 2 +- M6502/M6502.HarteTest/Test.cs | 6 +- M6502/M6502.HarteTest/TestRunner.cs | 20 +- M6502/M6502.Symbols/Line.cs | 2 - M6502/M6502.Symbols/Module.cs | 1 + M6502/M6502.Symbols/Parser.cs | 4 +- .../ReflectedSectionProperties.cs | 4 +- M6502/M6502.Symbols/Section.cs | 29 +- M6502/M6502.Test/Board.cs | 4 +- M6502/M6502.Test/Configuration.cs | 2 +- M6502/MOS6502.cs | 340 +++---- M6502/Profiler.cs | 80 +- M6502/WDC65C02.cs | 208 ++-- 20 files changed, 1095 insertions(+), 1118 deletions(-) diff --git a/M6502/Core.cs b/M6502/Core.cs index 33db8de..9d4b8e6 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -14,7 +14,7 @@ namespace M6502 #region NMI pin - public ref PinLevel NMI => ref nmiLine; + public ref PinLevel NMI => ref this.nmiLine; private PinLevel nmiLine = PinLevel.Low; public event EventHandler? RaisingNMI; public event EventHandler? RaisedNMI; @@ -29,21 +29,21 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseNMI() { - if (NMI.Lowered()) + if (this.NMI.Lowered()) { - OnRaisingNMI(); - NMI.Raise(); - OnRaisedNMI(); + this.OnRaisingNMI(); + this.NMI.Raise(); + this.OnRaisedNMI(); } } public virtual void LowerNMI() { - if (NMI.Raised()) + if (this.NMI.Raised()) { - OnLoweringNMI(); - NMI.Lower(); - OnLoweredNMI(); + this.OnLoweringNMI(); + this.NMI.Lower(); + this.OnLoweredNMI(); } } @@ -51,7 +51,7 @@ namespace M6502 #region SO pin - public ref PinLevel SO => ref soLine; + public ref PinLevel SO => ref this.soLine; private PinLevel soLine = PinLevel.Low; public event EventHandler? RaisingSO; public event EventHandler? RaisedSO; @@ -67,21 +67,21 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseSO() { - if (SO.Lowered()) + if (this.SO.Lowered()) { - OnRaisingSO(); - SO.Raise(); - OnRaisedSO(); + this.OnRaisingSO(); + this.SO.Raise(); + this.OnRaisedSO(); } } public virtual void LowerSO() { - if (SO.Raised()) + if (this.SO.Raised()) { - OnLoweringSO(); - SO.Lower(); - OnLoweredSO(); + this.OnLoweringSO(); + this.SO.Lower(); + this.OnLoweredSO(); } } @@ -89,7 +89,7 @@ namespace M6502 #region SYNC pin - public ref PinLevel SYNC => ref syncLine; + public ref PinLevel SYNC => ref this.syncLine; private PinLevel syncLine = PinLevel.Low; public event EventHandler? RaisingSYNC; public event EventHandler? RaisedSYNC; @@ -104,23 +104,23 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] protected virtual void RaiseSYNC() { - OnRaisingSYNC(); - SYNC.Raise(); - OnRaisedSYNC(); + this.OnRaisingSYNC(); + this.SYNC.Raise(); + this.OnRaisedSYNC(); } protected virtual void LowerSYNC() { - OnLoweringSYNC(); - SYNC.Lower(); - OnLoweredSYNC(); + this.OnLoweringSYNC(); + this.SYNC.Lower(); + this.OnLoweredSYNC(); } #endregion #region RDY pin - public ref PinLevel RDY => ref rdyLine; + public ref PinLevel RDY => ref this.rdyLine; private PinLevel rdyLine = PinLevel.Low; public event EventHandler? RaisingRDY; public event EventHandler? RaisedRDY; @@ -134,21 +134,21 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseRDY() { - if (RDY.Lowered()) + if (this.RDY.Lowered()) { - OnRaisingRDY(); - RDY.Raise(); - OnRaisedRDY(); + this.OnRaisingRDY(); + this.RDY.Raise(); + this.OnRaisedRDY(); } } public virtual void LowerRDY() { - if (RDY.Raised()) + if (this.RDY.Raised()) { - OnLoweringRDY(); - RDY.Lower(); - OnLoweredRDY(); + this.OnLoweringRDY(); + this.RDY.Lower(); + this.OnLoweredRDY(); } } @@ -156,7 +156,7 @@ namespace M6502 #region RW pin - public ref PinLevel RW => ref rwLine; + public ref PinLevel RW => ref this.rwLine; private PinLevel rwLine = PinLevel.Low; public event EventHandler? RaisingRW; public event EventHandler? RaisedRW; @@ -170,21 +170,21 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseRW() { - if (RW.Lowered()) + if (this.RW.Lowered()) { - OnRaisingRW(); - RW.Raise(); - OnRaisedRW(); + this.OnRaisingRW(); + this.RW.Raise(); + this.OnRaisedRW(); } } public virtual void LowerRW() { - if (RW.Raised()) + if (this.RW.Raised()) { - OnLoweringRW(); - RW.Lower(); - OnLoweredRW(); + this.OnLoweringRW(); + this.RW.Lower(); + this.OnLoweredRW(); } } @@ -192,13 +192,13 @@ namespace M6502 protected override void OnRaisedPOWER() { - X = (byte)Bits.Bit7; - Y = 0; - A = 0; - P = (byte)StatusBits.RF; - S = (byte)Mask.Eight; - LowerSYNC(); - LowerRW(); + this.X = (byte)Bits.Bit7; + this.Y = 0; + this.A = 0; + this.P = (byte)StatusBits.RF; + this.S = (byte)Mask.Eight; + this.LowerSYNC(); + this.LowerRW(); base.OnRaisedPOWER(); } @@ -206,9 +206,9 @@ namespace M6502 #region Interrupts - private const byte IRQvector = 0xfe; // IRQ vector - private const byte RSTvector = 0xfc; // RST vector - private const byte NMIvector = 0xfa; // NMI vector + private const byte IRQ_vector = 0xfe; // IRQ vector + private const byte RST_vector = 0xfc; // RST vector + private const byte NMI_vector = 0xfa; // NMI vector protected enum InterruptSource { hardware, software }; @@ -218,43 +218,43 @@ namespace M6502 { if (type == InterruptType.reset) { - DummyPush(); - DummyPush(); - DummyPush(); + this.DummyPush(); + this.DummyPush(); + this.DummyPush(); } else { - PushWord(PC); - Push((byte)(P | (source == InterruptSource.hardware ? 0 : (byte)StatusBits.BF))); + this.PushWord(this.PC); + this.Push((byte)(this.P | (source == InterruptSource.hardware ? 0 : (byte)StatusBits.BF))); } - SetFlag(StatusBits.IF); // Disable IRQ - Jump(GetWordPaged(0xff, vector)); + this.SetFlag(StatusBits.IF); // Disable IRQ + this.Jump(this.GetWordPaged(0xff, vector)); } #region Interrupt etc. handlers - protected override sealed void HandleRESET() + protected sealed override void HandleRESET() { - RaiseRESET(); - Interrupt(RSTvector, InterruptSource.hardware, InterruptType.reset); + this.RaiseRESET(); + this.Interrupt(RST_vector, InterruptSource.hardware, InterruptType.reset); } - protected override sealed void HandleINT() + protected sealed override void HandleINT() { - RaiseINT(); - Interrupt(IRQvector); + this.RaiseINT(); + this.Interrupt(IRQ_vector); } private void HandleNMI() { - RaiseNMI(); - Interrupt(NMIvector); + this.RaiseNMI(); + this.Interrupt(NMI_vector); } private void HandleSO() { - RaiseSO(); - SetFlag(StatusBits.VF); + this.RaiseSO(); + this.SetFlag(StatusBits.VF); } #endregion @@ -273,12 +273,12 @@ namespace M6502 #region Processor state helpers - protected int InterruptMasked => P & (byte)StatusBits.IF; - protected int DecimalMasked => P & (byte)StatusBits.DF; - protected int Negative => NegativeTest(P); - protected int Zero => ZeroTest(P); - protected int Overflow => OverflowTest(P); - protected int Carry => CarryTest(P); + protected int InterruptMasked => this.P & (byte)StatusBits.IF; + protected int DecimalMasked => this.P & (byte)StatusBits.DF; + protected int Negative => NegativeTest(this.P); + protected int Zero => ZeroTest(this.P); + protected int Overflow => OverflowTest(this.P); + protected int Carry => CarryTest(this.P); protected static int NegativeTest(byte data) => data & (byte)StatusBits.NF; protected static int ZeroTest(byte data) => data & (byte)StatusBits.ZF; @@ -305,30 +305,15 @@ namespace M6502 #region State flag twiddling - protected void SetFlag(StatusBits flag) - { - P = SetBit(P, flag); - } + protected void SetFlag(StatusBits flag) => this.P = SetBit(this.P, flag); - protected void SetFlag(StatusBits which, int condition) - { - P = SetBit(P, which, condition); - } + protected void SetFlag(StatusBits which, int condition) => this.P = SetBit(this.P, which, condition); - protected void SetFlag(StatusBits which, bool condition) - { - P = SetBit(P, which, condition); - } + protected void SetFlag(StatusBits which, bool condition) => this.P = SetBit(this.P, which, condition); - protected void ResetFlag(StatusBits which) - { - P = ClearBit(P, which); - } + protected void ResetFlag(StatusBits which) => this.P = ClearBit(this.P, which); - protected void ResetFlag(StatusBits which, int condition) - { - P = ClearBit(P, which, condition); - } + protected void ResetFlag(StatusBits which, int condition) => this.P = ClearBit(this.P, which, condition); #endregion @@ -336,230 +321,230 @@ namespace M6502 #region Cycle wastage - protected void SwallowRead() => MemoryRead(PC); + protected void SwallowRead() => this.MemoryRead(this.PC); - protected void SwallowPop() => MemoryRead(S, 1); + protected void SwallowPop() => this.MemoryRead(this.S, 1); - protected void SwallowFetch() => FetchByte(); + protected void SwallowFetch() => this.FetchByte(); #endregion #region Core instruction dispatching - public override void Execute() - { - MaybeExecute(); - } + public override void Execute() => this.MaybeExecute(); protected virtual bool MaybeExecute() { - var cycles = Cycles; - switch (OpCode) + var cycles = this.Cycles; + switch (this.OpCode) { - case 0x00: SwallowFetch(); Interrupt(IRQvector, InterruptSource.software); break; // BRK (implied) - case 0x01: IndexedIndirectXRead(); OrR(); break; // ORA (indexed indirect X) - case 0x05: ZeroPageRead(); OrR(); break; // ORA (zero page) - case 0x06: ZeroPageRead(); ModifyWrite(ASL()); break; // ASL (zero page) - case 0x08: SwallowRead(); PHP(); break; // PHP (implied) - case 0x09: ImmediateRead(); OrR(); break; // ORA (immediate) - case 0x0a: SwallowRead(); A = ASL(A); break; // ASL A (implied) - case 0x0d: AbsoluteRead(); OrR(); break; // ORA (absolute) - case 0x0e: AbsoluteRead(); ModifyWrite(ASL()); break; // ASL (absolute) + case 0x00: this.SwallowFetch(); this.Interrupt(IRQ_vector, InterruptSource.software); break;// BRK (implied) + case 0x01: this.IndexedIndirectXRead(); this.OrR(); break; // ORA (indexed indirect X) + case 0x05: this.ZeroPageRead(); this.OrR(); break; // ORA (zero page) + case 0x06: this.ZeroPageRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page) + case 0x08: this.SwallowRead(); this.PHP(); break; // PHP (implied) + case 0x09: this.ImmediateRead(); this.OrR(); break; // ORA (immediate) + case 0x0a: this.SwallowRead(); this.A = this.ASL(this.A); break; // ASL A (implied) + case 0x0d: this.AbsoluteRead(); this.OrR(); break; // ORA (absolute) + case 0x0e: this.AbsoluteRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute) - case 0x10: BranchNot(Negative); break; // BPL (relative) - case 0x11: IndirectIndexedYRead(); OrR(); break; // ORA (indirect indexed Y) - case 0x15: ZeroPageXRead(); OrR(); break; // ORA (zero page, X) - case 0x16: ZeroPageXRead(); ModifyWrite(ASL()); break; // ASL (zero page, X) - case 0x18: SwallowRead(); ResetFlag(StatusBits.CF); break; // CLC (implied) - case 0x19: AbsoluteYRead(); OrR(); break; // ORA (absolute, Y) - case 0x1d: AbsoluteXRead(); OrR(); break; // ORA (absolute, X) - case 0x1e: AbsoluteXAddress(); FixupRead(); ModifyWrite(ASL()); break; // ASL (absolute, X) + case 0x10: this.BranchNot(this.Negative); break; // BPL (relative) + case 0x11: this.IndirectIndexedYRead(); this.OrR(); break; // ORA (indirect indexed Y) + case 0x15: this.ZeroPageXRead(); this.OrR(); break; // ORA (zero page, X) + case 0x16: this.ZeroPageXRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page, X) + case 0x18: this.SwallowRead(); this.ResetFlag(StatusBits.CF); break; // CLC (implied) + case 0x19: this.AbsoluteYRead(); this.OrR(); break; // ORA (absolute, Y) + case 0x1d: this.AbsoluteXRead(); this.OrR(); break; // ORA (absolute, X) + case 0x1e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute, X) - case 0x20: JSR(); break; // JSR (absolute) - case 0x21: IndexedIndirectXRead(); AndR(); break; // AND (indexed indirect X) - case 0x24: ZeroPageRead(); BIT(); break; // BIT (zero page) - case 0x25: ZeroPageRead(); AndR(); break; // AND (zero page) - case 0x26: ZeroPageRead(); ModifyWrite(ROL()); break; // ROL (zero page) - case 0x28: SwallowRead(); PLP(); break; // PLP (implied) - case 0x29: ImmediateRead(); AndR(); break; // AND (immediate) - case 0x2a: SwallowRead(); A = ROL(A); break; // ROL A (implied) - case 0x2c: AbsoluteRead(); BIT(); break; // BIT (absolute) - case 0x2d: AbsoluteRead(); AndR(); break; // AND (absolute) - case 0x2e: AbsoluteRead(); ModifyWrite(ROL()); break; // ROL (absolute) + case 0x20: this.JSR(); break; // JSR (absolute) + case 0x21: this.IndexedIndirectXRead(); this.AndR(); break; // AND (indexed indirect X) + case 0x24: this.ZeroPageRead(); this.BIT(); break; // BIT (zero page) + case 0x25: this.ZeroPageRead(); this.AndR(); break; // AND (zero page) + case 0x26: this.ZeroPageRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page) + case 0x28: this.SwallowRead(); this.PLP(); break; // PLP (implied) + case 0x29: this.ImmediateRead(); this.AndR(); break; // AND (immediate) + case 0x2a: this.SwallowRead(); this.A = this.ROL(this.A); break; // ROL A (implied) + case 0x2c: this.AbsoluteRead(); this.BIT(); break; // BIT (absolute) + case 0x2d: this.AbsoluteRead(); this.AndR(); break; // AND (absolute) + case 0x2e: this.AbsoluteRead(); this.ModifyWrite(this.ROL()); break; // ROL (absolute) - case 0x30: Branch(Negative); break; // BMI (relative) - case 0x31: IndirectIndexedYRead(); AndR(); break; // AND (indirect indexed Y) - case 0x35: ZeroPageXRead(); AndR(); break; // AND (zero page, X) - case 0x36: ZeroPageXRead(); ModifyWrite(ROL()); break; // ROL (zero page, X) - case 0x38: SwallowRead(); SetFlag(StatusBits.CF); break; // SEC (implied) - case 0x39: AbsoluteYRead(); AndR(); break; // AND (absolute, Y) - case 0x3d: AbsoluteXRead(); AndR(); break; // AND (absolute, X) - case 0x3e: AbsoluteXAddress(); FixupRead(); ModifyWrite(ROL()); break; // ROL (absolute, X) + case 0x30: this.Branch(this.Negative); break; // BMI (relative) + case 0x31: this.IndirectIndexedYRead(); this.AndR(); break; // AND (indirect indexed Y) + case 0x35: this.ZeroPageXRead(); this.AndR(); break; // AND (zero page, X) + case 0x36: this.ZeroPageXRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page, X) + case 0x38: this.SwallowRead(); this.SetFlag(StatusBits.CF); break; // SEC (implied) + case 0x39: this.AbsoluteYRead(); this.AndR(); break; // AND (absolute, Y) + case 0x3d: this.AbsoluteXRead(); this.AndR(); break; // AND (absolute, X) + case 0x3e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROL()); break; // ROL (absolute, X) - case 0x40: SwallowRead(); RTI(); break; // RTI (implied) - case 0x41: IndexedIndirectXRead(); EorR(); break; // EOR (indexed indirect X) - case 0x44: ZeroPageRead(); break; // *NOP (zero page) - case 0x45: ZeroPageRead(); EorR(); break; // EOR (zero page) - case 0x46: ZeroPageRead(); ModifyWrite(LSR()); break; // LSR (zero page) - case 0x48: SwallowRead(); Push(A); break; // PHA (implied) - case 0x49: ImmediateRead(); EorR(); break; // EOR (immediate) - case 0x4a: SwallowRead(); A = LSR(A); break; // LSR A (implied) - case 0x4c: AbsoluteAddress(); Jump(Bus.Address); break; // JMP (absolute) - case 0x4d: AbsoluteRead(); EorR(); break; // EOR (absolute) - case 0x4e: AbsoluteRead(); ModifyWrite(LSR()); break; // LSR (absolute) + case 0x40: this.SwallowRead(); this.RTI(); break; // RTI (implied) + case 0x41: this.IndexedIndirectXRead(); this.EorR(); break; // EOR (indexed indirect X) + case 0x44: this.ZeroPageRead(); break; // *NOP (zero page) + case 0x45: this.ZeroPageRead(); this.EorR(); break; // EOR (zero page) + case 0x46: this.ZeroPageRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page) + case 0x48: this.SwallowRead(); this.Push(this.A); break; // PHA (implied) + case 0x49: this.ImmediateRead(); this.EorR(); break; // EOR (immediate) + case 0x4a: this.SwallowRead(); this.A = this.LSR(this.A); break; // LSR A (implied) + case 0x4c: this.AbsoluteAddress(); this.Jump(this.Bus.Address); break; // JMP (absolute) + case 0x4d: this.AbsoluteRead(); this.EorR(); break; // EOR (absolute) + case 0x4e: this.AbsoluteRead(); this.ModifyWrite(this.LSR()); break; // LSR (absolute) - case 0x50: BranchNot(Overflow); break; // BVC (relative) - case 0x51: IndirectIndexedYRead(); EorR(); break; // EOR (indirect indexed Y) - case 0x54: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0x55: ZeroPageXRead(); EorR(); break; // EOR (zero page, X) - case 0x56: ZeroPageXRead(); ModifyWrite(LSR()); break; // LSR (zero page, X) - case 0x58: SwallowRead(); ResetFlag(StatusBits.IF); break; // CLI (implied) - case 0x59: AbsoluteYRead(); EorR(); break; // EOR (absolute, Y) - case 0x5d: AbsoluteXRead(); EorR(); break; // EOR (absolute, X) - case 0x5e: AbsoluteXAddress(); FixupRead(); ModifyWrite(LSR()); break; // LSR (absolute, X) + case 0x50: this.BranchNot(this.Overflow); break; // BVC (relative) + case 0x51: this.IndirectIndexedYRead(); this.EorR(); break; // EOR (indirect indexed Y) + case 0x54: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0x55: this.ZeroPageXRead(); this.EorR(); break; // EOR (zero page, X) + case 0x56: this.ZeroPageXRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page, X) + case 0x58: this.SwallowRead(); this.ResetFlag(StatusBits.IF); break; // CLI (implied) + case 0x59: this.AbsoluteYRead(); this.EorR(); break; // EOR (absolute, Y) + case 0x5d: this.AbsoluteXRead(); this.EorR(); break; // EOR (absolute, X) + case 0x5e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.LSR()); break; // LSR (absolute, X) - case 0x60: SwallowRead(); Return(); break; // RTS (implied) - case 0x61: IndexedIndirectXRead(); ADC(); break; // ADC (indexed indirect X) - case 0x65: ZeroPageRead(); ADC(); break; // ADC (zero page) - case 0x66: ZeroPageRead(); ModifyWrite(ROR()); break; // ROR (zero page) - case 0x68: SwallowRead(); SwallowPop(); A = Through(Pop()); break; // PLA (implied) - case 0x69: ImmediateRead(); ADC(); break; // ADC (immediate) - case 0x6a: SwallowRead(); A = ROR(A); break; // ROR A (implied) - case 0x6c: IndirectAddress(); Jump(Bus.Address); break; // JMP (indirect) - case 0x6d: AbsoluteRead(); ADC(); break; // ADC (absolute) - case 0x6e: AbsoluteRead(); ModifyWrite(ROR()); break; // ROR (absolute) + case 0x60: this.SwallowRead(); this.Return(); break; // RTS (implied) + case 0x61: this.IndexedIndirectXRead(); this.ADC(); break; // ADC (indexed indirect X) + case 0x65: this.ZeroPageRead(); this.ADC(); break; // ADC (zero page) + case 0x66: this.ZeroPageRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page) + case 0x68: this.SwallowRead(); this.SwallowPop(); this.A = this.Through(this.Pop()); break; // PLA (implied) + case 0x69: this.ImmediateRead(); this.ADC(); break; // ADC (immediate) + case 0x6a: this.SwallowRead(); this.A = this.ROR(this.A); break; // ROR A (implied) + case 0x6c: this.IndirectAddress(); this.Jump(this.Bus.Address); break; // JMP (indirect) + case 0x6d: this.AbsoluteRead(); this.ADC(); break; // ADC (absolute) + case 0x6e: this.AbsoluteRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute) - case 0x70: Branch(Overflow); break; // BVS (relative) - case 0x71: IndirectIndexedYRead(); ADC(); break; // ADC (indirect indexed Y) - case 0x75: ZeroPageXRead(); ADC(); break; // ADC (zero page, X) - case 0x76: ZeroPageXRead(); ModifyWrite(ROR()); break; // ROR (zero page, X) - case 0x78: SwallowRead(); SetFlag(StatusBits.IF); break; // SEI (implied) - case 0x79: AbsoluteYRead(); ADC(); break; // ADC (absolute, Y) - case 0x7d: AbsoluteXRead(); ADC(); break; // ADC (absolute, X) - case 0x7e: AbsoluteXAddress(); FixupRead(); ModifyWrite(ROR()); break; // ROR (absolute, X) + case 0x70: this.Branch(this.Overflow); break; // BVS (relative) + case 0x71: this.IndirectIndexedYRead(); this.ADC(); break; // ADC (indirect indexed Y) + case 0x75: this.ZeroPageXRead(); this.ADC(); break; // ADC (zero page, X) + case 0x76: this.ZeroPageXRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page, X) + case 0x78: this.SwallowRead(); this.SetFlag(StatusBits.IF); break; // SEI (implied) + case 0x79: this.AbsoluteYRead(); this.ADC(); break; // ADC (absolute, Y) + case 0x7d: this.AbsoluteXRead(); this.ADC(); break; // ADC (absolute, X) + case 0x7e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute, X) - case 0x81: IndexedIndirectXAddress(); MemoryWrite(A); break; // STA (indexed indirect X) - case 0x82: ImmediateRead(); break; // *NOP (immediate) - case 0x84: ZeroPageAddress(); MemoryWrite(Y); break; // STY (zero page) - case 0x85: ZeroPageAddress(); MemoryWrite(A); break; // STA (zero page) - case 0x86: ZeroPageAddress(); MemoryWrite(X); break; // STX (zero page) - case 0x88: SwallowRead(); Y = DEC(Y); break; // DEY (implied) - case 0x8a: SwallowRead(); A = Through(X); break; // TXA (implied) - case 0x8c: AbsoluteAddress(); MemoryWrite(Y); break; // STY (absolute) - case 0x8d: AbsoluteAddress(); MemoryWrite(A); break; // STA (absolute) - case 0x8e: AbsoluteAddress(); MemoryWrite(X); break; // STX (absolute) + case 0x81: this.IndexedIndirectXAddress(); this.MemoryWrite(this.A); break; // STA (indexed indirect X) + case 0x82: this.ImmediateRead(); break; // *NOP (immediate) + case 0x84: this.ZeroPageAddress(); this.MemoryWrite(this.Y); break; // STY (zero page) + case 0x85: this.ZeroPageAddress(); this.MemoryWrite(this.A); break; // STA (zero page) + case 0x86: this.ZeroPageAddress(); this.MemoryWrite(this.X); break; // STX (zero page) + case 0x88: this.SwallowRead(); this.Y = this.DEC(this.Y); break; // DEY (implied) + case 0x8a: this.SwallowRead(); this.A = this.Through(this.X); break; // TXA (implied) + case 0x8c: this.AbsoluteAddress(); this.MemoryWrite(this.Y); break; // STY (absolute) + case 0x8d: this.AbsoluteAddress(); this.MemoryWrite(this.A); break; // STA (absolute) + case 0x8e: this.AbsoluteAddress(); this.MemoryWrite(this.X); break; // STX (absolute) - case 0x90: BranchNot(Carry); break; // BCC (relative) - case 0x91: IndirectIndexedYAddress(); Fixup(); MemoryWrite(A); break; // STA (indirect indexed Y) - case 0x94: ZeroPageXAddress(); MemoryWrite(Y); break; // STY (zero page, X) - case 0x95: ZeroPageXAddress(); MemoryWrite(A); break; // STA (zero page, X) - case 0x96: ZeroPageYAddress(); MemoryWrite(X); break; // STX (zero page, Y) - case 0x98: SwallowRead(); A = Through(Y); break; // TYA (implied) - case 0x99: AbsoluteYAddress(); Fixup(); MemoryWrite(A); break; // STA (absolute, Y) - case 0x9a: SwallowRead(); S = X; break; // TXS (implied) - case 0x9d: AbsoluteXAddress(); Fixup(); MemoryWrite(A); break; // STA (absolute, X) + case 0x90: this.BranchNot(this.Carry); break; // BCC (relative) + case 0x91: this.IndirectIndexedYAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (indirect indexed Y) + case 0x94: this.ZeroPageXAddress(); this.MemoryWrite(this.Y); break; // STY (zero page, X) + case 0x95: this.ZeroPageXAddress(); this.MemoryWrite(this.A); break; // STA (zero page, X) + case 0x96: this.ZeroPageYAddress(); this.MemoryWrite(this.X); break; // STX (zero page, Y) + case 0x98: this.SwallowRead(); this.A = this.Through(this.Y); break; // TYA (implied) + case 0x99: this.AbsoluteYAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (absolute, Y) + case 0x9a: this.SwallowRead(); this.S = this.X; break; // TXS (implied) + case 0x9d: this.AbsoluteXAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (absolute, X) - case 0xa0: ImmediateRead(); Y = Through(); break; // LDY (immediate) - case 0xa1: IndexedIndirectXRead(); A = Through(); break; // LDA (indexed indirect X) - case 0xa2: ImmediateRead(); X = Through(); break; // LDX (immediate) - case 0xa4: ZeroPageRead(); Y = Through(); break; // LDY (zero page) - case 0xa5: ZeroPageRead(); A = Through(); break; // LDA (zero page) - case 0xa6: ZeroPageRead(); X = Through(); break; // LDX (zero page) - case 0xa8: SwallowRead(); Y = Through(A); break; // TAY (implied) - case 0xa9: ImmediateRead(); A = Through(); break; // LDA (immediate) - case 0xaa: SwallowRead(); X = Through(A); break; // TAX (implied) - case 0xac: AbsoluteRead(); Y = Through(); break; // LDY (absolute) - case 0xad: AbsoluteRead(); A = Through(); break; // LDA (absolute) - case 0xae: AbsoluteRead(); X = Through(); break; // LDX (absolute) + case 0xa0: this.ImmediateRead(); this.Y = this.Through(); break; // LDY (immediate) + case 0xa1: this.IndexedIndirectXRead(); this.A = this.Through(); break; // LDA (indexed indirect X) + case 0xa2: this.ImmediateRead(); this.X = this.Through(); break; // LDX (immediate) + case 0xa4: this.ZeroPageRead(); this.Y = this.Through(); break; // LDY (zero page) + case 0xa5: this.ZeroPageRead(); this.A = this.Through(); break; // LDA (zero page) + case 0xa6: this.ZeroPageRead(); this.X = this.Through(); break; // LDX (zero page) + case 0xa8: this.SwallowRead(); this.Y = this.Through(this.A); break; // TAY (implied) + case 0xa9: this.ImmediateRead(); this.A = this.Through(); break; // LDA (immediate) + case 0xaa: this.SwallowRead(); this.X = this.Through(this.A); break; // TAX (implied) + case 0xac: this.AbsoluteRead(); this.Y = this.Through(); break; // LDY (absolute) + case 0xad: this.AbsoluteRead(); this.A = this.Through(); break; // LDA (absolute) + case 0xae: this.AbsoluteRead(); this.X = this.Through(); break; // LDX (absolute) - case 0xb0: Branch(Carry); break; // BCS (relative) - case 0xb1: IndirectIndexedYRead(); A = Through(); break; // LDA (indirect indexed Y) - case 0xb4: ZeroPageXRead(); Y = Through(); break; // LDY (zero page, X) - case 0xb5: ZeroPageXRead(); A = Through(); break; // LDA (zero page, X) - case 0xb6: ZeroPageYRead(); X = Through(); break; // LDX (zero page, Y) - case 0xb8: SwallowRead(); ResetFlag(StatusBits.VF); break; // CLV (implied) - case 0xb9: AbsoluteYRead(); A = Through(); break; // LDA (absolute, Y) - case 0xba: SwallowRead(); X = Through(S); break; // TSX (implied) - case 0xbc: AbsoluteXRead(); Y = Through(); break; // LDY (absolute, X) - case 0xbd: AbsoluteXRead(); A = Through(); break; // LDA (absolute, X) - case 0xbe: AbsoluteYRead(); X = Through(); break; // LDX (absolute, Y) + case 0xb0: this.Branch(this.Carry); break; // BCS (relative) + case 0xb1: this.IndirectIndexedYRead(); this.A = this.Through(); break; // LDA (indirect indexed Y) + case 0xb4: this.ZeroPageXRead(); this.Y = this.Through(); break; // LDY (zero page, X) + case 0xb5: this.ZeroPageXRead(); this.A = this.Through(); break; // LDA (zero page, X) + case 0xb6: this.ZeroPageYRead(); this.X = this.Through(); break; // LDX (zero page, Y) + case 0xb8: this.SwallowRead(); this.ResetFlag(StatusBits.VF); break; // CLV (implied) + case 0xb9: this.AbsoluteYRead(); this.A = this.Through(); break; // LDA (absolute, Y) + case 0xba: this.SwallowRead(); this.X = this.Through(this.S); break; // TSX (implied) + case 0xbc: this.AbsoluteXRead(); this.Y = this.Through(); break; // LDY (absolute, X) + case 0xbd: this.AbsoluteXRead(); this.A = this.Through(); break; // LDA (absolute, X) + case 0xbe: this.AbsoluteYRead(); this.X = this.Through(); break; // LDX (absolute, Y) - case 0xc0: ImmediateRead(); CMP(Y); break; // CPY (immediate) - case 0xc1: IndexedIndirectXRead(); CMP(A); break; // CMP (indexed indirect X) - case 0xc2: ImmediateRead(); break; // *NOP (immediate) - case 0xc4: ZeroPageRead(); CMP(Y); break; // CPY (zero page) - case 0xc5: ZeroPageRead(); CMP(A); break; // CMP (zero page) - case 0xc6: ZeroPageRead(); ModifyWrite(DEC()); break; // DEC (zero page) - case 0xc8: SwallowRead(); Y = INC(Y); break; // INY (implied) - case 0xc9: ImmediateRead(); CMP(A); break; // CMP (immediate) - case 0xca: SwallowRead(); X = DEC(X); break; // DEX (implied) - case 0xcc: AbsoluteRead(); CMP(Y); break; // CPY (absolute) - case 0xcd: AbsoluteRead(); CMP(A); break; // CMP (absolute) - case 0xce: AbsoluteRead(); ModifyWrite(DEC()); break; // DEC (absolute) + case 0xc0: this.ImmediateRead(); this.CMP(this.Y); break; // CPY (immediate) + case 0xc1: this.IndexedIndirectXRead(); this.CMP(this.A); break; // CMP (indexed indirect X) + case 0xc2: this.ImmediateRead(); break; // *NOP (immediate) + case 0xc4: this.ZeroPageRead(); this.CMP(this.Y); break; // CPY (zero page) + case 0xc5: this.ZeroPageRead(); this.CMP(this.A); break; // CMP (zero page) + case 0xc6: this.ZeroPageRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page) + case 0xc8: this.SwallowRead(); this.Y = this.INC(this.Y); break; // INY (implied) + case 0xc9: this.ImmediateRead(); this.CMP(this.A); break; // CMP (immediate) + case 0xca: this.SwallowRead(); this.X = this.DEC(this.X); break; // DEX (implied) + case 0xcc: this.AbsoluteRead(); this.CMP(this.Y); break; // CPY (absolute) + case 0xcd: this.AbsoluteRead(); this.CMP(this.A); break; // CMP (absolute) + case 0xce: this.AbsoluteRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute) - case 0xd0: BranchNot(Zero); break; // BNE (relative) - case 0xd1: IndirectIndexedYRead(); CMP(A); break; // CMP (indirect indexed Y) - case 0xd4: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0xd5: ZeroPageXRead(); CMP(A); break; // CMP (zero page, X) - case 0xd6: ZeroPageXRead(); ModifyWrite(DEC()); break; // DEC (zero page, X) - case 0xd8: SwallowRead(); ResetFlag(StatusBits.DF); break; // CLD (implied) - case 0xd9: AbsoluteYRead(); CMP(A); break; // CMP (absolute, Y) - case 0xdd: AbsoluteXRead(); CMP(A); break; // CMP (absolute, X) - case 0xde: AbsoluteXAddress(); FixupRead(); ModifyWrite(DEC()); break; // DEC (absolute, X) + case 0xd0: this.BranchNot(this.Zero); break; // BNE (relative) + case 0xd1: this.IndirectIndexedYRead(); this.CMP(this.A); break; // CMP (indirect indexed Y) + case 0xd4: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0xd5: this.ZeroPageXRead(); this.CMP(this.A); break; // CMP (zero page, X) + case 0xd6: this.ZeroPageXRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page, X) + case 0xd8: this.SwallowRead(); this.ResetFlag(StatusBits.DF); break; // CLD (implied) + case 0xd9: this.AbsoluteYRead(); this.CMP(this.A); break; // CMP (absolute, Y) + case 0xdd: this.AbsoluteXRead(); this.CMP(this.A); break; // CMP (absolute, X) + case 0xde: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute, X) - case 0xe0: ImmediateRead(); CMP(X); break; // CPX (immediate) - case 0xe1: IndexedIndirectXRead(); SBC(); break; // SBC (indexed indirect X) - case 0xe2: ImmediateRead(); break; // *NOP (immediate) - case 0xe4: ZeroPageRead(); CMP(X); break; // CPX (zero page) - case 0xe5: ZeroPageRead(); SBC(); break; // SBC (zero page) - case 0xe6: ZeroPageRead(); ModifyWrite(INC()); break; // INC (zero page) - case 0xe8: SwallowRead(); X = INC(X); break; // INX (implied) - case 0xe9: ImmediateRead(); SBC(); break; // SBC (immediate) - case 0xea: SwallowRead(); break; // NOP (implied) - case 0xec: AbsoluteRead(); CMP(X); break; // CPX (absolute) - case 0xed: AbsoluteRead(); SBC(); break; // SBC (absolute) - case 0xee: AbsoluteRead(); ModifyWrite(INC()); break; // INC (absolute) + case 0xe0: this.ImmediateRead(); this.CMP(this.X); break; // CPX (immediate) + case 0xe1: this.IndexedIndirectXRead(); this.SBC(); break; // SBC (indexed indirect X) + case 0xe2: this.ImmediateRead(); break; // *NOP (immediate) + case 0xe4: this.ZeroPageRead(); this.CMP(this.X); break; // CPX (zero page) + case 0xe5: this.ZeroPageRead(); this.SBC(); break; // SBC (zero page) + case 0xe6: this.ZeroPageRead(); this.ModifyWrite(this.INC()); break; // INC (zero page) + case 0xe8: this.SwallowRead(); this.X = this.INC(this.X); break; // INX (implied) + case 0xe9: this.ImmediateRead(); this.SBC(); break; // SBC (immediate) + case 0xea: this.SwallowRead(); break; // NOP (implied) + case 0xec: this.AbsoluteRead(); this.CMP(this.X); break; // CPX (absolute) + case 0xed: this.AbsoluteRead(); this.SBC(); break; // SBC (absolute) + case 0xee: this.AbsoluteRead(); this.ModifyWrite(this.INC()); break; // INC (absolute) - case 0xf0: Branch(Zero); break; // BEQ (relative) - case 0xf1: IndirectIndexedYRead(); SBC(); break; // SBC (indirect indexed Y) - case 0xf4: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0xf5: ZeroPageXRead(); SBC(); break; // SBC (zero page, X) - case 0xf6: ZeroPageXRead(); ModifyWrite(INC()); break; // INC (zero page, X) - case 0xf8: SwallowRead(); SetFlag(StatusBits.DF); break; // SED (implied) - case 0xf9: AbsoluteYRead(); SBC(); break; // SBC (absolute, Y) - case 0xfd: AbsoluteXRead(); SBC(); break; // SBC (absolute, X) - case 0xfe: AbsoluteXAddress(); FixupRead(); ModifyWrite(INC()); break; // INC (absolute, X) + case 0xf0: this.Branch(this.Zero); break; // BEQ (relative) + case 0xf1: this.IndirectIndexedYRead(); this.SBC(); break; // SBC (indirect indexed Y) + case 0xf4: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0xf5: this.ZeroPageXRead(); this.SBC(); break; // SBC (zero page, X) + case 0xf6: this.ZeroPageXRead(); this.ModifyWrite(this.INC()); break; // INC (zero page, X) + case 0xf8: this.SwallowRead(); this.SetFlag(StatusBits.DF); break; // SED (implied) + case 0xf9: this.AbsoluteYRead(); this.SBC(); break; // SBC (absolute, Y) + case 0xfd: this.AbsoluteXRead(); this.SBC(); break; // SBC (absolute, X) + case 0xfe: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.INC()); break; // INC (absolute, X) + + default: + break; } - return cycles != Cycles; + return cycles != this.Cycles; } public override void PoweredStep() { - Tick(); - if (SO.Lowered()) + this.Tick(); + if (this.SO.Lowered()) { - HandleSO(); + this.HandleSO(); } - if (RDY.Raised()) + if (this.RDY.Raised()) { - FetchInstruction(); - if (RESET.Lowered()) + this.FetchInstruction(); + if (this.RESET.Lowered()) { - HandleRESET(); + this.HandleRESET(); } - else if (NMI.Lowered()) + else if (this.NMI.Lowered()) { - HandleNMI(); + this.HandleNMI(); } - else if (INT.Lowered() && InterruptMasked == 0) + else if (this.INT.Lowered() && this.InterruptMasked == 0) { - HandleINT(); + this.HandleINT(); } else { - Execute(); + this.Execute(); } } } @@ -567,45 +552,45 @@ namespace M6502 private void FetchInstruction() { // Instruction fetch beginning - LowerSYNC(); + this.LowerSYNC(); - System.Diagnostics.Debug.Assert(Cycles == 1, "An extra cycle has occurred"); + System.Diagnostics.Debug.Assert(this.Cycles == 1, "An extra cycle has occurred"); // Can't use fetchByte, since that would add an extra tick. - ImmediateAddress(); - OpCode = ReadFromBus(); + this.ImmediateAddress(); + this.OpCode = this.ReadFromBus(); - System.Diagnostics.Debug.Assert(Cycles == 1, "BUS read has introduced stray cycles"); + System.Diagnostics.Debug.Assert(this.Cycles == 1, "BUS read has introduced stray cycles"); // Instruction fetch has now completed - RaiseSYNC(); + this.RaiseSYNC(); } #endregion #region Bus/Memory access - protected override sealed void BusWrite() + protected sealed override void BusWrite() { - Tick(); - WriteToBus(); + this.Tick(); + this.WriteToBus(); } - protected override sealed byte BusRead() + protected sealed override byte BusRead() { - Tick(); - return ReadFromBus(); + this.Tick(); + return this.ReadFromBus(); } private byte ReadFromBus() { - RaiseRW(); + this.RaiseRW(); return base.BusRead(); } private void WriteToBus() { - LowerRW(); + this.LowerRW(); base.BusWrite(); } @@ -617,29 +602,26 @@ namespace M6502 protected override byte Pop() { - RaiseStack(); - return MemoryRead(); + this.RaiseStack(); + return this.MemoryRead(); } protected override void Push(byte value) { - LowerStack(); - MemoryWrite(value); + this.LowerStack(); + this.MemoryWrite(value); } - private void UpdateStack(byte position) - { - Bus.Address.Assign(position, 1); - } + private void UpdateStack(byte position) => this.Bus.Address.Assign(position, 1); - private void LowerStack() => UpdateStack(S--); + private void LowerStack() => this.UpdateStack(this.S--); - private void RaiseStack() => UpdateStack(++S); + private void RaiseStack() => this.UpdateStack(++this.S); private void DummyPush() { - LowerStack(); - Tick(); // In place of the memory write + this.LowerStack(); + this.Tick(); // In place of the memory write } #endregion @@ -648,29 +630,17 @@ namespace M6502 #region Address page fixup - private byte fixedPage; + public byte FixedPage { get; protected set; } - private byte unfixedPage; + public byte UnfixedPage { get; protected set; } - public byte FixedPage - { - get => fixedPage; - protected set => fixedPage = value; - } - - public byte UnfixedPage - { - get => unfixedPage; - protected set => unfixedPage = value; - } - - public bool Fixed => FixedPage != UnfixedPage; + public bool Fixed => this.FixedPage != this.UnfixedPage; protected void MaybeFixup() { - if (Bus.Address.High != FixedPage) + if (this.Bus.Address.High != this.FixedPage) { - Fixup(); + this.Fixup(); } } @@ -678,90 +648,84 @@ namespace M6502 protected void MaybeFixupRead() { - MaybeFixup(); - MemoryRead(); + this.MaybeFixup(); + _ = this.MemoryRead(); } protected void FixupRead() { - Fixup(); - MemoryRead(); + this.Fixup(); + _ = this.MemoryRead(); } #endregion #region Address resolution - protected void NoteFixedAddress(int address) - { - NoteFixedAddress((ushort)address); - } + protected void NoteFixedAddress(int address) => this.NoteFixedAddress((ushort)address); protected void NoteFixedAddress(ushort address) { - UnfixedPage = Bus.Address.High; - Intermediate.Word = address; - FixedPage = Intermediate.High; - Bus.Address.Low = Intermediate.Low; + this.UnfixedPage = this.Bus.Address.High; + this.Intermediate.Word = address; + this.FixedPage = this.Intermediate.High; + this.Bus.Address.Low = this.Intermediate.Low; } protected void GetAddressPaged() { - GetWordPaged(); - Bus.Address.Assign(Intermediate); + _ = this.GetWordPaged(); + this.Bus.Address.Assign(this.Intermediate); } protected void ImmediateAddress() { - Bus.Address.Assign(PC); - ++PC.Word; + this.Bus.Address.Assign(this.PC); + ++this.PC.Word; } - protected void AbsoluteAddress() => FetchWordAddress(); + protected void AbsoluteAddress() => this.FetchWordAddress(); - protected void ZeroPageAddress() - { - Bus.Address.Assign(FetchByte(), 0); - } + protected void ZeroPageAddress() => this.Bus.Address.Assign(this.FetchByte(), 0); protected void ZeroPageIndirectAddress() { - ZeroPageAddress(); - GetAddressPaged(); + this.ZeroPageAddress(); + this.GetAddressPaged(); } protected abstract void IndirectAddress(); protected void ZeroPageWithIndexAddress(byte index) { - ZeroPageRead(); - Bus.Address.Low += index; + this.ZeroPageRead(); + this.Bus.Address.Low += index; } - protected void ZeroPageXAddress() => ZeroPageWithIndexAddress(X); + protected void ZeroPageXAddress() => this.ZeroPageWithIndexAddress(this.X); - protected void ZeroPageYAddress() => ZeroPageWithIndexAddress(Y); + protected void ZeroPageYAddress() => this.ZeroPageWithIndexAddress(this.Y); private void AbsoluteWithIndexAddress(byte index) { - AbsoluteAddress(); - NoteFixedAddress(Bus.Address.Word + index); + this.AbsoluteAddress(); + this.NoteFixedAddress(this.Bus.Address.Word + index); } - protected void AbsoluteXAddress() => AbsoluteWithIndexAddress(X); + protected void AbsoluteXAddress() => this.AbsoluteWithIndexAddress(this.X); - protected void AbsoluteYAddress() => AbsoluteWithIndexAddress(Y); + protected void AbsoluteYAddress() => this.AbsoluteWithIndexAddress(this.Y); protected void IndexedIndirectXAddress() { - ZeroPageXAddress(); - GetAddressPaged(); + this.ZeroPageXAddress(); + this.GetAddressPaged(); } protected void IndirectIndexedYAddress() { - ZeroPageIndirectAddress(); - NoteFixedAddress(Bus.Address.Word + Y); + this.ZeroPageIndirectAddress(); + this.NoteFixedAddress(this.Bus.Address.Word + this.Y); } #endregion @@ -770,56 +734,56 @@ namespace M6502 protected void ImmediateRead() { - ImmediateAddress(); - MemoryRead(); + this.ImmediateAddress(); + _ = this.MemoryRead(); } protected void AbsoluteRead() { - AbsoluteAddress(); - MemoryRead(); + this.AbsoluteAddress(); + _ = this.MemoryRead(); } protected void ZeroPageRead() { - ZeroPageAddress(); - MemoryRead(); + this.ZeroPageAddress(); + _ = this.MemoryRead(); } protected void ZeroPageXRead() { - ZeroPageXAddress(); - MemoryRead(); + this.ZeroPageXAddress(); + _ = this.MemoryRead(); } protected void ZeroPageYRead() { - ZeroPageYAddress(); - MemoryRead(); + this.ZeroPageYAddress(); + _ = this.MemoryRead(); } protected void IndexedIndirectXRead() { - IndexedIndirectXAddress(); - MemoryRead(); + this.IndexedIndirectXAddress(); + _ = this.MemoryRead(); } protected void AbsoluteXRead() { - AbsoluteXAddress(); - MaybeFixupRead(); + this.AbsoluteXAddress(); + this.MaybeFixupRead(); } protected void AbsoluteYRead() { - AbsoluteYAddress(); - MaybeFixupRead(); + this.AbsoluteYAddress(); + this.MaybeFixupRead(); } protected void IndirectIndexedYRead() { - IndirectIndexedYAddress(); - MaybeFixupRead(); + this.IndirectIndexedYAddress(); + this.MaybeFixupRead(); } #endregion @@ -828,19 +792,19 @@ namespace M6502 #region Branching - protected void BranchNot(int condition) => Branch(condition == 0); + protected void BranchNot(int condition) => this.Branch(condition == 0); - protected void Branch(int condition) => Branch(condition != 0); + protected void Branch(int condition) => this.Branch(condition != 0); protected void Branch(bool condition) { - ImmediateRead(); + this.ImmediateRead(); if (condition) { - var relative = (sbyte)Bus.Data; - SwallowRead(); - FixupBranch(relative); - Jump(Bus.Address); + var relative = (sbyte)this.Bus.Data; + this.SwallowRead(); + this.FixupBranch(relative); + this.Jump(this.Bus.Address); } } @@ -850,23 +814,23 @@ namespace M6502 #region Data flag adjustment - protected void AdjustZero(byte datum) => ResetFlag(StatusBits.ZF, datum); + protected void AdjustZero(byte datum) => this.ResetFlag(StatusBits.ZF, datum); - protected void AdjustNegative(byte datum) => SetFlag(StatusBits.NF, NegativeTest(datum)); + protected void AdjustNegative(byte datum) => this.SetFlag(StatusBits.NF, NegativeTest(datum)); protected void AdjustNZ(byte datum) { - AdjustZero(datum); - AdjustNegative(datum); + this.AdjustZero(datum); + this.AdjustNegative(datum); } - protected byte Through() => Through(Bus.Data); + protected byte Through() => this.Through(this.Bus.Data); - protected byte Through(int data) => Through((byte)data); + protected byte Through(int data) => this.Through((byte)data); protected byte Through(byte data) { - AdjustNZ(data); + this.AdjustNZ(data); return data; } @@ -882,35 +846,35 @@ namespace M6502 protected void AdjustOverflowSubtract(byte operand) { - var data = Bus.Data; - var intermediate = Intermediate.Low; - SetFlag(StatusBits.VF, NegativeTest((byte)((operand ^ data) & (operand ^ intermediate)))); + var data = this.Bus.Data; + var intermediate = this.Intermediate.Low; + this.SetFlag(StatusBits.VF, NegativeTest((byte)((operand ^ data) & (operand ^ intermediate)))); } protected void SBC() { - var operand = A; - A = SUB(operand, CarryTest((byte)~P)); + var operand = this.A; + this.A = this.SUB(operand, CarryTest((byte)~this.P)); - AdjustOverflowSubtract(operand); - AdjustNZ(Intermediate.Low); - ResetFlag(StatusBits.CF, Intermediate.High); + this.AdjustOverflowSubtract(operand); + this.AdjustNZ(this.Intermediate.Low); + this.ResetFlag(StatusBits.CF, this.Intermediate.High); } - private byte SUB(byte operand, int borrow) => DecimalMasked != 0 ? DecimalSUB(operand, borrow) : BinarySUB(operand, borrow); + private byte SUB(byte operand, int borrow) => this.DecimalMasked != 0 ? this.DecimalSUB(operand, borrow) : this.BinarySUB(operand, borrow); protected byte BinarySUB(byte operand, int borrow = 0) { - var data = Bus.Data; - Intermediate.Word = (ushort)(operand - data - borrow); - return Intermediate.Low; + var data = this.Bus.Data; + this.Intermediate.Word = (ushort)(operand - data - borrow); + return this.Intermediate.Low; } private byte DecimalSUB(byte operand, int borrow) { - _ = BinarySUB(operand, borrow); + _ = this.BinarySUB(operand, borrow); - var data = Bus.Data; + var data = this.Bus.Data; var low = (byte)(LowNibble(operand) - LowNibble(data) - borrow); var lowNegative = NegativeTest(low); if (lowNegative != 0) @@ -934,55 +898,54 @@ namespace M6502 protected void AdjustOverflowAdd(byte operand) { - var data = Bus.Data; - var intermediate = Intermediate.Low; - SetFlag(StatusBits.VF, NegativeTest((byte)(~(operand ^ data) & (operand ^ intermediate)))); + var data = this.Bus.Data; + var intermediate = this.Intermediate.Low; + this.SetFlag(StatusBits.VF, NegativeTest((byte)(~(operand ^ data) & (operand ^ intermediate)))); } - protected void ADC() - { - A = DecimalMasked != 0 ? DecimalADC() : BinaryADC(); - } + protected void ADC() => this.A = this.DecimalMasked != 0 ? this.DecimalADC() : this.BinaryADC(); private byte BinaryADC() { - var operand = A; - var data = Bus.Data; - Intermediate.Word = (ushort)(operand + data + Carry); + var operand = this.A; + var data = this.Bus.Data; + this.Intermediate.Word = (ushort)(operand + data + this.Carry); - AdjustOverflowAdd(operand); - SetFlag(StatusBits.CF, CarryTest(Intermediate.High)); + this.AdjustOverflowAdd(operand); + this.SetFlag(StatusBits.CF, CarryTest(this.Intermediate.High)); - AdjustNZ(Intermediate.Low); + this.AdjustNZ(this.Intermediate.Low); - return Intermediate.Low; + return this.Intermediate.Low; } private byte DecimalADC() { - var operand = A; - var data = Bus.Data; + var operand = this.A; + var data = this.Bus.Data; - var low = (ushort)(LowerNibble(operand) + LowerNibble(data) + Carry); - Intermediate.Word = (ushort)(HigherNibble(operand) + HigherNibble(data)); + var low = (ushort)(LowerNibble(operand) + LowerNibble(data) + this.Carry); + this.Intermediate.Word = (ushort)(HigherNibble(operand) + HigherNibble(data)); - AdjustZero(LowByte((ushort)(low + Intermediate.Word))); + this.AdjustZero(LowByte((ushort)(low + this.Intermediate.Word))); if (low > 0x09) { - Intermediate.Word += 0x10; + this.Intermediate.Word += 0x10; low += 0x06; } - AdjustNegative(Intermediate.Low); - AdjustOverflowAdd(operand); + this.AdjustNegative(this.Intermediate.Low); + this.AdjustOverflowAdd(operand); - if (Intermediate.Word > 0x90) - Intermediate.Word += 0x60; + if (this.Intermediate.Word > 0x90) + { + this.Intermediate.Word += 0x60; + } - SetFlag(StatusBits.CF, Intermediate.High); + this.SetFlag(StatusBits.CF, this.Intermediate.High); - return (byte)(LowerNibble(LowByte(low)) | HigherNibble(Intermediate.Low)); + return (byte)(LowerNibble(LowByte(low)) | HigherNibble(this.Intermediate.Low)); } #endregion @@ -993,39 +956,39 @@ namespace M6502 #region Bitwise operations - protected void OrR() => A = Through(A | Bus.Data); + protected void OrR() => this.A = this.Through(this.A | this.Bus.Data); - protected void AndR() => A = Through(A & Bus.Data); + protected void AndR() => this.A = this.Through(this.A & this.Bus.Data); - protected void EorR() => A = Through(A ^ Bus.Data); + protected void EorR() => this.A = this.Through(this.A ^ this.Bus.Data); protected void BIT() { - var data = Bus.Data; - SetFlag(StatusBits.VF, OverflowTest(data)); - AdjustZero((byte)(A & data)); - AdjustNegative(data); + var data = this.Bus.Data; + this.SetFlag(StatusBits.VF, OverflowTest(data)); + this.AdjustZero((byte)(this.A & data)); + this.AdjustNegative(data); } #endregion protected void CMP(byte first) { - var second = Bus.Data; - Intermediate.Word = (ushort)(first - second); - AdjustNZ(Intermediate.Low); - ResetFlag(StatusBits.CF, Intermediate.High); + var second = this.Bus.Data; + this.Intermediate.Word = (ushort)(first - second); + this.AdjustNZ(this.Intermediate.Low); + this.ResetFlag(StatusBits.CF, this.Intermediate.High); } #region Increment/decrement - protected byte DEC() => DEC(Bus.Data); + protected byte DEC() => this.DEC(this.Bus.Data); - protected byte DEC(byte value) => Through(value - 1); + protected byte DEC(byte value) => this.Through(value - 1); - protected byte INC() => INC(Bus.Data); + protected byte INC() => this.INC(this.Bus.Data); - protected byte INC(byte value) => Through(value + 1); + protected byte INC(byte value) => this.Through(value + 1); #endregion @@ -1033,32 +996,32 @@ namespace M6502 private void JSR() { - Intermediate.Low = FetchByte(); - SwallowPop(); - PushWord(PC); - PC.High = FetchByte(); - PC.Low = Intermediate.Low; + this.Intermediate.Low = this.FetchByte(); + this.SwallowPop(); + this.PushWord(this.PC); + this.PC.High = this.FetchByte(); + this.PC.Low = this.Intermediate.Low; } - private void PHP() => Push(SetBit(P, StatusBits.BF)); + private void PHP() => this.Push(SetBit(this.P, StatusBits.BF)); private void PLP() { - SwallowPop(); - P = ClearBit(SetBit(Pop(), StatusBits.RF), StatusBits.BF); + this.SwallowPop(); + this.P = ClearBit(SetBit(this.Pop(), StatusBits.RF), StatusBits.BF); } private void RTI() { - PLP(); + this.PLP(); base.Return(); } protected override void Return() { - SwallowPop(); + this.SwallowPop(); base.Return(); - SwallowFetch(); + this.SwallowFetch(); } #endregion @@ -1067,40 +1030,40 @@ namespace M6502 #region Shift - protected byte ASL() => ASL(Bus.Data); + protected byte ASL() => this.ASL(this.Bus.Data); protected byte ASL(byte value) { - SetFlag(StatusBits.CF, NegativeTest(value)); - return Through(value << 1); + this.SetFlag(StatusBits.CF, NegativeTest(value)); + return this.Through(value << 1); } - protected byte LSR() => LSR(Bus.Data); + protected byte LSR() => this.LSR(this.Bus.Data); protected byte LSR(byte value) { - SetFlag(StatusBits.CF, CarryTest(value)); - return Through(value >> 1); + this.SetFlag(StatusBits.CF, CarryTest(value)); + return this.Through(value >> 1); } #endregion #region Rotate - protected byte ROL() => ROL(Bus.Data); + protected byte ROL() => this.ROL(this.Bus.Data); protected byte ROL(byte value) { - var carryIn = Carry; - return Through(ASL(value) | carryIn); + var carryIn = this.Carry; + return this.Through(this.ASL(value) | carryIn); } - protected byte ROR() => ROR(Bus.Data); + protected byte ROR() => this.ROR(this.Bus.Data); protected byte ROR(byte value) { - var carryIn = Carry; - return Through(LSR(value) | carryIn << 7); + var carryIn = this.Carry; + return this.Through(this.LSR(value) | (carryIn << 7)); } #endregion diff --git a/M6502/Disassembler.cs b/M6502/Disassembler.cs index 99dd147..7877271 100644 --- a/M6502/Disassembler.cs +++ b/M6502/Disassembler.cs @@ -4,9 +4,9 @@ namespace M6502 { + using EightBit; using System.Globalization; using System.Text; - using EightBit; public class Disassembler(Bus bus, Core processor, Symbols.Parser symbols) { @@ -35,16 +35,16 @@ namespace M6502 public string Disassemble(ushort current) { - address = current; + this.address = current; var output = new StringBuilder(); - var cell = bus.Peek(current); + var cell = this.bus.Peek(current); output.Append(DumpByteValue(cell)); output.Append(' '); - var next = bus.Peek((ushort)(current + 1)); + var next = this.bus.Peek((ushort)(current + 1)); var relative = (ushort)(current + 2 + (sbyte)next); var aaa = (cell & 0b11100000) >> 5; @@ -60,28 +60,28 @@ namespace M6502 switch (bbb) { case 0b000: // BRK - output.Append(Disassemble_Implied("BRK")); + output.Append(this.Disassemble_Implied("BRK")); break; case 0b001: // DOP/NOP (0x04) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b010: // PHP - output.Append(Disassemble_Implied("PHP")); + output.Append(this.Disassemble_Implied("PHP")); break; case 0b011: // TOP/NOP (0b00001100, 0x0c) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b100: // BPL - output.Append(Disassemble_Relative("BPL", relative)); + output.Append(this.Disassemble_Relative("BPL", relative)); break; case 0b101: // DOP/NOP (0x14) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // CLC - output.Append(Disassemble_Implied("CLC")); + output.Append(this.Disassemble_Implied("CLC")); break; case 0b111: // TOP/NOP (0b00011100, 0x1c) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: throw new InvalidOperationException("Illegal instruction"); @@ -92,25 +92,25 @@ namespace M6502 switch (bbb) { case 0b000: // JSR - output.Append(Disassemble_Absolute("JSR")); + output.Append(this.Disassemble_Absolute("JSR")); break; case 0b010: // PLP - output.Append(Disassemble_Implied("PLP")); + output.Append(this.Disassemble_Implied("PLP")); break; case 0b100: // BMI - output.Append(Disassemble_Relative("BMI", relative)); + output.Append(this.Disassemble_Relative("BMI", relative)); break; case 0b101: // DOP/NOP (0x34) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // SEC - output.Append(Disassemble_Implied("SEC")); + output.Append(this.Disassemble_Implied("SEC")); break; case 0b111: // TOP/NOP (0b00111100, 0x3c) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: // BIT - output.Append(Disassemble_AM_00(bbb, "BIT")); + output.Append(this.Disassemble_AM_00(bbb, "BIT")); break; } @@ -119,28 +119,28 @@ namespace M6502 switch (bbb) { case 0b000: // RTI - output.Append(Disassemble_Implied("RTI")); + output.Append(this.Disassemble_Implied("RTI")); break; case 0b001: // DOP/NOP (0x44) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b010: // PHA - output.Append(Disassemble_Implied("PHA")); + output.Append(this.Disassemble_Implied("PHA")); break; case 0b011: // JMP - output.Append(Disassemble_Absolute("JMP")); + output.Append(this.Disassemble_Absolute("JMP")); break; case 0b100: // BVC - output.Append(Disassemble_Relative("BVC", relative)); + output.Append(this.Disassemble_Relative("BVC", relative)); break; case 0b101: // DOP/NOP (0x54) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // CLI - output.Append(Disassemble_Implied("CLI")); + output.Append(this.Disassemble_Implied("CLI")); break; case 0b111: // TOP/NOP (0b01011100, 0x5c) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: throw new InvalidOperationException("Illegal addressing mode"); @@ -151,28 +151,28 @@ namespace M6502 switch (bbb) { case 0b000: // RTS - output.Append(Disassemble_Implied("RTS")); + output.Append(this.Disassemble_Implied("RTS")); break; case 0b001: // DOP/NOP (0x64) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b010: // PLA - output.Append(Disassemble_Implied("PLA")); + output.Append(this.Disassemble_Implied("PLA")); break; case 0b011: // JMP (abs) - output.Append(Disassemble_Indirect("JMP")); + output.Append(this.Disassemble_Indirect("JMP")); break; case 0b100: // BVS - output.Append(Disassemble_Relative("BVS", relative)); + output.Append(this.Disassemble_Relative("BVS", relative)); break; case 0b101: // DOP/NOP (0x74) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // SEI - output.Append(Disassemble_Implied("SEI")); + output.Append(this.Disassemble_Implied("SEI")); break; case 0b111: // TOP/NOP (0b01111100, 0x7c) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: throw new InvalidOperationException("Illegal addressing mode"); @@ -183,19 +183,19 @@ namespace M6502 switch (bbb) { case 0b000: // DOP/NOP (0x80) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b010: // DEY - output.Append(Disassemble_Implied("DEY")); + output.Append(this.Disassemble_Implied("DEY")); break; case 0b100: // BCC - output.Append(Disassemble_Relative("BCC", relative)); + output.Append(this.Disassemble_Relative("BCC", relative)); break; case 0b110: // TYA - output.Append(Disassemble_Implied("TYA")); + output.Append(this.Disassemble_Implied("TYA")); break; default: // STY - output.Append(Disassemble_AM_00(bbb, "STY")); + output.Append(this.Disassemble_AM_00(bbb, "STY")); break; } @@ -204,16 +204,16 @@ namespace M6502 switch (bbb) { case 0b010: // TAY - output.Append(Disassemble_Implied("TAY")); + output.Append(this.Disassemble_Implied("TAY")); break; case 0b100: // BCS - output.Append(Disassemble_Relative("BCS", relative)); + output.Append(this.Disassemble_Relative("BCS", relative)); break; case 0b110: // CLV - output.Append(Disassemble_Implied("CLV")); + output.Append(this.Disassemble_Implied("CLV")); break; default: // LDY - output.Append(Disassemble_AM_00(bbb, "LDY")); + output.Append(this.Disassemble_AM_00(bbb, "LDY")); break; } @@ -222,22 +222,22 @@ namespace M6502 switch (bbb) { case 0b010: // INY - output.Append(Disassemble_Implied("INY")); + output.Append(this.Disassemble_Implied("INY")); break; case 0b100: // BNE - output.Append(Disassemble_Relative("BNE", relative)); + output.Append(this.Disassemble_Relative("BNE", relative)); break; case 0b101: // DOP/NOP (0xd4) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // CLD - output.Append(Disassemble_Implied("CLD")); + output.Append(this.Disassemble_Implied("CLD")); break; case 0b111: // TOP/NOP (0b11011100, 0xdc) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: // CPY - output.Append(Disassemble_AM_00(bbb, "CPY")); + output.Append(this.Disassemble_AM_00(bbb, "CPY")); break; } @@ -246,22 +246,22 @@ namespace M6502 switch (bbb) { case 0b010: // INX - output.Append(Disassemble_Implied("INX")); + output.Append(this.Disassemble_Implied("INX")); break; case 0b100: // BEQ - output.Append(Disassemble_Relative("BEQ", relative)); + output.Append(this.Disassemble_Relative("BEQ", relative)); break; case 0b101: // DOP/NOP (0xf4) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; case 0b110: // SED - output.Append(Disassemble_Implied("SED")); + output.Append(this.Disassemble_Implied("SED")); break; case 0b111: // TOP/NOP (0b11111100, 0xfc) - output.Append(Disassemble_AM_00(bbb, "*NOP")); + output.Append(this.Disassemble_AM_00(bbb, "*NOP")); break; default: // CPX - output.Append(Disassemble_AM_00(bbb, "CPX")); + output.Append(this.Disassemble_AM_00(bbb, "CPX")); break; } @@ -273,28 +273,28 @@ namespace M6502 switch (aaa) { case 0b000: // ORA - output.Append(Disassemble_AM_01(bbb, "ORA")); + output.Append(this.Disassemble_AM_01(bbb, "ORA")); break; case 0b001: // AND - output.Append(Disassemble_AM_01(bbb, "AND")); + output.Append(this.Disassemble_AM_01(bbb, "AND")); break; case 0b010: // EOR - output.Append(Disassemble_AM_01(bbb, "EOR")); + output.Append(this.Disassemble_AM_01(bbb, "EOR")); break; case 0b011: // ADC - output.Append(Disassemble_AM_01(bbb, "ADC")); + output.Append(this.Disassemble_AM_01(bbb, "ADC")); break; case 0b100: // STA - output.Append(Disassemble_AM_01(bbb, "STA")); + output.Append(this.Disassemble_AM_01(bbb, "STA")); break; case 0b101: // LDA - output.Append(Disassemble_AM_01(bbb, "LDA")); + output.Append(this.Disassemble_AM_01(bbb, "LDA")); break; case 0b110: // CMP - output.Append(Disassemble_AM_01(bbb, "CMP")); + output.Append(this.Disassemble_AM_01(bbb, "CMP")); break; case 0b111: // SBC - output.Append(Disassemble_AM_01(bbb, "SBC")); + output.Append(this.Disassemble_AM_01(bbb, "SBC")); break; default: throw new InvalidOperationException("Illegal addressing mode"); @@ -308,10 +308,10 @@ namespace M6502 switch (bbb) { case 0b110: // 0x1a - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: - output.Append(Disassemble_AM_10(bbb, "ASL")); + output.Append(this.Disassemble_AM_10(bbb, "ASL")); break; } @@ -320,10 +320,10 @@ namespace M6502 switch (bbb) { case 0b110: // 0x3a - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: - output.Append(Disassemble_AM_10(bbb, "ROL")); + output.Append(this.Disassemble_AM_10(bbb, "ROL")); break; } @@ -332,10 +332,10 @@ namespace M6502 switch (bbb) { case 0b110: // 0x5a - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: - output.Append(Disassemble_AM_10(bbb, "LSR")); + output.Append(this.Disassemble_AM_10(bbb, "LSR")); break; } @@ -344,10 +344,10 @@ namespace M6502 switch (bbb) { case 0b110: // 0x7a - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: - output.Append(Disassemble_AM_10(bbb, "ROR")); + output.Append(this.Disassemble_AM_10(bbb, "ROR")); break; } @@ -356,13 +356,13 @@ namespace M6502 switch (bbb) { case 0b010: // TXA - output.Append(Disassemble_Implied("TXA")); + output.Append(this.Disassemble_Implied("TXA")); break; case 0b110: // TXS - output.Append(Disassemble_Implied("TXS")); + output.Append(this.Disassemble_Implied("TXS")); break; default: // STX - output.Append(Disassemble_AM_10_x(bbb, "STX")); + output.Append(this.Disassemble_AM_10_x(bbb, "STX")); break; } @@ -371,13 +371,13 @@ namespace M6502 switch (bbb) { case 0b010: // TAX - output.Append(Disassemble_Implied("TAX")); + output.Append(this.Disassemble_Implied("TAX")); break; case 0b110: // TSX - output.Append(Disassemble_Implied("TSX")); + output.Append(this.Disassemble_Implied("TSX")); break; default: // LDX - output.Append(Disassemble_AM_10_x(bbb, "LDX")); + output.Append(this.Disassemble_AM_10_x(bbb, "LDX")); break; } @@ -386,13 +386,13 @@ namespace M6502 switch (bbb) { case 0b010: // DEX - output.Append(Disassemble_Implied("DEX")); + output.Append(this.Disassemble_Implied("DEX")); break; case 0b110: // 0xda - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: // DEC - output.Append(Disassemble_AM_10(bbb, "DEC")); + output.Append(this.Disassemble_AM_10(bbb, "DEC")); break; } @@ -401,13 +401,13 @@ namespace M6502 switch (bbb) { case 0b010: // NOP - output.Append(Disassemble_Implied("NOP")); + output.Append(this.Disassemble_Implied("NOP")); break; case 0b110: // 0xfa - output.Append(Disassemble_Implied("*NOP")); + output.Append(this.Disassemble_Implied("*NOP")); break; default: // INC - output.Append(Disassemble_AM_10(bbb, "INC")); + output.Append(this.Disassemble_AM_10(bbb, "INC")); break; } @@ -424,10 +424,10 @@ namespace M6502 switch (bbb) { case 0b010: - output.Append(Disassemble_Immediate("*AAC")); + output.Append(this.Disassemble_Immediate("*AAC")); break; default: - output.Append(Disassemble_AM_01(bbb, "*SLO")); + output.Append(this.Disassemble_AM_01(bbb, "*SLO")); break; } @@ -437,28 +437,28 @@ namespace M6502 switch (bbb) { case 0b010: - output.Append(Disassemble_Immediate("*AAC")); + output.Append(this.Disassemble_Immediate("*AAC")); break; default: - output.Append(Disassemble_AM_01(bbb, "*RLA")); + output.Append(this.Disassemble_AM_01(bbb, "*RLA")); break; } break; case 0b010: - output.Append(Disassemble_AM_01(bbb, "*SRE")); + output.Append(this.Disassemble_AM_01(bbb, "*SRE")); break; case 0b011: - output.Append(Disassemble_AM_01(bbb, "*RRA")); + output.Append(this.Disassemble_AM_01(bbb, "*RRA")); break; case 0b100: - output.Append(Disassemble_AM_11(bbb, "*SAX")); + output.Append(this.Disassemble_AM_11(bbb, "*SAX")); break; case 0b101: - output.Append(Disassemble_AM_11(bbb, "*LAX")); + output.Append(this.Disassemble_AM_11(bbb, "*LAX")); break; case 0b110: - output.Append(Disassemble_AM_11_x(bbb, "*DCP")); + output.Append(this.Disassemble_AM_11_x(bbb, "*DCP")); break; case 0b111: switch (bbb) @@ -470,10 +470,10 @@ namespace M6502 case 0b101: case 0b110: case 0b111: - output.Append(Disassemble_AM_01(bbb, "*ISB")); + output.Append(this.Disassemble_AM_01(bbb, "*ISB")); break; case 0b010: - output.Append(Disassemble_AM_11(bbb, "*SBC")); + output.Append(this.Disassemble_AM_11(bbb, "*SBC")); break; default: throw new InvalidOperationException("Impossible addressing mode"); @@ -496,27 +496,27 @@ namespace M6502 #region Label conversions - private string ConvertAddressAt(ushort absolute) => ConvertAddress(GetWord(absolute)); + private string ConvertAddressAt(ushort absolute) => this.ConvertAddress(this.GetWord(absolute)); - private string ConvertAddress(ushort absolute) => TryGetLabel(absolute, out var label) ? label : "$" + DumpWordValue(absolute); + private string ConvertAddress(ushort absolute) => this.TryGetLabel(absolute, out var label) ? label : "$" + DumpWordValue(absolute); - private string ConvertZPAddressAt(ushort absolute) => ConvertZPAddress(GetByte(absolute)); + private string ConvertZPAddressAt(ushort absolute) => this.ConvertZPAddress(this.GetByte(absolute)); - private string ConvertZPAddress(byte absolute) => TryGetLabel(absolute, out var label) ? label : "$" + DumpByteValue(absolute); + private string ConvertZPAddress(byte absolute) => this.TryGetLabel(absolute, out var label) ? label : "$" + DumpByteValue(absolute); private bool TryGetLabel(ushort absolute, out string name) { - return symbols.TryGetQualifiedLabelByAddress(absolute, out name); + return this.symbols.TryGetQualifiedLabelByAddress(absolute, out name); } private string MaybeGetLabel(ushort absolute) { - return symbols.MaybeGetQualifiedLabelByAddress(absolute); + return this.symbols.MaybeGetQualifiedLabelByAddress(absolute); } private string MaybeGetCodeLabel(ushort absolute) { - var label = MaybeGetLabel(absolute); + var label = this.MaybeGetLabel(absolute); if (string.IsNullOrEmpty(label)) { return string.Empty; @@ -526,7 +526,7 @@ namespace M6502 private string MaybeGetCodeLabel() { - return Pad(MaybeGetCodeLabel(address), 30); + return Pad(this.MaybeGetCodeLabel(this.address), 30); } #endregion @@ -535,46 +535,46 @@ namespace M6502 private bool TryGetConstant(ushort value, out string name) { - return symbols.TryGetQualifiedEquateValue(value, out name); + return this.symbols.TryGetQualifiedEquateValue(value, out name); } - private string ConvertConstantByte(ushort address) => ConvertConstant(GetByte(address)); + private string ConvertConstantByte(ushort address) => this.ConvertConstant(this.GetByte(address)); - private string ConvertConstant(byte constant) => TryGetConstant(constant, out var label) ? label : "$" + DumpByteValue(constant); + private string ConvertConstant(byte constant) => this.TryGetConstant(constant, out var label) ? label : "$" + DumpByteValue(constant); #endregion #endregion - private byte GetByte(ushort absolute) => bus.Peek(absolute); + private byte GetByte(ushort absolute) => this.bus.Peek(absolute); - private ushort GetWord(ushort absolute) => processor.PeekWord(absolute).Word; + private ushort GetWord(ushort absolute) => this.processor.PeekWord(absolute).Word; - private string Dump_Byte(ushort absolute) => DumpByteValue(GetByte(absolute)); + private string Dump_Byte(ushort absolute) => DumpByteValue(this.GetByte(absolute)); - private string Dump_DByte(ushort absolute) => Dump_Byte(absolute) + " " + Dump_Byte(++absolute); + private string Dump_DByte(ushort absolute) => this.Dump_Byte(absolute) + " " + this.Dump_Byte(++absolute); - private string Disassemble_Implied(string instruction) => $"{Pad()}\t{MaybeGetCodeLabel()}" + instruction; + private string Disassemble_Implied(string instruction) => $"{Pad()}\t{this.MaybeGetCodeLabel()}" + instruction; - private string Disassemble_Absolute(string instruction) => AM_Absolute_dump() + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_Absolute(); + private string Disassemble_Absolute(string instruction) => this.AM_Absolute_dump() + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_Absolute(); - private string Disassemble_Indirect(string instruction) => AM_Absolute_dump() + $"\t{MaybeGetCodeLabel()}" + instruction + " (" + AM_Absolute() + ")"; + private string Disassemble_Indirect(string instruction) => this.AM_Absolute_dump() + $"\t{this.MaybeGetCodeLabel()}" + instruction + " (" + this.AM_Absolute() + ")"; - private string Disassemble_Relative(string instruction, ushort absolute) => AM_Immediate_dump() + $"\t{MaybeGetCodeLabel()}" + instruction + " " + ConvertAddress(absolute); + private string Disassemble_Relative(string instruction, ushort absolute) => this.AM_Immediate_dump() + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.ConvertAddress(absolute); - private string Disassemble_Immediate(string instruction) => AM_Immediate_dump() + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_Immediate(); + private string Disassemble_Immediate(string instruction) => this.AM_Immediate_dump() + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_Immediate(); - private string Disassemble_AM_00(int bbb, string instruction) => AM_00_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_00(bbb); + private string Disassemble_AM_00(int bbb, string instruction) => this.AM_00_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_00(bbb); - private string Disassemble_AM_01(int bbb, string instruction) => AM_01_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_01(bbb); + private string Disassemble_AM_01(int bbb, string instruction) => this.AM_01_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_01(bbb); - private string Disassemble_AM_10(int bbb, string instruction) => AM_10_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_10(bbb); + private string Disassemble_AM_10(int bbb, string instruction) => this.AM_10_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_10(bbb); - private string Disassemble_AM_10_x(int bbb, string instruction) => AM_10_x_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_10_x(bbb); + private string Disassemble_AM_10_x(int bbb, string instruction) => this.AM_10_x_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_10_x(bbb); - private string Disassemble_AM_11(int bbb, string instruction) => AM_11_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_11(bbb); + private string Disassemble_AM_11(int bbb, string instruction) => this.AM_11_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_11(bbb); - private string Disassemble_AM_11_x(int bbb, string instruction) => AM_11_x_dump(bbb) + $"\t{MaybeGetCodeLabel()}" + instruction + " " + AM_11_x(bbb); + private string Disassemble_AM_11_x(int bbb, string instruction) => this.AM_11_x_dump(bbb) + $"\t{this.MaybeGetCodeLabel()}" + instruction + " " + this.AM_11_x(bbb); private static string Pad(string? value = null, int limit = 10) @@ -589,179 +589,179 @@ namespace M6502 return value + padding; } - private string AM_Immediate_dump() => Pad(Dump_Byte((ushort)(address + 1))); + private string AM_Immediate_dump() => Pad(this.Dump_Byte((ushort)(this.address + 1))); - private string AM_Immediate() => "#" + ConvertConstantByte((ushort)(address + 1)); + private string AM_Immediate() => "#" + this.ConvertConstantByte((ushort)(this.address + 1)); - private string AM_Absolute_dump() => Pad(Dump_DByte((ushort)(address + 1))); + private string AM_Absolute_dump() => Pad(this.Dump_DByte((ushort)(this.address + 1))); - private string AM_Absolute() => ConvertAddressAt((ushort)(address + 1)); + private string AM_Absolute() => this.ConvertAddressAt((ushort)(this.address + 1)); - private string AM_ZeroPage_dump() => Pad(Dump_Byte((ushort)(address + 1))); + private string AM_ZeroPage_dump() => Pad(this.Dump_Byte((ushort)(this.address + 1))); - private string AM_ZeroPage() => ConvertZPAddressAt((ushort)(address + 1)); + private string AM_ZeroPage() => this.ConvertZPAddressAt((ushort)(this.address + 1)); - private string AM_ZeroPageX_dump() => AM_ZeroPage_dump(); + private string AM_ZeroPageX_dump() => this.AM_ZeroPage_dump(); - private string AM_ZeroPageX() => AM_ZeroPage() + ",X"; + private string AM_ZeroPageX() => this.AM_ZeroPage() + ",X"; - private string AM_ZeroPageY_dump() => AM_ZeroPage_dump(); + private string AM_ZeroPageY_dump() => this.AM_ZeroPage_dump(); - private string AM_ZeroPageY() => AM_ZeroPage() + ",Y"; + private string AM_ZeroPageY() => this.AM_ZeroPage() + ",Y"; - private string AM_AbsoluteX_dump() => AM_Absolute_dump(); + private string AM_AbsoluteX_dump() => this.AM_Absolute_dump(); - private string AM_AbsoluteX() => AM_Absolute() + ",X"; + private string AM_AbsoluteX() => this.AM_Absolute() + ",X"; - private string AM_AbsoluteY_dump() => AM_Absolute_dump(); + private string AM_AbsoluteY_dump() => this.AM_Absolute_dump(); - private string AM_AbsoluteY() => AM_Absolute() + ",Y"; + private string AM_AbsoluteY() => this.AM_Absolute() + ",Y"; - private string AM_IndexedIndirectX_dump() => AM_ZeroPage_dump(); + private string AM_IndexedIndirectX_dump() => this.AM_ZeroPage_dump(); - private string AM_IndexedIndirectX() => "(" + ConvertZPAddressAt((ushort)(address + 1)) + ",X)"; + private string AM_IndexedIndirectX() => "(" + this.ConvertZPAddressAt((ushort)(this.address + 1)) + ",X)"; - private string AM_IndirectIndexedY_dump() => AM_ZeroPage_dump(); + private string AM_IndirectIndexedY_dump() => this.AM_ZeroPage_dump(); - private string AM_IndirectIndexedY() => "(" + ConvertZPAddressAt((ushort)(address + 1)) + "),Y"; + private string AM_IndirectIndexedY() => "(" + this.ConvertZPAddressAt((ushort)(this.address + 1)) + "),Y"; private string AM_00_dump(int bbb) => bbb switch { - 0b000 => AM_Immediate_dump(), - 0b001 => AM_ZeroPage_dump(), - 0b011 => AM_Absolute_dump(), - 0b101 => AM_ZeroPageX_dump(), - 0b111 => AM_AbsoluteX_dump(), + 0b000 => this.AM_Immediate_dump(), + 0b001 => this.AM_ZeroPage_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b101 => this.AM_ZeroPageX_dump(), + 0b111 => this.AM_AbsoluteX_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_00(int bbb) => bbb switch { - 0b000 => AM_Immediate(), - 0b001 => AM_ZeroPage(), - 0b011 => AM_Absolute(), - 0b101 => AM_ZeroPageX(), - 0b111 => AM_AbsoluteX(), + 0b000 => this.AM_Immediate(), + 0b001 => this.AM_ZeroPage(), + 0b011 => this.AM_Absolute(), + 0b101 => this.AM_ZeroPageX(), + 0b111 => this.AM_AbsoluteX(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_01_dump(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX_dump(), - 0b001 => AM_ZeroPage_dump(), - 0b010 => AM_Immediate_dump(), - 0b011 => AM_Absolute_dump(), - 0b100 => AM_IndirectIndexedY_dump(), - 0b101 => AM_ZeroPageX_dump(), - 0b110 => AM_AbsoluteY_dump(), - 0b111 => AM_AbsoluteX_dump(), + 0b000 => this.AM_IndexedIndirectX_dump(), + 0b001 => this.AM_ZeroPage_dump(), + 0b010 => this.AM_Immediate_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b100 => this.AM_IndirectIndexedY_dump(), + 0b101 => this.AM_ZeroPageX_dump(), + 0b110 => this.AM_AbsoluteY_dump(), + 0b111 => this.AM_AbsoluteX_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_01(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX(), - 0b001 => AM_ZeroPage(), - 0b010 => AM_Immediate(), - 0b011 => AM_Absolute(), - 0b100 => AM_IndirectIndexedY(), - 0b101 => AM_ZeroPageX(), - 0b110 => AM_AbsoluteY(), - 0b111 => AM_AbsoluteX(), + 0b000 => this.AM_IndexedIndirectX(), + 0b001 => this.AM_ZeroPage(), + 0b010 => this.AM_Immediate(), + 0b011 => this.AM_Absolute(), + 0b100 => this.AM_IndirectIndexedY(), + 0b101 => this.AM_ZeroPageX(), + 0b110 => this.AM_AbsoluteY(), + 0b111 => this.AM_AbsoluteX(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_10_dump(int bbb) => bbb switch { - 0b000 => AM_Immediate_dump(), - 0b001 => AM_ZeroPage_dump(), + 0b000 => this.AM_Immediate_dump(), + 0b001 => this.AM_ZeroPage_dump(), 0b010 => string.Empty, - 0b011 => AM_Absolute_dump(), - 0b101 => AM_ZeroPageX_dump(), - 0b111 => AM_AbsoluteX_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b101 => this.AM_ZeroPageX_dump(), + 0b111 => this.AM_AbsoluteX_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_10(int bbb) => bbb switch { - 0b000 => AM_Immediate(), - 0b001 => AM_ZeroPage(), + 0b000 => this.AM_Immediate(), + 0b001 => this.AM_ZeroPage(), 0b010 => "A", - 0b011 => AM_Absolute(), - 0b101 => AM_ZeroPageX(), - 0b111 => AM_AbsoluteX(), + 0b011 => this.AM_Absolute(), + 0b101 => this.AM_ZeroPageX(), + 0b111 => this.AM_AbsoluteX(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_10_x_dump(int bbb) => bbb switch { - 0b000 => AM_Immediate_dump(), - 0b001 => AM_ZeroPage_dump(), + 0b000 => this.AM_Immediate_dump(), + 0b001 => this.AM_ZeroPage_dump(), 0b010 => string.Empty, - 0b011 => AM_Absolute_dump(), - 0b101 => AM_ZeroPageY_dump(), - 0b111 => AM_AbsoluteY_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b101 => this.AM_ZeroPageY_dump(), + 0b111 => this.AM_AbsoluteY_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_10_x(int bbb) => bbb switch { - 0b000 => AM_Immediate(), - 0b001 => AM_ZeroPage(), + 0b000 => this.AM_Immediate(), + 0b001 => this.AM_ZeroPage(), 0b010 => "A", - 0b011 => AM_Absolute(), - 0b101 => AM_ZeroPageY(), - 0b111 => AM_AbsoluteY(), + 0b011 => this.AM_Absolute(), + 0b101 => this.AM_ZeroPageY(), + 0b111 => this.AM_AbsoluteY(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_11_dump(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX_dump(), - 0b001 => AM_ZeroPage_dump(), - 0b010 => AM_Immediate_dump(), - 0b011 => AM_Absolute_dump(), - 0b100 => AM_IndirectIndexedY_dump(), - 0b101 => AM_ZeroPageY_dump(), - 0b111 => AM_AbsoluteY_dump(), + 0b000 => this.AM_IndexedIndirectX_dump(), + 0b001 => this.AM_ZeroPage_dump(), + 0b010 => this.AM_Immediate_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b100 => this.AM_IndirectIndexedY_dump(), + 0b101 => this.AM_ZeroPageY_dump(), + 0b111 => this.AM_AbsoluteY_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_11_x_dump(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX_dump(), - 0b001 => AM_ZeroPage_dump(), - 0b010 => AM_Immediate_dump(), - 0b011 => AM_Absolute_dump(), - 0b100 => AM_IndirectIndexedY_dump(), - 0b101 => AM_ZeroPageX_dump(), - 0b110 => AM_AbsoluteY_dump(), - 0b111 => AM_AbsoluteX_dump(), + 0b000 => this.AM_IndexedIndirectX_dump(), + 0b001 => this.AM_ZeroPage_dump(), + 0b010 => this.AM_Immediate_dump(), + 0b011 => this.AM_Absolute_dump(), + 0b100 => this.AM_IndirectIndexedY_dump(), + 0b101 => this.AM_ZeroPageX_dump(), + 0b110 => this.AM_AbsoluteY_dump(), + 0b111 => this.AM_AbsoluteX_dump(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_11(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX(), - 0b001 => AM_ZeroPage(), - 0b010 => AM_Immediate(), - 0b011 => AM_Absolute(), - 0b100 => AM_IndirectIndexedY(), - 0b101 => AM_ZeroPageY(), - 0b111 => AM_AbsoluteY(), + 0b000 => this.AM_IndexedIndirectX(), + 0b001 => this.AM_ZeroPage(), + 0b010 => this.AM_Immediate(), + 0b011 => this.AM_Absolute(), + 0b100 => this.AM_IndirectIndexedY(), + 0b101 => this.AM_ZeroPageY(), + 0b111 => this.AM_AbsoluteY(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; private string AM_11_x(int bbb) => bbb switch { - 0b000 => AM_IndexedIndirectX(), - 0b001 => AM_ZeroPage(), - 0b010 => AM_Immediate(), - 0b011 => AM_Absolute(), - 0b100 => AM_IndirectIndexedY(), - 0b101 => AM_ZeroPageX(), - 0b110 => AM_AbsoluteY(), - 0b111 => AM_AbsoluteX(), + 0b000 => this.AM_IndexedIndirectX(), + 0b001 => this.AM_ZeroPage(), + 0b010 => this.AM_Immediate(), + 0b011 => this.AM_Absolute(), + 0b100 => this.AM_IndirectIndexedY(), + 0b101 => this.AM_ZeroPageX(), + 0b110 => this.AM_AbsoluteY(), + 0b111 => this.AM_AbsoluteX(), _ => throw new InvalidOperationException("Illegal addressing mode"), }; } diff --git a/M6502/M6502.HarteTest/Checker.cs b/M6502/M6502.HarteTest/Checker.cs index f05b0d2..dafa081 100644 --- a/M6502/M6502.HarteTest/Checker.cs +++ b/M6502/M6502.HarteTest/Checker.cs @@ -16,11 +16,11 @@ public bool Valid { get; private set; } - public bool Invalid => !Valid; + public bool Invalid => !this.Valid; - public bool Unimplemented => Invalid && CycleCountMismatch && (Cycles == 1); + public bool Unimplemented => this.Invalid && this.CycleCountMismatch && (this.Cycles == 1); - public bool Implemented => !Unimplemented; + public bool Implemented => !this.Unimplemented; public List Messages { get; } = []; @@ -28,67 +28,67 @@ public Checker(TestRunner runner) { - Runner = runner; - Disassembler = new(Runner, (M6502.Core)Runner.CPU, Symbols); + this.Runner = runner; + this.Disassembler = new(this.Runner, this.Runner.CPU, this.Symbols); } public void Check(Test test) { - var cpu = Runner.CPU; + var cpu = this.Runner.CPU; - Reset(); + this.Reset(); - Runner.RaisePOWER(); - InitialiseState(test); + this.Runner.RaisePOWER(); + this.InitialiseState(test); var pc = cpu.PC.Word; - Cycles = cpu.Step(); - Runner.LowerPOWER(); + this.Cycles = cpu.Step(); + this.Runner.LowerPOWER(); - Valid = CheckState(test); + this.Valid = this.CheckState(test); - if (Unimplemented) + if (this.Unimplemented) { - Messages.Add("Unimplemented"); + this.Messages.Add("Unimplemented"); return; } - Debug.Assert(Implemented); - if (Invalid) + Debug.Assert(this.Implemented); + if (this.Invalid) { - AddDisassembly(pc); + this.AddDisassembly(pc); var final = test.Final ?? throw new InvalidOperationException("Final test state cannot be null"); - Raise("PC", final.PC, cpu.PC.Word); - Raise("S", final.S, cpu.S); - Raise("A", final.A, cpu.A); - Raise("X", final.X, cpu.X); - Raise("Y", final.Y, cpu.Y); - Raise("P", final.P, cpu.P); + this.Raise("PC", final.PC, cpu.PC.Word); + this.Raise("S", final.S, cpu.S); + this.Raise("A", final.A, cpu.A); + this.Raise("X", final.X, cpu.X); + this.Raise("Y", final.Y, cpu.Y); + this.Raise("P", final.P, cpu.P); if (test.Cycles == null) { throw new InvalidOperationException("test cycles cannot be null"); } - Messages.Add($"Fixed page is: {cpu.FixedPage:X2}"); + this.Messages.Add($"Fixed page is: {cpu.FixedPage:X2}"); - Messages.Add($"Stepped cycles: {Cycles}, expected events: {test.Cycles.Count}, actual events: {ActualCycles.Count}"); + this.Messages.Add($"Stepped cycles: {this.Cycles}, expected events: {test.Cycles.Count}, actual events: {this.ActualCycles.Count}"); - DumpCycles("-- Expected cycles", test.AvailableCycles()); - DumpCycles("-- Actual cycles", ActualCycles); + this.DumpCycles("-- Expected cycles", test.AvailableCycles()); + this.DumpCycles("-- Actual cycles", this.ActualCycles); } } private void Reset() { - Messages.Clear(); - ActualCycles.Clear(); + this.Messages.Clear(); + this.ActualCycles.Clear(); - CycleCountMismatch = false; - Cycles = 0; - Valid = false; + this.CycleCountMismatch = false; + this.Cycles = 0; + this.Valid = false; } private bool Check(string what, ushort expected, ushort actual) @@ -96,7 +96,7 @@ var success = actual == expected; if (!success) { - Raise(what, expected, actual); + this.Raise(what, expected, actual); } return success; } @@ -106,7 +106,7 @@ var success = actual == expected; if (!success) { - Raise(what, expected, actual); + this.Raise(what, expected, actual); } return success; } @@ -118,7 +118,7 @@ var success = actual == expected; if (!success) { - Raise(what, expected, actual); + this.Raise(what, expected, actual); } return success; } @@ -128,7 +128,7 @@ var success = actual == expected; if (!success) { - Raise($"{what}: {address}", expected, actual); + this.Raise($"{what}: {address}", expected, actual); } return success; } @@ -138,32 +138,33 @@ string message; try { - message = Disassemble(address); + message = this.Disassemble(address); } catch (InvalidOperationException error) { message = $"Disassembly problem: {error.Message}"; } - Messages.Add(message); + this.Messages.Add(message); } - private string Disassemble(ushort address) => Disassembler.Disassemble(address); + private string Disassemble(ushort address) => this.Disassembler.Disassemble(address); private bool CheckState(Test test) { - var cpu = Runner.CPU; - var ram = Runner.RAM; + var cpu = this.Runner.CPU; + var ram = this.Runner.RAM; var expectedCycles = test.AvailableCycles(); - var actualCycles = ActualCycles; + var actualCycles = this.ActualCycles; var actualIDX = 0; - foreach (var expectedCycle in expectedCycles) { + foreach (var expectedCycle in expectedCycles) + { if (actualIDX >= actualCycles.Count) { - CycleCountMismatch = true; + this.CycleCountMismatch = true; return false; // more expected cycles than actual } @@ -171,40 +172,40 @@ var expectedAddress = expectedCycle.Address; var actualAddress = actualCycle.Address; - _ = Check("Cycle address", expectedAddress, actualAddress); + _ = this.Check("Cycle address", expectedAddress, actualAddress); var expectedValue = expectedCycle.Value; var actualValue = actualCycle.Value; - _ = Check("Cycle value", expectedValue, actualValue); + _ = this.Check("Cycle value", expectedValue, actualValue); var expectedAction = expectedCycle.Type; var actualAction = actualCycle.Type; - _ = Check("Cycle action", expectedAction, actualAction); + _ = this.Check("Cycle action", expectedAction, actualAction); } if (actualIDX < actualCycles.Count) { - CycleCountMismatch = true; + this.CycleCountMismatch = true; return false; // less expected cycles than actual } - if (Messages.Count > 0) + if (this.Messages.Count > 0) { return false; } var final = test.Final ?? throw new InvalidOperationException("Final state cannot be null"); - var pc_good = Check("PC", final.PC, cpu.PC.Word); - var s_good = Check("S", final.S, cpu.S); - var a_good = Check("A", final.A, cpu.A); - var x_good = Check("X", final.X, cpu.X); - var y_good = Check("Y", final.Y, cpu.Y); - var p_good = Check("P", final.P, cpu.P); + var pc_good = this.Check("PC", final.PC, cpu.PC.Word); + 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); + var y_good = this.Check("Y", final.Y, cpu.Y); + var p_good = this.Check("P", final.P, cpu.P); if (!p_good) { - Messages.Add($"Expected flags: {Disassembler.DumpFlags(final.P)}"); - Messages.Add($"Actual flags : {Disassembler.DumpFlags(cpu.P)}"); + this.Messages.Add($"Expected flags: {Disassembler.DumpFlags(final.P)}"); + this.Messages.Add($"Actual flags : {Disassembler.DumpFlags(cpu.P)}"); } if (final.RAM == null) @@ -223,7 +224,7 @@ var address = (ushort)entry[0]; var value = (byte)entry[1]; - var ramGood = Check("RAM", address, value, ram.Peek(address)); + var ramGood = this.Check("RAM", address, value, ram.Peek(address)); if (!ramGood && !ramProblem) { ramProblem = true; @@ -236,28 +237,28 @@ && !ramProblem; } - private void Raise(string what, ushort expected, ushort actual) => Messages.Add($"{what}: expected: {expected:X4}, actual: {actual:X4}"); + private void Raise(string what, ushort expected, ushort actual) => this.Messages.Add($"{what}: expected: {expected:X4}, actual: {actual:X4}"); - private void Raise(string what, byte expected, byte actual) => Messages.Add($"{what}: expected: {expected:X2}, actual: {actual:X2}"); + private void Raise(string what, byte expected, byte actual) => this.Messages.Add($"{what}: expected: {expected:X2}, actual: {actual:X2}"); - private void Raise(string what, string expected, string actual) => Messages.Add($"{what}: expected: {expected}, actual: {actual}"); + private void Raise(string what, string expected, string actual) => this.Messages.Add($"{what}: expected: {expected}, actual: {actual}"); public void Initialise() { - Runner.ReadByte += Runner_ReadByte; - Runner.WrittenByte += Runner_WrittenByte; + this.Runner.ReadByte += this.Runner_ReadByte; + this.Runner.WrittenByte += this.Runner_WrittenByte; } private void InitialiseState(Test test) { var initial = test.Initial ?? throw new InvalidOperationException("Test cannot have an invalid initial state"); - InitialiseState(initial); + this.InitialiseState(initial); } private void InitialiseState(State state) { - var cpu = Runner.CPU; - var ram = Runner.RAM; + var cpu = this.Runner.CPU; + var ram = this.Runner.RAM; cpu.PC.Word = state.PC; cpu.S = state.S; @@ -281,39 +282,39 @@ } } - private void Runner_ReadByte(object? sender, EventArgs e) => AddActualReadCycle(Runner.Address, Runner.Data); + private void Runner_ReadByte(object? sender, EventArgs e) => this.AddActualReadCycle(this.Runner.Address, this.Runner.Data); - private void Runner_WrittenByte(object? sender, EventArgs e) => AddActualWriteCycle(Runner.Address, Runner.Data); + private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualWriteCycle(this.Runner.Address, this.Runner.Data); - private void AddActualReadCycle(EightBit.Register16 address, byte value) => AddActualCycle(address, value, "read"); + private void AddActualReadCycle(EightBit.Register16 address, byte value) => this.AddActualCycle(address, value, "read"); - private void AddActualWriteCycle(EightBit.Register16 address, byte value) => AddActualCycle(address, value, "write"); + private void AddActualWriteCycle(EightBit.Register16 address, byte value) => this.AddActualCycle(address, value, "write"); - private void AddActualCycle(EightBit.Register16 address, byte value, string action) => AddActualCycle(address.Word, value, action); + private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action); - private void AddActualCycle(ushort address, byte value, string action) => ActualCycles.Add(new Cycle(address, value, action)); + private void AddActualCycle(ushort address, byte value, string action) => this.ActualCycles.Add(new Cycle(address, value, action)); private void DumpCycle(ushort address, byte value, string? action) { ArgumentNullException.ThrowIfNull(action); - Messages.Add($"Address: {address:X4}, value: {value:X2}, action: {action}"); + this.Messages.Add($"Address: {address:X4}, value: {value:X2}, action: {action}"); } - private void DumpCycle(Cycle cycle) => DumpCycle(cycle.Address, cycle.Value, cycle.Type); + private void DumpCycle(Cycle cycle) => this.DumpCycle(cycle.Address, cycle.Value, cycle.Type); private void DumpCycles(IEnumerable? cycles) { ArgumentNullException.ThrowIfNull(cycles); foreach (var cycle in cycles) { - DumpCycle(cycle); + this.DumpCycle(cycle); } } private void DumpCycles(string which, IEnumerable? events) { - Messages.Add(which); - DumpCycles(events); + this.Messages.Add(which); + this.DumpCycles(events); } } } diff --git a/M6502/M6502.HarteTest/Cycle.cs b/M6502/M6502.HarteTest/Cycle.cs index 6557b93..8b1cd4b 100644 --- a/M6502/M6502.HarteTest/Cycle.cs +++ b/M6502/M6502.HarteTest/Cycle.cs @@ -1,6 +1,6 @@ namespace M6502.HarteTest { - public sealed class Cycle + internal sealed class Cycle { public ushort Address { get; set; } @@ -10,9 +10,9 @@ public Cycle(ushort address, byte value, string type) { - Address = address; - Value = value; - Type = type; + this.Address = address; + this.Value = value; + this.Type = type; } public Cycle(List input) @@ -24,9 +24,9 @@ throw new ArgumentOutOfRangeException(nameof(input), input, "Cycles can only have three elements"); } - Address = AsElement(input[0]).GetUInt16(); - Value = AsElement(input[1]).GetByte(); - Type = AsElement(input[2]).GetString(); + this.Address = AsElement(input[0]).GetUInt16(); + this.Value = AsElement(input[1]).GetByte(); + this.Type = AsElement(input[2]).GetString(); } private static System.Text.Json.JsonElement AsElement(object part) => (System.Text.Json.JsonElement)part; diff --git a/M6502/M6502.HarteTest/OpcodeTestSuite.cs b/M6502/M6502.HarteTest/OpcodeTestSuite.cs index 196276d..6bae5c7 100644 --- a/M6502/M6502.HarteTest/OpcodeTestSuite.cs +++ b/M6502/M6502.HarteTest/OpcodeTestSuite.cs @@ -1,5 +1,6 @@ namespace M6502.HarteTest { + using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; @@ -12,28 +13,28 @@ }; private bool _disposed; - public string Path { get; set; } = path; + public string Path { get; } = path; private readonly FileStream _stream = File.Open(path, FileMode.Open); - public IAsyncEnumerable TestsAsync => JsonSerializer.DeserializeAsyncEnumerable(_stream, SerializerOptions); + public ConfiguredCancelableAsyncEnumerable TestsAsync => JsonSerializer.DeserializeAsyncEnumerable(this._stream, SerializerOptions).ConfigureAwait(false); private void Dispose(bool disposing) { - if (!_disposed) + if (!this._disposed) { if (disposing) { - _stream.Dispose(); + this._stream.Dispose(); } - _disposed = true; + this._disposed = true; } } public void Dispose() { - Dispose(disposing: true); + this.Dispose(disposing: true); GC.SuppressFinalize(this); } } diff --git a/M6502/M6502.HarteTest/ProcessorTestSuite.cs b/M6502/M6502.HarteTest/ProcessorTestSuite.cs index ea6105f..fe4414d 100644 --- a/M6502/M6502.HarteTest/ProcessorTestSuite.cs +++ b/M6502/M6502.HarteTest/ProcessorTestSuite.cs @@ -6,7 +6,7 @@ public IEnumerable OpcodeTests() { - foreach (var filename in Directory.EnumerateFiles(Location, "*.json")) + foreach (var filename in Directory.EnumerateFiles(this.Location, "*.json")) { var fileInformation = new FileInfo(filename); if (fileInformation.Length > 0) diff --git a/M6502/M6502.HarteTest/Program.cs b/M6502/M6502.HarteTest/Program.cs index c8973ba..cabc03c 100644 --- a/M6502/M6502.HarteTest/Program.cs +++ b/M6502/M6502.HarteTest/Program.cs @@ -11,7 +11,7 @@ namespace M6502.HarteTest var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\6502\v1"; //var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\wdc65c02\v1"; - await ProcessTestSuiteAsync(directory); + await ProcessTestSuiteAsync(directory).ConfigureAwait(false); } private static async Task ProcessTestSuiteAsync(string directory) @@ -33,7 +33,7 @@ namespace M6502.HarteTest Console.WriteLine($"Processing: {Path.GetFileName(opcode.Path)}"); List testNames = []; - var tests = opcode.TestsAsync ?? throw new InvalidOperationException("No tests are available"); + var tests = opcode.TestsAsync; await foreach (var test in tests) { if (test == null) @@ -55,7 +55,7 @@ namespace M6502.HarteTest // Let's see if we had any successes! if (testNames.Count > 0) { - Console.WriteLine("**** The follow test variations succeeeded"); + Console.WriteLine("**** The follow test variations succeeded"); foreach (var testName in testNames) { Console.WriteLine($"****** {testName}"); diff --git a/M6502/M6502.HarteTest/State.cs b/M6502/M6502.HarteTest/State.cs index efd2d3b..5d8aa19 100644 --- a/M6502/M6502.HarteTest/State.cs +++ b/M6502/M6502.HarteTest/State.cs @@ -1,6 +1,6 @@ namespace M6502.HarteTest { - public sealed class State + internal sealed class State { public ushort PC { get; set; } diff --git a/M6502/M6502.HarteTest/Test.cs b/M6502/M6502.HarteTest/Test.cs index 2a1456b..d926fb3 100644 --- a/M6502/M6502.HarteTest/Test.cs +++ b/M6502/M6502.HarteTest/Test.cs @@ -1,6 +1,6 @@ namespace M6502.HarteTest { - public sealed class Test + internal sealed class Test { public string? Name { get; set; } @@ -12,12 +12,12 @@ public IEnumerable AvailableCycles() { - if (Cycles == null) + if (this.Cycles == null) { throw new InvalidOperationException("Cycles have not been initialised"); } - foreach (var cycle in Cycles) + foreach (var cycle in this.Cycles) { yield return new Cycle(cycle); } diff --git a/M6502/M6502.HarteTest/TestRunner.cs b/M6502/M6502.HarteTest/TestRunner.cs index 061bb6d..b55e263 100644 --- a/M6502/M6502.HarteTest/TestRunner.cs +++ b/M6502/M6502.HarteTest/TestRunner.cs @@ -13,8 +13,8 @@ public TestRunner() { - CPU = new(this); - _mapping = new(RAM, 0x0000, (ushort)Mask.Sixteen, AccessLevel.ReadWrite); + this.CPU = new(this); + this._mapping = new(this.RAM, 0x0000, (ushort)Mask.Sixteen, AccessLevel.ReadWrite); } public override void Initialize() @@ -23,21 +23,21 @@ public override void LowerPOWER() { - CPU.LowerPOWER(); + this.CPU.LowerPOWER(); base.LowerPOWER(); } - public override MemoryMapping Mapping(ushort _) => _mapping; + public override MemoryMapping Mapping(ushort _) => this._mapping; public override void RaisePOWER() { base.RaisePOWER(); - CPU.RaisePOWER(); - CPU.RaiseRESET(); - CPU.RaiseINT(); - CPU.RaiseNMI(); - CPU.RaiseSO(); - CPU.RaiseRDY(); + this.CPU.RaisePOWER(); + this.CPU.RaiseRESET(); + this.CPU.RaiseINT(); + this.CPU.RaiseNMI(); + this.CPU.RaiseSO(); + this.CPU.RaiseRDY(); } } } diff --git a/M6502/M6502.Symbols/Line.cs b/M6502/M6502.Symbols/Line.cs index ffafad8..179e91b 100644 --- a/M6502/M6502.Symbols/Line.cs +++ b/M6502/M6502.Symbols/Line.cs @@ -1,7 +1,5 @@ namespace M6502.Symbols { - using M6502.Symbols; - // line id = 268, file = 1, line = 60, type = 2, count = 1, span = 286 + 195 [Section("line", "Lines")] public sealed class Line(Parser container) : IdentifiableSection(container) diff --git a/M6502/M6502.Symbols/Module.cs b/M6502/M6502.Symbols/Module.cs index 488695a..5cb047d 100644 --- a/M6502/M6502.Symbols/Module.cs +++ b/M6502/M6502.Symbols/Module.cs @@ -2,6 +2,7 @@ { // mod id=0,name="sudoku.o",file=0 [Section("mod", "Modules")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "External file format")] public sealed class Module(Parser container) : NamedSection(container) { [SectionReference("file")] diff --git a/M6502/M6502.Symbols/Parser.cs b/M6502/M6502.Symbols/Parser.cs index 5581b7c..d315888 100644 --- a/M6502/M6502.Symbols/Parser.cs +++ b/M6502/M6502.Symbols/Parser.cs @@ -124,7 +124,7 @@ public Scope? LookupScopeByAddress(int address) { - var index = _scopeAddressCache[address] ?? (_scopeAddressCache[address] = this.LocateScopeByAddress(address)); + var index = this._scopeAddressCache[address] ?? (this._scopeAddressCache[address] = this.LocateScopeByAddress(address)); return index == -1 ? null : this.AddressableScopes[index.Value]; } @@ -352,7 +352,7 @@ { if (this._version != null) { - throw new InvalidOperationException("Verson object has already been parsed"); + throw new InvalidOperationException("Version object has already been parsed"); } this._version = new(this); this._version.Parse(BuildDictionary(parts)); diff --git a/M6502/M6502.Symbols/ReflectedSectionProperties.cs b/M6502/M6502.Symbols/ReflectedSectionProperties.cs index 142e650..9f62994 100644 --- a/M6502/M6502.Symbols/ReflectedSectionProperties.cs +++ b/M6502/M6502.Symbols/ReflectedSectionProperties.cs @@ -26,6 +26,7 @@ public void Build(System.Type type) { + ArgumentNullException.ThrowIfNull(type); var sectionAttributes = type.GetCustomAttributes(typeof(SectionAttribute), true); Debug.Assert(sectionAttributes != null, "No section attributes available"); Debug.Assert(sectionAttributes.Length == 1, "Must be a single section attribute available"); @@ -154,7 +155,8 @@ if (attribute is SectionReferenceAttribute) { this.ReferenceAttributes.Add(key, new Tuple(name, originalType)); - } else if (attribute is SectionReferencesAttribute) + } + else if (attribute is SectionReferencesAttribute) { this.ReferencesAttributes.Add(key, new Tuple(name, originalType)); } diff --git a/M6502/M6502.Symbols/Section.cs b/M6502/M6502.Symbols/Section.cs index 6621b3f..f3d00e6 100644 --- a/M6502/M6502.Symbols/Section.cs +++ b/M6502/M6502.Symbols/Section.cs @@ -8,8 +8,8 @@ public class Section { - protected static readonly Dictionary _sectionPropertiesCache = []; - protected static readonly DateTime _unixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + protected static readonly Dictionary SectionPropertiesCache = []; + protected static readonly DateTime UnixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); protected readonly Parser _container; @@ -23,7 +23,7 @@ protected static ReflectedSectionProperties GetSectionProperties(System.Type type) { - var obtained = _sectionPropertiesCache.TryGetValue(type, out var properties); + var obtained = SectionPropertiesCache.TryGetValue(type, out var properties); Debug.Assert(obtained, $"Section properties for {type.Name} have not been built"); Debug.Assert(properties != null); return properties; @@ -35,8 +35,8 @@ { var type = this.GetType(); var entry = new ReflectedSectionProperties(); - Debug.Assert(_sectionPropertiesCache != null); - if (_sectionPropertiesCache.TryAdd(type, entry)) + Debug.Assert(SectionPropertiesCache != null); + if (SectionPropertiesCache.TryAdd(type, entry)) { entry.Build(type); } @@ -44,8 +44,9 @@ public T GetValueT(string key) => this.SectionProperties.GetValueT(this, key); - public virtual void Parse(Dictionary entries) + public virtual void Parse(Dictionary? entries) { + ArgumentNullException.ThrowIfNull(entries); this._parsed = entries; this._container.SectionEntries.Add(this); this.ProcessAttributesOfProperties(); @@ -129,7 +130,12 @@ } } - protected static string ExtractString(string value) => value.Trim('"'); + protected static string ExtractString(string? value) + { + ArgumentNullException.ThrowIfNull(value); + return value.Trim('"'); + } + protected static string ExtractEnumeration(string value) => value; private static T ExtractHexValue(string value) where T : INumberBase => T.Parse(value.AsSpan(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); @@ -139,8 +145,13 @@ protected static long ExtractHexLong(string value) => ExtractHexValue(value); protected static int ExtractInteger(string value) => ExtractNumericValue(value); protected static long ExtractLong(string value) => ExtractNumericValue(value); - protected static DateTime ExtractDateTime(string value) => _unixEpoch.AddSeconds(ExtractHexLong(value)); - protected static string[] ExtractCompoundString(string value) => value.Split('+'); + protected static DateTime ExtractDateTime(string value) => UnixEpoch.AddSeconds(ExtractHexLong(value)); + + protected static string[] ExtractCompoundString(string? value) + { + ArgumentNullException.ThrowIfNull(value); + return value.Split('+'); + } protected static List ExtractCompoundInteger(string value) { diff --git a/M6502/M6502.Test/Board.cs b/M6502/M6502.Test/Board.cs index 6113e31..bbeeea8 100644 --- a/M6502/M6502.Test/Board.cs +++ b/M6502/M6502.Test/Board.cs @@ -4,12 +4,12 @@ namespace M6502.Test { + using EightBit; + using M6502; using System.Diagnostics; using System.Globalization; using System.Text; using System.Threading.Tasks; - using EightBit; - using M6502; internal class Board : Bus { diff --git a/M6502/M6502.Test/Configuration.cs b/M6502/M6502.Test/Configuration.cs index 2a22c7a..4606a9f 100644 --- a/M6502/M6502.Test/Configuration.cs +++ b/M6502/M6502.Test/Configuration.cs @@ -10,7 +10,7 @@ namespace M6502.Test { public bool DebugMode { get; set; } - public bool Profile { get; set; } + public bool Profile { get; set; }; // Sudoku public string Program { get; } = "sudoku.65b"; diff --git a/M6502/MOS6502.cs b/M6502/MOS6502.cs index a69dd49..0e8f482 100644 --- a/M6502/MOS6502.cs +++ b/M6502/MOS6502.cs @@ -17,125 +17,125 @@ namespace M6502 return true; } - var cycles = Cycles; - switch (OpCode) + var cycles = this.Cycles; + switch (this.OpCode) { - case 0x02: Jam(); break; // *JAM - case 0x03: IndexedIndirectXRead(); SLO(); break; // *SLO (indexed indirect X) - case 0x04: ZeroPageRead(); break; // *NOP (zero page) - case 0x07: ZeroPageRead(); SLO(); break; // *SLO (zero page) - case 0x0b: ImmediateRead(); ANC(); break; // *ANC (immediate) - case 0x0c: AbsoluteRead(); break; // *NOP (absolute) - case 0x0f: AbsoluteRead(); SLO(); break; // *SLO (absolute) + case 0x02: this.Jam(); break; // *JAM + case 0x03: this.IndexedIndirectXRead(); this.SLO(); break; // *SLO (indexed indirect X) + case 0x04: this.ZeroPageRead(); break; // *NOP (zero page) + case 0x07: this.ZeroPageRead(); this.SLO(); break; // *SLO (zero page) + case 0x0b: this.ImmediateRead(); this.ANC(); break; // *ANC (immediate) + case 0x0c: this.AbsoluteRead(); break; // *NOP (absolute) + case 0x0f: this.AbsoluteRead(); this.SLO(); break; // *SLO (absolute) - case 0x12: Jam(); break; // *JAM - case 0x13: IndirectIndexedYAddress(); FixupRead(); SLO(); break; // *SLO (indirect indexed Y) - case 0x14: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0x17: ZeroPageXRead(); SLO(); break; // *SLO (zero page, X) - case 0x1a: SwallowRead(); break; // *NOP (implied) - case 0x1b: AbsoluteYAddress(); FixupRead(); SLO(); break; // *SLO (absolute, Y) - case 0x1c: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0x1f: AbsoluteXAddress(); FixupRead(); SLO(); break; // *SLO (absolute, X) + case 0x12: this.Jam(); break; // *JAM + case 0x13: this.IndirectIndexedYAddress(); this.FixupRead(); this.SLO(); break; // *SLO (indirect indexed Y) + case 0x14: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0x17: this.ZeroPageXRead(); this.SLO(); break; // *SLO (zero page, X) + case 0x1a: this.SwallowRead(); break; // *NOP (implied) + case 0x1b: this.AbsoluteYAddress(); this.FixupRead(); this.SLO(); break; // *SLO (absolute, Y) + case 0x1c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0x1f: this.AbsoluteXAddress(); this.FixupRead(); this.SLO(); break; // *SLO (absolute, X) - case 0x22: Jam(); break; // *JAM - case 0x23: IndexedIndirectXRead(); RLA(); ; break; // *RLA (indexed indirect X) - case 0x27: ZeroPageRead(); RLA(); ; break; // *RLA (zero page) - case 0x2b: ImmediateRead(); ANC(); break; // *ANC (immediate) - case 0x2f: AbsoluteRead(); RLA(); break; // *RLA (absolute) + case 0x22: this.Jam(); break; // *JAM + case 0x23: this.IndexedIndirectXRead(); this.RLA(); ; break; // *RLA (indexed indirect X) + case 0x27: this.ZeroPageRead(); this.RLA(); ; break; // *RLA (zero page) + case 0x2b: this.ImmediateRead(); this.ANC(); break; // *ANC (immediate) + case 0x2f: this.AbsoluteRead(); this.RLA(); break; // *RLA (absolute) - case 0x32: Jam(); break; // *JAM - case 0x33: IndirectIndexedYAddress(); FixupRead(); RLA(); break; // *RLA (indirect indexed Y) - case 0x34: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0x37: ZeroPageXRead(); RLA(); ; break; // *RLA (zero page, X) - case 0x3a: SwallowRead(); break; // *NOP (implied) - case 0x3b: AbsoluteYAddress(); FixupRead(); RLA(); break; // *RLA (absolute, Y) - case 0x3c: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0x3f: AbsoluteXAddress(); FixupRead(); RLA(); break; // *RLA (absolute, X) + case 0x32: this.Jam(); break; // *JAM + case 0x33: this.IndirectIndexedYAddress(); this.FixupRead(); this.RLA(); break; // *RLA (indirect indexed Y) + case 0x34: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0x37: this.ZeroPageXRead(); this.RLA(); ; break; // *RLA (zero page, X) + case 0x3a: this.SwallowRead(); break; // *NOP (implied) + case 0x3b: this.AbsoluteYAddress(); this.FixupRead(); this.RLA(); break; // *RLA (absolute, Y) + case 0x3c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0x3f: this.AbsoluteXAddress(); this.FixupRead(); this.RLA(); break; // *RLA (absolute, X) - case 0x42: Jam(); break; // *JAM - case 0x43: IndexedIndirectXRead(); SRE(); break; // *SRE (indexed indirect X) - case 0x47: ZeroPageRead(); SRE(); break; // *SRE (zero page) - case 0x4b: ImmediateRead(); ASR(); break; // *ASR (immediate) - case 0x4f: AbsoluteRead(); SRE(); break; // *SRE (absolute) + case 0x42: this.Jam(); break; // *JAM + case 0x43: this.IndexedIndirectXRead(); this.SRE(); break; // *SRE (indexed indirect X) + case 0x47: this.ZeroPageRead(); this.SRE(); break; // *SRE (zero page) + case 0x4b: this.ImmediateRead(); this.ASR(); break; // *ASR (immediate) + case 0x4f: this.AbsoluteRead(); this.SRE(); break; // *SRE (absolute) - case 0x52: Jam(); break; // *JAM - case 0x53: IndirectIndexedYAddress(); FixupRead(); SRE(); break; // *SRE (indirect indexed Y) - case 0x57: ZeroPageXRead(); SRE(); break; // *SRE (zero page, X) - case 0x5a: SwallowRead(); break; // *NOP (implied) - case 0x5b: AbsoluteYAddress(); FixupRead(); SRE(); break; // *SRE (absolute, Y) - case 0x5c: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0x5f: AbsoluteXAddress(); FixupRead(); SRE(); break; // *SRE (absolute, X) + case 0x52: this.Jam(); break; // *JAM + case 0x53: this.IndirectIndexedYAddress(); this.FixupRead(); this.SRE(); break; // *SRE (indirect indexed Y) + case 0x57: this.ZeroPageXRead(); this.SRE(); break; // *SRE (zero page, X) + case 0x5a: this.SwallowRead(); break; // *NOP (implied) + case 0x5b: this.AbsoluteYAddress(); this.FixupRead(); this.SRE(); break; // *SRE (absolute, Y) + case 0x5c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0x5f: this.AbsoluteXAddress(); this.FixupRead(); this.SRE(); break; // *SRE (absolute, X) - case 0x62: Jam(); break; // *JAM - case 0x63: IndexedIndirectXRead(); RRA(); break; // *RRA (indexed indirect X) - case 0x64: ZeroPageRead(); break; // *NOP (zero page) - case 0x67: ZeroPageRead(); RRA(); break; // *RRA (zero page) - case 0x6b: ImmediateRead(); ARR(); break; // *ARR (immediate) - case 0x6f: AbsoluteRead(); RRA(); break; // *RRA (absolute) + case 0x62: this.Jam(); break; // *JAM + case 0x63: this.IndexedIndirectXRead(); this.RRA(); break; // *RRA (indexed indirect X) + case 0x64: this.ZeroPageRead(); break; // *NOP (zero page) + case 0x67: this.ZeroPageRead(); this.RRA(); break; // *RRA (zero page) + case 0x6b: this.ImmediateRead(); this.ARR(); break; // *ARR (immediate) + case 0x6f: this.AbsoluteRead(); this.RRA(); break; // *RRA (absolute) - case 0x72: Jam(); break; // *JAM - case 0x73: IndirectIndexedYAddress(); FixupRead(); RRA(); break; // *RRA (indirect indexed Y) - case 0x74: ZeroPageXRead(); break; // *NOP (zero page, X) - case 0x77: ZeroPageXRead(); RRA(); break; // *RRA (zero page, X) - case 0x7a: SwallowRead(); break; // *NOP (implied) - case 0x7b: AbsoluteYAddress(); FixupRead(); RRA(); break; // *RRA (absolute, Y) - case 0x7c: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0x7f: AbsoluteXAddress(); FixupRead(); RRA(); break; // *RRA (absolute, X) + case 0x72: this.Jam(); break; // *JAM + case 0x73: this.IndirectIndexedYAddress(); this.FixupRead(); this.RRA(); break; // *RRA (indirect indexed Y) + case 0x74: this.ZeroPageXRead(); break; // *NOP (zero page, X) + case 0x77: this.ZeroPageXRead(); this.RRA(); break; // *RRA (zero page, X) + case 0x7a: this.SwallowRead(); break; // *NOP (implied) + case 0x7b: this.AbsoluteYAddress(); this.FixupRead(); this.RRA(); break; // *RRA (absolute, Y) + case 0x7c: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0x7f: this.AbsoluteXAddress(); this.FixupRead(); this.RRA(); break; // *RRA (absolute, X) - case 0x80: ImmediateRead(); break; // *NOP (immediate) - case 0x83: IndexedIndirectXAddress(); MemoryWrite((byte)(A & X)); break; // *SAX (indexed indirect X) - case 0x87: ZeroPageAddress(); MemoryWrite((byte)(A & X)); break; // *SAX (zero page) - case 0x89: ImmediateRead(); break; // *NOP (immediate) - case 0x8b: ImmediateRead(); ANE(); break; // *ANE (immediate) - case 0x8f: AbsoluteAddress(); MemoryWrite((byte)(A & X)); break; // *SAX (absolute) + case 0x80: this.ImmediateRead(); break; // *NOP (immediate) + case 0x83: this.IndexedIndirectXAddress(); this.MemoryWrite((byte)(this.A & this.X)); break; // *SAX (indexed indirect X) + case 0x87: this.ZeroPageAddress(); this.MemoryWrite((byte)(this.A & this.X)); break; // *SAX (zero page) + case 0x89: this.ImmediateRead(); break; // *NOP (immediate) + case 0x8b: this.ImmediateRead(); this.ANE(); break; // *ANE (immediate) + case 0x8f: this.AbsoluteAddress(); this.MemoryWrite((byte)(this.A & this.X)); break; // *SAX (absolute) - case 0x92: Jam(); break; // *JAM - case 0x93: IndirectIndexedYAddress(); Fixup(); SHA(); break; // *SHA (indirect indexed, Y) - case 0x97: ZeroPageYAddress(); MemoryWrite((byte)(A & X)); break; // *SAX (zero page, Y) - case 0x9b: AbsoluteYAddress(); Fixup(); TAS(); break; // *TAS (absolute, Y) - case 0x9c: AbsoluteXAddress(); Fixup(); SYA(); break; // *SYA (absolute, X) - case 0x9e: AbsoluteYAddress(); Fixup(); SXA(); break; // *SXA (absolute, Y) - case 0x9f: AbsoluteYAddress(); Fixup(); SHA(); break; // *SHA (absolute, Y) + case 0x92: this.Jam(); break; // *JAM + case 0x93: this.IndirectIndexedYAddress(); this.Fixup(); this.SHA(); break; // *SHA (indirect indexed, Y) + case 0x97: this.ZeroPageYAddress(); this.MemoryWrite((byte)(this.A & this.X)); break; // *SAX (zero page, Y) + case 0x9b: this.AbsoluteYAddress(); this.Fixup(); this.TAS(); break; // *TAS (absolute, Y) + case 0x9c: this.AbsoluteXAddress(); this.Fixup(); this.SYA(); break; // *SYA (absolute, X) + case 0x9e: this.AbsoluteYAddress(); this.Fixup(); this.SXA(); break; // *SXA (absolute, Y) + case 0x9f: this.AbsoluteYAddress(); this.Fixup(); this.SHA(); break; // *SHA (absolute, Y) - case 0xa3: IndexedIndirectXRead(); A = X = Through(); break; // *LAX (indexed indirect X) - case 0xa7: ZeroPageRead(); A = X = Through(); break; // *LAX (zero page) - case 0xab: ImmediateRead(); ATX(); break; // *ATX (immediate) - case 0xaf: AbsoluteRead(); A = X = Through(); break; // *LAX (absolute) + case 0xa3: this.IndexedIndirectXRead(); this.A = this.X = this.Through(); break; // *LAX (indexed indirect X) + case 0xa7: this.ZeroPageRead(); this.A = this.X = this.Through(); break; // *LAX (zero page) + case 0xab: this.ImmediateRead(); this.ATX(); break; // *ATX (immediate) + case 0xaf: this.AbsoluteRead(); this.A = this.X = this.Through(); break; // *LAX (absolute) - case 0xb2: Jam(); break; // *JAM - case 0xb3: IndirectIndexedYRead(); A = X = Through(); break; // *LAX (indirect indexed Y) - case 0xb7: ZeroPageYRead(); A = X = Through(); break; // *LAX (zero page, Y) - case 0xbb: AbsoluteYAddress(); MaybeFixup(); LAS(); break; // *LAS (absolute, Y) - case 0xbf: AbsoluteYRead(); A = X = Through(); break; // *LAX (absolute, Y) + case 0xb2: this.Jam(); break; // *JAM + case 0xb3: this.IndirectIndexedYRead(); this.A = this.X = this.Through(); break; // *LAX (indirect indexed Y) + case 0xb7: this.ZeroPageYRead(); this.A = this.X = this.Through(); break; // *LAX (zero page, Y) + case 0xbb: this.AbsoluteYAddress(); this.MaybeFixup(); this.LAS(); break; // *LAS (absolute, Y) + case 0xbf: this.AbsoluteYRead(); this.A = this.X = this.Through(); break; // *LAX (absolute, Y) - case 0xc3: IndexedIndirectXRead(); DCP(); break; // *DCP (indexed indirect X) - case 0xc7: ZeroPageRead(); DCP(); break; // *DCP (zero page) - case 0xcb: ImmediateRead(); AXS(); break; // *AXS (immediate) - case 0xcf: AbsoluteRead(); DCP(); break; // *DCP (absolute) + case 0xc3: this.IndexedIndirectXRead(); this.DCP(); break; // *DCP (indexed indirect X) + case 0xc7: this.ZeroPageRead(); this.DCP(); break; // *DCP (zero page) + case 0xcb: this.ImmediateRead(); this.AXS(); break; // *AXS (immediate) + case 0xcf: this.AbsoluteRead(); this.DCP(); break; // *DCP (absolute) - case 0xd2: Jam(); break; // *JAM - case 0xd3: IndirectIndexedYAddress(); FixupRead(); DCP(); break; // *DCP (indirect indexed Y) - case 0xd7: ZeroPageXRead(); DCP(); break; // *DCP (zero page, X) - case 0xda: SwallowRead(); break; // *NOP (implied) - case 0xdb: AbsoluteYAddress(); FixupRead(); DCP(); break; // *DCP (absolute, Y) - case 0xdc: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0xdf: AbsoluteXAddress(); FixupRead(); DCP(); break; // *DCP (absolute, X) + case 0xd2: this.Jam(); break; // *JAM + case 0xd3: this.IndirectIndexedYAddress(); this.FixupRead(); this.DCP(); break; // *DCP (indirect indexed Y) + case 0xd7: this.ZeroPageXRead(); this.DCP(); break; // *DCP (zero page, X) + case 0xda: this.SwallowRead(); break; // *NOP (implied) + case 0xdb: this.AbsoluteYAddress(); this.FixupRead(); this.DCP(); break; // *DCP (absolute, Y) + case 0xdc: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0xdf: this.AbsoluteXAddress(); this.FixupRead(); this.DCP(); break; // *DCP (absolute, X) - case 0xe3: IndexedIndirectXRead(); ISB(); break; // *ISB (indexed indirect X) - case 0xe7: ZeroPageRead(); ISB(); break; // *ISB (zero page) - case 0xeb: ImmediateRead(); SBC(); break; // *SBC (immediate) - case 0xef: AbsoluteRead(); ISB(); break; // *ISB (absolute) + case 0xe3: this.IndexedIndirectXRead(); this.ISB(); break; // *ISB (indexed indirect X) + case 0xe7: this.ZeroPageRead(); this.ISB(); break; // *ISB (zero page) + case 0xeb: this.ImmediateRead(); this.SBC(); break; // *SBC (immediate) + case 0xef: this.AbsoluteRead(); this.ISB(); break; // *ISB (absolute) - case 0xf2: Jam(); break; // *JAM - case 0xf3: IndirectIndexedYAddress(); FixupRead(); ISB(); break; // *ISB (indirect indexed Y) - case 0xf7: ZeroPageXRead(); ISB(); break; // *ISB (zero page, X) - case 0xfa: SwallowRead(); break; // *NOP (implied) - case 0xfb: AbsoluteYAddress(); FixupRead(); ISB(); break; // *ISB (absolute, Y) - case 0xfc: AbsoluteXAddress(); MaybeFixupRead(); break; // *NOP (absolute, X) - case 0xff: AbsoluteXAddress(); FixupRead(); ISB(); break; // *ISB (absolute, X) + case 0xf2: this.Jam(); break; // *JAM + case 0xf3: this.IndirectIndexedYAddress(); this.FixupRead(); this.ISB(); break; // *ISB (indirect indexed Y) + case 0xf7: this.ZeroPageXRead(); this.ISB(); break; // *ISB (zero page, X) + case 0xfa: this.SwallowRead(); break; // *NOP (implied) + case 0xfb: this.AbsoluteYAddress(); this.FixupRead(); this.ISB(); break; // *ISB (absolute, Y) + case 0xfc: this.AbsoluteXAddress(); this.MaybeFixupRead(); break; // *NOP (absolute, X) + case 0xff: this.AbsoluteXAddress(); this.FixupRead(); this.ISB(); break; // *ISB (absolute, X) } - return cycles != Cycles; + return cycles != this.Cycles; } #endregion @@ -145,8 +145,8 @@ namespace M6502 protected override void ModifyWrite(byte data) { // The read will have already taken place... - MemoryWrite(); // Modify cycle - MemoryWrite(data); // Write cycle + this.MemoryWrite(); // Modify cycle + this.MemoryWrite(data); // Write cycle } #endregion @@ -155,22 +155,22 @@ namespace M6502 protected override void IndirectAddress() { - AbsoluteAddress(); - GetAddressPaged(); + this.AbsoluteAddress(); + this.GetAddressPaged(); } #region Address page fixup protected override void Fixup() { - MemoryRead(); - Bus.Address.High = FixedPage; + this.MemoryRead(); + this.Bus.Address.High = this.FixedPage; } protected override void FixupBranch(sbyte relative) { - NoteFixedAddress(PC.Word + relative); - MaybeFixup(); + this.NoteFixedAddress(this.PC.Word + relative); + this.MaybeFixup(); } #endregion @@ -185,11 +185,11 @@ namespace M6502 private void ARR() { - var value = Bus.Data; - if (DecimalMasked != 0) - ARR_d(value); + var value = this.Bus.Data; + if (this.DecimalMasked != 0) + this.ARR_d(value); else - ARR_b(value); + this.ARR_b(value); } private void ARR_d(byte value) @@ -197,26 +197,26 @@ namespace M6502 // With thanks to https://github.com/TomHarte/CLK // What a very strange instruction ARR is... - A &= value; - var unshiftedA = A; - A = Through(A >> 1 | Carry << 7); - SetFlag(StatusBits.VF, OverflowTest((byte)(A ^ A << 1))); + this.A &= value; + var unshiftedA = this.A; + this.A = this.Through(this.A >> 1 | this.Carry << 7); + this.SetFlag(StatusBits.VF, OverflowTest((byte)(this.A ^ this.A << 1))); if (LowerNibble(unshiftedA) + (unshiftedA & 0x1) > 5) - A = (byte)(LowerNibble((byte)(A + 6)) | HigherNibble(A)); + this.A = (byte)(LowerNibble((byte)(this.A + 6)) | HigherNibble(this.A)); - SetFlag(StatusBits.CF, HigherNibble(unshiftedA) + (unshiftedA & 0x10) > 0x50); + this.SetFlag(StatusBits.CF, HigherNibble(unshiftedA) + (unshiftedA & 0x10) > 0x50); - if (Carry != 0) - A += 0x60; + if (this.Carry != 0) + this.A += 0x60; } private void ARR_b(byte value) { - A &= value; - A = Through(A >> 1 | Carry << 7); - SetFlag(StatusBits.CF, OverflowTest(A)); - SetFlag(StatusBits.VF, OverflowTest((byte)(A ^ A << 1))); + this.A &= value; + this.A = this.Through(this.A >> 1 | this.Carry << 7); + this.SetFlag(StatusBits.CF, OverflowTest(this.A)); + this.SetFlag(StatusBits.VF, OverflowTest((byte)(this.A ^ this.A << 1))); } #endregion @@ -236,108 +236,108 @@ namespace M6502 //this.MemoryWrite(updated); byte updated; - if (Fixed) + if (this.Fixed) { - updated = (byte)(data & FixedPage); - Bus.Address.High = updated; + updated = (byte)(data & this.FixedPage); + this.Bus.Address.High = updated; } else { - updated = (byte)(data & UnfixedPage); - Bus.Address.High = updated; + updated = (byte)(data & this.UnfixedPage); + this.Bus.Address.High = updated; } - MemoryWrite(updated); + this.MemoryWrite(updated); } - private void SHA() => StoreFixupEffect((byte)(A & X)); + private void SHA() => this.StoreFixupEffect((byte)(this.A & this.X)); - private void SYA() => StoreFixupEffect(Y); + private void SYA() => this.StoreFixupEffect(this.Y); - private void SXA() => StoreFixupEffect(X); + private void SXA() => this.StoreFixupEffect(this.X); #endregion private void ANC() { - AndR(); - SetFlag(StatusBits.CF, NegativeTest(A)); + this.AndR(); + this.SetFlag(StatusBits.CF, NegativeTest(this.A)); } private void AXS() { - X = Through(BinarySUB((byte)(A & X))); - ResetFlag(StatusBits.CF, Intermediate.High); + this.X = this.Through(this.BinarySUB((byte)(this.A & this.X))); + this.ResetFlag(StatusBits.CF, this.Intermediate.High); } private void Jam() { - Bus.Address.Assign(PC); - MemoryRead(); - MemoryRead(0xff, 0xff); - Bus.Address.Low = 0xfe; - MemoryRead(); - MemoryRead(); - Bus.Address.Low = 0xff; - MemoryRead(); - MemoryRead(); - MemoryRead(); - MemoryRead(); - MemoryRead(); - MemoryRead(); + this.Bus.Address.Assign(this.PC); + this.MemoryRead(); + this.MemoryRead(0xff, 0xff); + this.Bus.Address.Low = 0xfe; + this.MemoryRead(); + this.MemoryRead(); + this.Bus.Address.Low = 0xff; + this.MemoryRead(); + this.MemoryRead(); + this.MemoryRead(); + this.MemoryRead(); + this.MemoryRead(); + this.MemoryRead(); } private void TAS() { - S = (byte)(A & X); - SHA(); + this.S = (byte)(this.A & this.X); + this.SHA(); } - private void LAS() => A = X = S = Through(MemoryRead() & S); + private void LAS() => this.A = this.X = this.S = this.Through(this.MemoryRead() & this.S); - private void ANE() => A = Through((A | 0xee) & X & Bus.Data); + private void ANE() => this.A = this.Through((this.A | 0xee) & this.X & this.Bus.Data); - private void ATX() => A = X = Through((A | 0xee) & Bus.Data); + private void ATX() => this.A = this.X = this.Through((this.A | 0xee) & this.Bus.Data); private void ASR() { - AndR(); - A = LSR(A); + this.AndR(); + this.A = this.LSR(this.A); } private void ISB() { - ModifyWrite(INC()); - SBC(); + this.ModifyWrite(this.INC()); + this.SBC(); } private void RLA() { - ModifyWrite(ROL()); - AndR(); + this.ModifyWrite(this.ROL()); + this.AndR(); } private void RRA() { - ModifyWrite(ROR()); - ADC(); + this.ModifyWrite(this.ROR()); + this.ADC(); } private void SLO() { - ModifyWrite(ASL()); - OrR(); + this.ModifyWrite(this.ASL()); + this.OrR(); } private void SRE() { - ModifyWrite(LSR()); - EorR(); + this.ModifyWrite(this.LSR()); + this.EorR(); } private void DCP() { - ModifyWrite(DEC()); - CMP(A); + this.ModifyWrite(this.DEC()); + this.CMP(this.A); } #endregion diff --git a/M6502/Profiler.cs b/M6502/Profiler.cs index 4eb1603..058d15e 100644 --- a/M6502/Profiler.cs +++ b/M6502/Profiler.cs @@ -31,8 +31,8 @@ if (activate) { - this.processor.RaisingSYNC += Processor_RaisingSYNC; - this.processor.ExecutedInstruction += Processor_ExecutedInstruction; + this.processor.RaisingSYNC += this.Processor_RaisingSYNC; + this.processor.ExecutedInstruction += this.Processor_ExecutedInstruction; } } @@ -62,147 +62,147 @@ { get { - Debug.Assert(totalCyclesValid); - return totalCycles; + Debug.Assert(this.totalCyclesValid); + return this.totalCycles; } private set { - Debug.Assert(!totalCyclesValid); - totalCycles = value; - totalCyclesValid = true; + Debug.Assert(!this.totalCyclesValid); + this.totalCycles = value; + this.totalCyclesValid = true; } } public void Generate() { - OnStartingOutput(); + this.OnStartingOutput(); try { - EmitProfileInformation(); + this.EmitProfileInformation(); } finally { - OnFinishedOutput(); + this.OnFinishedOutput(); } } private void EmitProfileInformation() { - TotalCycles = instructionCycles.Sum(); + this.TotalCycles = this.instructionCycles.Sum(); - EmitProfileLineInformation(); - EmitProfileScopeInformation(); - EmitProfileInstructionInformation(); + this.EmitProfileLineInformation(); + this.EmitProfileScopeInformation(); + this.EmitProfileInstructionInformation(); } private void EmitProfileScopeInformation() { - OnStartingScopeOutput(); + this.OnStartingScopeOutput(); try { - foreach (var (id, cycles) in scopeCycles) + foreach (var (id, cycles) in this.scopeCycles) { - var symbol = symbols.LookupLabelByID(id); + var symbol = this.symbols.LookupLabelByID(id); Debug.Assert(symbol != null); - var available = ExtractCycleDistribution((ushort)symbol.Value, out var _, out var _, out var count); + var available = this.ExtractCycleDistribution((ushort)symbol.Value, out var _, out var _, out var count); Debug.Assert(available); - OnEmitScope(id, cycles, count); + this.OnEmitScope(id, cycles, count); } } finally { - OnFinishedScopeOutput(); + this.OnFinishedScopeOutput(); } } private void EmitProfileLineInformation() { - OnStartingLineOutput(); + this.OnStartingLineOutput(); try { // For each memory address for (var i = 0; i < 0x10000; ++i) { var address = (ushort)i; - var available = ExtractCycleDistribution(address, out var cycleDistributions, out var cycles, out var count); + var available = this.ExtractCycleDistribution(address, out var cycleDistributions, out var cycles, out var count); if (available) { // Dump a profile/disassembly line - var source = disassembler.Disassemble(address); + var source = this.disassembler.Disassemble(address); Debug.Assert(cycleDistributions != null); - OnEmitLine(address, source, cycles, count, cycleDistributions); + this.OnEmitLine(address, source, cycles, count, cycleDistributions); } } } finally { - OnFinishedLineOutput(); + this.OnFinishedLineOutput(); } } private void EmitProfileInstructionInformation() { - OnStartingInstructionOutput(); + this.OnStartingInstructionOutput(); try { // For each instruction for (var i = 0; i < 0x100; ++i) { // If there are any cycles associated - var cycles = instructionCycles[i]; + var cycles = this.instructionCycles[i]; if (cycles > 0) { - var count = instructionCounts[i]; + var count = this.instructionCounts[i]; Debug.Assert(count > 0); var instruction = (byte)i; // Emit an instruction event - OnEmitInstruction(instruction, cycles, count); + this.OnEmitInstruction(instruction, cycles, count); } } } finally { - OnFinishedInstructionOutput(); + this.OnFinishedInstructionOutput(); } } private void Processor_RaisingSYNC(object? sender, EventArgs e) { - executingAddress = processor.Bus.Address.Word; - ++instructionCounts[executingInstruction = processor.Bus.Data]; + this.executingAddress = this.processor.Bus.Address.Word; + ++this.instructionCounts[this.executingInstruction = this.processor.Bus.Data]; } private void Processor_ExecutedInstruction(object? sender, EventArgs e) { - var cycles = processor.Cycles; + var cycles = this.processor.Cycles; { - var addressDistribution = addressCycleDistributions[executingAddress]; + var addressDistribution = this.addressCycleDistributions[this.executingAddress]; if (addressDistribution == null) { - addressCycleDistributions[executingAddress] = addressDistribution = []; + this.addressCycleDistributions[this.executingAddress] = addressDistribution = []; } _ = addressDistribution.TryGetValue(cycles, out var current); addressDistribution[cycles] = ++current; } - instructionCycles[executingInstruction] += cycles; + this.instructionCycles[this.executingInstruction] += cycles; { - var scope = symbols.LookupScopeByAddress(executingAddress); + var scope = this.symbols.LookupScopeByAddress(this.executingAddress); if (scope != null) { var id = scope.ID; // Current will be initialised to zero, if absent - _ = scopeCycles.TryGetValue(id, out var current); - scopeCycles[id] = current + cycles; + _ = this.scopeCycles.TryGetValue(id, out var current); + this.scopeCycles[id] = current + cycles; } } } private bool ExtractCycleDistribution(ushort address, out Dictionary? cycleDistribution, out long cycleCount, out long hitCount) { - cycleDistribution = addressCycleDistributions[address]; + cycleDistribution = this.addressCycleDistributions[address]; if (cycleDistribution == null) { cycleCount = -1; diff --git a/M6502/WDC65C02.cs b/M6502/WDC65C02.cs index 4563732..c3bba37 100644 --- a/M6502/WDC65C02.cs +++ b/M6502/WDC65C02.cs @@ -13,22 +13,22 @@ namespace M6502 private bool Stopped { - get => _stopped; set => _stopped = value; + get => this._stopped; set => this._stopped = value; } private bool Waiting { - get => _waiting; set => _waiting = value; + get => this._waiting; set => this._waiting = value; } - private bool Paused => Stopped || Waiting; + private bool Paused => this.Stopped || this.Waiting; #region Interrupts protected override void Interrupt(byte vector, InterruptSource source, InterruptType type) { base.Interrupt(vector, source, type); - ResetFlag(StatusBits.DF); // Disable decimal mode (Change from MOS6502) + this.ResetFlag(StatusBits.DF); // Disable decimal mode (Change from MOS6502) } #endregion @@ -42,130 +42,130 @@ namespace M6502 return true; } - var cycles = Cycles; - switch (OpCode) + var cycles = this.Cycles; + switch (this.OpCode) { - case 0x02: SwallowFetch(); break; // NOP + case 0x02: this.SwallowFetch(); break; // NOP case 0x03: break; // null - case 0x04: ZeroPageRead(); TSB(); break; // TSB zp - case 0x07: ZeroPageRead(); RMB(Bit(0)); break; // RMB0 zp + case 0x04: this.ZeroPageRead(); this.TSB(); break; // TSB zp + case 0x07: this.ZeroPageRead(); this.RMB(Bit(0)); break; // RMB0 zp case 0x0b: break; // null - case 0x0c: AbsoluteRead(); TSB(); break; // TSB a - case 0x0f: ZeroPageRead(); BBR(Bit(0)); break; // BBR0 r + case 0x0c: this.AbsoluteRead(); this.TSB(); break; // TSB a + case 0x0f: this.ZeroPageRead(); this.BBR(Bit(0)); break; // BBR0 r - case 0x12: ZeroPageIndirectAddress(); OrR(); break; // ORA (zp),y + case 0x12: this.ZeroPageIndirectAddress(); this.OrR(); break; // ORA (zp),y case 0x13: break; // null - case 0x14: ZeroPageRead(); TRB(); break; // TRB zp - case 0x17: ZeroPageRead(); RMB(Bit(1)); break; // RMB1 zp - case 0x1a: SwallowRead(); A = INC(A); break; // INC A + case 0x14: this.ZeroPageRead(); this.TRB(); break; // TRB zp + case 0x17: this.ZeroPageRead(); this.RMB(Bit(1)); break; // RMB1 zp + case 0x1a: this.SwallowRead(); this.A = this.INC(this.A); break; // INC A case 0x1b: break; // null - case 0x1c: AbsoluteRead(); TRB(); break; // TRB a - case 0x1f: ZeroPageRead(); BBR(Bit(1)); break; // BBR1 r + case 0x1c: this.AbsoluteRead(); this.TRB(); break; // TRB a + case 0x1f: this.ZeroPageRead(); this.BBR(Bit(1)); break; // BBR1 r - case 0x22: SwallowFetch(); break; // NOP + case 0x22: this.SwallowFetch(); break; // NOP case 0x23: break; // null - case 0x27: ZeroPageRead(); RMB(Bit(2)); break; // RMB2 zp + case 0x27: this.ZeroPageRead(); this.RMB(Bit(2)); break; // RMB2 zp case 0x2b: break; // null - case 0x2f: ZeroPageRead(); BBR(Bit(2)); break; // BBR2 r + case 0x2f: this.ZeroPageRead(); this.BBR(Bit(2)); break; // BBR2 r - case 0x32: ZeroPageIndirectRead(); AndR(); break; // AND (zp) + case 0x32: this.ZeroPageIndirectRead(); this.AndR(); break; // AND (zp) case 0x33: break; // null case 0x34: break; // BIT zp,x - case 0x37: ZeroPageRead(); RMB(Bit(3)); break; // RMB3 zp - case 0x3a: SwallowRead(); A = DEC(A); break; // DEC A + case 0x37: this.ZeroPageRead(); this.RMB(Bit(3)); break; // RMB3 zp + case 0x3a: this.SwallowRead(); this.A = this.DEC(this.A); break; // DEC A case 0x3b: break; // null case 0x3c: break; // BIT a,x - case 0x3f: ZeroPageRead(); BBR(Bit(3)); break; // BBR3 r + case 0x3f: this.ZeroPageRead(); this.BBR(Bit(3)); break; // BBR3 r - case 0x42: SwallowFetch(); break; // NOP + case 0x42: this.SwallowFetch(); break; // NOP case 0x43: break; // null - case 0x47: ZeroPageRead(); RMB(Bit(4)); break; // RMB4 zp + case 0x47: this.ZeroPageRead(); this.RMB(Bit(4)); break; // RMB4 zp case 0x4b: break; // null - case 0x4f: ZeroPageRead(); BBR(Bit(4)); break; // BBR4 r + case 0x4f: this.ZeroPageRead(); this.BBR(Bit(4)); break; // BBR4 r - case 0x52: ZeroPageIndirectRead(); EorR(); break; // EOR (zp) + case 0x52: this.ZeroPageIndirectRead(); this.EorR(); break; // EOR (zp) case 0x53: break; // null - case 0x57: ZeroPageRead(); RMB(Bit(5)); break; // RMB5 zp - case 0x5a: SwallowRead(); Push(Y); break; // PHY s + case 0x57: this.ZeroPageRead(); this.RMB(Bit(5)); break; // RMB5 zp + case 0x5a: this.SwallowRead(); this.Push(this.Y); break; // PHY s case 0x5b: break; // null case 0x5c: break; // null - case 0x5f: ZeroPageRead(); BBR(Bit(5)); break; // BBR5 r + case 0x5f: this.ZeroPageRead(); this.BBR(Bit(5)); break; // BBR5 r - case 0x62: SwallowFetch(); break; // *NOP + case 0x62: this.SwallowFetch(); break; // *NOP case 0x63: break; // null - case 0x64: ZeroPageAddress(); MemoryWrite(0); break; // STZ zp - case 0x67: ZeroPageRead(); RMB(Bit(6)); break; // RMB6 zp + case 0x64: this.ZeroPageAddress(); this.MemoryWrite(0); break; // STZ zp + case 0x67: this.ZeroPageRead(); this.RMB(Bit(6)); break; // RMB6 zp case 0x6b: break; // null - case 0x6f: ZeroPageRead(); BBR(Bit(6)); break; // BBR6 r + case 0x6f: this.ZeroPageRead(); this.BBR(Bit(6)); break; // BBR6 r - case 0x72: ZeroPageIndirectRead(); ADC(); break; // ADC (zp) + case 0x72: this.ZeroPageIndirectRead(); this.ADC(); break; // ADC (zp) case 0x73: break; // null - case 0x74: ZeroPageXAddress(); MemoryWrite(0); break; // STZ zp,x - case 0x77: ZeroPageRead(); RMB(Bit(7)); break; // RMB7 zp - case 0x7a: SwallowRead(); SwallowPop(); Y = Through(Pop()); break; // PLY s + case 0x74: this.ZeroPageXAddress(); this.MemoryWrite(0); break; // STZ zp,x + case 0x77: this.ZeroPageRead(); this.RMB(Bit(7)); break; // RMB7 zp + case 0x7a: this.SwallowRead(); this.SwallowPop(); this.Y = this.Through(this.Pop()); break; // PLY s case 0x7b: break; // null case 0x7c: break; // JMP (a,x) - case 0x7f: ZeroPageRead(); BBR(Bit(7)); break; // BBR7 r + case 0x7f: this.ZeroPageRead(); this.BBR(Bit(7)); break; // BBR7 r - case 0x80: Branch(true); break; // BRA r + case 0x80: this.Branch(true); break; // BRA r case 0x83: break; // null - case 0x87: ZeroPageRead(); SMB(Bit(0)); break; // SMB0 zp + case 0x87: this.ZeroPageRead(); this.SMB(Bit(0)); break; // SMB0 zp case 0x89: break; // BIT # (TBC) case 0x8b: break; // null - case 0x8f: ZeroPageRead(); BBS(Bit(0)); break; // BBS0 r + case 0x8f: this.ZeroPageRead(); this.BBS(Bit(0)); break; // BBS0 r - case 0x92: ZeroPageIndirectAddress(); MemoryWrite(A); break; // STA (zp) + case 0x92: this.ZeroPageIndirectAddress(); this.MemoryWrite(this.A); break; // STA (zp) case 0x93: break; // null - case 0x97: ZeroPageRead(); SMB(Bit(1)); break; // SMB1 zp + case 0x97: this.ZeroPageRead(); this.SMB(Bit(1)); break; // SMB1 zp case 0x9b: break; // null - case 0x9c: AbsoluteAddress(); MemoryWrite(0); break; // STZ a - case 0x9e: AbsoluteXAddress(); MemoryWrite(0); break; // STZ a,x - case 0x9f: ZeroPageRead(); BBS(Bit(1)); break; // BBS1 r + case 0x9c: this.AbsoluteAddress(); this.MemoryWrite(0); break; // STZ a + case 0x9e: this.AbsoluteXAddress(); this.MemoryWrite(0); break; // STZ a,x + case 0x9f: this.ZeroPageRead(); this.BBS(Bit(1)); break; // BBS1 r case 0xa3: break; // null - case 0xa7: ZeroPageRead(); SMB(Bit(2)); break; // SMB2 zp + case 0xa7: this.ZeroPageRead(); this.SMB(Bit(2)); break; // SMB2 zp case 0xab: break; // null - case 0xaf: ZeroPageRead(); BBS(Bit(2)); break; // BBS2 r + case 0xaf: this.ZeroPageRead(); this.BBS(Bit(2)); break; // BBS2 r - case 0xb2: ZeroPageIndirectRead(); A = Through(); break; // LDA (zp) + case 0xb2: this.ZeroPageIndirectRead(); this.A = this.Through(); break; // LDA (zp) case 0xb3: break; // null - case 0xb7: ZeroPageRead(); SMB(Bit(3)); break; // SMB3 zp + case 0xb7: this.ZeroPageRead(); this.SMB(Bit(3)); break; // SMB3 zp case 0xbb: break; // null - case 0xbf: ZeroPageRead(); BBS(Bit(3)); break; // BBS3 r + case 0xbf: this.ZeroPageRead(); this.BBS(Bit(3)); break; // BBS3 r case 0xc3: break; // null - case 0xc7: ZeroPageRead(); SMB(Bit(4)); break; // SMB4 zp - case 0xcb: SwallowRead(); Waiting = true; break; // WAI i - case 0xcf: ZeroPageRead(); BBS(Bit(4)); break; // BBS4 r + case 0xc7: this.ZeroPageRead(); this.SMB(Bit(4)); break; // SMB4 zp + case 0xcb: this.SwallowRead(); this.Waiting = true; break; // WAI i + case 0xcf: this.ZeroPageRead(); this.BBS(Bit(4)); break; // BBS4 r - case 0xd2: ZeroPageIndirectRead(); CMP(A); break; // CMP (zp) + case 0xd2: this.ZeroPageIndirectRead(); this.CMP(this.A); break; // CMP (zp) case 0xd3: break; // null - case 0xd7: ZeroPageRead(); SMB(Bit(5)); break; // SMB5 zp - case 0xda: SwallowRead(); Push(X); break; // PHX s - case 0xdb: SwallowRead(); Stopped = true; break; // STP i - case 0xdc: SwallowRead(); break; // null - case 0xdf: ZeroPageRead(); BBS(Bit(5)); break; // BBS5 r + case 0xd7: this.ZeroPageRead(); this.SMB(Bit(5)); break; // SMB5 zp + case 0xda: this.SwallowRead(); this.Push(this.X); break; // PHX s + case 0xdb: this.SwallowRead(); this.Stopped = true; break; // STP i + case 0xdc: this.SwallowRead(); break; // null + case 0xdf: this.ZeroPageRead(); this.BBS(Bit(5)); break; // BBS5 r case 0xe3: break; // null - case 0xe7: ZeroPageRead(); SMB(Bit(6)); break; // SMB6 zp + case 0xe7: this.ZeroPageRead(); this.SMB(Bit(6)); break; // SMB6 zp case 0xeb: break; // null - case 0xef: ZeroPageRead(); BBS(Bit(6)); break; // BBS6 r + case 0xef: this.ZeroPageRead(); this.BBS(Bit(6)); break; // BBS6 r - case 0xf2: ZeroPageIndirectRead(); SBC(); break; // SBC (zp) + case 0xf2: this.ZeroPageIndirectRead(); this.SBC(); break; // SBC (zp) case 0xf3: break; // null - case 0xf7: ZeroPageRead(); SMB(Bit(7)); break; // SMB7 zp - case 0xfa: SwallowRead(); SwallowPop(); X = Through(Pop()); break; // PLX s + case 0xf7: this.ZeroPageRead(); this.SMB(Bit(7)); break; // SMB7 zp + case 0xfa: this.SwallowRead(); this.SwallowPop(); this.X = this.Through(this.Pop()); break; // PLX s case 0xfb: break; // null case 0xfc: break; // null - case 0xff: ZeroPageRead(); BBS(Bit(7)); break; // BBS7 r + case 0xff: this.ZeroPageRead(); this.BBS(Bit(7)); break; // BBS7 r } - return cycles != Cycles; + return cycles != this.Cycles; } public override void PoweredStep() { - if (!Paused) + if (!this.Paused) { base.PoweredStep(); } @@ -174,19 +174,19 @@ namespace M6502 protected override void OnLoweredRESET() { base.OnLoweredRESET(); - Stopped = Waiting = false; + this.Stopped = this.Waiting = false; } protected override void OnLoweredINT() { base.OnLoweredINT(); - Waiting = false; + this.Waiting = false; } protected override void OnLoweredNMI() { base.OnLoweredNMI(); - Waiting = false; + this.Waiting = false; } #endregion @@ -196,8 +196,8 @@ namespace M6502 protected override void ModifyWrite(byte data) { // The read will have already taken place... - MemoryRead(); // Modify cycle (Change from MOS6502) - MemoryWrite(data); // Write cycle + this.MemoryRead(); // Modify cycle (Change from MOS6502) + this.MemoryWrite(data); // Write cycle } #endregion @@ -210,22 +210,22 @@ namespace M6502 protected override byte FetchByte() { - lastFetchAddress.Assign(PC); + this.lastFetchAddress.Assign(this.PC); return base.FetchByte(); } protected override void Fixup() { - var fixingLow = Bus.Address.Low; - MemoryRead(lastFetchAddress); - Bus.Address.Assign(fixingLow, FixedPage); + var fixingLow = this.Bus.Address.Low; + this.MemoryRead(this.lastFetchAddress); + this.Bus.Address.Assign(fixingLow, this.FixedPage); } protected override void FixupBranch(sbyte relative) { - NoteFixedAddress(PC.Word + relative); - lastFetchAddress.Assign(Bus.Address); // Effectively negate the use of "lastFetchAddress" for branch fixup usages - MaybeFixup(); + this.NoteFixedAddress(this.PC.Word + relative); + this.lastFetchAddress.Assign(this.Bus.Address); // Effectively negate the use of "lastFetchAddress" for branch fixup usages + this.MaybeFixup(); } #endregion @@ -234,20 +234,20 @@ namespace M6502 protected void GetAddress() { - GetWordPaged(); + this.GetWordPaged(); - if (Bus.Address.Low == 0) + if (this.Bus.Address.Low == 0) { - Bus.Address.High++; + this.Bus.Address.High++; } - Bus.Address.Assign(Intermediate.Low, MemoryRead()); + this.Bus.Address.Assign(this.Intermediate.Low, this.MemoryRead()); } protected override void IndirectAddress() { - AbsoluteAddress(); - GetAddress(); + this.AbsoluteAddress(); + this.GetAddress(); } #endregion @@ -256,8 +256,8 @@ namespace M6502 private void ZeroPageIndirectRead() { - ZeroPageIndirectAddress(); - MemoryRead(); + this.ZeroPageIndirectAddress(); + this.MemoryRead(); } #endregion @@ -266,40 +266,40 @@ namespace M6502 private void RMB(byte flag) { - MemoryRead(); - Bus.Data &= (byte)~flag; - MemoryWrite(); + this.MemoryRead(); + this.Bus.Data &= (byte)~flag; + this.MemoryWrite(); } private void SMB(byte flag) { - MemoryRead(); - Bus.Data |= flag; - MemoryWrite(); + this.MemoryRead(); + this.Bus.Data |= flag; + this.MemoryWrite(); } private void BBS(byte flag) { - MemoryRead(); - Branch(Bus.Data & flag); + this.MemoryRead(); + this.Branch(this.Bus.Data & flag); } private void BBR(byte flag) { - MemoryRead(); - BranchNot(Bus.Data & flag); + this.MemoryRead(); + this.BranchNot(this.Bus.Data & flag); } private void TSB() { - AdjustZero((byte)(A & Bus.Data)); - ModifyWrite((byte)(A | Bus.Data)); + this.AdjustZero((byte)(this.A & this.Bus.Data)); + this.ModifyWrite((byte)(this.A | this.Bus.Data)); } private void TRB() { - AdjustZero((byte)(A & Bus.Data)); - ModifyWrite((byte)(~A & Bus.Data)); + this.AdjustZero((byte)(this.A & this.Bus.Data)); + this.ModifyWrite((byte)(~this.A & this.Bus.Data)); } } } \ No newline at end of file