예제 #1
0
        private static void Transfer(OpCode op, bool decrement, bool isOutput)
        {
            using (var fixture = new ExecuteFixture())
            {
                fixture.Operation.OpCode(op);

                if (isOutput)
                {
                    fixture.With(c => c.Mmu.Setup(x => x.ReadByte(c.Registers.HL)).Returns(c.Byte).Verifiable());
                    fixture.Assert(c => c.Io.Verify(x => x.WriteByteToPort(c.Registers.C, c.InitialRegisters.B, c.Byte)));
                }
                else
                {
                    fixture.With(c => c.Io.Setup(x => x.ReadByteFromPort(c.Registers.C, c.InitialRegisters.B)).Returns(c.Byte).Verifiable());
                    fixture.Assert(c => c.Mmu.Verify(x => x.WriteByte(c.InitialRegisters.HL, c.Byte)));
                }


                fixture.Assert(c => c.Registers.B.ShouldBe(unchecked ((byte)(c.InitialRegisters.B - 1))));
                fixture.AssertFlags(c => c.Registers.B, subtract: true, setResult: true);

                if (decrement)
                {
                    fixture.Assert(c => c.Registers.HL.ShouldBe(unchecked ((ushort)(c.InitialRegister16(Operand.HL) - 1))));
                }
                else
                {
                    fixture.Assert(c => c.Registers.HL.ShouldBe(unchecked ((ushort)(c.InitialRegister16(Operand.HL) + 1))));
                }
            }
        }
예제 #2
0
        public void TransferRepeat(OpCode op, bool decrement)
        {
            var repeats = Rng.Word(2, 10);

            using (var fixture = new ExecuteFixture())
            {
                fixture.Operation.OpCode(op);
                fixture.RuntimeTiming((repeats - 1) * 5, (repeats - 1) * 21);
                const ushort HL = 100, DE = 1000; // Avoiding overflows.
                fixture.With(c => c.Registers.BC = repeats, c => c.Registers.HL = HL, c => c.Registers.DE = DE);

                if (decrement)
                {
                    fixture.Assert(c => c.Mmu.Verify(x => x.TransferByte(It.Is <ushort>(b => b > HL - repeats && b <= HL),
                                                                         It.Is <ushort>(b => b > DE - repeats && b <= DE)), Times.Exactly(repeats)));
                    fixture.Assert(c => c.Registers.HL.ShouldBe((ushort)(HL - repeats)),
                                   c => c.Registers.DE.ShouldBe((ushort)(DE - repeats)));
                }
                else
                {
                    fixture.Assert(c => c.Mmu.Verify(x => x.TransferByte(It.Is <ushort>(b => b >= HL && b < HL + repeats),
                                                                         It.Is <ushort>(b => b >= DE && b < DE + repeats)), Times.Exactly(repeats)));
                    fixture.Assert(c => c.Registers.HL.ShouldBe((ushort)(HL + repeats)),
                                   c => c.Registers.DE.ShouldBe((ushort)(DE + repeats)));
                }

                fixture.Assert(c => c.Registers.BC.ShouldBe((ushort)0));
            }
        }
예제 #3
0
 private static void TestHalt(OpCode op)
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         fixture.Operation.OpCode(op);
     }
 }
예제 #4
0
 public void JumpRelative()
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         SetupRelativeJump(fixture, OpCode.JumpRelative, FlagTest.None);
     }
 }
예제 #5
0
        private static void SetupJump(ExecuteFixture fixture, OpCode op, FlagTest test, bool success = true)
        {
            fixture.Operation.OpCode(op).Operands(Operand.nn).RandomLiterals().FlagTest(test);
            var times = success ? Times.Exactly(1) : Times.Never();

            fixture.Assert(c => c.MockRegisters.VerifySet(r => r.ProgramCounter = c.Operation.WordLiteral, times));
        }
예제 #6
0
        private static void SetupRelativeJump(ExecuteFixture fixture, OpCode op, FlagTest test, bool success = true)
        {
            fixture.Operation.OpCode(op).RandomLiterals().FlagTest(test);
            var times = success ? Times.Exactly(1) : Times.Never();

            fixture.Assert(c => c.MockRegisters.VerifySet(r => r.ProgramCounter = unchecked ((ushort)(c.InitialProgramCounter + c.BlockLength + c.Operation.Displacement)), times));
        }
예제 #7
0
 private static void TestCall(OpCode op)
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         SetupCall(fixture, op, FlagTest.None);
     }
 }
