Exemple #1
0
        public void RotateRightInMemory()
        {
            Memory memory  = new Memory();
            var    bitUnit = new BitUnit(memory);

            memory.WriteByte(0xACDC, 0b00000011);
            byte flags = 0b01100000;

            bitUnit.RotateRight(0xAC, 0xDC, ref flags);

            Assert.Equal(0b10000001, memory.ReadByte(0xACDC));
            Assert.Equal(0b00010000, flags);
        }
Exemple #2
0
        public void RotateRight()
        {
            // No carry
            var  bitUnit = new BitUnit(new Memory());
            byte value   = 0b01111110;
            byte flags   = 0b01110000;

            bitUnit.RotateRight(ref value, ref flags, false);

            Assert.Equal(0b00111111, value);
            Assert.Equal(0x0, flags);

            // Set carry
            value = 0b10000001;
            flags = 0b01100000;

            bitUnit.RotateRight(ref value, ref flags, false);

            Assert.Equal(0b11000000, value);
            Assert.Equal(0b00010000, flags);

            // Set zero
            value = 0x0;
            flags = 0b01110000;

            bitUnit.RotateRight(ref value, ref flags, false);

            Assert.Equal(0x0, value);
            Assert.Equal(0b10000000, flags);

            // Reset zero forced
            value = 0x0;
            flags = 0b11110000;

            bitUnit.RotateRight(ref value, ref flags, true);

            Assert.Equal(0x0, value);
            Assert.Equal(0b00000000, flags);
        }
