Beispiel #1
0
    void Test_ADC(Setter set, Opcode op, bool extra) {
        const auto expectedCycles = extra ? op.Cycles + 1 : op.Cycles;
        auto tester = [&] (Byte a, Byte m, Flag c, Byte expA, Flag expC, Flag expZ, Flag expV, Flag expN) {
            set(m);
            cpu.A = a;
            cpu.C = c;

            cpu.PC = BASE_PC;
            cpu.Ticks = BASE_TICKS;
            cpu.Execute(op);

            EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC);
            EXPECT_EQ(BASE_TICKS + expectedCycles, cpu.Ticks);
            EXPECT_EQ(expA, cpu.A);
            EXPECT_EQ(expC, cpu.C);
            EXPECT_EQ(expZ, cpu.Z);
            EXPECT_EQ(expV, cpu.V);
            EXPECT_EQ(expN, cpu.N);
        };

        tester(0x10, 0x20, 0, 0x30, 0, 0, 0, 0); // pos pos > pos
        tester(0x10, 0x20, 1, 0x31, 0, 0, 0, 0); // pos pos C > pos
        tester(0x00, 0x00, 0, 0x00, 0, 1, 0, 0); // Zero
        tester(0x7F, 0x80, 1, 0x00, 1, 1, 0, 0); // Zero by carry
        tester(0x80, 0x80, 0, 0x00, 1, 1, 1, 0); // Zero by overflow
        tester(0x20, 0xF0, 0, 0x10, 1, 0, 0, 0); // Carry w/o overflow w/o sign change
        tester(0xF0, 0x20, 0, 0x10, 1, 0, 0, 0); // Carry w/o overflow w/  sign change
        tester(0xA0, 0xA0, 0, 0x40, 1, 0, 1, 0); // Carry with overflow
        tester(0x70, 0x10, 0, 0x80, 0, 0, 1, 1); // Overflow pos > neg
        tester(0xB0, 0xB0, 0, 0x60, 1, 0, 1, 0); // Overflow neg > pos
        tester(0x00, 0xF0, 0, 0xF0, 0, 0, 0, 1); // Negative
    }
Beispiel #2
0
    void Test_SBC(Setter set, Opcode op, int extra) {
        auto tester = [&] (Byte a, Byte m, Flag c, Byte expA, Flag expC, Flag expZ, Flag expV, Flag expN) {
            set(m);
            cpu.A = a;
            cpu.C = c;

            cpu.PC = BASE_PC;
            cpu.Ticks = BASE_TICKS;
            cpu.Execute(op);

            EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC);
            EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks);
            EXPECT_EQ(expA, cpu.A);
            EXPECT_EQ(expC, cpu.C);
            EXPECT_EQ(expZ, cpu.Z);
            EXPECT_EQ(expV, cpu.V);
            EXPECT_EQ(expN, cpu.N);
        };

        tester(0x40, 0x20, 1, 0x20, 0, 0, 0, 0); // pos pos > pos
        tester(0x40, 0x1F, 0, 0x20, 0, 0, 0, 0); // pos pos C > pos
        tester(0x00, 0x00, 1, 0x00, 0, 1, 0, 0); // Zero
        tester(0x80, 0x7F, 0, 0x00, 0, 1, 1, 0); // Zero by overflow
        tester(0x00, 0xFF, 0, 0x00, 1, 1, 0, 0); // Zero by carry
        tester(0x20, 0x40, 1, 0xE0, 1, 0, 0, 1); // Carry w/o overflow
        tester(0x20, 0xA0, 1, 0x80, 1, 0, 1, 1); // Carry w/ overflow
        tester(0x00, 0x00, 0, 0xFF, 1, 0, 0, 1); // Carry by borrow
        tester(0x20, 0xA0, 1, 0x80, 1, 0, 1, 1); // Overflow pos > neg
        tester(0x80, 0x20, 1, 0x60, 0, 0, 1, 0); // Overflow neg > pos
        tester(0x80, 0x00, 1, 0x80, 0, 0, 0, 1); // Negative
    }
Beispiel #3
0
    void Test_Transfer(Getter get, Setter set, Opcode op) {
        auto tester = [&] (Byte value, Flag expZ, Flag expN) {
            set(value);

            cpu.PC = BASE_PC;
            cpu.Ticks = BASE_TICKS;
            cpu.Execute(op);

            EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC);
            EXPECT_EQ(BASE_TICKS + op.Cycles, cpu.Ticks);
            EXPECT_EQ(value, get());
            EXPECT_EQ(expZ, cpu.Z);
            EXPECT_EQ(expN, cpu.N);
        };

        tester(0x20, 0, 0);
        tester(0xA0, 0, 1);
        tester(0x00, 1, 0);
    }
Beispiel #4
0
    void Test_Branch(Setter set, Flag success, Flag failure, Opcode op) {
        auto tester = [&] (Word pc, Byte offset, Flag c, Word expPC, int extra) {
            cpu.Memory.SetByteAt(pc, 0xFF);
            cpu.Memory.SetByteAt(pc + 1, offset);
            set(c);

            cpu.PC = pc;
            cpu.Ticks = BASE_TICKS;
            cpu.Execute(op);

            EXPECT_EQ(expPC, cpu.PC);
            EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks);
        };

        tester(0x0080, 0x20, failure, 0x0082, 0); // Fail
        tester(0x0080, 0x20, success, 0x00A0, 1); // Success, positive offset
        tester(0x0080, 0xE0, success, 0x0060, 1); // Success, negative offset
        tester(0x00F0, 0x20, success, 0x0110, 3); // Success, positive offset, crossing page
        tester(0x0110, 0xE0, success, 0x00F0, 3); // Success, negative offset, crossing page
    }
Beispiel #5
0
    void Test_Compare(SetterReg setR, SetterMem setM, Opcode op, int extra) {
        auto tester = [&] (Byte r, Byte m, Flag expC, Flag expZ, Flag expN) {
            setR(r);
            setM(m);

            cpu.PC = BASE_PC;
            cpu.Ticks = BASE_TICKS;
            cpu.Execute(op);

            EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC);
            EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks);
            EXPECT_EQ(expC, cpu.C);
            EXPECT_EQ(expZ, cpu.Z);
            EXPECT_EQ(expN, cpu.N);
        };

        tester(0x20, 0x10, 1, 0, 0); // Greater
        tester(0x20, 0x20, 1, 1, 0); // Equal
        tester(0x20, 0x40, 0, 0, 1); // Lower

        tester(0xF0, 0xE0, 1, 0, 0); // Greater
        tester(0xF0, 0xF0, 1, 1, 0); // Equal
        tester(0xF0, 0xF8, 0, 0, 1); // Lower
    }