예제 #1
0
        public void TestOr(OpCode opCode, ChangeType orRegister, byte aRegisterVal, byte orRegisterVal, byte expectedResult, bool expectedZeroFlag)
        {
            //setup
            var prog = new byte[] { (byte)opCode };
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            cpu.AF = 0xFF;
            cpu.BC = 0xFF;
            cpu.DE = 0xFF;
            cpu.HL = 0xFF;
            cpu.A  = aRegisterVal;
            CpuHelpers.SetValue(cpu, orRegister, orRegisterVal);

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 4;
            cpuExpected.ProgramCounter = 1;
            cpuExpected.A        = expectedResult;
            cpuExpected.F        = 0;
            cpuExpected.ZeroFlag = expectedZeroFlag;

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #2
0
        public void TestXor_A()
        {
            //setup
            var prog = new byte[] { 0xAF }; //XOR A
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            cpu.AF = 0xFF;
            cpu.BC = 0x08;
            cpu.DE = 0x08;
            cpu.HL = 0x08;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 4;
            cpuExpected.ProgramCounter = 1;
            cpuExpected.A        = 0;
            cpuExpected.F        = 0;
            cpuExpected.ZeroFlag = true;

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #3
0
        public void TestOr_A(byte value, bool expectedZeroFlag)
        {
            //setup
            var prog = new byte[] { (byte)OpCode.Or_A };
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            cpu.AF = 0xFF;
            cpu.BC = 0x08;
            cpu.DE = 0x08;
            cpu.HL = 0x08;
            cpu.A  = value;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 4;
            cpuExpected.ProgramCounter = 1;
            cpuExpected.A        = value;
            cpuExpected.F        = 0;
            cpuExpected.ZeroFlag = expectedZeroFlag;

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #4
0
        public void TestLd_addrHL_n()
        {
            //setup
            byte   testValue   = 0x0E;
            ushort testAddress = 0xF1;
            var    prog        = new byte[256];

            prog[0] = (byte)OpCode.LD_addrHL_n;
            prog[1] = testValue;
            var mmu = new SimpleMmu(prog);
            var cpu = new Cpu(mmu);

            //put nonsense in target address
            mmu.WriteByte(testAddress, 0xFF);
            //set HL to address to be copied to
            cpu.HL = testAddress;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 12;
            cpuExpected.ProgramCounter = 2;
            cpuExpected.Mmu.WriteByte(testAddress, testValue);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #5
0
        public void TestLd_R_addrHL(ChangeType targetRegister, OpCode opCode)
        {
            //setup
            byte   testValue   = 0x0E;
            ushort testAddress = 0xF1;
            var    prog        = new byte[256];

            prog[0] = (byte)opCode; //LD r,(HL)
            var mmu = new SimpleMmu(prog);
            var cpu = new Cpu(mmu);

            //set value to be copied to target register in memory
            mmu.WriteByte(testAddress, testValue);
            //put address to be copied from into HL
            cpu.HL = testAddress;

            //put some nonsense in target register to make sure it changes
            //H/L are special cases as they affect the target address, so can't be altered
            if (targetRegister != ChangeType.H && targetRegister != ChangeType.L)
            {
                CpuHelpers.SetValue(cpu, targetRegister, 0xFF);
            }

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 8;
            cpuExpected.ProgramCounter = 1;
            CpuHelpers.SetValue(cpuExpected, targetRegister, testValue);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #6
0
        public void TestSetBit(ChangeType register, byte registerInitialVal, byte bitToSet, byte expectedRegisterVal)
        {
            //build opcode - 0b11<reg><bit>
            var opCode = 0b1100_0000 | (bitToSet << 3) | (byte)register;
            //setup
            var mem = new byte[256];

            mem[0] = 0xCB;
            mem[1] = (byte)opCode;
            var aHL = (byte)0xF1;
            var mmu = new SimpleMmu(mem);
            var cpu = new Cpu(mmu);

            cpu.F = 0;
            if (register == ChangeType.aHL)
            {
                cpu.HL = aHL;
                mmu.WriteByte(aHL, registerInitialVal);
            }
            else
            {
                CpuHelpers.SetValue(cpu, register, registerInitialVal);
            }

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = (uint)(register == ChangeType.aHL ? 12 : 8);
            cpuExpected.ProgramCounter = 2;
            cpuExpected.ZeroFlag       = false;
            cpuExpected.HalfCarryFlag  = false;
            cpuExpected.SubFlag        = false;
            cpuExpected.CarryFlag      = false;
            if (register == ChangeType.aHL)
            {
                cpuExpected.Mmu.WriteByte(aHL, expectedRegisterVal);
            }
            else
            {
                CpuHelpers.SetValue(cpuExpected, register, expectedRegisterVal);
            }


            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #7
0
        public void TestRotate(byte opCode, ChangeType register, byte registerInitialVal, bool carryFlagInitialVal, byte expectedRegisterVal, bool expectedCarryFlag, bool expectedZeroFlag)
        {
            //setup
            var mem = new byte[256];

            mem[0] = 0xCB;
            mem[1] = (byte)(opCode | (byte)register); //build opcode - 0bcccc_crrr
            var aHL = (byte)0xF1;
            var mmu = new SimpleMmu(mem);
            var cpu = new Cpu(mmu);

            cpu.F         = 0;
            cpu.CarryFlag = carryFlagInitialVal;
            if (register == ChangeType.aHL)
            {
                cpu.HL = aHL;
                mmu.WriteByte(aHL, registerInitialVal);
            }
            else
            {
                CpuHelpers.SetValue(cpu, register, registerInitialVal);
            }

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = (uint)(register == ChangeType.aHL ? 12 : 8);
            cpuExpected.ProgramCounter = 2;
            cpuExpected.ZeroFlag       = expectedZeroFlag;
            cpuExpected.HalfCarryFlag  = false;
            cpuExpected.SubFlag        = false;
            cpuExpected.CarryFlag      = expectedCarryFlag;
            if (register == ChangeType.aHL)
            {
                cpuExpected.Mmu.WriteByte(aHL, expectedRegisterVal);
            }
            else
            {
                CpuHelpers.SetValue(cpuExpected, register, expectedRegisterVal);
            }

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #8
0
        public void TestLd_Rr_D16(ChangeType register, byte opCode)
        {
            //setup
            var prog = new byte[] { opCode, 0xFE, 0xEF }; //LD rr,nn, rr = 0xEFFE
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 12;
            cpuExpected.ProgramCounter = 3;
            CpuHelpers.SetValue(cpuExpected, register, 0xEFFE);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #9
0
        public void TestLd_R_D8(ChangeType register, OpCode opCode)
        {
            //setup
            var prog = new byte[] { (byte)opCode, 0xFE }; //LD r,n
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 8;
            cpuExpected.ProgramCounter = 2;
            CpuHelpers.SetValue(cpuExpected, register, 0xFE);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #10
0
        public void TestLd_addrHL_R(ChangeType sourceRegister, OpCode opCode)
        {
            //setup
            byte testValue = 0x0E;

            //H/L are special cases as they hold the address AND the value
            if (sourceRegister == ChangeType.H)
            {
                testValue = 0x01;
            }
            if (sourceRegister == ChangeType.L)
            {
                testValue = 0xF1;
            }
            ushort testAddress = 0x01F1;
            var    prog        = new byte[512];

            prog[0] = (byte)opCode; //LD r,(HL)
            var mmu = new SimpleMmu(prog);
            var cpu = new Cpu(mmu);

            //put nonsense in target address
            mmu.WriteByte(testAddress, 0xFF);

            //set value in register to be copied
            CpuHelpers.SetValue(cpu, sourceRegister, testValue);
            //set HL to address to be copied to
            cpu.HL = testAddress;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 8;
            cpuExpected.ProgramCounter = 1;
            cpuExpected.Mmu.WriteByte(testAddress, testValue);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #11
0
        public void TestNoop()
        {
            //setup
            var prog = new byte[] { 0x00 }; //Nop
            var mmu  = new SimpleMmu(prog);
            var cpu  = new Cpu(mmu);

            cpu.AF = 0xFF;
            cpu.BC = 0xFF;
            cpu.DE = 0xFF;
            cpu.HL = 0xFF;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 4;
            cpuExpected.ProgramCounter = 1;

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #12
0
        public void TestLd_R_R(ChangeType targetRegister, ChangeType sourceRegister, OpCode opCode)
        {
            //setup
            byte testValue = 0xFE;
            var  prog      = new byte[] { (byte)opCode }; //LD r,r
            var  mmu       = new SimpleMmu(prog);
            var  cpu       = new Cpu(mmu);

            CpuHelpers.SetValue(cpu, targetRegister, 0xFF);
            CpuHelpers.SetValue(cpu, sourceRegister, testValue);

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = 4;
            cpuExpected.ProgramCounter = 1;
            CpuHelpers.SetValue(cpuExpected, targetRegister, testValue);

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }
예제 #13
0
        [DataRow(false, (ushort)0x00, (ushort)0xFFFD, (byte)0xFB, (uint)12)] //ushort wrap around
        public void TestJR_NZ_r8(bool zeroFlag, ushort programCounterBefore, ushort expectedProgramCounterAfter, byte r8, uint expectedCycles)
        {
            //setup
            var prog = new byte[256];

            prog[programCounterBefore]     = (byte)OpCode.JR_NZ_r8;
            prog[programCounterBefore + 1] = r8;
            var mmu = new SimpleMmu(prog);
            var cpu = new Cpu(mmu);

            cpu.ProgramCounter = programCounterBefore;
            cpu.ZeroFlag       = zeroFlag;

            //expected outcome
            var cpuExpected = cpu.CopyState();

            cpuExpected.Cycles         = expectedCycles;
            cpuExpected.ProgramCounter = expectedProgramCounterAfter;

            //execute & validate
            cpu.Step();
            CpuHelpers.ValidateState(cpuExpected, cpu);
        }