예제 #8
0
        private static void TestRepeat(OpCode op, bool decrement)
        {
            using (var fixture = new ExecuteFixture())
            {
                const ushort HL      = 100; // Change HL so we don't need to worry about overflow.
                var          repeats = Rng.Word(2, 10);
                fixture.Operation.OpCode(op);
                fixture.With(c => c.Registers.BC = repeats, c => c.Registers.HL = HL);
                fixture.RuntimeTiming((repeats - 1) * 5, (repeats - 1) * 21);

                if (decrement)
                {
                    fixture.With(c => c.Mmu.Setup(x => x.ReadByte(It.Is <ushort>(a => a <= HL && a > HL - repeats))).Returns <ushort>(a => (byte)(HL - a)));
                    fixture.Assert(c => c.Mmu.Verify(x => x.ReadByte(It.Is <ushort>(a => a <= HL && a > HL - repeats)), Times.Exactly(repeats)));
                }
                else
                {
                    fixture.With(c => c.Mmu.Setup(x => x.ReadByte(It.Is <ushort>(a => a >= HL && a < HL + repeats))).Returns <ushort>(a => (byte)(a - HL)));
                    fixture.Assert(c => c.Mmu.Verify(x => x.ReadByte(It.Is <ushort>(a => a >= HL && a < HL + repeats)), Times.Exactly(repeats)));
                }

                fixture.Assert(c => c.Alu.Verify(x => x.Compare(c.Accumulator.A, It.Is <byte>(b => b < repeats))));
                fixture.Assert(c => c.Registers.BC.ShouldBe((ushort)0));
            }
        }
예제 #9
0
 public void CallWithTest_Success(FlagTest test)
 {
     using (var fixture = new ExecuteFixture().DoNotHalt().RuntimeTiming(2, 7))
     {
         fixture.With(c => c.Flags.Setup(GetFlagExpression(test)).Returns(GetPositiveValue(test)));
         SetupCall(fixture, OpCode.Call, test);
     }
 }
예제 #10
0
        private static void SetupCall(ExecuteFixture fixture, OpCode op, FlagTest test, bool success = true)
        {
            SetupJump(fixture, op, test, success);
            var times = success ? Times.Exactly(1) : Times.Never();

            fixture.Assert(c => c.MockRegisters.VerifySet(r => r.StackPointer = c.PushedStackPointer, times),
                           c => c.Mmu.Verify(x => x.WriteWord(c.StackPointer, c.SyncedProgramCounter), times));
        }
예제 #11
0
 public void ReturnFromInterrupt()
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         SetupReturn(fixture, OpCode.ReturnFromInterrupt, FlagTest.None);
         fixture.Assert(c => c.MockRegisters.VerifySet(x => x.InterruptFlipFlop1 = true));
     }
 }
예제 #12
0
 public void JumpWithTest_Fail(FlagTest test)
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         fixture.With(c => c.Flags.Setup(GetFlagExpression(test)).Returns(!GetPositiveValue(test)));
         SetupJump(fixture, OpCode.Jump, test, false);
     }
 }
예제 #13
0
 public void BitTest(Operand o, byte bit)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.BitTest).Operands(o).ByteLiteral(bit);
         fixture.With(c => c.Alu.Setup(x => x.BitTest(c.Operand8(o), bit)).Verifiable());
     }
 }
예제 #14
0
 private static void SetInterruptMode(OpCode op, InterruptMode mode)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(op);
         fixture.Assert(c => c.MockRegisters.VerifySet(x => x.InterruptMode = mode));
     }
 }
예제 #15
0
 public void Decrement16()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.Decrement16).Random16BitRegister(out var o);
         fixture.Assert(c => c.Operand16(o).ShouldBe(unchecked ((ushort)(c.InitialRegister16(o) - 1))));
     }
 }
예제 #16
0
 private static void ManageInterrupts(OpCode o, bool value)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(o);
         fixture.Assert(c => c.MockRegisters.VerifySet(r => r.InterruptFlipFlop1 = value), c => c.MockRegisters.VerifySet(r => r.InterruptFlipFlop2 = value));
     }
 }
예제 #17
0
 public void ExchangeGeneralPurpose()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.ExchangeGeneralPurpose);
         fixture.Assert(c => c.MockRegisters.Verify(x => x.SwitchToAlternativeGeneralPurposeRegisters(), Times.Once));
     }
 }
예제 #18
0
파일: LoadTests.cs 프로젝트: jrp7/Alizarin
 public void When_writing_16bit_operands(Operand r)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.Load16).Operands(r).Random16BitRegister2(out var o).RandomLiterals();
         fixture.Assert(c => c.Operand16(r).ShouldBe(c.Operand16(o)));
     }
 }
