public void Lsr([Range(0x0, 0xF, 0x5)] int lowOperand, [Range(0x0, 0xF, 0x5)] int highOperand) { // Arrange var operand = lowOperand + (highOperand << 4); var expectedResult = operand >> 1; var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; var expectedOverflow = Cpu.V; var expectedCarry = (operand & 0x01) != 0; System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(0x00) .Returns(operand); Cpu.SetOpcode(0x46); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must not be modified"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must be set correctly"); System.Verify(m => m.Write(0, operand)); System.Verify(m => m.Write(0, expectedResult)); }
public void Ora([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0x0, 0xF, 0x5)] int lowOperand, [Range(0x0, 0xF, 0x5)] int highOperand) { // Arrange var a = lowA + (highA << 4); var operand = lowOperand + (highOperand << 4); var expectedResult = a | operand; var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; var expectedOverflow = Cpu.V; var expectedCarry = Cpu.C; Cpu.SetOpcode(0x09); Cpu.SetA(a); System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(operand); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must not be modified"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must not be modified"); Cpu.A.Should().Be(expectedResult & 0xFF, "A must be set correctly"); }
public void AdcNoDecimal([Range(0x0, 0xC, 0x4)] int lowA, [Range(0x0, 0xC, 0x4)] int highA, [Range(0x0, 0xC, 0x4)] int lowOperand, [Range(0x0, 0xC, 0x4)] int highOperand, [Range(0, 1)] int c) { // Arrange var a = lowA + (highA << 4); var operand = lowOperand + (highOperand << 4); var carry = c != 0; var expectedResult = a + operand + (carry ? 1 : 0); var expectedOverflow = ((a ^ expectedResult) & (a ^ operand) & 0x80) == 0; var expectedCarry = (expectedResult & 0x100) != 0; var expectedZero = (expectedResult & 0xFF) == 0; var expectedSign = (expectedResult & 0x80) != 0; Cpu.SetD(false); Cpu.SetC(carry); Cpu.SetA(a); System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(operand); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must be set correctly"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must be set correctly"); Cpu.A.Should().Be(expectedResult & 0xFF, "A must be set correctly"); }
public void RorA([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0, 1)] int carry) { // Arrange var a = lowA + (highA << 4); var expectedResult = (a >> 1) | (carry != 0 ? 0x80 : 0x00); var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; var expectedOverflow = Cpu.V; var expectedCarry = (a & 0x01) != 0; expectedResult &= 0xFF; Cpu.SetA(a); Cpu.SetOpcode(0x6A); Cpu.SetC(carry != 0); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must not be modified"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must be set correctly"); Cpu.A.Should().Be(expectedResult, "A must be set correctly"); }
public void Sei([Range(0, 1)] int i) { // Arrange Cpu.SetOpcode(0x78); Cpu.SetI(i != 0); // Act Cpu.ClockStep(); // Assert Cpu.I.Should().BeTrue("I must be set"); }
public void Cli([Range(0, 1)] int i) { // Arrange Cpu.SetOpcode(0x58); Cpu.SetI(i != 0); // Act Cpu.ClockStep(); // Assert Cpu.I.Should().BeFalse("I must be cleared"); }
public void Sec([Range(0, 1)] int c) { // Arrange Cpu.SetOpcode(0x38); Cpu.SetC(c != 0); // Act Cpu.ClockStep(); // Assert Cpu.C.Should().BeTrue("C must be set"); }
public void Clc([Range(0, 1)] int c) { // Arrange Cpu.SetOpcode(0x18); Cpu.SetC(c != 0); // Act Cpu.ClockStep(); // Assert Cpu.C.Should().BeFalse("C must be cleared"); }
public void Sed([Range(0, 1)] int d) { // Arrange Cpu.SetOpcode(0xF8); Cpu.SetD(d != 0); // Act Cpu.ClockStep(); // Assert Cpu.D.Should().BeTrue("D must be set"); }
public void Clv([Range(0, 1)] int v) { // Arrange Cpu.SetOpcode(0xB8); Cpu.SetV(v != 0); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().BeFalse("V must be cleared"); }
public void Cld([Range(0, 1)] int d) { // Arrange Cpu.SetOpcode(0xD8); Cpu.SetD(d != 0); // Act Cpu.ClockStep(); // Assert Cpu.D.Should().BeFalse("D must be cleared"); }
public void Tax([Random(0x00, 0x7F, 1)] int r0, [Random(0x80, 0xFF, 1)] int r1) { // Arrange Cpu.SetA(r0); Cpu.SetX(r1); Cpu.SetOpcode(0xAA); // Act Cpu.ClockStep(); // Assert Cpu.X.Should().Be(r0); }
public void Bcc([Range(0x20, 0xE0, 0x40)] int offset, [Range(0x0000, 0xFFFF, 0x5555)] int pc, [Range(0, 1)] int carry) { // Arrange Cpu.SetOpcode(0x90); Cpu.SetC(carry != 0); Cpu.SetPC(pc); System.Setup(m => m.Read(It.IsAny <int>())).Returns(offset); var expectedPc = CalculateBranch(pc, offset, carry == 0); // Act Cpu.ClockStep(); // Assert Cpu.PC.Should().Be(expectedPc); }
public void Cpx([Range(0x0, 0xF, 0x5)] int lowX, [Range(0x0, 0xF, 0x5)] int highX, [Range(0x0, 0xF, 0x5)] int lowData, [Range(0x0, 0xF, 0x5)] int highData) { // Arrange var x = lowX + (highX << 4); var data = lowData + (highData << 4); Cpu.SetX(x); Cpu.SetOpcode(0xE0); System.Setup(m => m.Read(It.IsAny <int>())).Returns(data); // Act Cpu.ClockStep(); // Assert Console.WriteLine("X=${0:x2}; CPX #${1:x2}", x, data); Cpu.X.Should().Be(x, "X must not be modified"); CompareFlags(x, data); }
public void Cpy([Range(0x0, 0xF, 0x5)] int lowY, [Range(0x0, 0xF, 0x5)] int highY, [Range(0x0, 0xF, 0x5)] int lowData, [Range(0x0, 0xF, 0x5)] int highData) { // Arrange var y = lowY + (highY << 4); var data = lowData + (highData << 4); Cpu.SetY(y); Cpu.SetOpcode(0xC0); System.Setup(m => m.Read(It.IsAny <int>())).Returns(data); // Act Cpu.ClockStep(); // Assert Console.WriteLine("Y=${0:x2}; CPY #${1:x2}", y, data); Cpu.Y.Should().Be(y, "Y must not be modified"); CompareFlags(y, data); }
public void Cmp([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0x0, 0xF, 0x5)] int lowData, [Range(0x0, 0xF, 0x5)] int highData) { // Arrange var a = lowA + (highA << 4); var data = lowData + (highData << 4); Cpu.SetA(a); Cpu.SetOpcode(0xC9); System.Setup(m => m.Read(It.IsAny <int>())).Returns(data); // Act Cpu.ClockStep(); // Assert Console.WriteLine("A=${0:x2}; CMP #${1:x2}", a, data); Cpu.A.Should().Be(a, "A must not be modified"); CompareFlags(a, data); }
public void SbcDecimal([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0x0, 0xF, 0x5)] int lowOperand, [Range(0x0, 0xF, 0x5)] int highOperand, [Range(0, 1)] int c) { // Arrange var a = lowA + (highA << 4); var operand = lowOperand + (highOperand << 4); var carry = c != 0; var temp = a - operand - (carry ? 0 : 1); var temp2 = (a & 0xF) - (operand & 0xF) - (carry ? 0 : 1); if ((temp2 & 0x10) != 0) { temp2 = ((temp2 - 6) & 0xF) | ((a & 0xF0) - (operand & 0xF0) - 0x10); } else { temp2 = (temp2 & 0xF) | ((a & 0xF0) - (operand & 0xF0)); } if ((temp2 & 0x100) != 0) { temp2 -= 0x60; } var expectedCarry = temp >= 0; var expectedZero = (temp & 0xFF) == 0; var expectedSign = (temp & 0x80) != 0; var expectedOverflow = ((a ^ temp) & (a ^ operand) & 0x80) != 0; var expectedResult = temp2 & 0xFF; Cpu.SetD(true); Cpu.SetC(carry); Cpu.SetA(a); System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(operand); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must be set correctly"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must be set correctly"); Cpu.A.Should().Be(expectedResult & 0xFF, "A must be set correctly"); }
public void AdcDecimal([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0x0, 0xF, 0x5)] int lowOperand, [Range(0x0, 0xF, 0x5)] int highOperand, [Range(0, 1)] int c) { // Arrange var a = lowA + (highA << 4); var operand = lowOperand + (highOperand << 4); var carry = c != 0; var lowTemp = lowA + lowOperand + c; if (lowTemp > 9) { lowTemp += 6; } var highTemp = highA + highOperand + (lowTemp > 0xF ? 1 : 0); var temp = (lowTemp & 0xF) + (highTemp << 4); var expectedZero = ((a + operand + c) & 0xFF) == 0; var expectedSign = (temp & 0x80) != 0; var expectedOverflow = ((a ^ temp) & (a ^ operand) & 0x80) == 0; if (temp > 0x99) { temp += 96; } var expectedCarry = temp > 0x99; var expectedResult = temp & 0xFF; Cpu.SetD(true); Cpu.SetC(carry); Cpu.SetA(a); System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(operand); // Act Cpu.ClockStep(); // Assert Cpu.V.Should().Be(expectedOverflow, "V must be set correctly"); Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.C.Should().Be(expectedCarry, "C must be set correctly"); Cpu.A.Should().Be(expectedResult & 0xFF, "A must be set correctly"); }
public void Dex([Range(0x0, 0xF, 0x5)] int lowX, [Range(0x0, 0xF, 0x5)] int highX) { // Arrange var x = lowX + (highX << 4); var expectedResult = (x - 1); var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; expectedResult &= 0xFF; Cpu.SetOpcode(0xCA); Cpu.SetX(x); // Act Cpu.ClockStep(); // Assert Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.X.Should().Be(expectedResult, "X must be set correctly"); }
public void Dey([Range(0x0, 0xF, 0x5)] int lowY, [Range(0x0, 0xF, 0x5)] int highY) { // Arrange var y = lowY + (highY << 4); var expectedResult = (y - 1); var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; expectedResult &= 0xFF; Cpu.SetOpcode(0x88); Cpu.SetY(y); // Act Cpu.ClockStep(); // Assert Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); Cpu.Y.Should().Be(expectedResult, "Y must be set correctly"); }
public void Bit([Range(0x0, 0xF, 0x5)] int lowA, [Range(0x0, 0xF, 0x5)] int highA, [Range(0x0, 0xF, 0x5)] int lowData, [Range(0x0, 0xF, 0x5)] int highData) { // Arrange var a = lowA + (highA << 4); var data = lowData + (highData << 4); var expectedN = (data & 0x80) != 0; var expectedV = (data & 0x40) != 0; var expectedZ = (data & a) == 0; System.Setup(m => m.Read(It.IsAny <int>())).Returns(data); Cpu.SetA(a); // Act Cpu.ClockStep(); // Assert Cpu.A.Should().Be(a); Cpu.N.Should().Be(expectedN); Cpu.V.Should().Be(expectedV); Cpu.Z.Should().Be(expectedZ); }
public void Dec([Range(0x0, 0xF, 0x5)] int lowOperand, [Range(0x0, 0xF, 0x5)] int highOperand) { // Arrange var operand = lowOperand + (highOperand << 4); var expectedResult = (operand - 1); var expectedSign = (expectedResult & 0x80) != 0; var expectedZero = (expectedResult & 0xFF) == 0; expectedResult &= 0xFF; System.SetupSequence(m => m.Read(It.IsAny <int>())) .Returns(0x00) .Returns(operand); Cpu.SetOpcode(0xC6); // Act Cpu.ClockStep(); // Assert Cpu.Z.Should().Be(expectedZero, "Z must be set correctly"); Cpu.N.Should().Be(expectedSign, "N must be set correctly"); System.Verify(m => m.Write(0, operand)); System.Verify(m => m.Write(0, expectedResult)); }