diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index 0fd5766..d40ffe1 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -21,8 +21,8 @@ namespace EightBit public override void PokeWord(ushort address, Register16 value) { - this.Bus.Poke(address, value.Low); - this.Bus.Poke(++address, value.High); + this.Bus.Poke(address, value.High); + this.Bus.Poke(++address, value.Low); } protected override Register16 FetchWord() diff --git a/EightBit/EightBit.UnitTest/ChipUnitTest.cs b/EightBit/EightBit.UnitTest/ChipUnitTest.cs index 7832a72..4250b13 100644 --- a/EightBit/EightBit.UnitTest/ChipUnitTest.cs +++ b/EightBit/EightBit.UnitTest/ChipUnitTest.cs @@ -2,9 +2,8 @@ // Copyright (c) Adrian Conlon. All rights reserved. // -namespace UnitTestEightBit +namespace EightBit { - using EightBit; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -14,7 +13,7 @@ namespace UnitTestEightBit public void TestLowByte() { const ushort input = 0xf00f; - byte low = Chip.LowByte(input); + var low = Chip.LowByte(input); Assert.AreEqual(0xf, low); } @@ -22,7 +21,7 @@ namespace UnitTestEightBit public void TestHighByte() { const ushort input = 0xf00f; - byte high = Chip.HighByte(input); + var high = Chip.HighByte(input); Assert.AreEqual(0xf0, high); } @@ -118,7 +117,7 @@ namespace UnitTestEightBit public void TestHigherPart() { const ushort input = 0xf00f; - ushort higher = Chip.HigherPart(input); + var higher = Chip.HigherPart(input); Assert.AreEqual(0xf000, higher); } @@ -126,7 +125,7 @@ namespace UnitTestEightBit public void TestDemoteByte() { const ushort input = 0xf00f; - byte demoted = Chip.DemoteByte(input); + var demoted = Chip.DemoteByte(input); Assert.AreEqual(0xf0, demoted); } @@ -134,7 +133,7 @@ namespace UnitTestEightBit public void TestPromoteByte() { const byte input = 0xf0; - ushort promoted = Chip.PromoteByte(input); + var promoted = Chip.PromoteByte(input); Assert.AreEqual(0xf000, promoted); } @@ -142,7 +141,7 @@ namespace UnitTestEightBit public void TestLowNibble() { const byte input = 0xab; - int nibble = Chip.LowNibble(input); + var nibble = Chip.LowNibble(input); Assert.AreEqual(0xb, nibble); } @@ -150,7 +149,7 @@ namespace UnitTestEightBit public void TestHighNibble() { const byte input = 0xab; - int nibble = Chip.HighNibble(input); + var nibble = Chip.HighNibble(input); Assert.AreEqual(0xa, nibble); } @@ -158,7 +157,7 @@ namespace UnitTestEightBit public void TestDemoteNibble() { const byte input = 0xab; - int nibble = Chip.DemoteNibble(input); + var nibble = Chip.DemoteNibble(input); Assert.AreEqual(0xa, nibble); } @@ -166,7 +165,7 @@ namespace UnitTestEightBit public void TestPromoteNibble() { const byte input = 0xab; - int nibble = Chip.PromoteNibble(input); + var nibble = Chip.PromoteNibble(input); Assert.AreEqual(0xb0, nibble); } @@ -174,7 +173,7 @@ namespace UnitTestEightBit public void TestHigherNibble() { const byte input = 0xab; - int nibble = Chip.HigherNibble(input); + var nibble = Chip.HigherNibble(input); Assert.AreEqual(0xa0, nibble); } @@ -182,14 +181,14 @@ namespace UnitTestEightBit public void TestLowerNibble() { const byte input = 0xab; - int nibble = Chip.LowerNibble(input); + var nibble = Chip.LowerNibble(input); Assert.AreEqual(0xb, nibble); } [TestMethod] public void TestMakeWord() { - ushort word = Chip.MakeWord(0xcd, 0xab); + var word = Chip.MakeWord(0xcd, 0xab); Assert.AreEqual(0xabcd, word); } } diff --git a/EightBit/EightBit.UnitTest/EightBit.UnitTest.csproj b/EightBit/EightBit.UnitTest/EightBit.UnitTest.csproj index ffac447..54d10f6 100644 --- a/EightBit/EightBit.UnitTest/EightBit.UnitTest.csproj +++ b/EightBit/EightBit.UnitTest/EightBit.UnitTest.csproj @@ -68,8 +68,8 @@ - - + + diff --git a/EightBit/EightBit.UnitTest/packages.config b/EightBit/EightBit.UnitTest/packages.config index 5d91928..2e1890d 100644 --- a/EightBit/EightBit.UnitTest/packages.config +++ b/EightBit/EightBit.UnitTest/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 4bbd5ff..4eb64ac 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -73,6 +73,8 @@ namespace EightBit public abstract void PokeWord(ushort address, Register16 value); + public void PokeWord(ushort address, ushort value) => this.PokeWord(address, new Register16(value)); + public virtual void RaiseRESET() { this.OnRaisingRESET(); diff --git a/Intel8080/Intel8080.Test/Intel8080.Test.csproj b/Intel8080/Intel8080.Test/Intel8080.Test.csproj index f0e9af7..a29569f 100644 --- a/Intel8080/Intel8080.Test/Intel8080.Test.csproj +++ b/Intel8080/Intel8080.Test/Intel8080.Test.csproj @@ -61,8 +61,8 @@ - - + + \ No newline at end of file diff --git a/Intel8080/Intel8080.Test/packages.config b/Intel8080/Intel8080.Test/packages.config index 01177e8..68fc00e 100644 --- a/Intel8080/Intel8080.Test/packages.config +++ b/Intel8080/Intel8080.Test/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/M6502/M6502.Test/M6502.Test.csproj b/M6502/M6502.Test/M6502.Test.csproj index 0a5e0a5..10230f5 100644 --- a/M6502/M6502.Test/M6502.Test.csproj +++ b/M6502/M6502.Test/M6502.Test.csproj @@ -70,8 +70,8 @@ - - + + \ No newline at end of file diff --git a/M6502/M6502.Test/packages.config b/M6502/M6502.Test/packages.config index 01177e8..2c95c37 100644 --- a/M6502/M6502.Test/packages.config +++ b/M6502/M6502.Test/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/M6502/M6502.csproj b/M6502/M6502.csproj index 6609bdc..c6cd4ec 100644 --- a/M6502/M6502.csproj +++ b/M6502/M6502.csproj @@ -67,8 +67,8 @@ - - + + - + \ No newline at end of file diff --git a/M6502/packages.config b/M6502/packages.config index 01177e8..68fc00e 100644 --- a/M6502/packages.config +++ b/M6502/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/AbxTests.cs b/MC6809/MC6809.UnitTest/AbxTests.cs new file mode 100644 index 0000000..0d8c26b --- /dev/null +++ b/MC6809/MC6809.UnitTest/AbxTests.cs @@ -0,0 +1,84 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AbxTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AbxTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x3a); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestInherent() + { + this.cpu.B = 0x84; + this.cpu.X.Word = 0x1097; + this.cpu.Step(); + Assert.AreEqual(0x111b, this.cpu.X.Word); + Assert.AreEqual(3, this.cpu.Cycles); + } + + [TestMethod] + public void TestInherentABX1() + { + this.cpu.A = 0; + this.cpu.B = 0xce; + this.cpu.X.Word = 0x8006; + this.cpu.Y.Word = 0; + this.cpu.U.Word = 0; + this.cpu.CC = 0; + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0xce, this.cpu.B); + Assert.AreEqual(0x80d4, this.cpu.X.Word); + Assert.AreEqual(0, this.cpu.Y.Word); + Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(3, this.cpu.Cycles); + } + + [TestMethod] + public void TestInherentABX2() + { + this.cpu.A = 0; + this.cpu.B = 0xd6; + this.cpu.X.Word = 0x7ffe; + this.cpu.Y.Word = 0; + this.cpu.U.Word = 0; + this.cpu.CC = (byte)(StatusBits.CF | StatusBits.VF | StatusBits.ZF); + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0xd6, this.cpu.B); + Assert.AreEqual(0x80d4, this.cpu.X.Word); + Assert.AreEqual(0, this.cpu.Y.Word); + Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(3, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/AdcTests.cs b/MC6809/MC6809.UnitTest/AdcTests.cs new file mode 100644 index 0000000..ca1c461 --- /dev/null +++ b/MC6809/MC6809.UnitTest/AdcTests.cs @@ -0,0 +1,108 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AdcTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AdcTests() => 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 TestImmediate() + { + this.board.Poke(0, 0x89); + this.board.Poke(1, 0x7c); + this.cpu.CC = EightBit.Chip.SetFlag(this.cpu.CC, (byte)StatusBits.CF); + this.cpu.A = 0x3a; + this.cpu.Step(); + Assert.AreEqual(0xb7, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.HalfCarry); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + [TestMethod] + public void TestImmediateADCANoC1() + { + this.cpu.A = 0x5; + this.cpu.CC = 0; + this.board.Poke(0, 0x89); + this.board.Poke(1, 0x02); + this.cpu.Step(); + Assert.AreEqual(7, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + /* Test half-carry $E + $2 = $10 */ + [TestMethod] + public void TestImmediateADCANoC2() + { + this.cpu.A = 0xe; + this.cpu.CC = 0; + this.board.Poke(0, 0x89); + this.board.Poke(1, 0x02); + this.cpu.Step(); + Assert.AreEqual(0x10, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + /* Add $22 and carry to register A ($14) */ + [TestMethod] + public void TestImmediateADCAWiC() + { + this.cpu.A = 0x14; + this.cpu.CC = (byte)(StatusBits.CF | StatusBits.HF); + this.board.Poke(0, 0x89); + this.board.Poke(1, 0x22); + this.cpu.Step(); + Assert.AreEqual(0x37, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + /* Test that half-carry is set when adding with a carry */ + [TestMethod] + public void TestImmediateADCAWiHC() + { + this.cpu.A = 0x14; + this.cpu.CC = (byte)StatusBits.CF; + this.board.Poke(0, 0x89); + this.board.Poke(1, 0x2B); + this.cpu.Step(); + Assert.AreEqual(0x40, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/AddTests.cs b/MC6809/MC6809.UnitTest/AddTests.cs new file mode 100644 index 0000000..029465a --- /dev/null +++ b/MC6809/MC6809.UnitTest/AddTests.cs @@ -0,0 +1,234 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AddTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AddTests() => 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 TestImmediate() + { + this.board.Poke(0, 0x8b); + this.board.Poke(1, 0x8b); + this.cpu.A = 0x24; + this.cpu.Step(); + Assert.AreEqual(0xaf, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Add 0x02 to A=0x04. + [TestMethod] + public void TestImmediateADDANoC() + { + this.board.Poke(0, 0x8b); + this.board.Poke(1, 0x02); + this.cpu.CC = 0; + this.cpu.A = 4; + this.cpu.B = 5; + this.cpu.Step(); + Assert.AreEqual(6, this.cpu.A); + Assert.AreEqual(5, this.cpu.B); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // The overflow (V) bit indicates signed two’s complement overflow, which occurs when the + // sign bit differs from the carry bit after an arithmetic operation. + // A=0x03 + 0xFF becomes 0x02 + [TestMethod] + public void TestImmediateADDAWiC() + { + this.board.Poke(0, 0x8b); + this.board.Poke(1, 0xff); + this.cpu.CC = 0; + this.cpu.A = 3; + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // positive + positive with overflow. + // B=0x40 + 0x41 becomes 0x81 or -127 + [TestMethod] + public void TestImmediateADDB1() + { + this.board.Poke(0, 0xcb); + this.board.Poke(1, 0x41); + this.cpu.B = 0x40; + this.cpu.CC = 0; + this.cpu.Step(); + Assert.AreEqual(0x81, this.cpu.B); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.HalfCarry); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // negative + negative. + // B=0xFF + 0xFF becomes 0xFE or -2 + [TestMethod] + public void TestImmediateADDB2() + { + this.board.Poke(0, 0xcb); + this.board.Poke(1, 0xff); + this.cpu.B = 0xff; + this.cpu.CC = 0; + this.cpu.Step(); + Assert.AreEqual(0xfe, this.cpu.B); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // negative + negative with overflow. + // B=0xC0 + 0xBF becomes 0x7F or 127 + [TestMethod] + public void TestImmediateADDB3() + { + this.board.Poke(0, 0xcb); + this.board.Poke(1, 0xbf); + this.cpu.B = 0xc0; + this.cpu.CC = 0; + this.cpu.Step(); + Assert.AreEqual(0x7f, this.cpu.B); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // positive + negative with negative result. + // B=0x02 + 0xFC becomes 0xFE or -2 + [TestMethod] + public void TestImmediateADDB4() + { + this.board.Poke(0, 0xcb); + this.board.Poke(1, 0xfc); + this.cpu.B = 0x02; + this.cpu.CC = 0; + this.cpu.Step(); + Assert.AreEqual(0xfe, this.cpu.B); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Add 0x02B0 to D=0x0405 becomes 0x6B5. + // positive + positive = positive + [TestMethod] + public void TestImmediateADDDNoC() + { + this.board.Poke(0, 0xc3); + this.board.Poke(1, 0x02); + this.board.Poke(2, 0xb0); + this.cpu.CC = 0; + this.cpu.A = 4; + this.cpu.B = 5; + this.cpu.Step(); + Assert.AreEqual(0x06, this.cpu.A); + Assert.AreEqual(0xb5, this.cpu.B); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // Add 0xE2B0 to D=0x8405 becomes 0x66B5. + // negative + negative = positive + overflow + [TestMethod] + public void TestImmediateADDD1() + { + this.board.Poke(0, 0xc3); + this.board.Poke(1, 0xe2); + this.board.Poke(2, 0xb0); + this.cpu.CC = 0; + this.cpu.A = 0x84; + this.cpu.B = 5; + this.cpu.Step(); + Assert.AreEqual(0x66, this.cpu.A); + Assert.AreEqual(0xb5, this.cpu.B); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // negative + negative = negative. + // Add 0xE000 to D=0xD000 becomes 0xB000 + [TestMethod] + public void TestImmediateADDD2() + { + this.board.Poke(0, 0xc3); + this.board.Poke(1, 0xe0); + this.board.Poke(2, 0); + this.cpu.CC = 0; + this.cpu.A = 0xd0; + this.cpu.B = 0; + this.cpu.Step(); + Assert.AreEqual(0xb0, this.cpu.A); + Assert.AreEqual(0x00, this.cpu.B); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // positive + positive = negative + overflow. + // Add 0x7000 to D=0x7000 becomes 0xE000 + [TestMethod] + public void TestImmediateADDD3() + { + this.board.Poke(0, 0xc3); + this.board.Poke(1, 0x70); + this.board.Poke(2, 0); + this.cpu.CC = 0; + this.cpu.A = 0x70; + this.cpu.B = 0; + this.cpu.Step(); + Assert.AreEqual(0xe0, this.cpu.A); + Assert.AreEqual(0x00, this.cpu.B); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/AndTests.cs b/MC6809/MC6809.UnitTest/AndTests.cs new file mode 100644 index 0000000..51b43ad --- /dev/null +++ b/MC6809/MC6809.UnitTest/AndTests.cs @@ -0,0 +1,41 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AndTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AndTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x84); + this.board.Poke(1, 0x13); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestImmediate() + { + this.cpu.A = 0xfc; + this.cpu.Step(); + Assert.AreEqual(0x10, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/AslTests.cs b/MC6809/MC6809.UnitTest/AslTests.cs new file mode 100644 index 0000000..d39667b --- /dev/null +++ b/MC6809/MC6809.UnitTest/AslTests.cs @@ -0,0 +1,40 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AslTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AslTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x48); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestInherent() + { + this.cpu.A = 0x7a; + this.cpu.Step(); + Assert.AreEqual(0xf4, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/AsrTests.cs b/MC6809/MC6809.UnitTest/AsrTests.cs new file mode 100644 index 0000000..f2eef0d --- /dev/null +++ b/MC6809/MC6809.UnitTest/AsrTests.cs @@ -0,0 +1,40 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class AsrTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public AsrTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x47); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestInherent() + { + this.cpu.A = 0xcb; + this.cpu.Step(); + Assert.AreEqual(0xe5, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/BgtTests.cs b/MC6809/MC6809.UnitTest/BgtTests.cs new file mode 100644 index 0000000..acc595d --- /dev/null +++ b/MC6809/MC6809.UnitTest/BgtTests.cs @@ -0,0 +1,87 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class BgtTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public BgtTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x2e); // BGT + this.board.Poke(1, 0x03); + this.board.Poke(2, 0x86); // LDA #1 + this.board.Poke(3, 0x01); + this.board.Poke(4, 0x12); // NOP + this.board.Poke(5, 0x86); // LDA #2 + this.board.Poke(6, 0x02); + this.board.Poke(7, 0x12); // NOP + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestBGT1() + { + this.cpu.A = 0; + this.cpu.CC = (byte)StatusBits.ZF; + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + + [TestMethod] + public void TestBGT2() + { + Assert.AreEqual(0, this.cpu.PC.Word); + this.cpu.CC = 0; + this.cpu.Step(); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + } + + [TestMethod] + public void TestBGT3() + { + Assert.AreEqual(0, this.cpu.PC.Word); + this.cpu.CC = (byte)StatusBits.NF; + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + + [TestMethod] + public void TestBGT4() + { + Assert.AreEqual(0, this.cpu.PC.Word); + this.cpu.CC = (byte)(StatusBits.NF | StatusBits.VF); + this.cpu.Step(); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + } + + [TestMethod] + public void TestBGT5() + { + Assert.AreEqual(0, this.cpu.PC.Word); + this.cpu.CC = (byte)(StatusBits.ZF | StatusBits.NF); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/BhiTests.cs b/MC6809/MC6809.UnitTest/BhiTests.cs new file mode 100644 index 0000000..e8126df --- /dev/null +++ b/MC6809/MC6809.UnitTest/BhiTests.cs @@ -0,0 +1,45 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class BhiTests + { + private readonly Board board = new Board(); + private MC6809 cpu; + + public BhiTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x22); // BHI + this.board.Poke(1, 0x03); + this.board.Poke(2, 0x86); // LDA #1 + this.board.Poke(3, 0x01); + this.board.Poke(4, 0x12); // NOP + this.board.Poke(5, 0x86); // LDA #2 + this.board.Poke(6, 0x02); + this.board.Poke(7, 0x12); // NOP + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestBHI1() + { + this.cpu.A = 0; + this.cpu.CC = (byte)StatusBits.ZF; + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + } +} diff --git a/MC6809/MC6809.UnitTest/BitTests.cs b/MC6809/MC6809.UnitTest/BitTests.cs new file mode 100644 index 0000000..16998f5 --- /dev/null +++ b/MC6809/MC6809.UnitTest/BitTests.cs @@ -0,0 +1,41 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class BitTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public BitTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x85); + this.board.Poke(1, 0xe0); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestImmediate() + { + this.cpu.A = 0xa6; + this.cpu.CC = (byte)StatusBits.ZF; + this.cpu.Step(); + Assert.AreEqual(0xa6, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/BleTests.cs b/MC6809/MC6809.UnitTest/BleTests.cs new file mode 100644 index 0000000..f028ba0 --- /dev/null +++ b/MC6809/MC6809.UnitTest/BleTests.cs @@ -0,0 +1,86 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class BleTests + { + private readonly Board board = new Board(); + private MC6809 cpu; + + public BleTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x2f); // BLE + this.board.Poke(1, 0x03); + this.board.Poke(2, 0x86); // LDA #1 + this.board.Poke(3, 0x01); + this.board.Poke(4, 0x12); // NOP + this.board.Poke(5, 0x86); // LDA #2 + this.board.Poke(6, 0x02); + this.board.Poke(7, 0x12); // NOP + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestBLE1() + { + Assert.AreEqual(0, this.cpu.PC.Word); + this.cpu.CC = (byte)StatusBits.ZF; + this.cpu.Step(); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + } + + [TestMethod] + public void TestBLE2() + { + this.cpu.A = 0; + this.cpu.CC = 0; + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + + [TestMethod] + public void TestBLE3() + { + this.cpu.CC = (byte)StatusBits.NF; + this.cpu.Step(); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + } + + [TestMethod] + public void TestBLE4() + { + this.cpu.A = 0; + this.cpu.CC = (byte)(StatusBits.NF | StatusBits.VF); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + } + + [TestMethod] + public void TestBGT5() + { + this.cpu.CC = (byte)(StatusBits.ZF | StatusBits.NF); + this.cpu.Step(); + this.cpu.Step(); + this.cpu.Step(); + Assert.AreEqual(2, this.cpu.A); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/Board.cs b/MC6809/MC6809.UnitTest/Board.cs new file mode 100644 index 0000000..6c1cc40 --- /dev/null +++ b/MC6809/MC6809.UnitTest/Board.cs @@ -0,0 +1,42 @@ +namespace EightBit +{ + public sealed class Board : EightBit.Bus + { + private readonly Ram ram = new Ram(0x10000); // 0000 - FFFF, 64K RAM + private readonly MemoryMapping mapping; + + public Board() + { + this.CPU = new MC6809(this); + this.mapping = new MemoryMapping(this.ram, 0x0000, 0xffff, EightBit.AccessLevel.ReadWrite); + } + + public MC6809 CPU { get; } + + public override void Initialize() + { + } + + public override MemoryMapping Mapping(ushort absolute) => this.mapping; + + public override void RaisePOWER() + { + base.RaisePOWER(); + + this.CPU.RaisePOWER(); + + this.CPU.LowerRESET(); + this.CPU.RaiseINT(); + + this.CPU.RaiseNMI(); + this.CPU.RaiseFIRQ(); + this.CPU.RaiseHALT(); + } + + public override void LowerPOWER() + { + this.CPU.LowerPOWER(); + base.LowerPOWER(); + } + } +} diff --git a/MC6809/MC6809.UnitTest/ClrTests.cs b/MC6809/MC6809.UnitTest/ClrTests.cs new file mode 100644 index 0000000..30cb809 --- /dev/null +++ b/MC6809/MC6809.UnitTest/ClrTests.cs @@ -0,0 +1,41 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class ClrTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public ClrTests() + { + this.cpu = this.board.CPU; + + this.board.Poke(0, 0x4f); + } + + [TestInitialize] + public void Initialise() + { + this.board.RaisePOWER(); + this.cpu.Step(); // Step over the reset + } + + [TestCleanup] + public void Cleanup() => this.board.LowerPOWER(); + + [TestMethod] + public void TestImplied() + { + this.cpu.A = 0x43; + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/CmpTests.cs b/MC6809/MC6809.UnitTest/CmpTests.cs new file mode 100644 index 0000000..56398e8 --- /dev/null +++ b/MC6809/MC6809.UnitTest/CmpTests.cs @@ -0,0 +1,126 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class CmpTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public CmpTests() => 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 TestImmediateByte() + { + this.board.Poke(0, 0x81); + this.board.Poke(1, 0x18); + this.cpu.A = 0xf6; + this.cpu.Step(); + Assert.AreEqual(0xf6, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Indirect mode: CMPA ,Y+ (CMP1) + [TestMethod] + public void TestCMP1() + { + this.board.Poke(0, 0xa1); + this.board.Poke(1, 0xa0); + this.board.Poke(0x205, 0xff); + this.cpu.CC = 0; + this.cpu.A = 0xff; + this.cpu.B = 0; + this.cpu.X.Word = 0; + this.cpu.Y.Word = 0x205; + this.cpu.U.Word = 0; + this.cpu.Step(); + Assert.AreEqual(0xff, this.cpu.A); + Assert.AreEqual(0, this.cpu.B); + Assert.AreEqual(0, this.cpu.X.Word); + Assert.AreEqual(0x206, this.cpu.Y.Word); + Assert.AreEqual(0, this.cpu.U.Word); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(6, this.cpu.Cycles); + } + + // B = 0xA0, CMPB with 0xA0 + [TestMethod] + public void TestCMP2() + { + this.board.Poke(0, 0xc1); + this.board.Poke(1, 0xa0); + this.cpu.CC = (byte)StatusBits.NF; + this.cpu.B = 0xa0; + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // B = 0x70, CMPB with 0xA0 + [TestMethod] + public void TestCMP3() + { + this.board.Poke(0, 0xc1); + this.board.Poke(1, 0xa0); + this.cpu.CC = (byte)StatusBits.NF; + this.cpu.B = 0x70; + this.cpu.Step(); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Compare 0x5410 with 0x5410 + [TestMethod] + public void TestCMP16() + { + this.cpu.CC = (byte)(StatusBits.HF | StatusBits.VF | StatusBits.CF); + this.cpu.X.Word = 0x5410; + this.cpu.PokeWord(0x33, 0x5410); + this.board.Poke(0, 0xbc); + this.cpu.PokeWord(1, 0x33); + this.cpu.Step(); + Assert.AreEqual(0x5410, this.cpu.X.Word); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(7, this.cpu.Cycles); + } + + [TestMethod] + public void TestImmediateWord() + { + this.board.Poke(0, 0x8c); + this.cpu.PokeWord(1, 0x1bb0); + this.cpu.X.Word = 0x1ab0; + this.cpu.Step(); + Assert.AreEqual(0x1ab0, this.cpu.X.Word); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/DecTests.cs b/MC6809/MC6809.UnitTest/DecTests.cs new file mode 100644 index 0000000..58c6b3b --- /dev/null +++ b/MC6809/MC6809.UnitTest/DecTests.cs @@ -0,0 +1,70 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class DecTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public DecTests() => 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 TestInherentDECA0x32() + { + this.board.Poke(0, 0x4a); + this.cpu.CC = 0; + this.cpu.A = 0x32; + this.cpu.Step(); + Assert.AreEqual(0x31, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Test 0x80 - special case + [TestMethod] + public void TestInherentDECA0x80() + { + this.board.Poke(0, 0x4a); + this.cpu.CC = 0; + this.cpu.A = 0x80; + this.cpu.Step(); + Assert.AreEqual(0x7f, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Test 0x00 - special case + [TestMethod] + public void TestInherentDECA0x00() + { + this.board.Poke(0, 0x4a); + this.cpu.CC = 0; + this.cpu.A = 0; + this.cpu.Step(); + Assert.AreEqual(0xff, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/IncTests.cs b/MC6809/MC6809.UnitTest/IncTests.cs new file mode 100644 index 0000000..b5e71a4 --- /dev/null +++ b/MC6809/MC6809.UnitTest/IncTests.cs @@ -0,0 +1,68 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class IncTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public IncTests() => 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 TestInherentINCA1() + { + this.board.Poke(0, 0x4c); + this.cpu.CC = 0; + this.cpu.A = 0x32; + this.cpu.Step(); + Assert.AreEqual(0x33, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + + [TestMethod] + public void TestInherentINCA2() + { + this.board.Poke(0, 0x4c); + this.cpu.CC = 0; + this.cpu.A = 0x7f; + this.cpu.Step(); + Assert.AreEqual(0x80, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + [TestMethod] + public void TestInherentINCA3() + { + this.board.Poke(0, 0x4c); + this.cpu.CC = 0; + this.cpu.A = 0xff; + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + } +} diff --git a/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj b/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj new file mode 100644 index 0000000..3badefd --- /dev/null +++ b/MC6809/MC6809.UnitTest/MC6809.UnitTest.csproj @@ -0,0 +1,96 @@ + + + + + + Debug + AnyCPU + {4391A363-ECEF-44C8-9335-BF6ECB811E4B} + Library + Properties + MC6809.UnitTest + MC6809.UnitTest + v4.7.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + latest + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + latest + + + + ..\..\packages\MSTest.TestFramework.2.0.0-beta4\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\..\packages\MSTest.TestFramework.2.0.0-beta4\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + {6ebf8857-62a3-4ef4-af21-c1844031d7e4} + EightBit + + + {3a63972b-ab50-4a01-8a10-0d2165580fad} + MC6809 + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/Properties/AssemblyInfo.cs b/MC6809/MC6809.UnitTest/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2affe5e --- /dev/null +++ b/MC6809/MC6809.UnitTest/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("MC6809.UnitTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MC6809.UnitTest")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("4391a363-ecef-44c8-9335-bf6ecb811e4b")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/MC6809/MC6809.UnitTest/SbcTests.cs b/MC6809/MC6809.UnitTest/SbcTests.cs new file mode 100644 index 0000000..9334a0f --- /dev/null +++ b/MC6809/MC6809.UnitTest/SbcTests.cs @@ -0,0 +1,113 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class SbcTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public SbcTests() => 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 TestImmediateByte() + { + this.board.Poke(0, 0x82); + this.board.Poke(1, 0x34); + this.cpu.CC = (byte)StatusBits.CF; + this.cpu.A = 0x14; + this.cpu.Step(); + Assert.AreEqual(0xdf, this.cpu.A); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // Test the subtraction with carry instruction. + // B=0x35 - addr(0x503)=0x3 - C=1 becomes 0x31 + // SBCB dp+03 + [TestMethod] + public void TestDirectSBCB() + { + this.board.Poke(0, 0xd2); + this.board.Poke(1, 0x03); + this.board.Poke(0x503, 0x03); + this.cpu.CC = (byte)StatusBits.CF; + this.cpu.DP = 5; + this.cpu.B = 0x35; + this.cpu.Step(); + Assert.AreEqual(0x31, this.cpu.B); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // Test the SBCA instruction. + // A=0xFF - 0xFE - C=1 becomes 0x00 + [TestMethod] + public void TestImmediateSBCASBCA1() + { + this.board.Poke(0, 0x82); + this.board.Poke(1, 0xfe); + this.cpu.CC = (byte)(StatusBits.CF | StatusBits.NF); + this.cpu.A = 0xff; + this.cpu.Step(); + Assert.AreEqual(0, this.cpu.A); + Assert.AreEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // Test the SBCA instruction. + // A=0x00 - 0xFF - C=0 becomes 0x01 + [TestMethod] + public void TestImmediateSBCASBCA2() + { + this.board.Poke(0, 0x82); + this.board.Poke(1, 0xff); + this.cpu.CC = (byte)(StatusBits.NF | StatusBits.VF); + this.cpu.A = 0; + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(4, this.cpu.Cycles); + } + + // Test the SBCA instruction. + // A=0x00 - 0x01 - C=0 becomes 0xFF + [TestMethod] + public void TestImmediateSBCASBCA3() + { + this.board.Poke(0, 0x82); + this.board.Poke(1, 1); + this.cpu.CC = (byte)(StatusBits.NF | StatusBits.VF); + this.cpu.A = 0; + this.cpu.Step(); + Assert.AreEqual(0xff, this.cpu.A); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(4, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/SubTests.cs b/MC6809/MC6809.UnitTest/SubTests.cs new file mode 100644 index 0000000..8f87b38 --- /dev/null +++ b/MC6809/MC6809.UnitTest/SubTests.cs @@ -0,0 +1,126 @@ +namespace EightBit +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class SubTests + { + private readonly Board board = new Board(); + private readonly MC6809 cpu; + + public SubTests() => 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(); + + // Test the SUBA instruction. + // The overflow (V) bit indicates signed two’s complement overflow, which + // occurs when the sign bit differs from the carry bit after an arithmetic + // operation. + // A=0x00 - 0xFF becomes 0x01 + // positive - negative = positive + [TestMethod] + public void TestImmediateSUBASUBA1() + { + this.board.Poke(0, 0x80); + this.board.Poke(1, 0xff); + this.cpu.CC = (byte)(StatusBits.CF | StatusBits.NF); + this.cpu.A = 0; + this.cpu.Step(); + Assert.AreEqual(1, this.cpu.A); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Test the SUBA instruction. + // The overflow (V) bit indicates signed two’s complement overflow, which + // occurs when the sign bit differs from the carry bit after an arithmetic + // operation. + // A=0x00 - 0xFF becomes 0x01 + // positive - negative = positive + [TestMethod] + public void TestImmediateSUBASUBA2() + { + this.board.Poke(0, 0x80); + this.board.Poke(1, 1); + this.cpu.CC = (byte)(StatusBits.CF | StatusBits.NF); + this.cpu.A = 0; + 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); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Test the subtraction instruction. + // IMMEDIATE mode: B=0x02 - 0xB3 becomes 0x4F + // positive - negative = positive + [TestMethod] + public void TestImmediateSUBBSUBB1() + { + this.board.Poke(0, 0xc0); + this.board.Poke(1, 0xb3); + this.cpu.CC = 0; + this.cpu.B = 2; + this.cpu.Step(); + Assert.AreEqual(0x4f, this.cpu.B); + Assert.AreEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Test the subtraction instruction. + // IMMEDIATE mode: B=0x02 - 0x81 becomes 0x81 + // positive - negative = negative + overflow + [TestMethod] + public void TestImmediateSUBBSUBB2() + { + this.board.Poke(0, 0xc0); + this.board.Poke(1, 0x81); + this.cpu.CC = 0; + this.cpu.B = 2; + this.cpu.Step(); + Assert.AreEqual(0x81, this.cpu.B); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreNotEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(2, this.cpu.Cycles); + } + + // Example from Programming the 6809. + // 0x03 - 0x21 = 0xE2 + // positive - positive = negative + [TestMethod] + public void TestImmediateSUBBSUBBY() + { + this.board.Poke(0, 0xe0); + this.board.Poke(1, 0xa4); + this.board.Poke(0x21, 0x21); + this.cpu.CC = (byte)StatusBits.ZF; + this.cpu.B = 3; + this.cpu.Y.Word = 0x21; + this.cpu.Step(); + Assert.AreEqual(0xe2, this.cpu.B); + Assert.AreNotEqual(0, this.cpu.Negative); + Assert.AreEqual(0, this.cpu.Zero); + Assert.AreEqual(0, this.cpu.Overflow); + Assert.AreNotEqual(0, this.cpu.Carry); + Assert.AreEqual(4, this.cpu.Cycles); + } + } +} \ No newline at end of file diff --git a/MC6809/MC6809.UnitTest/packages.config b/MC6809/MC6809.UnitTest/packages.config new file mode 100644 index 0000000..ebe8154 --- /dev/null +++ b/MC6809/MC6809.UnitTest/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index 2eadba8..a3526c7 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -27,12 +27,6 @@ private const byte SWI3vector = 0xf2; // SWI3 vector private const byte RESERVEDvector = 0xf0; // RESERVED vector - private readonly Register16 d = new Register16(); - private readonly Register16 x = new Register16(); - private readonly Register16 y = new Register16(); - private readonly Register16 u = new Register16(); - private readonly Register16 s = new Register16(); - private byte cc = 0; private byte dp = 0; @@ -94,19 +88,19 @@ public event EventHandler LoweredBS; - public Register16 D => this.d; + public Register16 D { get; } = new Register16(); public ref byte A => ref this.D.High; public ref byte B => ref this.D.Low; - public Register16 X => this.x; + public Register16 X { get; } = new Register16(); - public Register16 Y => this.y; + public Register16 Y { get; } = new Register16(); - public Register16 U => this.u; + public Register16 U { get; } = new Register16(); - public Register16 S => this.s; + public Register16 S { get; } = new Register16(); public ref byte DP => ref this.dp; @@ -114,27 +108,27 @@ public bool Halted => this.HALT().Lowered(); - private int EntireRegisterSet => this.CC & (byte)StatusBits.EF; + public int EntireRegisterSet => this.CC & (byte)StatusBits.EF; - private int FastInterruptMasked => this.CC & (byte)StatusBits.FF; + public int FastInterruptMasked => this.CC & (byte)StatusBits.FF; - private int HalfCarry => this.CC & (byte)StatusBits.HF; + public int HalfCarry => this.CC & (byte)StatusBits.HF; - private int InterruptMasked => this.CC & (byte)StatusBits.IF; + public int InterruptMasked => this.CC & (byte)StatusBits.IF; - private int Negative => this.CC & (byte)StatusBits.NF; + public int Negative => this.CC & (byte)StatusBits.NF; - private int Zero => this.CC & (byte)StatusBits.ZF; + public int Zero => this.CC & (byte)StatusBits.ZF; - private int Overflow => this.CC & (byte)StatusBits.VF; + public int Overflow => this.CC & (byte)StatusBits.VF; - private int Carry => this.CC & (byte)StatusBits.CF; + public int Carry => this.CC & (byte)StatusBits.CF; private bool LS => (this.Carry != 0) || (this.Zero != 0); // (C OR Z) private bool HI => !this.LS; // !(C OR Z) - private bool LT => ((this.Negative >> 3) ^ (this.Overflow >> 3)) != 0; // (N XOR V) + private bool LT => ((this.Negative >> 3) ^ (this.Overflow >> 1)) != 0; // (N XOR V) private bool GE => !this.LT; // !(N XOR V) @@ -331,7 +325,6 @@ protected override void Push(byte value) => this.PushS(value); - private void HandleHALT() { this.RaiseBA(); @@ -420,7 +413,7 @@ private void PushS(byte value) => this.Push(this.S, value); - private void PushU(byte value) => this.Push(this.U, value); + //private void PushU(byte value) => this.Push(this.U, value); private void PushWord(Register16 stack, Register16 value) { @@ -428,15 +421,15 @@ this.Push(stack, value.High); } - private void PushWordS(Register16 value) => this.PushWord(this.S, value); + //private void PushWordS(Register16 value) => this.PushWord(this.S, value); - private void PushWordU(Register16 value) => this.PushWord(this.U, value); + //private void PushWordU(Register16 value) => this.PushWord(this.U, value); private byte Pop(Register16 stack) => this.BusRead(stack++); private byte PopS() => this.Pop(this.S); - private byte PopU() => this.Pop(this.U); + //private byte PopU() => this.Pop(this.U); private Register16 PopWord(Register16 stack) { @@ -445,9 +438,9 @@ return new Register16(low, high); } - private Register16 PopWordS() => this.PopWord(this.S); + //private Register16 PopWordS() => this.PopWord(this.S); - private Register16 PopWordU() => this.PopWord(this.U); + //private Register16 PopWordU() => this.PopWord(this.U); private Register16 RR(int which) { @@ -485,7 +478,7 @@ { case 0b0000: // ,R+ this.Tick(2); - address.Word = r++.Word; + address.Word = r.Word++; break; case 0b0001: // ,R++ this.Tick(3); @@ -572,129 +565,129 @@ private Register16 AM_extended_word() => this.GetWord(this.Address_extended()); - private void AdjustZero(byte datum) => ClearFlag(this.CC, StatusBits.ZF, datum); + private byte AdjustZero(byte datum) => ClearFlag(this.CC, StatusBits.ZF, datum); - private void AdjustZero(ushort datum) => ClearFlag(this.CC, StatusBits.ZF, datum); + private byte AdjustZero(ushort datum) => ClearFlag(this.CC, StatusBits.ZF, datum); - private void AdjustZero(Register16 datum) => this.AdjustZero(datum.Word); + private byte AdjustZero(Register16 datum) => this.AdjustZero(datum.Word); - private void AdjustNegative(byte datum) => SetFlag(this.CC, StatusBits.NF, datum & (byte)Bits.Bit7); + private byte AdjustNegative(byte datum) => SetFlag(this.CC, StatusBits.NF, datum & (byte)Bits.Bit7); - private void AdjustNegative(ushort datum) => SetFlag(this.CC, StatusBits.NF, datum & (ushort)Bits.Bit15); + private byte AdjustNegative(ushort datum) => SetFlag(this.CC, StatusBits.NF, datum & (ushort)Bits.Bit15); - private void AdjustNegative(Register16 datum) => this.AdjustNegative(datum.Word); + //private void AdjustNegative(Register16 datum) => this.AdjustNegative(datum.Word); - private void AdjustNZ(byte datum) + private byte AdjustNZ(byte datum) { - this.AdjustZero(datum); - this.AdjustNegative(datum); + this.CC = this.AdjustZero(datum); + return this.AdjustNegative(datum); } - private void AdjustNZ(ushort datum) + private byte AdjustNZ(ushort datum) { - this.AdjustZero(datum); - this.AdjustNegative(datum); + this.CC = this.AdjustZero(datum); + return this.AdjustNegative(datum); } - private void AdjustNZ(Register16 datum) => this.AdjustNZ(datum.Word); + private byte AdjustNZ(Register16 datum) => this.AdjustNZ(datum.Word); - private void AdjustCarry(ushort datum) => SetFlag(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit addition + private byte AdjustCarry(ushort datum) => SetFlag(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit addition - private void AdjustCarry(uint datum) => SetFlag(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit addition + private byte AdjustCarry(uint datum) => SetFlag(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit addition - private void AdjustCarry(Register16 datum) => this.AdjustCarry(datum.Word); + private byte AdjustCarry(Register16 datum) => this.AdjustCarry(datum.Word); - private void AdjustBorrow(ushort datum) => ClearFlag(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit subtraction + //private void AdjustBorrow(ushort datum) => ClearFlag(this.CC, StatusBits.CF, datum & (ushort)Bits.Bit8); // 8-bit subtraction - private void AdjustBorrow(uint datum) => ClearFlag(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit subtraction + //private void AdjustBorrow(uint datum) => ClearFlag(this.CC, StatusBits.CF, (int)(datum & (uint)Bits.Bit16)); // 16-bit subtraction - private void AdjustBorrow(Register16 datum) => this.AdjustBorrow(datum.Word); + //private void AdjustBorrow(Register16 datum) => this.AdjustBorrow(datum.Word); - private void AdjustOverflow(byte before, byte data, Register16 after) + private byte AdjustOverflow(byte before, byte data, Register16 after) { var lowAfter = after.Low; var highAfter = after.High; - SetFlag(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & (int)Bits.Bit7); + return SetFlag(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & (int)Bits.Bit7); } - private void AdjustOverflow(ushort before, ushort data, uint after) + private byte AdjustOverflow(ushort before, ushort data, uint after) { var lowAfter = (ushort)(after & (uint)Mask.Mask16); var highAfter = (ushort)(after >> 16); - SetFlag(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & (int)Bits.Bit15); + return SetFlag(this.CC, StatusBits.VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & (int)Bits.Bit15); } - private void AdjustOverflow(Register16 before, Register16 data, Register16 after) => this.AdjustOverflow(before.Word, data.Word, after.Word); + //private void AdjustOverflow(Register16 before, Register16 data, Register16 after) => this.AdjustOverflow(before.Word, data.Word, after.Word); - private void AdjustHalfCarry(byte before, byte data, byte after) => SetFlag(this.CC, StatusBits.HF, (before ^ data ^ after) & (int)Bits.Bit4); + private byte AdjustHalfCarry(byte before, byte data, byte after) => SetFlag(this.CC, StatusBits.HF, (before ^ data ^ after) & (int)Bits.Bit4); - private void AdjustAddition(byte before, byte data, Register16 after) + private byte AdjustAddition(byte before, byte data, Register16 after) { var result = after.Low; - this.AdjustNZ(result); - this.AdjustCarry(after); - this.AdjustOverflow(before, data, after); - this.AdjustHalfCarry(before, data, result); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustCarry(after); + this.CC = this.AdjustOverflow(before, data, after); + return this.AdjustHalfCarry(before, data, result); } - private void AdjustAddition(ushort before, ushort data, uint after) + private byte AdjustAddition(ushort before, ushort data, uint after) { var result = new Register16(after & (uint)Mask.Mask16); - this.AdjustNZ(result); - this.AdjustCarry(after); - this.AdjustOverflow(before, data, after); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustCarry(after); + return this.AdjustOverflow(before, data, after); } - private void AdjustAddition(Register16 before, Register16 data, uint after) => this.AdjustAddition(before.Word, data.Word, after); + private byte AdjustAddition(Register16 before, Register16 data, uint after) => this.AdjustAddition(before.Word, data.Word, after); - private void AdjustSubtraction(byte before, byte data, Register16 after) + private byte AdjustSubtraction(byte before, byte data, Register16 after) { var result = after.Low; - this.AdjustNZ(result); - this.AdjustCarry(after); - this.AdjustOverflow(before, data, after); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustCarry(after); + return this.AdjustOverflow(before, data, after); } - private void AdjustSubtraction(ushort before, ushort data, uint after) + private byte AdjustSubtraction(ushort before, ushort data, uint after) { var result = new Register16(after & (uint)Mask.Mask16); - this.AdjustNZ(result); - this.AdjustCarry(after); - this.AdjustOverflow(before, data, after); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustCarry(after); + return this.AdjustOverflow(before, data, after); } - private void AdjustSubtraction(Register16 before, Register16 data, uint after) => this.AdjustSubtraction(before.Word, data.Word, after); + private byte AdjustSubtraction(Register16 before, Register16 data, uint after) => this.AdjustSubtraction(before.Word, data.Word, after); private byte Through(byte data) { - ClearFlag(this.CC, StatusBits.VF); - this.AdjustNZ(data); + this.CC = ClearFlag(this.CC, StatusBits.VF); + this.CC = this.AdjustNZ(data); return data; } - private ushort Through(ushort data) - { - ClearFlag(this.CC, StatusBits.VF); - this.AdjustNZ(data); - return data; - } + //private ushort Through(ushort data) + //{ + // ClearFlag(this.CC, StatusBits.VF); + // this.AdjustNZ(data); + // return data; + //} private Register16 Through(Register16 data) { - ClearFlag(this.CC, StatusBits.VF); - this.AdjustNZ(data); + this.CC = ClearFlag(this.CC, StatusBits.VF); + this.CC = this.AdjustNZ(data); return data; } private byte LD(byte data) => this.Through(data); - private ushort LD(ushort data) => this.Through(data); + //private ushort LD(ushort data) => this.Through(data); private Register16 LD(Register16 data) => this.Through(data); private byte ST(byte data) => this.Through(data); - private ushort ST(ushort data) => this.Through(data); + //private ushort ST(ushort data) => this.Through(data); private Register16 ST(Register16 data) => this.Through(data); @@ -712,9 +705,9 @@ private bool Branch(Register16 destination, bool condition) => this.Branch(destination.Word, condition); - private void Branch(ushort destination, int condition) => this.Branch(destination, condition != 0); + //private void Branch(ushort destination, int condition) => this.Branch(destination, condition != 0); - private void Branch(Register16 destination, int condition) => this.Branch(destination.Word, condition); + //private void Branch(Register16 destination, int condition) => this.Branch(destination.Word, condition); private void BranchShort(bool condition) => this.Branch(this.Address_relative_byte(), condition); @@ -728,13 +721,13 @@ private void SaveEntireRegisterState() { - SetFlag(this.CC, StatusBits.EF); + this.CC = SetFlag(this.CC, StatusBits.EF); this.SaveRegisterState(); } private void SavePartialRegisterState() { - ClearFlag(this.CC, StatusBits.EF); + this.CC = ClearFlag(this.CC, StatusBits.EF); this.SaveRegisterState(); } @@ -968,8 +961,8 @@ case 0xbe: this.Tick(6); this.X.Word = this.LD(this.AM_extended_word()).Word; break; // LD (LDX extended) // LEA - case 0x30: this.Tick(4); this.AdjustZero(this.X.Word = this.Address_indexed().Word); break; // LEA (LEAX indexed) - case 0x31: this.Tick(4); this.AdjustZero(this.Y.Word = this.Address_indexed().Word); break; // LEA (LEAY indexed) + case 0x30: this.Tick(4); this.CC = this.AdjustZero(this.X.Word = this.Address_indexed().Word); break; // LEA (LEAX indexed) + case 0x31: this.Tick(4); this.CC = this.AdjustZero(this.Y.Word = this.Address_indexed().Word); break; // LEA (LEAY indexed) case 0x32: this.Tick(4); this.S.Word = this.Address_indexed().Word; break; // LEA (LEAS indexed) case 0x33: this.Tick(4); this.U.Word = this.Address_indexed().Word; break; // LEA (LEAU indexed) @@ -1247,14 +1240,14 @@ private byte ADD(byte operand, byte data, byte carry = 0) { var addition = new Register16(operand + data + carry); - this.AdjustAddition(operand, data, addition); + this.CC = this.AdjustAddition(operand, data, addition); return addition.Low; } private Register16 ADD(Register16 operand, Register16 data) { var addition = (uint)(operand.Word + data.Word); - this.AdjustAddition(operand, data, addition); + this.CC = this.AdjustAddition(operand, data, addition); return new Register16(addition & (uint)Mask.Mask16); } @@ -1262,18 +1255,18 @@ private byte ASL(byte operand) { - SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); - this.AdjustNZ(operand <<= 1); + this.CC = SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); + this.CC = this.AdjustNZ(operand <<= 1); var overflow = this.Carry ^ (this.Negative >> 3); - SetFlag(this.CC, StatusBits.VF, overflow); + this.CC = SetFlag(this.CC, StatusBits.VF, overflow); return operand; } private byte ASR(byte operand) { - SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); + this.CC = SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); var result = (byte)((operand >> 1) | (int)Bits.Bit7); - this.AdjustNZ(result); + this.CC = this.AdjustNZ(result); return result; } @@ -1281,7 +1274,7 @@ private byte CLR() { - ClearFlag(this.CC, StatusBits.CF); + this.CC = ClearFlag(this.CC, StatusBits.CF); return this.Through((byte)0U); } @@ -1291,7 +1284,7 @@ private byte COM(byte operand) { - SetFlag(this.CC, StatusBits.CF); + this.CC = SetFlag(this.CC, StatusBits.CF); return this.Through((byte)~operand); } @@ -1304,7 +1297,7 @@ private byte DA(byte operand) { - SetFlag(this.CC, StatusBits.CF, operand > 0x99); + this.CC = SetFlag(this.CC, StatusBits.CF, operand > 0x99); var lowAdjust = (this.HalfCarry != 0) || (Chip.LowNibble(operand) > 9); var highAdjust = (this.Carry != 0) || (operand > 0x99); @@ -1326,8 +1319,8 @@ { var subtraction = new Register16(operand - 1); var result = subtraction.Low; - this.AdjustNZ(result); - this.AdjustOverflow(operand, 1, subtraction); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustOverflow(operand, 1, subtraction); return result; } @@ -1357,9 +1350,9 @@ { var addition = new Register16(operand + 1); var result = addition.Low; - this.AdjustNZ(result); - this.AdjustOverflow(operand, 1, addition); - this.AdjustHalfCarry(operand, 1, result); + this.CC = this.AdjustNZ(result); + this.CC = this.AdjustOverflow(operand, 1, addition); + this.CC = this.AdjustHalfCarry(operand, 1, result); return result; } @@ -1369,26 +1362,26 @@ private byte LSR(byte operand) { - SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); - this.AdjustNZ(operand >>= 1); + this.CC = SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); + this.CC = this.AdjustNZ(operand >>= 1); return operand; } private Register16 MUL(byte first, byte second) { var result = new Register16(first * second); - this.AdjustZero(result); - SetFlag(this.CC, StatusBits.CF, result.Low & (byte)Bits.Bit7); + this.CC = this.AdjustZero(result); + this.CC = SetFlag(this.CC, StatusBits.CF, result.Low & (byte)Bits.Bit7); return result; } private byte NEG(byte operand) { - SetFlag(this.CC, StatusBits.VF, operand == (byte)Bits.Bit7); + this.CC = SetFlag(this.CC, StatusBits.VF, operand == (byte)Bits.Bit7); var result = new Register16(0 - operand); operand = result.Low; - this.AdjustNZ(operand); - this.AdjustCarry(result); + this.CC = this.AdjustNZ(operand); + this.CC = this.AdjustCarry(result); return operand; } @@ -1501,19 +1494,19 @@ private byte ROL(byte operand) { var carryIn = this.Carry; - SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); - SetFlag(this.CC, StatusBits.VF, ((operand & (byte)Bits.Bit7) >> 7) ^ ((operand & (byte)Bits.Bit6) >> 6)); + this.CC = SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit7); + this.CC = SetFlag(this.CC, StatusBits.VF, ((operand & (byte)Bits.Bit7) >> 7) ^ ((operand & (byte)Bits.Bit6) >> 6)); var result = (byte)((operand << 1) | carryIn); - this.AdjustNZ(result); + this.CC = this.AdjustNZ(result); return result; } private byte ROR(byte operand) { var carryIn = this.Carry; - SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); + this.CC = SetFlag(this.CC, StatusBits.CF, operand & (byte)Bits.Bit0); var result = (byte)((operand >> 1) | (carryIn << 7)); - this.AdjustNZ(result); + this.CC = this.AdjustNZ(result); return result; } @@ -1526,28 +1519,28 @@ private byte SUB(byte operand, byte data, byte carry = 0) { var subtraction = new Register16(operand - data - carry); - this.AdjustSubtraction(operand, data, subtraction); + this.CC = this.AdjustSubtraction(operand, data, subtraction); return subtraction.Low; } private Register16 SUB(Register16 operand, Register16 data) { var subtraction = (uint)(operand.Word - data.Word); - this.AdjustSubtraction(operand, data, subtraction); + this.CC = this.AdjustSubtraction(operand, data, subtraction); return new Register16(subtraction & (uint)Mask.Mask16); } private byte SEX(byte from) { - this.AdjustNZ(from); + this.CC = this.AdjustNZ(from); return (from & (byte)Bits.Bit7) != 0 ? (byte)Mask.Mask8 : (byte)0; } private void SWI() { this.SaveEntireRegisterState(); - SetFlag(this.CC, StatusBits.IF); // Disable IRQ - SetFlag(this.CC, StatusBits.FF); // Disable FIRQ + this.CC = SetFlag(this.CC, StatusBits.IF); // Disable IRQ + this.CC = SetFlag(this.CC, StatusBits.FF); // Disable FIRQ this.Jump(this.GetWordPaged(0xff, SWIvector)); } diff --git a/MC6809/MC6809.csproj b/MC6809/MC6809.csproj index 9a58b11..97b9469 100644 --- a/MC6809/MC6809.csproj +++ b/MC6809/MC6809.csproj @@ -21,6 +21,7 @@ DEBUG;TRACE prompt 4 + latest pdbonly @@ -30,16 +31,12 @@ prompt 4 latest + AllRules.ruleset - - - - - diff --git a/MC6809/packages.config b/MC6809/packages.config index c7973f9..2c95c37 100644 --- a/MC6809/packages.config +++ b/MC6809/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/Z80/Z80.Test/Z80.Test.csproj b/Z80/Z80.Test/Z80.Test.csproj index 91f6443..b0fc41a 100644 --- a/Z80/Z80.Test/Z80.Test.csproj +++ b/Z80/Z80.Test/Z80.Test.csproj @@ -69,8 +69,8 @@ - - + + \ No newline at end of file diff --git a/Z80/Z80.Test/packages.config b/Z80/Z80.Test/packages.config index 01177e8..68fc00e 100644 --- a/Z80/Z80.Test/packages.config +++ b/Z80/Z80.Test/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Z80/Z80.csproj b/Z80/Z80.csproj index 23bc635..5eca390 100644 --- a/Z80/Z80.csproj +++ b/Z80/Z80.csproj @@ -59,8 +59,8 @@ - - + + - + \ No newline at end of file diff --git a/Z80/packages.config b/Z80/packages.config index 01177e8..68fc00e 100644 --- a/Z80/packages.config +++ b/Z80/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file