test(core): add arithmetic and logic opcode tests

This commit is contained in:
dualfroz committed 2026-08-28 09:50:44 +02:00
1 parent a41e3840c4
commit 219c7b895c
1 file changed
+140
+140
View File
@@ -0,0 +1,140 @@
using Chip8.Core;
using Xunit;
namespace Chip8.Tests;
public class ArithmeticTests
{
[Fact]
public void addImmediateWrapsWithoutTouchingFlag()
{
var machine = TestHarness.withOpcode(0x70FF);
machine.v[0] = 0x05;
machine.v[0xF] = 0xAB;
machine.step();
Assert.Equal(0x04, machine.v[0]);
Assert.Equal(0xAB, machine.v[0xF]);
}
[Fact]
public void moveCopiesVyIntoVx()
{
var machine = TestHarness.withOpcode(0x8010);
machine.v[1] = 0x42;
machine.step();
Assert.Equal(0x42, machine.v[0]);
}
[Fact]
public void orAndXorProduceExpectedBits()
{
var or = TestHarness.withOpcode(0x8011);
or.v[0] = 0b1100; or.v[1] = 0b1010; or.step();
Assert.Equal(0b1110, or.v[0]);
var and = TestHarness.withOpcode(0x8012);
and.v[0] = 0b1100; and.v[1] = 0b1010; and.step();
Assert.Equal(0b1000, and.v[0]);
var xor = TestHarness.withOpcode(0x8013);
xor.v[0] = 0b1100; xor.v[1] = 0b1010; xor.step();
Assert.Equal(0b0110, xor.v[0]);
}
[Fact]
public void logicLeavesFlagUntouchedOnModernButClearsOnCosmac()
{
var modern = TestHarness.withOpcode(0x8011, Quirks.modern());
modern.v[0] = 1; modern.v[1] = 2; modern.v[0xF] = 0x7;
modern.step();
Assert.Equal(0x7, modern.v[0xF]);
var cosmac = TestHarness.withOpcode(0x8011, Quirks.cosmacVip());
cosmac.v[0] = 1; cosmac.v[1] = 2; cosmac.v[0xF] = 0x7;
cosmac.step();
Assert.Equal(0, cosmac.v[0xF]);
}
[Fact]
public void addSetsCarryFlag()
{
var overflow = TestHarness.withOpcode(0x8014);
overflow.v[0] = 200; overflow.v[1] = 100;
overflow.step();
Assert.Equal(44, overflow.v[0]);
Assert.Equal(1, overflow.v[0xF]);
var noOverflow = TestHarness.withOpcode(0x8014);
noOverflow.v[0] = 20; noOverflow.v[1] = 30;
noOverflow.step();
Assert.Equal(50, noOverflow.v[0]);
Assert.Equal(0, noOverflow.v[0xF]);
}
[Fact]
public void addIntoVfKeepsCarryNotSum()
{
var machine = TestHarness.withOpcode(0x8F14);
machine.v[0xF] = 200; machine.v[1] = 100;
machine.step();
Assert.Equal(1, machine.v[0xF]);
}
[Fact]
public void subtractSetsNotBorrowFlag()
{
var positive = TestHarness.withOpcode(0x8015);
positive.v[0] = 50; positive.v[1] = 20;
positive.step();
Assert.Equal(30, positive.v[0]);
Assert.Equal(1, positive.v[0xF]);
var borrow = TestHarness.withOpcode(0x8015);
borrow.v[0] = 20; borrow.v[1] = 50;
borrow.step();
Assert.Equal(226, borrow.v[0]);
Assert.Equal(0, borrow.v[0xF]);
}
[Fact]
public void subtractReverseUsesVyMinusVx()
{
var machine = TestHarness.withOpcode(0x8017);
machine.v[0] = 20; machine.v[1] = 50;
machine.step();
Assert.Equal(30, machine.v[0]);
Assert.Equal(1, machine.v[0xF]);
}
[Fact]
public void shiftRightUsesConfiguredSource()
{
var modern = TestHarness.withOpcode(0x8016, Quirks.modern());
modern.v[0] = 0b0000_0101; modern.v[1] = 0xFF;
modern.step();
Assert.Equal(0b0000_0010, modern.v[0]);
Assert.Equal(1, modern.v[0xF]);
var cosmac = TestHarness.withOpcode(0x8016, Quirks.cosmacVip());
cosmac.v[0] = 0x00; cosmac.v[1] = 0b0000_0101;
cosmac.step();
Assert.Equal(0b0000_0010, cosmac.v[0]);
Assert.Equal(1, cosmac.v[0xF]);
}
[Fact]
public void shiftLeftUsesConfiguredSource()
{
var modern = TestHarness.withOpcode(0x801E, Quirks.modern());
modern.v[0] = 0b1000_0001;
modern.step();
Assert.Equal(0b0000_0010, modern.v[0]);
Assert.Equal(1, modern.v[0xF]);
var cosmac = TestHarness.withOpcode(0x801E, Quirks.cosmacVip());
cosmac.v[0] = 0x00; cosmac.v[1] = 0b1000_0001;
cosmac.step();
Assert.Equal(0b0000_0010, cosmac.v[0]);
Assert.Equal(1, cosmac.v[0xF]);
}
}