diff --git a/MC6809/MC6809.UnitTest/ComTests.cs b/MC6809/MC6809.UnitTest/ComTests.cs new file mode 100644 index 0000000..511d54a --- /dev/null +++ b/MC6809/MC6809.UnitTest/ComTests.cs @@ -0,0 +1,60 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class ComTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public ComTests() => 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 TestCOM_direct() + { + this.board.Poke(0xb00, 0x03); + this.board.Poke(0xb01, 0x00); + this.board.Poke(0x0200, 0x07); + this.cpu.CC = 0; + this.cpu.DP = 2; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xf8, this.board.Peek(0x0200)); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + } + + [TestMethod] + public void TestCOM_a() + { + this.cpu.CC = 0; + this.cpu.A = 0x74; + this.board.Poke(0xb00, 0x43); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x8B, this.cpu.A); + Assert.AreEqual(0x09, this.cpu.CC); + } + } +} diff --git a/MC6809/MC6809.UnitTest/LsrTests.cs b/MC6809/MC6809.UnitTest/LsrTests.cs new file mode 100644 index 0000000..8280ca8 --- /dev/null +++ b/MC6809/MC6809.UnitTest/LsrTests.cs @@ -0,0 +1,111 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class LsrTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public LsrTests() => 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(); + + // Logical Shift Right of 0x3E to 0x1F + [TestMethod] + public void TestLSR_a_one() + { + this.board.Poke(0xb00, 0x44); + this.cpu.CC = 0xf; + this.cpu.A = 0x3e; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x1F, this.cpu.A); + Assert.AreEqual(2, this.cpu.CC); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Negative); + } + + // Logical Shift Right of 1 + [TestMethod] + public void TestLSR_a_two() + { + this.board.Poke(0xb00, 0x44); + this.cpu.CC &= (byte)~StatusBits.CF; + this.cpu.CC |= (byte)StatusBits.VF; + this.cpu.CC |= (byte)StatusBits.NF; + this.cpu.A = 1; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Negative); + } + + // Logical Shift Right of 0xB8 + [TestMethod] + public void TestLSR_a_three() + { + this.board.Poke(0xb00, 0x44); + this.cpu.CC &= (byte)~StatusBits.CF; + this.cpu.CC &= (byte)~StatusBits.VF; + this.cpu.A = 0xb8; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x5c, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Carry); + } + + // Shift a byte at 0x0402, because DP = 0x04. + [TestMethod] + public void TestLSR_direct() + { + this.board.Poke(0xb00, 0x4); + this.board.Poke(0xb01, 0x2); + this.cpu.PC.Word = 0xb00; + this.cpu.CC = 0; + this.cpu.A = 0; + this.cpu.B = 0; + this.cpu.DP = 4; + this.cpu.X.Word = 0; + this.cpu.Y.Word = 0; + this.cpu.S.Word = 0; + this.cpu.U.Word = 0; + this.board.Poke(0x0402, 0xf1); + + this.cpu.Step(); + + Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(1, this.cpu.CC); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0, this.cpu.B); + Assert.AreEqual(4, this.cpu.DP); + Assert.AreEqual(0, this.cpu.X.Word); + Assert.AreEqual(0, this.cpu.Y.Word); + Assert.AreEqual(0, this.cpu.S.Word); + Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0x78, this.board.Peek(0x402)); + } + } +} diff --git a/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj b/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj index 1a801ae..d057768 100644 --- a/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj +++ b/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj @@ -8,7 +8,7 @@ {4391A363-ECEF-44C8-9335-BF6ECB811E4B} Library Properties - MC6809.UnitTest + EightBit MC6809.UnitTest v4.7.2 512 @@ -74,6 +74,14 @@ + + + + + + + + diff --git a/MC6809/MC6809.UnitTest/OrTests.cs b/MC6809/MC6809.UnitTest/OrTests.cs new file mode 100644 index 0000000..8a5d8b9 --- /dev/null +++ b/MC6809/MC6809.UnitTest/OrTests.cs @@ -0,0 +1,42 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class OrTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public OrTests() => 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 TestORA_immediate() + { + this.cpu.CC = 0x43; + this.cpu.A = 0xda; + this.board.Poke(0xb00, 0x8a); + this.board.Poke(0xb01, 0x0f); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xdf, this.cpu.A); + Assert.AreEqual(0x49, this.cpu.CC); + } + } +} diff --git a/MC6809/MC6809.UnitTest/PshTests.cs b/MC6809/MC6809.UnitTest/PshTests.cs new file mode 100644 index 0000000..2918934 --- /dev/null +++ b/MC6809/MC6809.UnitTest/PshTests.cs @@ -0,0 +1,99 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class PshTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public PshTests() => 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 TestPSHS_all() + { + this.cpu.S.Word = 517; + this.cpu.CC = 0xf; + this.cpu.A = 1; + this.cpu.B = 2; + this.cpu.DP = 3; + this.cpu.X.Word = 0x405; + this.cpu.Y.Word = 0x607; + this.cpu.U.Word = 0x809; + this.cpu.PC.Word = 0xb00; + this.board.Poke(0xb00, 0x34); + this.board.Poke(0xb01, 0xff); + + this.cpu.Step(); + + Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(0xf, this.cpu.CC); + Assert.AreEqual(1, this.cpu.A); + Assert.AreEqual(2, this.cpu.B); + Assert.AreEqual(517 - 12, this.cpu.S.Word); + Assert.AreEqual(0x02, this.board.Peek(517 - 1)); + Assert.AreEqual(0x0b, this.board.Peek(517 - 2)); + Assert.AreEqual(0x09, this.board.Peek(517 - 3)); + Assert.AreEqual(0x08, this.board.Peek(517 - 4)); + Assert.AreEqual(0x07, this.board.Peek(517 - 5)); + Assert.AreEqual(0x06, this.board.Peek(517 - 6)); + Assert.AreEqual(0x05, this.board.Peek(517 - 7)); + Assert.AreEqual(0x04, this.board.Peek(517 - 8)); + Assert.AreEqual(0x03, this.board.Peek(517 - 9)); + Assert.AreEqual(0x02, this.board.Peek(517 - 10)); + Assert.AreEqual(0x01, this.board.Peek(517 - 11)); + Assert.AreEqual(0x0f, this.board.Peek(517 - 12)); + } + + [TestMethod] + public void TestPSHU_all() + { + this.cpu.U.Word = 517; + this.cpu.CC = 0xf; + this.cpu.A = 1; + this.cpu.B = 2; + this.cpu.DP = 3; + this.cpu.X.Word = 0x405; + this.cpu.Y.Word = 0x607; + this.cpu.S.Word = 0x809; + this.cpu.PC.Word = 0xb00; + this.board.Poke(0xb00, 0x36); + this.board.Poke(0xb01, 0xff); + + this.cpu.Step(); + + Assert.AreEqual(0xb02, this.cpu.PC.Word); + Assert.AreEqual(0xf, this.cpu.CC); + Assert.AreEqual(1, this.cpu.A); + Assert.AreEqual(2, this.cpu.B); + Assert.AreEqual(517 - 12, this.cpu.U.Word); + Assert.AreEqual(0x02, this.board.Peek(517 - 1)); + Assert.AreEqual(0x0b, this.board.Peek(517 - 2)); + Assert.AreEqual(0x09, this.board.Peek(517 - 3)); + Assert.AreEqual(0x08, this.board.Peek(517 - 4)); + Assert.AreEqual(0x07, this.board.Peek(517 - 5)); + Assert.AreEqual(0x06, this.board.Peek(517 - 6)); + Assert.AreEqual(0x05, this.board.Peek(517 - 7)); + Assert.AreEqual(0x04, this.board.Peek(517 - 8)); + Assert.AreEqual(0x03, this.board.Peek(517 - 9)); + Assert.AreEqual(0x02, this.board.Peek(517 - 10)); + Assert.AreEqual(0x01, this.board.Peek(517 - 11)); + Assert.AreEqual(0x0f, this.board.Peek(517 - 12)); + } + } +} diff --git a/MC6809/MC6809.UnitTest/PulTests.cs b/MC6809/MC6809.UnitTest/PulTests.cs new file mode 100644 index 0000000..74f628d --- /dev/null +++ b/MC6809/MC6809.UnitTest/PulTests.cs @@ -0,0 +1,106 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class PulTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public PulTests() => 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 TestPULS_all() + { + this.board.Poke(512 - 12, 0x00); + this.board.Poke(512 - 11, 0x11); + this.board.Poke(512 - 10, 0x12); + this.board.Poke(512 - 9, 0x13); + this.cpu.PokeWord(512 - 8, 0x9141); + this.cpu.PokeWord(512 - 6, 0xa142); + this.cpu.PokeWord(512 - 4, 0xb140); + this.cpu.PokeWord(512 - 2, 0x04ff); + this.cpu.Y.Word = 0x1115; + this.cpu.S.Word = 500; + this.cpu.CC = 0xf; + this.board.Poke(0xb00, 0x35); + this.board.Poke(0xb01, 0xff); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0, this.cpu.CC); + Assert.AreEqual(0x11, this.cpu.A); + Assert.AreEqual(0x12, this.cpu.B); + Assert.AreEqual(0x13, this.cpu.DP); + Assert.AreEqual(0x9141, this.cpu.X.Word); + Assert.AreEqual(0xa142, this.cpu.Y.Word); + Assert.AreEqual(0xb140, this.cpu.U.Word); + Assert.AreEqual(0x4ff, this.cpu.PC.Word); + } + + [TestMethod] + public void TestPULU_all() + { + this.board.Poke(512 - 12, 0x00); + this.board.Poke(512 - 11, 0x11); + this.board.Poke(512 - 10, 0x12); + this.board.Poke(512 - 9, 0x13); + this.cpu.PokeWord(512 - 8, 0x9141); + this.cpu.PokeWord(512 - 6, 0xa142); + this.cpu.PokeWord(512 - 4, 0xb140); + this.cpu.PokeWord(512 - 2, 0x04ff); + this.cpu.Y.Word = 0x1115; + this.cpu.U.Word = 500; + this.cpu.CC = 0xf; + this.board.Poke(0xb00, 0x37); + this.board.Poke(0xb01, 0xff); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0, this.cpu.CC); + Assert.AreEqual(0x11, this.cpu.A); + Assert.AreEqual(0x12, this.cpu.B); + Assert.AreEqual(0x13, this.cpu.DP); + Assert.AreEqual(0x9141, this.cpu.X.Word); + Assert.AreEqual(0xa142, this.cpu.Y.Word); + Assert.AreEqual(0xb140, this.cpu.S.Word); + Assert.AreEqual(0x4ff, this.cpu.PC.Word); + } + + [TestMethod] + public void TestPULS_y() + { + this.cpu.PokeWord(0x205, 0xb140); + this.cpu.PokeWord(0x207, 0x04ff); + this.cpu.Y.Word = 0x1115; + this.cpu.S.Word = 0x205; + this.cpu.CC = 0xf; + this.board.Poke(0xb00, 0x35); + this.board.Poke(0xb01, 0xa0); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xb140, this.cpu.Y.Word); + Assert.AreEqual(0x4ff, this.cpu.PC.Word); + Assert.AreEqual(0xf, this.cpu.CC); + } + } +} diff --git a/MC6809/MC6809.UnitTest/RolTests.cs b/MC6809/MC6809.UnitTest/RolTests.cs new file mode 100644 index 0000000..a214b69 --- /dev/null +++ b/MC6809/MC6809.UnitTest/RolTests.cs @@ -0,0 +1,79 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class RolTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public RolTests() => 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 TestROLB_inherent_one() + { + this.board.Poke(0xB00, 0x59); + this.cpu.B = 0x89; + this.cpu.CC = 0; + this.cpu.CC |= (byte)StatusBits.NF; + this.cpu.CC |= (byte)StatusBits.CF; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xb01, this.cpu.PC.Word); + Assert.AreEqual(0x13, this.cpu.B); + Assert.AreEqual(0x3, this.cpu.CC); + Assert.AreNotEqual(0, this.cpu.Carry); + } + + [TestMethod] + public void TestROLB_inherent_two() + { + this.board.Poke(0xB00, 0x59); + this.cpu.CC = 0; + this.cpu.CC |= (byte)StatusBits.CF; + this.cpu.CC |= (byte)StatusBits.VF; + this.cpu.B = 1; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x3, this.cpu.B); + Assert.AreEqual(0, this.cpu.CC); + } + + [TestMethod] + public void TestROLB_inherent_three() + { + this.board.Poke(0xB00, 0x59); + this.cpu.CC = 0; + this.cpu.B = 0xd8; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xb0, this.cpu.B); + Assert.AreEqual(9, this.cpu.CC); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + } + } +} diff --git a/MC6809/MC6809.UnitTest/RorTests.cs b/MC6809/MC6809.UnitTest/RorTests.cs new file mode 100644 index 0000000..012d45f --- /dev/null +++ b/MC6809/MC6809.UnitTest/RorTests.cs @@ -0,0 +1,61 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class RorTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public RorTests() => 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 TestRORB_inherent_one() + { + this.board.Poke(0xb00, 0x56); + this.cpu.B = 0x89; + this.cpu.CC = 0; + this.cpu.CC |= (byte)StatusBits.CF; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xc4, this.cpu.B); + Assert.AreEqual(9, this.cpu.CC); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.Negative); + } + + [TestMethod] + public void TestRORB_inherent_two() + { + this.board.Poke(0xb00, 0x56); + this.cpu.B = 0x89; + this.cpu.CC = 0; + this.cpu.CC &= (byte)~StatusBits.CF; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x44, this.cpu.B); + Assert.AreEqual(1, this.cpu.CC); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Negative); + } + } +} diff --git a/MC6809/MC6809.UnitTest/TstTests.cs b/MC6809/MC6809.UnitTest/TstTests.cs new file mode 100644 index 0000000..fda0837 --- /dev/null +++ b/MC6809/MC6809.UnitTest/TstTests.cs @@ -0,0 +1,90 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// + +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TstTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public TstTests() => 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 TestTSTA_inherent_one() + { + this.board.Poke(0xb00, 0x4D); + this.cpu.CC = 0; + this.cpu.A = 0xff; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xff, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + } + + [TestMethod] + public void TestTSTA_inherent_two() + { + this.board.Poke(0xb00, 0x4D); + this.cpu.CC = 0; + this.cpu.CC |= (byte)StatusBits.VF; + this.cpu.A = 0x01; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0x01, this.cpu.A); + Assert.AreEqual(0, this.cpu.CC); + } + + [TestMethod] + public void TestTSTA_inherent_three() + { + this.board.Poke(0xb00, 0x4D); + this.cpu.CC = 0; + this.cpu.A = 0; + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + } + + [TestMethod] + public void TestTSTA_indirect() + { + this.board.Poke(0x205, 0xff); + this.cpu.Y.Word = 0x205; + this.board.Poke(0xb00, 0x6d); + this.board.Poke(0xb01, 0xa4); + this.cpu.PC.Word = 0xb00; + + this.cpu.Step(); + + Assert.AreEqual(0xff, this.board.Peek(0x205)); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + } + } +}