예제 #1
0
        public void DecrementSetsHalfCarryTest()
        {
            var  memory = new Memory();
            var  alu    = new ALU(memory);
            byte value  = 0x10;
            byte flags  = 0b11000000;

            alu.Decrement(ref value, ref flags);

            Assert.Equal(0x0F, value);
            Assert.Equal(0b01100000, flags);
        }
예제 #2
0
        public void DecrementSetsZeroTest()
        {
            var  memory = new Memory();
            var  alu    = new ALU(memory);
            byte value  = 0x01;
            byte flags  = 0b00010000;

            alu.Decrement(ref value, ref flags);

            Assert.Equal(0, value);
            Assert.Equal(0b11010000, flags);
        }
        public void TestDecrement(byte a, byte result, bool h, bool z)
        {
            var device = TestUtils.CreateTestDevice();
            var cpu    = device.CPU;
            var alu    = new ALU(cpu);

            alu.Decrement(ref a);

            Assert.Equal(result, a);
            Assert.Equal(h, cpu.Registers.GetFlag(CpuFlags.HalfCarryFlag));
            Assert.True(cpu.Registers.GetFlag(CpuFlags.SubtractFlag));
            Assert.Equal(z, cpu.Registers.GetFlag(CpuFlags.ZeroFlag));
        }
예제 #4
0
파일: CPU.cs 프로젝트: jarkkopa/GeemuBoy
        private void CreateALUOpCodes()
        {
            CreateOpCode(0x87, () => alu.Add(ref A, A, ref F), "ADD A, A");
            CreateOpCode(0x80, () => alu.Add(ref A, B, ref F), "ADD A, B");
            CreateOpCode(0x81, () => alu.Add(ref A, C, ref F), "ADD A, C");
            CreateOpCode(0x82, () => alu.Add(ref A, D, ref F), "ADD A, D");
            CreateOpCode(0x83, () => alu.Add(ref A, E, ref F), "ADD A, E");
            CreateOpCode(0x84, () => alu.Add(ref A, H, ref F), "ADD A, H");
            CreateOpCode(0x85, () => alu.Add(ref A, L, ref F), "ADD A, L");
            CreateOpCode(0x86, () => { ReadFromMemory(H, L, out var memValue); alu.Add(ref A, memValue, ref F); }, "ADD A, (HL)");
            CreateOpCode(0xC6, () => { ReadImmediateByte(out var immediate); alu.Add(ref A, immediate, ref F); }, "ADD A, d8");

            CreateOpCode(0x8F, () => alu.Add(ref A, A, ref F, true), "ADC A,A");
            CreateOpCode(0x88, () => alu.Add(ref A, B, ref F, true), "ADC A,B");
            CreateOpCode(0x89, () => alu.Add(ref A, C, ref F, true), "ADC A,C");
            CreateOpCode(0x8A, () => alu.Add(ref A, D, ref F, true), "ADC A,D");
            CreateOpCode(0x8B, () => alu.Add(ref A, E, ref F, true), "ADC A,E");
            CreateOpCode(0x8C, () => alu.Add(ref A, H, ref F, true), "ADC A,H");
            CreateOpCode(0x8D, () => alu.Add(ref A, L, ref F, true), "ADC A,L");
            CreateOpCode(0x8E, () => { ReadFromMemory(H, L, out var memValue); alu.Add(ref A, memValue, ref F, true); }, "ADC A, (HL)");
            CreateOpCode(0xCE, () => { ReadImmediateByte(out var immediate); alu.Add(ref A, immediate, ref F, true); }, "ADC A, d8");

            CreateOpCode(0x97, () => alu.Subtract(ref A, A, ref F), "SUB A");
            CreateOpCode(0x90, () => alu.Subtract(ref A, B, ref F), "SUB B");
            CreateOpCode(0x91, () => alu.Subtract(ref A, C, ref F), "SUB C");
            CreateOpCode(0x92, () => alu.Subtract(ref A, D, ref F), "SUB D");
            CreateOpCode(0x93, () => alu.Subtract(ref A, E, ref F), "SUB E");
            CreateOpCode(0x94, () => alu.Subtract(ref A, H, ref F), "SUB H");
            CreateOpCode(0x95, () => alu.Subtract(ref A, L, ref F), "SUB L");
            CreateOpCode(0x96, () => { ReadFromMemory(H, L, out var memValue); alu.Subtract(ref A, memValue, ref F); }, "SUB (HL)");
            CreateOpCode(0xD6, () => { ReadImmediateByte(out var immediate); alu.Subtract(ref A, immediate, ref F); }, "SUB d8");

            CreateOpCode(0x9F, () => alu.Subtract(ref A, A, ref F, true), "SBC A, A");
            CreateOpCode(0x98, () => alu.Subtract(ref A, B, ref F, true), "SBC A, B");
            CreateOpCode(0x99, () => alu.Subtract(ref A, C, ref F, true), "SBC A, C");
            CreateOpCode(0x9A, () => alu.Subtract(ref A, D, ref F, true), "SBC A, D");
            CreateOpCode(0x9B, () => alu.Subtract(ref A, E, ref F, true), "SBC A, E");
            CreateOpCode(0x9C, () => alu.Subtract(ref A, H, ref F, true), "SBC A, H");
            CreateOpCode(0x9D, () => alu.Subtract(ref A, L, ref F, true), "SBC A, L");
            CreateOpCode(0x9E, () => { ReadFromMemory(H, L, out var memValue); alu.Subtract(ref A, memValue, ref F, true); }, "SBC A, (HL)");
            CreateOpCode(0xDE, () => { ReadImmediateByte(out var immediate); alu.Subtract(ref A, immediate, ref F, true); }, "SBC A, d8");

            CreateOpCode(0xA7, () => alu.And(ref A, A, ref F), "AND A");
            CreateOpCode(0xA0, () => alu.And(ref A, B, ref F), "AND B");
            CreateOpCode(0xA1, () => alu.And(ref A, C, ref F), "AND C");
            CreateOpCode(0xA2, () => alu.And(ref A, D, ref F), "AND D");
            CreateOpCode(0xA3, () => alu.And(ref A, E, ref F), "AND E");
            CreateOpCode(0xA4, () => alu.And(ref A, H, ref F), "AND H");
            CreateOpCode(0xA5, () => alu.And(ref A, L, ref F), "AND L");
            CreateOpCode(0xA6, () => { ReadFromMemory(H, L, out var memValue); alu.And(ref A, memValue, ref F); }, "AND (HL)");
            CreateOpCode(0xE6, () => { ReadImmediateByte(out var immediate); alu.And(ref A, immediate, ref F); }, "AND d8");

            CreateOpCode(0xB7, () => alu.Or(ref A, A, ref F), "OR A");
            CreateOpCode(0xB0, () => alu.Or(ref A, B, ref F), "OR B");
            CreateOpCode(0xB1, () => alu.Or(ref A, C, ref F), "OR C");
            CreateOpCode(0xB2, () => alu.Or(ref A, D, ref F), "OR D");
            CreateOpCode(0xB3, () => alu.Or(ref A, E, ref F), "OR E");
            CreateOpCode(0xB4, () => alu.Or(ref A, H, ref F), "OR H");
            CreateOpCode(0xB5, () => alu.Or(ref A, L, ref F), "OR L");
            CreateOpCode(0xB6, () => { ReadFromMemory(H, L, out var memValue); alu.Or(ref A, memValue, ref F); }, "OR (HL)");
            CreateOpCode(0xF6, () => { ReadImmediateByte(out var immediate); alu.Or(ref A, immediate, ref F); }, "OR d8");

            CreateOpCode(0xAF, () => alu.Xor(ref A, A, ref F), "XOR A");
            CreateOpCode(0xA8, () => alu.Xor(ref A, B, ref F), "XOR B");
            CreateOpCode(0xA9, () => alu.Xor(ref A, C, ref F), "XOR C");
            CreateOpCode(0xAA, () => alu.Xor(ref A, D, ref F), "XOR D");
            CreateOpCode(0xAB, () => alu.Xor(ref A, E, ref F), "XOR E");
            CreateOpCode(0xAC, () => alu.Xor(ref A, H, ref F), "XOR H");
            CreateOpCode(0xAD, () => alu.Xor(ref A, L, ref F), "XOR L");
            CreateOpCode(0xAE, () => { ReadFromMemory(H, L, out var memValue); alu.Xor(ref A, memValue, ref F); }, "XOR (HL)");
            CreateOpCode(0xEE, () => { ReadImmediateByte(out var immediate); alu.Xor(ref A, immediate, ref F); }, "XOR d8");

            CreateOpCode(0xBF, () => alu.Compare(A, A, ref F), "CP A");
            CreateOpCode(0xB8, () => alu.Compare(A, B, ref F), "CP B");
            CreateOpCode(0xB9, () => alu.Compare(A, C, ref F), "CP C");
            CreateOpCode(0xBA, () => alu.Compare(A, D, ref F), "CP D");
            CreateOpCode(0xBB, () => alu.Compare(A, E, ref F), "CP E");
            CreateOpCode(0xBC, () => alu.Compare(A, H, ref F), "CP H");
            CreateOpCode(0xBD, () => alu.Compare(A, L, ref F), "CP L");
            CreateOpCode(0xBE, () => { ReadFromMemory(H, L, out var memValue); alu.Compare(A, memValue, ref F); }, "CP (HL)");
            CreateOpCode(0xFE, () => { ReadImmediateByte(out var immediate); alu.Compare(A, immediate, ref F); }, "CP d8");

            CreateOpCode(0x3C, () => alu.Increment(ref A, ref F), "INC A");
            CreateOpCode(0x04, () => alu.Increment(ref B, ref F), "INC B");
            CreateOpCode(0x0C, () => alu.Increment(ref C, ref F), "INC C");
            CreateOpCode(0x14, () => alu.Increment(ref D, ref F), "INC D");
            CreateOpCode(0x1C, () => alu.Increment(ref E, ref F), "INC E");
            CreateOpCode(0x24, () => alu.Increment(ref H, ref F), "INC H");
            CreateOpCode(0x2C, () => alu.Increment(ref L, ref F), "INC L");
            CreateOpCode(0x34, () => alu.IncrementInMemory(H, L, ref F), "INC (HL)");

            CreateOpCode(0x3D, () => alu.Decrement(ref A, ref F), "DEC A");
            CreateOpCode(0x05, () => alu.Decrement(ref B, ref F), "DEC B");
            CreateOpCode(0x0D, () => alu.Decrement(ref C, ref F), "DEC C");
            CreateOpCode(0x15, () => alu.Decrement(ref D, ref F), "DEC D");
            CreateOpCode(0x1D, () => alu.Decrement(ref E, ref F), "DEC E");
            CreateOpCode(0x25, () => alu.Decrement(ref H, ref F), "DEC H");
            CreateOpCode(0x2D, () => alu.Decrement(ref L, ref F), "DEC L");
            CreateOpCode(0x35, () => alu.DecrementInMemory(H, L, ref F), "DEC (HL)");

            CreateOpCode(0x09, () => alu.Add(ref H, ref L, B, C, ref F), "ADD HL, BC");
            CreateOpCode(0x19, () => alu.Add(ref H, ref L, D, E, ref F), "ADD HL, DE");
            CreateOpCode(0x29, () => alu.Add(ref H, ref L, H, L, ref F), "ADD HL, HL");
            CreateOpCode(0x39, () => alu.Add(ref H, ref L, BitUtils.MostSignificantByte(SP), BitUtils.LeastSignificantByte(SP), ref F), "ADD HL, SP");

            CreateOpCode(0xE8, () => { ReadImmediateByte(out var data); alu.AddSigned(ref SP, data, ref F); }, "ADD SP, r8");

            CreateOpCode(0x03, () => alu.IncrementWord(ref B, ref C), "INC BC");
            CreateOpCode(0x13, () => alu.IncrementWord(ref D, ref E), "INC DE");
            CreateOpCode(0x23, () => alu.IncrementWord(ref H, ref L), "INC HL");
            CreateOpCode(0x33, () => alu.IncrementWord(ref SP), "INC SP");

            CreateOpCode(0x0B, () => alu.DecrementWord(ref B, ref C), "DEC BC");
            CreateOpCode(0x1B, () => alu.DecrementWord(ref D, ref E), "DEC DE");
            CreateOpCode(0x2B, () => alu.DecrementWord(ref H, ref L), "DEC HL");
            CreateOpCode(0x3B, () => alu.DecrementWord(ref SP), "DEC SP");
        }