diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index d40ffe1..808857d 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -34,16 +34,16 @@ namespace EightBit protected override Register16 GetWord() { - this.intermediate.High = this.BusRead(); + this.intermediate.High = this.MemoryRead(); ++this.Bus.Address.Word; - this.intermediate.Low = this.BusRead(); + this.intermediate.Low = this.MemoryRead(); return this.intermediate; } protected override Register16 GetWordPaged(byte page, byte offset) { - this.intermediate.High = this.BusRead(offset, page); - this.intermediate.Low = this.BusRead(++offset, page); + this.intermediate.High = this.MemoryRead(offset, page); + this.intermediate.Low = this.MemoryRead(++offset, page); return this.intermediate; } @@ -62,15 +62,15 @@ namespace EightBit protected override void SetWord(Register16 value) { - this.BusWrite(value.High); + this.MemoryWrite(value.High); ++this.Bus.Address.Word; - this.BusWrite(value.Low); + this.MemoryWrite(value.Low); } protected override void SetWordPaged(byte page, byte offset, Register16 value) { - this.BusWrite(offset, page, value.High); - this.BusWrite(++offset, page, value.Low); + this.MemoryWrite(offset, page, value.High); + this.MemoryWrite(++offset, page, value.Low); } } } diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index 562952e..588754e 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -127,9 +127,9 @@ namespace EightBit this.Jump(0); } - protected sealed override void Push(byte value) => this.BusWrite(--this.SP.Word, value); + protected sealed override void Push(byte value) => this.MemoryWrite(--this.SP.Word, value); - protected sealed override byte Pop() => this.BusRead(this.SP.Word++); + protected sealed override byte Pop() => this.MemoryRead(this.SP.Word++); protected sealed override Register16 GetWord() { @@ -196,7 +196,7 @@ namespace EightBit var offsetAddress = this.PC.Word++; if (condition) { - var offset = (sbyte)this.BusRead(offsetAddress); + var offset = (sbyte)this.MemoryRead(offsetAddress); this.JumpRelative(offset); } diff --git a/EightBit/LittleEndianProcessor.cs b/EightBit/LittleEndianProcessor.cs index c8a68ce..66ff1d8 100644 --- a/EightBit/LittleEndianProcessor.cs +++ b/EightBit/LittleEndianProcessor.cs @@ -35,16 +35,16 @@ namespace EightBit protected override Register16 GetWord() { - this.intermediate.Low = this.BusRead(); + this.intermediate.Low = this.MemoryRead(); ++this.Bus.Address.Word; - this.intermediate.High = this.BusRead(); + this.intermediate.High = this.MemoryRead(); return this.intermediate; } protected override Register16 GetWordPaged(byte page, byte offset) { - this.intermediate.Low = this.BusRead(offset, page); - this.intermediate.High = this.BusRead(++offset, page); + this.intermediate.Low = this.MemoryRead(offset, page); + this.intermediate.High = this.MemoryRead(++offset, page); return this.intermediate; } @@ -63,15 +63,15 @@ namespace EightBit protected override void SetWord(Register16 value) { - this.BusWrite(value.Low); + this.MemoryWrite(value.Low); ++this.Bus.Address.Word; - this.BusWrite(value.High); + this.MemoryWrite(value.High); } protected override void SetWordPaged(byte page, byte offset, Register16 value) { - this.BusWrite(offset, page, value.Low); - this.BusWrite(++offset, page, value.High); + this.MemoryWrite(offset, page, value.Low); + this.MemoryWrite(++offset, page, value.High); } } } diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 13793db..cbd105b 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -136,47 +136,51 @@ namespace EightBit protected virtual void HandleINT() => this.RaiseINT(); - protected void BusWrite(byte low, byte high, byte data) + protected void MemoryWrite(byte low, byte high, byte data) { this.Bus.Address.Low = low; this.Bus.Address.High = high; - this.BusWrite(data); + this.MemoryWrite(data); } - protected void BusWrite(ushort address, byte data) + protected void MemoryWrite(ushort address, byte data) { this.Bus.Address.Word = address; - this.BusWrite(data); + this.MemoryWrite(data); } - protected void BusWrite(Register16 address, byte data) => this.BusWrite(address.Word, data); + protected void MemoryWrite(Register16 address, byte data) => this.MemoryWrite(address.Word, data); - protected void BusWrite(byte data) + protected void MemoryWrite(byte data) { this.Bus.Data = data; - this.BusWrite(); + this.MemoryWrite(); } + protected virtual void MemoryWrite() => this.BusWrite(); + protected virtual void BusWrite() => this.Bus.Write(); // N.B. Should be the only real call into the "Bus.Write" code. - protected byte BusRead(byte low, byte high) + protected byte MemoryRead(byte low, byte high) { this.Bus.Address.Low = low; this.Bus.Address.High = high; - return this.BusRead(); + return this.MemoryRead(); } - protected byte BusRead(ushort address) + protected byte MemoryRead(ushort address) { this.Bus.Address.Word = address; - return this.BusRead(); + return this.MemoryRead(); } - protected byte BusRead(Register16 address) => this.BusRead(address.Word); + protected byte MemoryRead(Register16 address) => this.MemoryRead(address.Word); + + protected virtual byte MemoryRead() => this.BusRead(); protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code. - protected byte FetchByte() => this.BusRead(this.PC.Word++); + protected byte FetchByte() => this.MemoryRead(this.PC.Word++); protected abstract Register16 GetWord(); diff --git a/Fuse/TestEvent.cs b/Fuse/TestEvent.cs index ee9eb4e..e91dc60 100644 --- a/Fuse/TestEvent.cs +++ b/Fuse/TestEvent.cs @@ -4,9 +4,8 @@ namespace Fuse { using System; - using System.Diagnostics; + using EightBit; - [DebuggerDisplay("Cycles = {Cycles}, Specifier = {Specifier}, Address = {Address}, Value = {Value}")] public class TestEvent { private int cycles; @@ -23,6 +22,9 @@ namespace Fuse this.Value = value; } + public TestEvent(int cycles, string specifier, ushort address) + : this(cycles, specifier, address, (byte)Mask.Eight) => this.ContentionEvent = true; + public int Cycles => this.cycles; public string Specifier { get; private set; } @@ -31,6 +33,8 @@ namespace Fuse public byte Value { get; private set; } = (byte)EightBit.Mask.Eight; + private bool ContentionEvent { get; set; } = false; + public bool TryParse(Lines lines) { if (lines == null) @@ -47,6 +51,17 @@ namespace Fuse return returned; } + public override string ToString() + { + var possible = $"Cycles = {this.Cycles}, Specifier = {this.Specifier}, Address = {this.Address:X4}"; + if (!this.ContentionEvent) + { + possible += $", Value = {this.Value:X2}"; + } + + return possible; + } + private bool TryParseLine(string line) { var split = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); diff --git a/Intel8080/Intel8080.cs b/Intel8080/Intel8080.cs index e87fdc3..21156b3 100644 --- a/Intel8080/Intel8080.cs +++ b/Intel8080/Intel8080.cs @@ -156,7 +156,7 @@ namespace EightBit case 5: return this.L; case 6: - return this.BusRead(this.HL.Word); + return this.MemoryRead(this.HL.Word); case 7: return this.A; default: @@ -187,7 +187,7 @@ namespace EightBit this.L = value; break; case 6: - this.BusWrite(this.HL.Word, value); + this.MemoryWrite(this.HL.Word, value); break; case 7: this.A = value; @@ -270,11 +270,11 @@ namespace EightBit switch (p) { case 0: // LD (BC),A - this.BusWrite(this.BC, this.A); + this.MemoryWrite(this.BC, this.A); this.Tick(7); break; case 1: // LD (DE),A - this.BusWrite(this.DE, this.A); + this.MemoryWrite(this.DE, this.A); this.Tick(7); break; case 2: // LD (nn),HL @@ -284,7 +284,7 @@ namespace EightBit break; case 3: // LD (nn),A this.Bus.Address.Word = this.FetchWord().Word; - this.BusWrite(this.A); + this.MemoryWrite(this.A); this.Tick(13); break; default: @@ -296,11 +296,11 @@ namespace EightBit switch (p) { case 0: // LD A,(BC) - this.A = this.BusRead(this.BC); + this.A = this.MemoryRead(this.BC); this.Tick(7); break; case 1: // LD A,(DE) - this.A = this.BusRead(this.DE); + this.A = this.MemoryRead(this.DE); this.Tick(7); break; case 2: // LD HL,(nn) @@ -310,7 +310,7 @@ namespace EightBit break; case 3: // LD A,(nn) this.Bus.Address.Word = this.FetchWord().Word; - this.A = this.BusRead(); + this.A = this.MemoryRead(); this.Tick(13); break; default: @@ -811,13 +811,13 @@ namespace EightBit private void XHTL(Register16 exchange) { - this.MEMPTR.Low = this.BusRead(this.SP.Word); + this.MEMPTR.Low = this.MemoryRead(this.SP.Word); ++this.Bus.Address.Word; - this.MEMPTR.High = this.BusRead(); - this.BusWrite(exchange.High); + this.MEMPTR.High = this.MemoryRead(); + this.MemoryWrite(exchange.High); exchange.High = this.MEMPTR.High; --this.Bus.Address.Word; - this.BusWrite(exchange.Low); + this.MemoryWrite(exchange.Low); exchange.Low = this.MEMPTR.Low; } diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index 1af4bb2..f1c60b2 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -181,7 +181,7 @@ namespace EightBit.GameBoy case 5: return this.L; case 6: - return this.BusRead(this.HL.Word); + return this.MemoryRead(this.HL.Word); case 7: return this.A; default: @@ -212,7 +212,7 @@ namespace EightBit.GameBoy this.L = value; break; case 6: - this.BusWrite(this.HL.Word, value); + this.MemoryWrite(this.HL.Word, value); break; case 7: this.A = value; @@ -408,22 +408,22 @@ namespace EightBit.GameBoy switch (p) { case 0: // LD (BC),A - this.BusWrite(this.BC, this.A); + this.MemoryWrite(this.BC, this.A); this.Tick(2); break; case 1: // LD (DE),A - this.BusWrite(this.DE, this.A); + this.MemoryWrite(this.DE, this.A); this.Tick(2); break; case 2: // GB: LDI (HL),A - this.BusWrite(this.HL.Word++, this.A); + this.MemoryWrite(this.HL.Word++, this.A); this.Tick(2); break; case 3: // GB: LDD (HL),A - this.BusWrite(this.HL.Word--, this.A); + this.MemoryWrite(this.HL.Word--, this.A); this.Tick(2); break; @@ -437,22 +437,22 @@ namespace EightBit.GameBoy switch (p) { case 0: // LD A,(BC) - this.A = this.BusRead(this.BC); + this.A = this.MemoryRead(this.BC); this.Tick(2); break; case 1: // LD A,(DE) - this.A = this.BusRead(this.DE); + this.A = this.MemoryRead(this.DE); this.Tick(2); break; case 2: // GB: LDI A,(HL) - this.A = this.BusRead(this.HL.Word++); + this.A = this.MemoryRead(this.HL.Word++); this.Tick(2); break; case 3: // GB: LDD A,(HL) - this.A = this.BusRead(this.HL.Word--); + this.A = this.MemoryRead(this.HL.Word--); this.Tick(2); break; @@ -625,7 +625,7 @@ namespace EightBit.GameBoy break; case 4: // GB: LD (FF00 + n),A - this.BusWrite((ushort)(IoRegisters.BASE + this.FetchByte()), this.A); + this.MemoryWrite((ushort)(IoRegisters.BASE + this.FetchByte()), this.A); this.Tick(3); break; @@ -645,7 +645,7 @@ namespace EightBit.GameBoy break; case 6: // GB: LD A,(FF00 + n) - this.A = this.BusRead((ushort)(IoRegisters.BASE + this.FetchByte())); + this.A = this.MemoryRead((ushort)(IoRegisters.BASE + this.FetchByte())); this.Tick(3); break; @@ -721,21 +721,21 @@ namespace EightBit.GameBoy this.Tick(3); break; case 4: // GB: LD (FF00 + C),A - this.BusWrite((ushort)(IoRegisters.BASE + this.C), this.A); + this.MemoryWrite((ushort)(IoRegisters.BASE + this.C), this.A); this.Tick(2); break; case 5: // GB: LD (nn),A this.Bus.Address.Word = this.MEMPTR.Word = this.FetchWord().Word; - this.BusWrite(this.A); + this.MemoryWrite(this.A); this.Tick(4); break; case 6: // GB: LD A,(FF00 + C) - this.A = this.BusRead((ushort)(IoRegisters.BASE + this.C)); + this.A = this.MemoryRead((ushort)(IoRegisters.BASE + this.C)); this.Tick(2); break; case 7: // GB: LD A,(nn) this.Bus.Address.Word = this.MEMPTR.Word = this.FetchWord().Word; - this.A = this.BusRead(); + this.A = this.MemoryRead(); this.Tick(4); break; default: diff --git a/M6502/M6502.cs b/M6502/M6502.cs index 83b4c44..a9a22f4 100644 --- a/M6502/M6502.cs +++ b/M6502/M6502.cs @@ -198,15 +198,15 @@ namespace EightBit case 0x03: this.SLO(this.AM_IndexedIndirectX()); break; // *SLO (indexed indirect X) case 0x04: this.AM_ZeroPage(); break; // *NOP (zero page) case 0x05: this.A = this.OrR(this.A, this.AM_ZeroPage()); break; // ORA (zero page) - case 0x06: this.BusReadModifyWrite(this.ASL(this.AM_ZeroPage())); break; // ASL (zero page) + case 0x06: this.ReadModifyWrite(this.ASL(this.AM_ZeroPage())); break; // ASL (zero page) case 0x07: this.SLO(this.AM_ZeroPage()); break; // *SLO (zero page) - case 0x08: this.BusRead(); this.PHP(); break; // PHP (implied) + case 0x08: this.MemoryRead(); this.PHP(); break; // PHP (implied) case 0x09: this.A = this.OrR(this.A, this.AM_Immediate()); break; // ORA (immediate) - case 0x0a: this.BusRead(); this.A = this.ASL(this.A); break; // ASL A (implied) + case 0x0a: this.MemoryRead(); this.A = this.ASL(this.A); break; // ASL A (implied) case 0x0b: this.ANC(this.AM_Immediate()); break; // *ANC (immediate) case 0x0c: this.AM_Absolute(); break; // *NOP (absolute) case 0x0d: this.A = this.OrR(this.A, this.AM_Absolute()); break; // ORA (absolute) - case 0x0e: this.BusReadModifyWrite(this.ASL(this.AM_Absolute())); break; // ASL (absolute) + case 0x0e: this.ReadModifyWrite(this.ASL(this.AM_Absolute())); break; // ASL (absolute) case 0x0f: this.SLO(this.AM_Absolute()); break; // *SLO (absolute) case 0x10: this.Branch(this.Negative == 0); break; // BPL (relative) @@ -215,15 +215,15 @@ namespace EightBit case 0x13: this.SLO(this.AM_IndirectIndexedY()); break; // *SLO (indirect indexed Y) case 0x14: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x15: this.A = this.OrR(this.A, this.AM_ZeroPageX()); break; // ORA (zero page, X) - case 0x16: this.BusReadModifyWrite(this.ASL(this.AM_ZeroPageX())); break; // ASL (zero page, X) + case 0x16: this.ReadModifyWrite(this.ASL(this.AM_ZeroPageX())); break; // ASL (zero page, X) case 0x17: this.SLO(this.AM_ZeroPageX()); break; // *SLO (zero page, X) - case 0x18: this.BusRead(); this.P = ClearBit(this.P, StatusBits.CF); break; // CLC (implied) + case 0x18: this.MemoryRead(); this.P = ClearBit(this.P, StatusBits.CF); break; // CLC (implied) case 0x19: this.A = this.OrR(this.A, this.AM_AbsoluteY()); break; // ORA (absolute, Y) - case 0x1a: this.BusRead(); break; // *NOP (implied) + case 0x1a: this.MemoryRead(); break; // *NOP (implied) case 0x1b: this.SLO(this.AM_AbsoluteY()); break; // *SLO (absolute, Y) case 0x1c: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x1d: this.A = this.OrR(this.A, this.AM_AbsoluteX()); break; // ORA (absolute, X) - case 0x1e: this.BusReadModifyWrite(this.ASL(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ASL (absolute, X) + case 0x1e: this.ReadModifyWrite(this.ASL(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ASL (absolute, X) case 0x1f: this.SLO(this.AM_AbsoluteX()); break; // *SLO (absolute, X) case 0x20: this.JSR(); break; // JSR (absolute) @@ -232,15 +232,15 @@ namespace EightBit case 0x23: this.RLA(this.AM_IndexedIndirectX()); break; // *RLA (indexed indirect X) case 0x24: this.BIT(this.A, this.AM_ZeroPage()); break; // BIT (zero page) case 0x25: this.A = this.AndR(this.A, this.AM_ZeroPage()); break; // AND (zero page) - case 0x26: this.BusReadModifyWrite(this.ROL(this.AM_ZeroPage())); break; // ROL (zero page) + case 0x26: this.ReadModifyWrite(this.ROL(this.AM_ZeroPage())); break; // ROL (zero page) case 0x27: this.RLA(this.AM_ZeroPage()); break; // *RLA (zero page) - case 0x28: this.BusRead(); this.BusRead(this.S, 1); this.PLP(); break; // PLP (implied) + case 0x28: this.MemoryRead(); this.MemoryRead(this.S, 1); this.PLP(); break; // PLP (implied) case 0x29: this.A = this.AndR(this.A, this.AM_Immediate()); break; // AND (immediate) - case 0x2a: this.BusRead(); this.A = this.ROL(this.A); break; // ROL A (implied) + case 0x2a: this.MemoryRead(); this.A = this.ROL(this.A); break; // ROL A (implied) case 0x2b: this.ANC(this.AM_Immediate()); break; // *ANC (immediate) case 0x2c: this.BIT(this.A, this.AM_Absolute()); break; // BIT (absolute) case 0x2d: this.A = this.AndR(this.A, this.AM_Absolute()); break; // AND (absolute) - case 0x2e: this.BusReadModifyWrite(this.ROL(this.AM_Absolute())); break; // ROL (absolute) + case 0x2e: this.ReadModifyWrite(this.ROL(this.AM_Absolute())); break; // ROL (absolute) case 0x2f: this.RLA(this.AM_Absolute()); break; // *RLA (absolute) case 0x30: this.Branch(this.Negative); break; // BMI (relative) @@ -249,32 +249,32 @@ namespace EightBit case 0x33: this.RLA(this.AM_IndirectIndexedY()); break; // *RLA (indirect indexed Y) case 0x34: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x35: this.A = this.AndR(this.A, this.AM_ZeroPageX()); break; // AND (zero page, X) - case 0x36: this.BusReadModifyWrite(this.ROL(this.AM_ZeroPageX())); break; // ROL (zero page, X) + case 0x36: this.ReadModifyWrite(this.ROL(this.AM_ZeroPageX())); break; // ROL (zero page, X) case 0x37: this.RLA(this.AM_ZeroPageX()); break; // *RLA (zero page, X) - case 0x38: this.BusRead(); this.P = SetBit(this.P, StatusBits.CF); break; // SEC (implied) + case 0x38: this.MemoryRead(); this.P = SetBit(this.P, StatusBits.CF); break; // SEC (implied) case 0x39: this.A = this.AndR(this.A, this.AM_AbsoluteY()); break; // AND (absolute, Y) - case 0x3a: this.BusRead(); break; // *NOP (implied) + case 0x3a: this.MemoryRead(); break; // *NOP (implied) case 0x3b: this.RLA(this.AM_AbsoluteY()); break; // *RLA (absolute, Y) case 0x3c: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x3d: this.A = this.AndR(this.A, this.AM_AbsoluteX()); break; // AND (absolute, X) - case 0x3e: this.BusReadModifyWrite(this.ROL(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ROL (absolute, X) + case 0x3e: this.ReadModifyWrite(this.ROL(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ROL (absolute, X) case 0x3f: this.RLA(this.AM_AbsoluteX()); break; // *RLA (absolute, X) - case 0x40: this.BusRead(); this.RTI(); break; // RTI (implied) + case 0x40: this.MemoryRead(); this.RTI(); break; // RTI (implied) case 0x41: this.A = this.EorR(this.A, this.AM_IndexedIndirectX()); break; // EOR (indexed indirect X) case 0x42: break; case 0x43: this.SRE(this.AM_IndexedIndirectX()); break; // *SRE (indexed indirect X) case 0x44: this.AM_ZeroPage(); break; // *NOP (zero page) case 0x45: this.A = this.EorR(this.A, this.AM_ZeroPage()); break; // EOR (zero page) - case 0x46: this.BusReadModifyWrite(this.LSR(this.AM_ZeroPage())); break; // LSR (zero page) + case 0x46: this.ReadModifyWrite(this.LSR(this.AM_ZeroPage())); break; // LSR (zero page) case 0x47: this.SRE(this.AM_ZeroPage()); break; // *SRE (zero page) - case 0x48: this.BusRead(); this.Push(this.A); break; // PHA (implied) + case 0x48: this.MemoryRead(); this.Push(this.A); break; // PHA (implied) case 0x49: this.A = this.EorR(this.A, this.AM_Immediate()); break; // EOR (immediate) - case 0x4a: this.BusRead(); this.A = this.LSR(this.A); break; // LSR A (implied) + case 0x4a: this.MemoryRead(); this.A = this.LSR(this.A); break; // LSR A (implied) case 0x4b: this.ASR(this.AM_Immediate()); break; // *ASR (immediate) case 0x4c: this.Jump(this.Address_Absolute().Word); break; // JMP (absolute) case 0x4d: this.A = this.EorR(this.A, this.AM_Absolute()); break; // EOR (absolute) - case 0x4e: this.BusReadModifyWrite(this.LSR(this.AM_Absolute())); break; // LSR (absolute) + case 0x4e: this.ReadModifyWrite(this.LSR(this.AM_Absolute())); break; // LSR (absolute) case 0x4f: this.SRE(this.AM_Absolute()); break; // *SRE (absolute) case 0x50: this.Branch(this.Overflow == 0); break; // BVC (relative) @@ -283,32 +283,32 @@ namespace EightBit case 0x53: this.SRE(this.AM_IndirectIndexedY()); break; // *SRE (indirect indexed Y) case 0x54: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x55: this.A = this.EorR(this.A, this.AM_ZeroPageX()); break; // EOR (zero page, X) - case 0x56: this.BusReadModifyWrite(this.LSR(this.AM_ZeroPageX())); break; // LSR (zero page, X) + case 0x56: this.ReadModifyWrite(this.LSR(this.AM_ZeroPageX())); break; // LSR (zero page, X) case 0x57: this.SRE(this.AM_ZeroPageX()); break; // *SRE (zero page, X) - case 0x58: this.BusRead(); this.P = ClearBit(this.P, StatusBits.IF); break; // CLI (implied) + case 0x58: this.MemoryRead(); this.P = ClearBit(this.P, StatusBits.IF); break; // CLI (implied) case 0x59: this.A = this.EorR(this.A, this.AM_AbsoluteY()); break; // EOR (absolute, Y) - case 0x5a: this.BusRead(); break; // *NOP (implied) + case 0x5a: this.MemoryRead(); break; // *NOP (implied) case 0x5b: this.SRE(this.AM_AbsoluteY()); break; // *SRE (absolute, Y) case 0x5c: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x5d: this.A = this.EorR(this.A, this.AM_AbsoluteX()); break; // EOR (absolute, X) - case 0x5e: this.BusReadModifyWrite(this.LSR(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // LSR (absolute, X) + case 0x5e: this.ReadModifyWrite(this.LSR(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // LSR (absolute, X) case 0x5f: this.SRE(this.AM_AbsoluteX()); break; // *SRE (absolute, X) - case 0x60: this.BusRead(); this.RTS(); break; // RTS (implied) + case 0x60: this.MemoryRead(); this.RTS(); break; // RTS (implied) case 0x61: this.A = this.ADC(this.A, this.AM_IndexedIndirectX()); break; // ADC (indexed indirect X) case 0x62: break; case 0x63: this.RRA(this.AM_IndexedIndirectX()); break; // *RRA (indexed indirect X) case 0x64: this.AM_ZeroPage(); break; // *NOP (zero page) case 0x65: this.A = this.ADC(this.A, this.AM_ZeroPage()); break; // ADC (zero page) - case 0x66: this.BusReadModifyWrite(this.ROR(this.AM_ZeroPage())); break; // ROR (zero page) + case 0x66: this.ReadModifyWrite(this.ROR(this.AM_ZeroPage())); break; // ROR (zero page) case 0x67: this.RRA(this.AM_ZeroPage()); break; // *RRA (zero page) - case 0x68: this.BusRead(); this.BusRead(this.S, 1); this.A = this.Through(this.Pop()); break; // PLA (implied) + case 0x68: this.MemoryRead(); this.MemoryRead(this.S, 1); this.A = this.Through(this.Pop()); break; // PLA (implied) case 0x69: this.A = this.ADC(this.A, this.AM_Immediate()); break; // ADC (immediate) - case 0x6a: this.BusRead(); this.A = this.ROR(this.A); break; // ROR A (implied) + case 0x6a: this.MemoryRead(); this.A = this.ROR(this.A); break; // ROR A (implied) case 0x6b: this.ARR(this.AM_Immediate()); break; // *ARR (immediate) case 0x6c: this.Jump(this.Address_Indirect().Word); break; // JMP (indirect) case 0x6d: this.A = this.ADC(this.A, this.AM_Absolute()); break; // ADC (absolute) - case 0x6e: this.BusReadModifyWrite(this.ROR(this.AM_Absolute())); break; // ROR (absolute) + case 0x6e: this.ReadModifyWrite(this.ROR(this.AM_Absolute())); break; // ROR (absolute) case 0x6f: this.RRA(this.AM_Absolute()); break; // *RRA (absolute) case 0x70: this.Branch(this.Overflow); break; // BVS (relative) @@ -317,45 +317,45 @@ namespace EightBit case 0x73: this.RRA(this.AM_IndirectIndexedY()); break; // *RRA (indirect indexed Y) case 0x74: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0x75: this.A = this.ADC(this.A, this.AM_ZeroPageX()); break; // ADC (zero page, X) - case 0x76: this.BusReadModifyWrite(this.ROR(this.AM_ZeroPageX())); break; // ROR (zero page, X) + case 0x76: this.ReadModifyWrite(this.ROR(this.AM_ZeroPageX())); break; // ROR (zero page, X) case 0x77: this.RRA(this.AM_ZeroPageX()); break; // *RRA (zero page, X) - case 0x78: this.BusRead(); this.P = SetBit(this.P, StatusBits.IF); break; // SEI (implied) + case 0x78: this.MemoryRead(); this.P = SetBit(this.P, StatusBits.IF); break; // SEI (implied) case 0x79: this.A = this.ADC(this.A, this.AM_AbsoluteY()); break; // ADC (absolute, Y) - case 0x7a: this.BusRead(); break; // *NOP (implied) + case 0x7a: this.MemoryRead(); break; // *NOP (implied) case 0x7b: this.RRA(this.AM_AbsoluteY()); break; // *RRA (absolute, Y) case 0x7c: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0x7d: this.A = this.ADC(this.A, this.AM_AbsoluteX()); break; // ADC (absolute, X) - case 0x7e: this.BusReadModifyWrite(this.ROR(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ROR (absolute, X) + case 0x7e: this.ReadModifyWrite(this.ROR(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // ROR (absolute, X) case 0x7f: this.RRA(this.AM_AbsoluteX()); break; // *RRA (absolute, X) case 0x80: this.AM_Immediate(); break; // *NOP (immediate) - case 0x81: this.BusWrite(this.Address_IndexedIndirectX(), this.A); break; // STA (indexed indirect X) + case 0x81: this.MemoryWrite(this.Address_IndexedIndirectX(), this.A); break; // STA (indexed indirect X) case 0x82: this.AM_Immediate(); break; // *NOP (immediate) - case 0x83: this.BusWrite(this.Address_IndexedIndirectX(), (byte)(this.A & this.X)); break; // *SAX (indexed indirect X) - case 0x84: this.BusWrite(this.Address_ZeroPage(), this.Y); break; // STY (zero page) - case 0x85: this.BusWrite(this.Address_ZeroPage(), this.A); break; // STA (zero page) - case 0x86: this.BusWrite(this.Address_ZeroPage(), this.X); break; // STX (zero page) - case 0x87: this.BusWrite(this.Address_ZeroPage(), (byte)(this.A & this.X)); break; // *SAX (zero page) - case 0x88: this.BusRead(); this.Y = this.DEC(this.Y); break; // DEY (implied) + case 0x83: this.MemoryWrite(this.Address_IndexedIndirectX(), (byte)(this.A & this.X)); break; // *SAX (indexed indirect X) + case 0x84: this.MemoryWrite(this.Address_ZeroPage(), this.Y); break; // STY (zero page) + case 0x85: this.MemoryWrite(this.Address_ZeroPage(), this.A); break; // STA (zero page) + case 0x86: this.MemoryWrite(this.Address_ZeroPage(), this.X); break; // STX (zero page) + case 0x87: this.MemoryWrite(this.Address_ZeroPage(), (byte)(this.A & this.X)); break; // *SAX (zero page) + case 0x88: this.MemoryRead(); this.Y = this.DEC(this.Y); break; // DEY (implied) case 0x89: this.AM_Immediate(); break; // *NOP (immediate) - case 0x8a: this.BusRead(); this.A = this.Through(this.X); break; // TXA (implied) + case 0x8a: this.MemoryRead(); this.A = this.Through(this.X); break; // TXA (implied) case 0x8b: break; - case 0x8c: this.BusWrite(this.Address_Absolute(), this.Y); break; // STY (absolute) - case 0x8d: this.BusWrite(this.Address_Absolute(), this.A); break; // STA (absolute) - case 0x8e: this.BusWrite(this.Address_Absolute(), this.X); break; // STX (absolute) - case 0x8f: this.BusWrite(this.Address_Absolute(), (byte)(this.A & this.X)); break; // *SAX (absolute) + case 0x8c: this.MemoryWrite(this.Address_Absolute(), this.Y); break; // STY (absolute) + case 0x8d: this.MemoryWrite(this.Address_Absolute(), this.A); break; // STA (absolute) + case 0x8e: this.MemoryWrite(this.Address_Absolute(), this.X); break; // STX (absolute) + case 0x8f: this.MemoryWrite(this.Address_Absolute(), (byte)(this.A & this.X)); break; // *SAX (absolute) case 0x90: this.Branch(this.Carry == 0); break; // BCC (relative) - case 0x91: this.AM_IndirectIndexedY(); this.BusWrite(this.A); break; // STA (indirect indexed Y) + case 0x91: this.AM_IndirectIndexedY(); this.MemoryWrite(this.A); break; // STA (indirect indexed Y) case 0x92: break; case 0x93: break; - case 0x94: this.BusWrite(this.Address_ZeroPageX(), this.Y); break; // STY (zero page, X) - case 0x95: this.BusWrite(this.Address_ZeroPageX(), this.A); break; // STA (zero page, X) - case 0x96: this.BusWrite(this.Address_ZeroPageY(), this.X); break; // STX (zero page, Y) - case 0x97: this.BusWrite(this.Address_ZeroPageY(), (byte)(this.A & this.X)); break; // *SAX (zero page, Y) - case 0x98: this.BusRead(); this.A = this.Through(this.Y); break; // TYA (implied) + case 0x94: this.MemoryWrite(this.Address_ZeroPageX(), this.Y); break; // STY (zero page, X) + case 0x95: this.MemoryWrite(this.Address_ZeroPageX(), this.A); break; // STA (zero page, X) + case 0x96: this.MemoryWrite(this.Address_ZeroPageY(), this.X); break; // STX (zero page, Y) + case 0x97: this.MemoryWrite(this.Address_ZeroPageY(), (byte)(this.A & this.X)); break; // *SAX (zero page, Y) + case 0x98: this.MemoryRead(); this.A = this.Through(this.Y); break; // TYA (implied) case 0x99: this.STA_AbsoluteY(); break; // STA (absolute, Y) - case 0x9a: this.BusRead(); this.S = this.X; break; // TXS (implied) + case 0x9a: this.MemoryRead(); this.S = this.X; break; // TXS (implied) case 0x9b: break; case 0x9c: break; case 0x9d: this.STA_AbsoluteX(); break; // STA (absolute, X) @@ -370,9 +370,9 @@ namespace EightBit case 0xa5: this.A = this.Through(this.AM_ZeroPage()); break; // LDA (zero page) case 0xa6: this.X = this.Through(this.AM_ZeroPage()); break; // LDX (zero page) case 0xa7: this.A = this.X = this.Through(this.AM_ZeroPage()); break; // *LAX (zero page) - case 0xa8: this.BusRead(); this.Y = this.Through(this.A); break; // TAY (implied) + case 0xa8: this.MemoryRead(); this.Y = this.Through(this.A); break; // TAY (implied) case 0xa9: this.A = this.Through(this.AM_Immediate()); break; // LDA (immediate) - case 0xaa: this.BusRead(); this.X = this.Through(this.A); break; // TAX (implied) + case 0xaa: this.MemoryRead(); this.X = this.Through(this.A); break; // TAX (implied) case 0xab: this.A = this.X = this.Through(this.AM_Immediate()); break; // *ATX (immediate) case 0xac: this.Y = this.Through(this.AM_Absolute()); break; // LDY (absolute) case 0xad: this.A = this.Through(this.AM_Absolute()); break; // LDA (absolute) @@ -387,9 +387,9 @@ namespace EightBit case 0xb5: this.A = this.Through(this.AM_ZeroPageX()); break; // LDA (zero page, X) case 0xb6: this.X = this.Through(this.AM_ZeroPageY()); break; // LDX (zero page, Y) case 0xb7: this.A = this.X = this.Through(this.AM_ZeroPageY()); break; // *LAX (zero page, Y) - case 0xb8: this.BusRead(); this.P = ClearBit(this.P, StatusBits.VF); break; // CLV (implied) + case 0xb8: this.MemoryRead(); this.P = ClearBit(this.P, StatusBits.VF); break; // CLV (implied) case 0xb9: this.A = this.Through(this.AM_AbsoluteY()); break; // LDA (absolute, Y) - case 0xba: this.BusRead(); this.X = this.Through(this.S); break; // TSX (implied) + case 0xba: this.MemoryRead(); this.X = this.Through(this.S); break; // TSX (implied) case 0xbb: break; case 0xbc: this.Y = this.Through(this.AM_AbsoluteX()); break; // LDY (absolute, X) case 0xbd: this.A = this.Through(this.AM_AbsoluteX()); break; // LDA (absolute, X) @@ -402,15 +402,15 @@ namespace EightBit case 0xc3: this.DCP(this.AM_IndexedIndirectX()); break; // *DCP (indexed indirect X) case 0xc4: this.CMP(this.Y, this.AM_ZeroPage()); break; // CPY (zero page) case 0xc5: this.CMP(this.A, this.AM_ZeroPage()); break; // CMP (zero page) - case 0xc6: this.BusReadModifyWrite(this.DEC(this.AM_ZeroPage())); break; // DEC (zero page) + case 0xc6: this.ReadModifyWrite(this.DEC(this.AM_ZeroPage())); break; // DEC (zero page) case 0xc7: this.DCP(this.AM_ZeroPage()); break; // *DCP (zero page) - case 0xc8: this.BusRead(); this.Y = this.INC(this.Y); break; // INY (implied) + case 0xc8: this.MemoryRead(); this.Y = this.INC(this.Y); break; // INY (implied) case 0xc9: this.CMP(this.A, this.AM_Immediate()); break; // CMP (immediate) - case 0xca: this.BusRead(); this.X = this.DEC(this.X); break; // DEX (implied) + case 0xca: this.MemoryRead(); this.X = this.DEC(this.X); break; // DEX (implied) case 0xcb: this.AXS(this.AM_Immediate()); break; // *AXS (immediate) case 0xcc: this.CMP(this.Y, this.AM_Absolute()); break; // CPY (absolute) case 0xcd: this.CMP(this.A, this.AM_Absolute()); break; // CMP (absolute) - case 0xce: this.BusReadModifyWrite(this.DEC(this.AM_Absolute())); break; // DEC (absolute) + case 0xce: this.ReadModifyWrite(this.DEC(this.AM_Absolute())); break; // DEC (absolute) case 0xcf: this.DCP(this.AM_Absolute()); break; // *DCP (absolute) case 0xd0: this.Branch(this.Zero == 0); break; // BNE (relative) @@ -419,15 +419,15 @@ namespace EightBit case 0xd3: this.DCP(this.AM_IndirectIndexedY()); break; // *DCP (indirect indexed Y) case 0xd4: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0xd5: this.CMP(this.A, this.AM_ZeroPageX()); break; // CMP (zero page, X) - case 0xd6: this.BusReadModifyWrite(this.DEC(this.AM_ZeroPageX())); break; // DEC (zero page, X) + case 0xd6: this.ReadModifyWrite(this.DEC(this.AM_ZeroPageX())); break; // DEC (zero page, X) case 0xd7: this.DCP(this.AM_ZeroPageX()); break; // *DCP (zero page, X) - case 0xd8: this.BusRead(); this.P = ClearBit(this.P, StatusBits.DF); break; // CLD (implied) + case 0xd8: this.MemoryRead(); this.P = ClearBit(this.P, StatusBits.DF); break; // CLD (implied) case 0xd9: this.CMP(this.A, this.AM_AbsoluteY()); break; // CMP (absolute, Y) - case 0xda: this.BusRead(); break; // *NOP (implied) + case 0xda: this.MemoryRead(); break; // *NOP (implied) case 0xdb: this.DCP(this.AM_AbsoluteY()); break; // *DCP (absolute, Y) case 0xdc: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0xdd: this.CMP(this.A, this.AM_AbsoluteX()); break; // CMP (absolute, X) - case 0xde: this.BusReadModifyWrite(this.DEC(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // DEC (absolute, X) + case 0xde: this.ReadModifyWrite(this.DEC(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // DEC (absolute, X) case 0xdf: this.DCP(this.AM_AbsoluteX()); break; // *DCP (absolute, X) case 0xe0: this.CMP(this.X, this.AM_Immediate()); break; // CPX (immediate) @@ -436,15 +436,15 @@ namespace EightBit case 0xe3: this.ISB(this.AM_IndexedIndirectX()); break; // *ISB (indexed indirect X) case 0xe4: this.CMP(this.X, this.AM_ZeroPage()); break; // CPX (zero page) case 0xe5: this.A = this.SBC(this.A, this.AM_ZeroPage()); break; // SBC (zero page) - case 0xe6: this.BusReadModifyWrite(this.INC(this.AM_ZeroPage())); break; // INC (zero page) + case 0xe6: this.ReadModifyWrite(this.INC(this.AM_ZeroPage())); break; // INC (zero page) case 0xe7: this.ISB(this.AM_ZeroPage()); break; // *ISB (zero page) - case 0xe8: this.BusRead(); this.X = this.INC(this.X); break; // INX (implied) + case 0xe8: this.MemoryRead(); this.X = this.INC(this.X); break; // INX (implied) case 0xe9: this.A = this.SBC(this.A, this.AM_Immediate()); break; // SBC (immediate) - case 0xea: this.BusRead(); break; // NOP (implied) + case 0xea: this.MemoryRead(); break; // NOP (implied) case 0xeb: this.A = this.SBC(this.A, this.AM_Immediate()); break; // *SBC (immediate) case 0xec: this.CMP(this.X, this.AM_Absolute()); break; // CPX (absolute) case 0xed: this.A = this.SBC(this.A, this.AM_Absolute()); break; // SBC (absolute) - case 0xee: this.BusReadModifyWrite(this.INC(this.AM_Absolute())); break; // *ISB (absolute) + case 0xee: this.ReadModifyWrite(this.INC(this.AM_Absolute())); break; // *ISB (absolute) case 0xf0: this.Branch(this.Zero); break; // BEQ (relative) case 0xf1: this.A = this.SBC(this.A, this.AM_IndirectIndexedY()); break; // SBC (indirect indexed Y) @@ -452,15 +452,15 @@ namespace EightBit case 0xf3: this.ISB(this.AM_IndirectIndexedY()); break; // *ISB (indirect indexed Y) case 0xf4: this.AM_ZeroPageX(); break; // *NOP (zero page, X) case 0xf5: this.A = this.SBC(this.A, this.AM_ZeroPageX()); break; // SBC (zero page, X) - case 0xf6: this.BusReadModifyWrite(this.INC(this.AM_ZeroPageX())); break; // INC (zero page, X) + case 0xf6: this.ReadModifyWrite(this.INC(this.AM_ZeroPageX())); break; // INC (zero page, X) case 0xf7: this.ISB(this.AM_ZeroPageX()); break; // *ISB (zero page, X) - case 0xf8: this.BusRead(); this.P = SetBit(this.P, StatusBits.DF); break; // SED (implied) + case 0xf8: this.MemoryRead(); this.P = SetBit(this.P, StatusBits.DF); break; // SED (implied) case 0xf9: this.A = this.SBC(this.A, this.AM_AbsoluteY()); break; // SBC (absolute, Y) - case 0xfa: this.BusRead(); break; // *NOP (implied) + case 0xfa: this.MemoryRead(); break; // *NOP (implied) case 0xfb: this.ISB(this.AM_AbsoluteY()); break; // *ISB (absolute, Y) case 0xfc: this.AM_AbsoluteX(); break; // *NOP (absolute, X) case 0xfd: this.A = this.SBC(this.A, this.AM_AbsoluteX()); break; // SBC (absolute, X) - case 0xfe: this.BusReadModifyWrite(this.INC(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // INC (absolute, X) + case 0xfe: this.ReadModifyWrite(this.INC(this.AM_AbsoluteX(PageCrossingBehavior.AlwaysReadTwice))); break; // INC (absolute, X) case 0xff: this.ISB(this.AM_AbsoluteX()); break; // *ISB (absolute, X) } @@ -561,9 +561,9 @@ namespace EightBit base.OnRaisedPOWER(); } - protected override byte Pop() => this.BusRead(++this.S, 1); + protected override byte Pop() => this.MemoryRead(++this.S, 1); - protected override void Push(byte value) => this.BusWrite(this.S--, 1, value); + protected override void Push(byte value) => this.MemoryWrite(this.S--, 1, value); protected virtual void RaiseSYNC() { @@ -678,14 +678,14 @@ namespace EightBit private byte Address_ZeroPageX() { var address = this.Address_ZeroPage(); - this.BusRead(address); + this.MemoryRead(address); return Chip.LowByte(address + this.X); } private byte Address_ZeroPageY() { var address = this.Address_ZeroPage(); - this.BusRead(address); + this.MemoryRead(address); return Chip.LowByte(address + this.Y); } @@ -724,17 +724,17 @@ namespace EightBit private byte AM_Immediate() => this.FetchByte(); - private byte AM_Absolute() => this.BusRead(this.Address_Absolute()); + private byte AM_Absolute() => this.MemoryRead(this.Address_Absolute()); - private byte AM_ZeroPage() => this.BusRead(this.Address_ZeroPage()); + private byte AM_ZeroPage() => this.MemoryRead(this.Address_ZeroPage()); private byte AM_AbsoluteX(PageCrossingBehavior behaviour = PageCrossingBehavior.MaybeReadTwice) { var address = this.Address_AbsoluteX(); - var possible = this.BusRead(address.Low, this.crossedPage); + var possible = this.MemoryRead(address.Low, this.crossedPage); if ((behaviour == PageCrossingBehavior.AlwaysReadTwice) || (this.crossedPage != address.High)) { - possible = this.BusRead(address.Word); + possible = this.MemoryRead(address.Word); } return possible; @@ -743,28 +743,28 @@ namespace EightBit private byte AM_AbsoluteY() { var address = this.Address_AbsoluteY(); - var possible = this.BusRead(address.Low, this.crossedPage); + var possible = this.MemoryRead(address.Low, this.crossedPage); if (this.crossedPage != address.High) { - possible = this.BusRead(address.Word); + possible = this.MemoryRead(address.Word); } return possible; } - private byte AM_ZeroPageX() => this.BusRead(this.Address_ZeroPageX()); + private byte AM_ZeroPageX() => this.MemoryRead(this.Address_ZeroPageX()); - private byte AM_ZeroPageY() => this.BusRead(this.Address_ZeroPageY()); + private byte AM_ZeroPageY() => this.MemoryRead(this.Address_ZeroPageY()); - private byte AM_IndexedIndirectX() => this.BusRead(this.Address_IndexedIndirectX()); + private byte AM_IndexedIndirectX() => this.MemoryRead(this.Address_IndexedIndirectX()); private byte AM_IndirectIndexedY() { var address = this.Address_IndirectIndexedY(); - var possible = this.BusRead(address.Low, this.crossedPage); + var possible = this.MemoryRead(address.Low, this.crossedPage); if (this.crossedPage != address.High) { - possible = this.BusRead(address); + possible = this.MemoryRead(address); } return possible; @@ -787,12 +787,12 @@ namespace EightBit var destination = this.Address_relative_byte(); if (condition) { - this.BusRead(); + this.MemoryRead(); var page = this.PC.High; this.Jump(destination); if (this.PC.High != page) { - this.BusRead(this.PC.Low, page); + this.MemoryRead(this.PC.Low, page); } } } @@ -805,11 +805,11 @@ namespace EightBit return data; } - private void BusReadModifyWrite(byte data) + private void ReadModifyWrite(byte data) { // The read will have already taken place... - this.BusWrite(); - this.BusWrite(data); + this.MemoryWrite(); + this.MemoryWrite(data); } private byte SBC(byte operand, byte data) @@ -925,7 +925,7 @@ namespace EightBit private void JSR() { var low = this.FetchByte(); - this.BusRead(this.S, 1); // dummy read + this.MemoryRead(this.S, 1); // dummy read this.PushWord(this.PC); var high = this.FetchByte(); this.PC.Low = low; @@ -962,14 +962,14 @@ namespace EightBit private void RTI() { - this.BusRead(this.S, 1); // dummy read + this.MemoryRead(this.S, 1); // dummy read this.PLP(); this.Return(); } private void RTS() { - this.BusRead(this.S, 1); // dummy read + this.MemoryRead(this.S, 1); // dummy read this.Return(); this.FetchByte(); } @@ -1002,52 +1002,52 @@ namespace EightBit private void DCP(byte value) { - this.BusReadModifyWrite(this.DEC(value)); + this.ReadModifyWrite(this.DEC(value)); this.CMP(this.A, this.Bus.Data); } private void ISB(byte value) { - this.BusReadModifyWrite(this.INC(value)); + this.ReadModifyWrite(this.INC(value)); this.A = this.SBC(this.A, this.Bus.Data); } private void RLA(byte value) { - this.BusReadModifyWrite(this.ROL(value)); + this.ReadModifyWrite(this.ROL(value)); this.A = this.AndR(this.A, this.Bus.Data); } private void RRA(byte value) { - this.BusReadModifyWrite(this.ROR(value)); + this.ReadModifyWrite(this.ROR(value)); this.A = this.ADC(this.A, this.Bus.Data); } private void SLO(byte value) { - this.BusReadModifyWrite(this.ASL(value)); + this.ReadModifyWrite(this.ASL(value)); this.A = this.OrR(this.A, this.Bus.Data); } private void SRE(byte value) { - this.BusReadModifyWrite(this.LSR(value)); + this.ReadModifyWrite(this.LSR(value)); this.A = this.EorR(this.A, this.Bus.Data); } private void STA_AbsoluteX() { var address = this.Address_AbsoluteX(); - this.BusRead(address.Low, this.crossedPage); - this.BusWrite(address, this.A); + this.MemoryRead(address.Low, this.crossedPage); + this.MemoryWrite(address, this.A); } private void STA_AbsoluteY() { var address = this.Address_AbsoluteY(); - this.BusRead(address.Low, this.crossedPage); - this.BusWrite(address, this.A); + this.MemoryRead(address.Low, this.crossedPage); + this.MemoryWrite(address, this.A); } } } diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index a837a75..cb727b5 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -496,7 +496,7 @@ namespace EightBit private void OnExecutedInstruction() => this.ExecutedInstruction?.Invoke(this, EventArgs.Empty); - private void Push(Register16 stack, byte value) => this.BusWrite(--stack.Word, value); + private void Push(Register16 stack, byte value) => this.MemoryWrite(--stack.Word, value); private void PushS(byte value) => this.Push(this.S, value); @@ -506,7 +506,7 @@ namespace EightBit this.Push(stack, value.High); } - private byte Pop(Register16 stack) => this.BusRead(stack.Word++); + private byte Pop(Register16 stack) => this.MemoryRead(stack.Word++); private byte PopS() => this.Pop(this.S); @@ -636,11 +636,11 @@ namespace EightBit private byte AM_immediate_byte() => this.FetchByte(); - private byte AM_direct_byte() => this.BusRead(this.Address_direct()); + private byte AM_direct_byte() => this.MemoryRead(this.Address_direct()); - private byte AM_indexed_byte() => this.BusRead(this.Address_indexed()); + private byte AM_indexed_byte() => this.MemoryRead(this.Address_indexed()); - private byte AM_extended_byte() => this.BusRead(this.Address_extended()); + private byte AM_extended_byte() => this.MemoryRead(this.Address_extended()); private Register16 AM_immediate_word() => this.FetchWord(); @@ -884,18 +884,18 @@ namespace EightBit case 0x1c: this.Tick(3); this.CC &= this.AM_immediate_byte(); break; // AND (ANDCC immediate) // ASL/LSL - case 0x08: this.Tick(6); this.BusWrite(this.ASL(this.AM_direct_byte())); break; // ASL (direct) + case 0x08: this.Tick(6); this.MemoryWrite(this.ASL(this.AM_direct_byte())); break; // ASL (direct) case 0x48: this.Tick(2); this.A = this.ASL(this.A); break; // ASL (ASLA inherent) case 0x58: this.Tick(2); this.B = this.ASL(this.B); break; // ASL (ASLB inherent) - case 0x68: this.Tick(6); this.BusWrite(this.ASL(this.AM_indexed_byte())); break; // ASL (indexed) - case 0x78: this.Tick(7); this.BusWrite(this.ASL(this.AM_extended_byte())); break; // ASL (extended) + case 0x68: this.Tick(6); this.MemoryWrite(this.ASL(this.AM_indexed_byte())); break; // ASL (indexed) + case 0x78: this.Tick(7); this.MemoryWrite(this.ASL(this.AM_extended_byte())); break; // ASL (extended) // ASR - case 0x07: this.Tick(6); this.BusWrite(this.ASR(this.AM_direct_byte())); break; // ASR (direct) + case 0x07: this.Tick(6); this.MemoryWrite(this.ASR(this.AM_direct_byte())); break; // ASR (direct) case 0x47: this.Tick(2); this.A = this.ASR(this.A); break; // ASR (ASRA inherent) case 0x57: this.Tick(2); this.B = this.ASR(this.B); break; // ASR (ASRB inherent) - case 0x67: this.Tick(6); this.BusWrite(this.ASR(this.AM_indexed_byte())); break; // ASR (indexed) - case 0x77: this.Tick(7); this.BusWrite(this.ASR(this.AM_extended_byte())); break; // ASR (extended) + case 0x67: this.Tick(6); this.MemoryWrite(this.ASR(this.AM_indexed_byte())); break; // ASR (indexed) + case 0x77: this.Tick(7); this.MemoryWrite(this.ASR(this.AM_extended_byte())); break; // ASR (extended) // BIT case 0x85: this.Tick(2); this.BIT(this.A, this.AM_immediate_byte()); break; // BIT (BITA immediate) @@ -909,11 +909,11 @@ namespace EightBit case 0xf5: this.Tick(5); this.BIT(this.B, this.AM_extended_byte()); break; // BIT (BITB extended) // CLR - case 0x0f: this.Tick(6); this.BusWrite(this.Address_direct(), this.CLR()); break; // CLR (direct) + case 0x0f: this.Tick(6); this.MemoryWrite(this.Address_direct(), this.CLR()); break; // CLR (direct) case 0x4f: this.Tick(2); this.A = this.CLR(); break; // CLR (CLRA implied) case 0x5f: this.Tick(2); this.B = this.CLR(); break; // CLR (CLRB implied) - case 0x6f: this.Tick(6); this.BusWrite(this.Address_indexed(), this.CLR()); break; // CLR (indexed) - case 0x7f: this.Tick(7); this.BusWrite(this.Address_extended(), this.CLR()); break; // CLR (extended) + case 0x6f: this.Tick(6); this.MemoryWrite(this.Address_indexed(), this.CLR()); break; // CLR (indexed) + case 0x7f: this.Tick(7); this.MemoryWrite(this.Address_extended(), this.CLR()); break; // CLR (extended) // CMP @@ -936,11 +936,11 @@ namespace EightBit case 0xbc: this.Tick(7); this.CMP(this.X, this.AM_extended_word()); break; // CMP (CMPX, extended) // COM - case 0x03: this.Tick(6); this.BusWrite(this.COM(this.AM_direct_byte())); break; // COM (direct) + case 0x03: this.Tick(6); this.MemoryWrite(this.COM(this.AM_direct_byte())); break; // COM (direct) case 0x43: this.Tick(2); this.A = this.COM(this.A); break; // COM (COMA inherent) case 0x53: this.Tick(2); this.B = this.COM(this.B); break; // COM (COMB inherent) - case 0x63: this.Tick(6); this.BusWrite(this.COM(this.AM_indexed_byte())); break; // COM (indexed) - case 0x73: this.Tick(7); this.BusWrite(this.COM(this.AM_extended_byte())); break; // COM (extended) + case 0x63: this.Tick(6); this.MemoryWrite(this.COM(this.AM_indexed_byte())); break; // COM (indexed) + case 0x73: this.Tick(7); this.MemoryWrite(this.COM(this.AM_extended_byte())); break; // COM (extended) // CWAI case 0x3c: this.Tick(11); this.CWAI(this.AM_direct_byte()); break; // CWAI (direct) @@ -949,11 +949,11 @@ namespace EightBit case 0x19: this.Tick(2); this.A = this.DA(this.A); break; // DAA (inherent) // DEC - case 0x0a: this.Tick(6); this.BusWrite(this.DEC(this.AM_direct_byte())); break; // DEC (direct) + case 0x0a: this.Tick(6); this.MemoryWrite(this.DEC(this.AM_direct_byte())); break; // DEC (direct) case 0x4a: this.Tick(2); this.A = this.DEC(this.A); break; // DEC (DECA inherent) case 0x5a: this.Tick(2); this.B = this.DEC(this.B); break; // DEC (DECB inherent) - case 0x6a: this.Tick(6); this.BusWrite(this.DEC(this.AM_indexed_byte())); break; // DEC (indexed) - case 0x7a: this.Tick(7); this.BusWrite(this.DEC(this.AM_extended_byte())); break; // DEC (extended) + case 0x6a: this.Tick(6); this.MemoryWrite(this.DEC(this.AM_indexed_byte())); break; // DEC (indexed) + case 0x7a: this.Tick(7); this.MemoryWrite(this.DEC(this.AM_extended_byte())); break; // DEC (extended) // EOR @@ -973,11 +973,11 @@ namespace EightBit case 0x1e: this.Tick(8); this.EXG(this.AM_immediate_byte()); break; // EXG (R1,R2 immediate) // INC - case 0x0c: this.Tick(6); this.BusWrite(this.INC(this.AM_direct_byte())); break; // INC (direct) + case 0x0c: this.Tick(6); this.MemoryWrite(this.INC(this.AM_direct_byte())); break; // INC (direct) case 0x4c: this.Tick(2); this.A = this.INC(this.A); break; // INC (INCA inherent) case 0x5c: this.Tick(2); this.B = this.INC(this.B); break; // INC (INCB inherent) - case 0x6c: this.Tick(6); this.BusWrite(this.INC(this.AM_indexed_byte())); break; // INC (indexed) - case 0x7c: this.Tick(7); this.BusWrite(this.INC(this.AM_extended_byte())); break; // INC (extended) + case 0x6c: this.Tick(6); this.MemoryWrite(this.INC(this.AM_indexed_byte())); break; // INC (indexed) + case 0x7c: this.Tick(7); this.MemoryWrite(this.INC(this.AM_extended_byte())); break; // INC (extended) // JMP case 0x0e: this.Tick(6); this.Jump(this.Address_direct()); break; // JMP (direct) @@ -1028,21 +1028,21 @@ namespace EightBit case 0x33: this.Tick(4); this.U.Word = this.Address_indexed().Word; break; // LEA (LEAU indexed) // LSR - case 0x04: this.Tick(6); this.BusWrite(this.LSR(this.AM_direct_byte())); break; // LSR (direct) + case 0x04: this.Tick(6); this.MemoryWrite(this.LSR(this.AM_direct_byte())); break; // LSR (direct) case 0x44: this.Tick(2); this.A = this.LSR(this.A); break; // LSR (LSRA inherent) case 0x54: this.Tick(2); this.B = this.LSR(this.B); break; // LSR (LSRB inherent) - case 0x64: this.Tick(6); this.BusWrite(this.LSR(this.AM_indexed_byte())); break; // LSR (indexed) - case 0x74: this.Tick(7); this.BusWrite(this.LSR(this.AM_extended_byte())); break; // LSR (extended) + case 0x64: this.Tick(6); this.MemoryWrite(this.LSR(this.AM_indexed_byte())); break; // LSR (indexed) + case 0x74: this.Tick(7); this.MemoryWrite(this.LSR(this.AM_extended_byte())); break; // LSR (extended) // MUL case 0x3d: this.Tick(11); this.D.Word = this.MUL(this.A, this.B).Word; break; // MUL (inherent) // NEG - case 0x00: this.Tick(6); this.BusWrite(this.NEG(this.AM_direct_byte())); break; // NEG (direct) + case 0x00: this.Tick(6); this.MemoryWrite(this.NEG(this.AM_direct_byte())); break; // NEG (direct) case 0x40: this.Tick(2); this.A = this.NEG(this.A); break; // NEG (NEGA, inherent) case 0x50: this.Tick(2); this.B = this.NEG(this.B); break; // NEG (NEGB, inherent) - case 0x60: this.Tick(6); this.BusWrite(this.NEG(this.AM_indexed_byte())); break; // NEG (indexed) - case 0x70: this.Tick(7); this.BusWrite(this.NEG(this.AM_extended_byte())); break; // NEG (extended) + case 0x60: this.Tick(6); this.MemoryWrite(this.NEG(this.AM_indexed_byte())); break; // NEG (indexed) + case 0x70: this.Tick(7); this.MemoryWrite(this.NEG(this.AM_extended_byte())); break; // NEG (extended) // NOP case 0x12: this.Tick(2); break; // NOP (inherent) @@ -1073,18 +1073,18 @@ namespace EightBit case 0x37: this.Tick(5); this.PUL(this.U, this.AM_immediate_byte()); break; // PUL (PULU immediate) // ROL - case 0x09: this.Tick(6); this.BusWrite(this.ROL(this.AM_direct_byte())); break; // ROL (direct) + case 0x09: this.Tick(6); this.MemoryWrite(this.ROL(this.AM_direct_byte())); break; // ROL (direct) case 0x49: this.Tick(2); this.A = this.ROL(this.A); break; // ROL (ROLA inherent) case 0x59: this.Tick(2); this.B = this.ROL(this.B); break; // ROL (ROLB inherent) - case 0x69: this.Tick(6); this.BusWrite(this.ROL(this.AM_indexed_byte())); break; // ROL (indexed) - case 0x79: this.Tick(7); this.BusWrite(this.ROL(this.AM_extended_byte())); break; // ROL (extended) + case 0x69: this.Tick(6); this.MemoryWrite(this.ROL(this.AM_indexed_byte())); break; // ROL (indexed) + case 0x79: this.Tick(7); this.MemoryWrite(this.ROL(this.AM_extended_byte())); break; // ROL (extended) // ROR - case 0x06: this.Tick(6); this.BusWrite(this.ROR(this.AM_direct_byte())); break; // ROR (direct) + case 0x06: this.Tick(6); this.MemoryWrite(this.ROR(this.AM_direct_byte())); break; // ROR (direct) case 0x46: this.Tick(2); this.A = this.ROR(this.A); break; // ROR (RORA inherent) case 0x56: this.Tick(2); this.B = this.ROR(this.B); break; // ROR (RORB inherent) - case 0x66: this.Tick(6); this.BusWrite(this.ROR(this.AM_indexed_byte())); break; // ROR (indexed) - case 0x76: this.Tick(7); this.BusWrite(this.ROR(this.AM_extended_byte())); break; // ROR (extended) + case 0x66: this.Tick(6); this.MemoryWrite(this.ROR(this.AM_indexed_byte())); break; // ROR (indexed) + case 0x76: this.Tick(7); this.MemoryWrite(this.ROR(this.AM_extended_byte())); break; // ROR (extended) // RTI case 0x3B: this.Tick(6); this.RTI(); break; // RTI (inherent) @@ -1112,14 +1112,14 @@ namespace EightBit // ST // STA - case 0x97: this.Tick(4); this.BusWrite(this.Address_direct(), this.ST(this.A)); break; // ST (STA direct) - case 0xa7: this.Tick(4); this.BusWrite(this.Address_indexed(), this.ST(this.A)); break; // ST (STA indexed) - case 0xb7: this.Tick(5); this.BusWrite(this.Address_extended(), this.ST(this.A)); break; // ST (STA extended) + case 0x97: this.Tick(4); this.MemoryWrite(this.Address_direct(), this.ST(this.A)); break; // ST (STA direct) + case 0xa7: this.Tick(4); this.MemoryWrite(this.Address_indexed(), this.ST(this.A)); break; // ST (STA indexed) + case 0xb7: this.Tick(5); this.MemoryWrite(this.Address_extended(), this.ST(this.A)); break; // ST (STA extended) // STB - case 0xd7: this.Tick(4); this.BusWrite(this.Address_direct(), this.ST(this.B)); break; // ST (STB direct) - case 0xe7: this.Tick(4); this.BusWrite(this.Address_indexed(), this.ST(this.B)); break; // ST (STB indexed) - case 0xf7: this.Tick(5); this.BusWrite(this.Address_extended(), this.ST(this.B)); break; // ST (STB extended) + case 0xd7: this.Tick(4); this.MemoryWrite(this.Address_direct(), this.ST(this.B)); break; // ST (STB direct) + case 0xe7: this.Tick(4); this.MemoryWrite(this.Address_indexed(), this.ST(this.B)); break; // ST (STB indexed) + case 0xf7: this.Tick(5); this.MemoryWrite(this.Address_extended(), this.ST(this.B)); break; // ST (STB extended) // STD case 0xdd: this.Tick(5); this.SetWord(this.Address_direct(), this.ST(this.D)); break; // ST (STD direct) diff --git a/Z80/Z80.FuseTest/TestRunner.cs b/Z80/Z80.FuseTest/TestRunner.cs index f5ae039..1257b34 100644 --- a/Z80/Z80.FuseTest/TestRunner.cs +++ b/Z80/Z80.FuseTest/TestRunner.cs @@ -4,6 +4,7 @@ namespace Fuse { + using System; using System.Collections.Generic; public enum Register @@ -38,8 +39,8 @@ namespace Fuse public TestRunner(Test test, Result result) { this.cpu = new EightBit.Z80(this, this.ports); - this.test = test; - this.result = result; + this.test = test ?? throw new ArgumentNullException(nameof(test)); + this.result = result ?? throw new ArgumentNullException(nameof(result)); foreach (var e in result.Events.Container) { @@ -438,20 +439,14 @@ namespace Fuse { foreach (var e in events) { - var output = $" Event issue {ToString(e)}"; - System.Console.Error.WriteLine(output); + DumpEvent(e); } } - private static string ToString(TestEvent e) + private static void DumpEvent(TestEvent e) { - var output = $"Cycles = {e.Cycles}, Specifier = {e.Specifier}, Address = {e.Address:X4}"; - if (!e.Specifier.EndsWith("C", System.StringComparison.Ordinal)) - { - output += $", Value={e.Value:X2}"; - } - - return output; + var output = $" Event issue {e}"; + System.Console.Error.WriteLine(output); } private void CheckMemory() diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 2f30540..4ed7fda 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -493,22 +493,22 @@ namespace EightBit protected virtual void OnRaisedWR() => this.RaisedWR?.Invoke(this, EventArgs.Empty); - protected override void BusWrite() + protected override void MemoryWrite() { this.Tick(3); this.LowerMREQ(); this.LowerWR(); - base.BusWrite(); + base.MemoryWrite(); this.RaiseWR(); this.RaiseMREQ(); } - protected override byte BusRead() + protected override byte MemoryRead() { this.Tick(3); this.LowerMREQ(); this.LowerRD(); - var returned = base.BusRead(); + var returned = base.MemoryRead(); this.RaiseRD(); this.RaiseMREQ(); return returned; @@ -659,7 +659,7 @@ namespace EightBit 3 => this.E, 4 => this.HL2().High, 5 => this.HL2().Low, - 6 => this.BusRead(this.displaced ? this.DisplacedAddress : this.HL.Word), + 6 => this.MemoryRead(this.displaced ? this.DisplacedAddress : this.HL.Word), 7 => this.A, _ => throw new ArgumentOutOfRangeException(nameof(r)), }; @@ -687,7 +687,7 @@ namespace EightBit this.HL2().Low = value; break; case 6: - this.BusWrite(this.displaced ? this.DisplacedAddress : this.HL.Word, value); + this.MemoryWrite(this.displaced ? this.DisplacedAddress : this.HL.Word, value); break; case 7: this.A = value; @@ -720,7 +720,7 @@ namespace EightBit this.L = value; break; case 6: - this.BusWrite(this.HL, value); + this.MemoryWrite(this.HL, value); break; case 7: this.A = value; @@ -740,7 +740,7 @@ namespace EightBit if (this.displaced) { this.Tick(2); - operand = this.BusRead(this.DisplacedAddress); + operand = this.MemoryRead(this.DisplacedAddress); } else { @@ -784,7 +784,7 @@ namespace EightBit this.Tick(); if (this.displaced) { - this.BusWrite(operand); + this.MemoryWrite(operand); if (!memoryZ) { this.R2(z, operand); @@ -1120,13 +1120,13 @@ namespace EightBit this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word; ++this.MEMPTR.Word; this.MEMPTR.High = this.Bus.Data = this.A; - this.BusWrite(); + this.MemoryWrite(); break; case 1: // LD (DE),A this.MEMPTR.Word = this.Bus.Address.Word = this.DE.Word; ++this.MEMPTR.Word; this.MEMPTR.High = this.Bus.Data = this.A; - this.BusWrite(); + this.MemoryWrite(); break; case 2: // LD (nn),HL this.Bus.Address.Word = this.FetchWord().Word; @@ -1136,7 +1136,7 @@ namespace EightBit this.MEMPTR.Word = this.Bus.Address.Word = this.FetchWord().Word; ++this.MEMPTR.Word; this.MEMPTR.High = this.Bus.Data = this.A; - this.BusWrite(); + this.MemoryWrite(); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -1149,12 +1149,12 @@ namespace EightBit case 0: // LD A,(BC) this.MEMPTR.Word = this.Bus.Address.Word = this.BC.Word; ++this.MEMPTR.Word; - this.A = this.BusRead(); + this.A = this.MemoryRead(); break; case 1: // LD A,(DE) this.MEMPTR.Word = this.Bus.Address.Word = this.DE.Word; ++this.MEMPTR.Word; - this.A = this.BusRead(); + this.A = this.MemoryRead(); break; case 2: // LD HL,(nn) this.Bus.Address.Word = this.FetchWord().Word; @@ -1163,7 +1163,7 @@ namespace EightBit case 3: // LD A,(nn) this.MEMPTR.Word = this.Bus.Address.Word = this.FetchWord().Word; ++this.MEMPTR.Word; - this.A = this.BusRead(); + this.A = this.MemoryRead(); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -1596,7 +1596,7 @@ namespace EightBit { this.Tick(); this.LowerM1(); - var returned = this.BusRead(this.PC.Word); + var returned = this.MemoryRead(this.PC.Word); this.RaiseM1(); this.Bus.Address.Low = this.REFRESH; this.Bus.Address.High = this.IV; @@ -1929,20 +1929,20 @@ namespace EightBit private void XHTL(Register16 exchange) { - this.MEMPTR.Low = this.BusRead(this.SP.Word); + this.MEMPTR.Low = this.MemoryRead(this.SP.Word); ++this.Bus.Address.Word; - this.MEMPTR.High = this.BusRead(); + this.MEMPTR.High = this.MemoryRead(); this.Tick(); - this.BusWrite(exchange.High); + this.MemoryWrite(exchange.High); exchange.High = this.MEMPTR.High; --this.Bus.Address.Word; - this.BusWrite(exchange.Low); + this.MemoryWrite(exchange.Low); exchange.Low = this.MEMPTR.Low; } private void BlockCompare(ushort source, ushort counter) { - var value = this.BusRead(source); + var value = this.MemoryRead(source); var result = (byte)(this.A - value); this.F = SetBit(this.F, StatusBits.PF, counter); @@ -1983,8 +1983,8 @@ namespace EightBit private void BlockLoad(ushort source, ushort destination, ushort counter) { - var value = this.BusRead(source); - this.BusWrite(destination, value); + var value = this.MemoryRead(source); + this.MemoryWrite(destination, value); var xy = this.A + value; this.F = SetBit(this.F, StatusBits.XF, xy & (int)Bits.Bit3); this.F = SetBit(this.F, StatusBits.YF, xy & (int)Bits.Bit1); @@ -2014,7 +2014,7 @@ namespace EightBit this.Tick(); var value = this.ReadPort(); this.Tick(3); - this.BusWrite(destination, value); + this.MemoryWrite(destination, value); source.High = this.Decrement(source.High); this.F = SetBit(this.F, StatusBits.NF); } @@ -2046,7 +2046,7 @@ namespace EightBit private void BlockOut(ushort source, Register16 destination) { this.Tick(); - var value = this.BusRead(source); + var value = this.MemoryRead(source); destination.High = this.Decrement(destination.High); this.Bus.Address.Word = destination.Word; this.WritePort(); @@ -2100,9 +2100,9 @@ namespace EightBit { this.MEMPTR.Word = this.Bus.Address.Word = this.HL.Word; ++this.MEMPTR.Word; - var memory = this.BusRead(); + var memory = this.MemoryRead(); this.Tick(4); - this.BusWrite((byte)(PromoteNibble(this.A) | HighNibble(memory))); + this.MemoryWrite((byte)(PromoteNibble(this.A) | HighNibble(memory))); this.A = (byte)(HigherNibble(this.A) | LowerNibble(memory)); this.F = AdjustSZPXY(this.F, this.A); this.F = ClearBit(this.F, StatusBits.NF | StatusBits.HC); @@ -2112,9 +2112,9 @@ namespace EightBit { this.MEMPTR.Word = this.Bus.Address.Word = this.HL.Word; ++this.MEMPTR.Word; - var memory = this.BusRead(); + var memory = this.MemoryRead(); this.Tick(4); - this.BusWrite((byte)(PromoteNibble(memory) | LowNibble(this.A))); + this.MemoryWrite((byte)(PromoteNibble(memory) | LowNibble(this.A))); this.A = (byte)(HigherNibble(this.A) | HighNibble(memory)); this.F = AdjustSZPXY(this.F, this.A); this.F = ClearBit(this.F, StatusBits.NF | StatusBits.HC);