Exemple #3
0
        private void CreateBitUnitOpCodes()
        {
            CreateOpCode(0x07, () => { bitUnit.RotateLeft(ref A, ref F, true); }, "RLCA");
            CreateOpCode(0x17, () => { bitUnit.RotateLeftThroughCarry(ref A, ref F, true); }, "RLA");
            CreateOpCode(0x0F, () => { bitUnit.RotateRight(ref A, ref F, true); }, "RRCA");
            CreateOpCode(0x1F, () => { bitUnit.RotateRightThroughCarry(ref A, ref F, true); }, "RRA");

            CreateOpCode(0x2F, () => bitUnit.Complement(ref A, ref F), "CPL");
            CreateOpCode(0x3F, () => bitUnit.ComplementCarry(ref F), "CCF");

            foreach (byte code in Enumerable.Range(0x40, 0x40))
            {
                int target = (code - 0x40) % 8;
                int index  = (code - 0x40) / 8;
                switch (target)
                {
                case 0: CreatePrefixedOpCode(code, () => bitUnit.TestBit(B, index, ref F), $"BIT {index}, B"); break;

                case 1: CreatePrefixedOpCode(code, () => bitUnit.TestBit(C, index, ref F), $"BIT {index}, C"); break;

                case 2: CreatePrefixedOpCode(code, () => bitUnit.TestBit(D, index, ref F), $"BIT {index}, D"); break;

                case 3: CreatePrefixedOpCode(code, () => bitUnit.TestBit(E, index, ref F), $"BIT {index}, E"); break;

                case 4: CreatePrefixedOpCode(code, () => bitUnit.TestBit(H, index, ref F), $"BIT {index}, H"); break;

                case 5: CreatePrefixedOpCode(code, () => bitUnit.TestBit(L, index, ref F), $"BIT {index}, L"); break;

                case 6: CreatePrefixedOpCode(code, () => { ReadFromMemory(H, L, out var data); bitUnit.TestBit(data, index, ref F); }, $"BIT {index}, (HL)"); break;

                case 7: CreatePrefixedOpCode(code, () => bitUnit.TestBit(A, index, ref F), $"BIT {index}, A"); break;
                }
                ;
            }

            CreatePrefixedOpCode(0x00, () => bitUnit.RotateLeft(ref B, ref F, false), "RLC B");
            CreatePrefixedOpCode(0x01, () => bitUnit.RotateLeft(ref C, ref F, false), "RLC C");
            CreatePrefixedOpCode(0x02, () => bitUnit.RotateLeft(ref D, ref F, false), "RLC D");
            CreatePrefixedOpCode(0x03, () => bitUnit.RotateLeft(ref E, ref F, false), "RLC E");
            CreatePrefixedOpCode(0x04, () => bitUnit.RotateLeft(ref H, ref F, false), "RLC H");
            CreatePrefixedOpCode(0x05, () => bitUnit.RotateLeft(ref L, ref F, false), "RLC L");
            CreatePrefixedOpCode(0x06, () => bitUnit.RotateLeft(H, L, ref F), "RLC (HL)");
            CreatePrefixedOpCode(0x07, () => bitUnit.RotateLeft(ref A, ref F, false), "RLC A");

            CreatePrefixedOpCode(0x08, () => bitUnit.RotateRight(ref B, ref F, false), "RRC B");
            CreatePrefixedOpCode(0x09, () => bitUnit.RotateRight(ref C, ref F, false), "RRC C");
            CreatePrefixedOpCode(0x0A, () => bitUnit.RotateRight(ref D, ref F, false), "RRC D");
            CreatePrefixedOpCode(0x0B, () => bitUnit.RotateRight(ref E, ref F, false), "RRC E");
            CreatePrefixedOpCode(0x0C, () => bitUnit.RotateRight(ref H, ref F, false), "RRC H");
            CreatePrefixedOpCode(0x0D, () => bitUnit.RotateRight(ref L, ref F, false), "RRC L");
            CreatePrefixedOpCode(0x0E, () => bitUnit.RotateRight(H, L, ref F), "RRC (HL)");
            CreatePrefixedOpCode(0x0F, () => bitUnit.RotateRight(ref A, ref F, false), "RRC A");

            CreatePrefixedOpCode(0x10, () => bitUnit.RotateLeftThroughCarry(ref B, ref F, false), "RL B");
            CreatePrefixedOpCode(0x11, () => bitUnit.RotateLeftThroughCarry(ref C, ref F, false), "RL C");
            CreatePrefixedOpCode(0x12, () => bitUnit.RotateLeftThroughCarry(ref D, ref F, false), "RL D");
            CreatePrefixedOpCode(0x13, () => bitUnit.RotateLeftThroughCarry(ref E, ref F, false), "RL E");
            CreatePrefixedOpCode(0x14, () => bitUnit.RotateLeftThroughCarry(ref H, ref F, false), "RL H");
            CreatePrefixedOpCode(0x15, () => bitUnit.RotateLeftThroughCarry(ref L, ref F, false), "RL L");
            CreatePrefixedOpCode(0x16, () => bitUnit.RotateLeftThroughCarry(H, L, ref F), "RL (HL)");
            CreatePrefixedOpCode(0x17, () => bitUnit.RotateLeftThroughCarry(ref A, ref F, false), "RL A");

            CreatePrefixedOpCode(0x18, () => bitUnit.RotateRightThroughCarry(ref B, ref F, false), "RR B");
            CreatePrefixedOpCode(0x19, () => bitUnit.RotateRightThroughCarry(ref C, ref F, false), "RR C");
            CreatePrefixedOpCode(0x1A, () => bitUnit.RotateRightThroughCarry(ref D, ref F, false), "RR D");
            CreatePrefixedOpCode(0x1B, () => bitUnit.RotateRightThroughCarry(ref E, ref F, false), "RR E");
            CreatePrefixedOpCode(0x1C, () => bitUnit.RotateRightThroughCarry(ref H, ref F, false), "RR H");
            CreatePrefixedOpCode(0x1D, () => bitUnit.RotateRightThroughCarry(ref L, ref F, false), "RR L");
            CreatePrefixedOpCode(0x1E, () => bitUnit.RotateRightThroughCarry(H, L, ref F), "RR (HL)");
            CreatePrefixedOpCode(0x1F, () => bitUnit.RotateRightThroughCarry(ref A, ref F, false), "RR A");

            CreatePrefixedOpCode(0x20, () => bitUnit.ShiftLeftArithmetic(ref B, ref F), "SLA B");
            CreatePrefixedOpCode(0x21, () => bitUnit.ShiftLeftArithmetic(ref C, ref F), "SLA C");
            CreatePrefixedOpCode(0x22, () => bitUnit.ShiftLeftArithmetic(ref D, ref F), "SLA D");
            CreatePrefixedOpCode(0x23, () => bitUnit.ShiftLeftArithmetic(ref E, ref F), "SLA E");
            CreatePrefixedOpCode(0x24, () => bitUnit.ShiftLeftArithmetic(ref H, ref F), "SLA H");
            CreatePrefixedOpCode(0x25, () => bitUnit.ShiftLeftArithmetic(ref L, ref F), "SLA L");
            CreatePrefixedOpCode(0x26, () => bitUnit.ShiftLeftArithmetic(H, L, ref F), "SLA (HL)");
            CreatePrefixedOpCode(0x27, () => bitUnit.ShiftLeftArithmetic(ref A, ref F), "SLA A");

            CreatePrefixedOpCode(0x28, () => bitUnit.ShiftRightArithmetic(ref B, ref F), "SRA B");
            CreatePrefixedOpCode(0x29, () => bitUnit.ShiftRightArithmetic(ref C, ref F), "SRA C");
            CreatePrefixedOpCode(0x2A, () => bitUnit.ShiftRightArithmetic(ref D, ref F), "SRA D");
            CreatePrefixedOpCode(0x2B, () => bitUnit.ShiftRightArithmetic(ref E, ref F), "SRA E");
            CreatePrefixedOpCode(0x2C, () => bitUnit.ShiftRightArithmetic(ref H, ref F), "SRA H");
            CreatePrefixedOpCode(0x2D, () => bitUnit.ShiftRightArithmetic(ref L, ref F), "SRA L");
            CreatePrefixedOpCode(0x2E, () => bitUnit.ShiftRightArithmetic(H, L, ref F), "SRA (HL)");
            CreatePrefixedOpCode(0x2F, () => bitUnit.ShiftRightArithmetic(ref A, ref F), "SRA A");

            CreatePrefixedOpCode(0x30, () => bitUnit.Swap(ref B, ref F), "SWAP B");
            CreatePrefixedOpCode(0x31, () => bitUnit.Swap(ref C, ref F), "SWAP C");
            CreatePrefixedOpCode(0x32, () => bitUnit.Swap(ref D, ref F), "SWAP D");
            CreatePrefixedOpCode(0x33, () => bitUnit.Swap(ref E, ref F), "SWAP E");
            CreatePrefixedOpCode(0x34, () => bitUnit.Swap(ref H, ref F), "SWAP H");
            CreatePrefixedOpCode(0x35, () => bitUnit.Swap(ref L, ref F), "SWAP L");
            CreatePrefixedOpCode(0x36, () => bitUnit.Swap(H, L, ref F), "SWAP (HL)");
            CreatePrefixedOpCode(0x37, () => bitUnit.Swap(ref A, ref F), "SWAP A");

            CreatePrefixedOpCode(0x38, () => bitUnit.ShiftRightLogic(ref B, ref F), "SRL B");
            CreatePrefixedOpCode(0x39, () => bitUnit.ShiftRightLogic(ref C, ref F), "SRL C");
            CreatePrefixedOpCode(0x3A, () => bitUnit.ShiftRightLogic(ref D, ref F), "SRL D");
            CreatePrefixedOpCode(0x3B, () => bitUnit.ShiftRightLogic(ref E, ref F), "SRL E");
            CreatePrefixedOpCode(0x3C, () => bitUnit.ShiftRightLogic(ref H, ref F), "SRL H");
            CreatePrefixedOpCode(0x3D, () => bitUnit.ShiftRightLogic(ref L, ref F), "SRL L");
            CreatePrefixedOpCode(0x3E, () => bitUnit.ShiftRightLogic(H, L, ref F), "SRL (HL)");
            CreatePrefixedOpCode(0x3F, () => bitUnit.ShiftRightLogic(ref A, ref F), "SRL A");

            // RES and SET instructions all share the same pattern
            foreach (byte code in Enumerable.Range(0x80, 0x80))
            {
                bool bitValue = code >= 0xC0;
                int  target   = (code - 0x80) % 8;
                int  index    = (code - (bitValue == true ? 0xC0 : 0x80)) / 8;
                switch (target)
                {
                case 0: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref B, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, B"); break;

                case 1: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref C, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, C"); break;

                case 2: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref D, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, D"); break;

                case 3: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref E, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, E"); break;

                case 4: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref H, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, H"); break;

                case 5: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref L, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, L"); break;

                case 6: CreatePrefixedOpCode(code, () => bitUnit.SetBit(H, L, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, (HL)"); break;

                case 7: CreatePrefixedOpCode(code, () => bitUnit.SetBit(ref A, index, bitValue), $"{(bitValue ? "SET" : "RES")} {index}, A"); break;
                }
                ;
            }
        }