Add tests for EXG, TFR and NEG. Also added some undocumented behaviour to EXG and TFR.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-06-02 19:04:27 +01:00
parent fa16dd1486
commit 8b3c0801ce
5 changed files with 337 additions and 32 deletions

View File

@ -0,0 +1,75 @@
// <copyright file="ExgTests.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class ExgTests
{
private readonly Board board = new Board();
private readonly MC6809 cpu;
public ExgTests() => this.cpu = this.board.CPU;
[TestInitialize]
public void Initialise()
{
this.board.RaisePOWER();
this.cpu.Step(); // Step over the reset
}
[TestCleanup]
public void Cleanup() => this.board.LowerPOWER();
[TestMethod]
public void TestEXG_a_dp()
{
this.board.Poke(0xb00, 0x1e);
this.board.Poke(0xb01, 0x8B);
this.cpu.CC = 0;
this.cpu.A = 0x7f;
this.cpu.DP = 0xf6;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x7f, this.cpu.DP);
Assert.AreEqual(0xf6, this.cpu.A);
}
[TestMethod]
public void TestEXG_d_x()
{
this.board.Poke(0xb00, 0x1e);
this.board.Poke(0xb01, 0x01);
this.cpu.CC = 0;
this.cpu.D.Word = 0x117f;
this.cpu.X.Word = 0xff16;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0xff16, this.cpu.D.Word);
Assert.AreEqual(0x117f, this.cpu.X.Word);
}
[TestMethod]
public void TestEXG_a_x()
{
this.board.Poke(0xb00, 0x1e);
this.board.Poke(0xb01, 0x81);
this.cpu.CC = 0;
this.cpu.A = 0x56;
this.cpu.X.Word = 0x1234;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x34, this.cpu.A);
Assert.AreEqual(0xff56, this.cpu.X.Word);
}
}
}

View File

@ -65,12 +65,15 @@
<Compile Include="ClrTests.cs" />
<Compile Include="CmpTests.cs" />
<Compile Include="DecTests.cs" />
<Compile Include="ExgTests.cs" />
<Compile Include="IncTests.cs" />
<Compile Include="JsrTests.cs" />
<Compile Include="NegTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RtsTests.cs" />
<Compile Include="SbcTests.cs" />
<Compile Include="SubTests.cs" />
<Compile Include="TfrTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\EightBit\EightBit.csproj">

View File

@ -0,0 +1,83 @@
// <copyright file="NegTests.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class NegTests
{
private readonly Board board = new Board();
private readonly MC6809 cpu;
public NegTests() => this.cpu = this.board.CPU;
[TestInitialize]
public void Initialise()
{
this.board.RaisePOWER();
this.cpu.Step(); // Step over the reset
}
[TestCleanup]
public void Cleanup() => this.board.LowerPOWER();
[TestMethod]
public void TestNEG_zero()
{
this.board.Poke(0xb00, 0x40);
this.cpu.A = 0;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0, this.cpu.A);
Assert.AreEqual(0, this.cpu.Carry);
}
[TestMethod]
public void TestNEG_one()
{
this.board.Poke(0xb00, 0x40);
this.cpu.A = 1;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0xff, this.cpu.A);
Assert.AreNotEqual(0, this.cpu.Carry);
}
[TestMethod]
public void TestNEG_two()
{
this.board.Poke(0xb00, 0x40);
this.cpu.A = 2;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0xfe, this.cpu.A);
Assert.AreNotEqual(0, this.cpu.Carry);
Assert.AreEqual(0, this.cpu.Overflow);
}
[TestMethod]
public void TestNEG_eighty()
{
this.board.Poke(0xb00, 0x40);
this.cpu.A = 0x80;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x80, this.cpu.A);
Assert.AreNotEqual(0, this.cpu.Carry);
Assert.AreNotEqual(0, this.cpu.Overflow);
Assert.AreEqual(0, this.cpu.Zero);
Assert.AreNotEqual(0, this.cpu.Negative);
}
}
}

View File

@ -0,0 +1,119 @@
// <copyright file="TfrTests.cs" company="Adrian Conlon">
// Copyright (c) Adrian Conlon. All rights reserved.
// </copyright>
namespace EightBit
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class TfrTests
{
private readonly Board board = new Board();
private readonly MC6809 cpu;
public TfrTests() => this.cpu = this.board.CPU;
[TestInitialize]
public void Initialise()
{
this.board.RaisePOWER();
this.cpu.Step(); // Step over the reset
}
[TestCleanup]
public void Cleanup() => this.board.LowerPOWER();
[TestMethod]
public void TestTFR_d_y()
{
this.board.Poke(0xb00, 0x1f);
this.board.Poke(0xb01, 0x02);
this.cpu.CC = 0;
this.cpu.D.Word = 0xabba;
this.cpu.Y.Word = 0x101;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0xb02, this.cpu.PC.Word);
Assert.AreEqual(0xabba, this.cpu.D.Word);
Assert.AreEqual(0xabba, this.cpu.Y.Word);
Assert.AreEqual(0, this.cpu.Negative);
Assert.AreEqual(0, this.cpu.Zero);
Assert.AreEqual(0, this.cpu.Overflow);
}
[TestMethod]
public void TestTFR_s_pc()
{
this.board.Poke(0xb00, 0x1f);
this.board.Poke(0xb01, 0x45);
this.cpu.CC = 0;
this.cpu.S.Word = 0x1bb1;
this.cpu.Y.Word = 0x101;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x1bb1, this.cpu.PC.Word);
Assert.AreEqual(0x1bb1, this.cpu.S.Word);
Assert.AreEqual(0, this.cpu.Negative);
Assert.AreEqual(0, this.cpu.Zero);
Assert.AreEqual(0, this.cpu.Overflow);
}
[TestMethod]
public void TestTFR_dp_cc()
{
this.board.Poke(0xb00, 0x1f);
this.board.Poke(0xb01, 0xba);
this.cpu.CC = 0;
this.cpu.DP = 0x1b;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x1b, this.cpu.DP);
Assert.AreEqual(0x1b, this.cpu.CC);
Assert.AreEqual(0, this.cpu.HalfCarry);
Assert.AreNotEqual(0, this.cpu.InterruptMasked);
Assert.AreNotEqual(0, this.cpu.Negative);
Assert.AreEqual(0, this.cpu.Zero);
Assert.AreNotEqual(0, this.cpu.Overflow);
Assert.AreNotEqual(0, this.cpu.Carry);
}
[TestMethod]
public void TestTFR_a_x()
{
this.board.Poke(0xb00, 0x1f);
this.board.Poke(0xb01, 0x81);
this.cpu.A = 0x56;
this.cpu.B = 0x78;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x56, this.cpu.A);
Assert.AreEqual(0xff56, this.cpu.X.Word);
}
[TestMethod]
public void TestTFR_x_b()
{
this.board.Poke(0xb00, 0x1f);
this.board.Poke(0xb01, 0x19);
this.cpu.CC = 0;
this.cpu.X.Word = 0x6541;
this.cpu.B = 0x78;
this.cpu.PC.Word = 0xb00;
this.cpu.Step();
Assert.AreEqual(0x41, this.cpu.B);
Assert.AreEqual(0x6541, this.cpu.X.Word);
}
}
}