예제 #19
0
 public void ExchangeAccumulatorAndFlags()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.ExchangeAccumulatorAndFlags);
         fixture.Assert(c => c.MockRegisters.Verify(x => x.SwitchToAlternativeAccumulatorAndFlagsRegisters(), Times.Once));
     }
 }
예제 #20
0
 public void JumpRelativeWithTest_Success(FlagTest test)
 {
     using (var fixture = new ExecuteFixture().DoNotHalt().RuntimeTiming(1, 5))
     {
         fixture.With(c => c.Flags.Setup(GetFlagExpression(test)).Returns(GetPositiveValue(test)));
         SetupRelativeJump(fixture, OpCode.JumpRelative, test);
     }
 }
예제 #21
0
 private static void TestCall(OpCode op, Expression <Action <IAlu, byte, byte> > f)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(op).RandomRegister(out var o).RandomLiterals();
         fixture.With(c => c.Alu.Setup(c.AluAction(f, Operand.A, o)).Verifiable());
     }
 }
예제 #22
0
 private static void FlagAflection(OpCode op, bool?sign = null, bool?zero     = null, bool?halfCarry = null,
                                   bool?parityOverflow  = null, bool?subtract = null, bool?carry     = null)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(op);
         fixture.AssertFlags(c => c.Accumulator.A, sign, zero, halfCarry, parityOverflow, subtract, carry);
     }
 }
예제 #23
0
 public void NegateTwosComplement()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.NegateTwosComplement);
         fixture.With(c => c.Alu.Setup(alu => alu.Subtract(0, c.Accumulator.A)).Returns(c.Byte).Verifiable());
         fixture.Assert(c => c.Accumulator.A.ShouldBe(c.Byte));
     }
 }
예제 #24
0
 public void DecimalArithmeticAdjust()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.DecimalArithmeticAdjust);
         fixture.With(c => c.Alu.Setup(alu => alu.DecimalAdjust(c.Accumulator.A, true)).Returns(c.Byte).Verifiable());
         fixture.Assert(c => c.Accumulator.A.ShouldBe(c.Byte));
     }
 }
예제 #25
0
 public void DecrementJumpRelativeIfNonZero_Success()
 {
     using (var fixture = new ExecuteFixture().DoNotHalt().RuntimeTiming(1, 5))
     {
         fixture.With(x => x.Registers.B = 2);
         SetupRelativeJump(fixture, OpCode.DecrementJumpRelativeIfNonZero, FlagTest.None);
         fixture.Assert(x => x.Registers.B.ShouldBe((byte)1));
     }
 }
예제 #26
0
 public void Exchange(Operand o0, Operand o1)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.Exchange).Operands(o0, o1);
         fixture.Assert(c => c.Operand16(o0).ShouldBe(c.InitialRegister16(o1)),
                        c => c.Operand16(o1).ShouldBe(c.InitialRegister16(o0)));
     }
 }
예제 #27
0
 public void BitReset(Operand o, byte bit)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.BitReset).Operands(o).ByteLiteral(bit);
         fixture.With(c => c.Alu.Setup(x => x.BitReset(c.Operand8(o), bit)).Returns(c.Byte).Verifiable());
         fixture.Assert(c => c.Operand8(o).ShouldBe(c.Byte));
     }
 }
예제 #28
0
 private static void TestAssign(OpCode op, Expression <Func <IAlu, ushort, ushort, ushort> > f)
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(op).Random16BitRegisters(out var o1, out var o2);
         fixture.With(c => c.Alu.Setup(c.Alu16Call(f, o1, o2)).Returns(c.Word).Verifiable());
         fixture.Assert(c => c.Operand16(o1).ShouldBe(c.Word));
     }
 }
예제 #29
0
 public void NegateOnesComplement()
 {
     using (var fixture = new ExecuteFixture())
     {
         fixture.Operation.OpCode(OpCode.NegateOnesComplement);
         fixture.Assert(c => c.Accumulator.A.ShouldBe((byte)~c.InitialAccumulator.A));
         fixture.AssertFlags(c => c.Accumulator.A, halfCarry: true, subtract: true);
     }
 }
예제 #30
0
 public void DecrementJumpRelativeIfNonZero_Fail()
 {
     using (var fixture = new ExecuteFixture().DoNotHalt())
     {
         fixture.With(x => x.Registers.B = 1);
         SetupRelativeJump(fixture, OpCode.DecrementJumpRelativeIfNonZero, FlagTest.None, false);
         fixture.Assert(x => x.Registers.B.ShouldBe((byte)0));
     }
 }