View File

@ -1298,28 +1298,41 @@
private void EXG(byte data)
{
var specifier1 = Chip.HighNibble(data);
var type1 = specifier1 & (int)Bits.Bit3; // transfer type, part 1
var leftSpecifier = Chip.HighNibble(data);
var leftType = leftSpecifier & (int)Bits.Bit3;
var specifier2 = Chip.LowNibble(data);
var type2 = specifier2 & (int)Bits.Bit3; // transfer type, part 2
var rightSpecifier = Chip.LowNibble(data);
var rightType = rightSpecifier & (int)Bits.Bit3;
if (type1 != type2)
if (leftType == 0)
{
throw new ArgumentOutOfRangeException(nameof(data), data, "Type specifications do not match");
}
if (type1 == 0)
{
var register1 = this.ReferenceTransfer16(specifier1);
var register2 = this.ReferenceTransfer16(specifier2);
(register1.Word, register2.Word) = (register2.Word, register1.Word);
var leftRegister = this.ReferenceTransfer16(leftSpecifier);
if (rightType == 0)
{
var rightRegister = this.ReferenceTransfer16(rightSpecifier);
(leftRegister.Word, rightRegister.Word) = (rightRegister.Word, leftRegister.Word);
}
else
{
var rightRegister = this.ReferenceTransfer8(rightSpecifier);
(leftRegister.Low, rightRegister) = (rightRegister, leftRegister.Low);
leftRegister.High = (byte)Mask.Mask8;
}
}
else
{
ref var register1 = ref this.ReferenceTransfer8(specifier1);
ref var register2 = ref this.ReferenceTransfer8(specifier2);
(register1, register2) = (register2, register1);
ref var leftRegister = ref this.ReferenceTransfer8(leftSpecifier);
if (rightType == 0)
{
var rightRegister = this.ReferenceTransfer16(rightSpecifier);
(leftRegister, rightRegister.Low) = (rightRegister.Low, leftRegister);
rightRegister.High =(byte)Mask.Mask8;
}
else
{
ref var rightRegister = ref this.ReferenceTransfer8(rightSpecifier);
(leftRegister, rightRegister) = (rightRegister, leftRegister);
}
}
}
@ -1535,28 +1548,40 @@
private void TFR(byte data)
{
var specifier1 = Chip.HighNibble(data);
var type1 = specifier1 & (int)Bits.Bit3; // transfer type, part 1
var sourceSpecifier = Chip.HighNibble(data);
var sourceType = sourceSpecifier & (int)Bits.Bit3;
var specifier2 = Chip.LowNibble(data);
var type2 = specifier2 & (int)Bits.Bit3; // transfer type, part 2
var destinationSpecifier = Chip.LowNibble(data);
var destinationType = destinationSpecifier & (int)Bits.Bit3;
if (type1 != type2)
if (sourceType == 0)
{
throw new ArgumentOutOfRangeException(nameof(data), data, "Type specifications do not match");
}
if (type1 == 0)
{
var register1 = this.ReferenceTransfer16(specifier1);
var register2 = this.ReferenceTransfer16(specifier2);
register2.Word = register1.Word;
var sourceRegister = this.ReferenceTransfer16(sourceSpecifier);
if (destinationType == 0)
{
var destinationRegister = this.ReferenceTransfer16(destinationSpecifier);
destinationRegister.Word = sourceRegister.Word;
}
else
{
ref var destinationRegister = ref this.ReferenceTransfer8(destinationSpecifier);
destinationRegister = sourceRegister.Low;
}
}
else
{
ref var register1 = ref this.ReferenceTransfer8(specifier1);
ref var register2 = ref this.ReferenceTransfer8(specifier2);
register2 = register1;
ref var sourceRegister = ref this.ReferenceTransfer8(sourceSpecifier);
if (destinationType == 0)
{
var destinationRegister = this.ReferenceTransfer16(destinationSpecifier);
destinationRegister.Low = sourceRegister;
destinationRegister.High = (byte)Mask.Mask8;
}
else
{
ref var destinationRegister = ref this.ReferenceTransfer8(destinationSpecifier);
destinationRegister = sourceRegister;
}
}
}