Esempio n. 1
0
        public static int DEC_r(IZ80CPU cpu, byte[] instruction)
        {
            var  reg = instruction[0].ExtractBits(3, 3);
            byte val;

            switch (reg)
            {
            case 0b111: cpu.Registers.A--; val = cpu.Registers.A; break;

            case 0b000: cpu.Registers.B--; val = cpu.Registers.B; break;

            case 0b001: cpu.Registers.C--; val = cpu.Registers.C; break;

            case 0b010: cpu.Registers.D--; val = cpu.Registers.D; break;

            case 0b011: cpu.Registers.E--; val = cpu.Registers.E; break;

            case 0b100: cpu.Registers.H--; val = cpu.Registers.H; break;

            case 0b101: cpu.Registers.L--; val = cpu.Registers.L; break;

            default: throw new InvalidOperationException();
            }

            DecrementByteSetConditionBits(cpu, val);

            return(4);
        }
Esempio n. 2
0
        public static int LD_IY_nn_mem(IZ80CPU cpu, byte[] instruction)
        {
            var nn = Utilities.LETo16Bit(instruction[2], instruction[3]);

            cpu.Registers.IY = cpu.ReadWord(nn);
            return(20);
        }
Esempio n. 3
0
 private static byte RotateByteRight(IZ80CPU cpu, byte val)
 {
     cpu.Registers.HalfCarry = false;
     cpu.Registers.Subtract  = false;
     cpu.Registers.Carry     = val.GetBit(0);
     return((byte)((val >> 1) | (val.GetBitAsByte(0) << 7)));
 }
Esempio n. 4
0
        private static void AddWordsWithCarryAndSetConditionBits(IZ80CPU cpu, bool subtract, ushort b)
        {
            var a = cpu.Registers.HL;
            var c = (ushort)(cpu.Registers.Carry ? 1 : 0);

            if (subtract)
            {
                b = b.TwosComplement();
                c = c.TwosComplement();
            }

            var sum        = a + b + c;
            var noCarrySum = a ^ b ^ c;

            var carryInto = sum ^ noCarrySum;
            var halfCarry = carryInto & 0x1000;
            var carry     = carryInto & 0x10000;
            var overflow  = carryInto & 0x8000;

            var result = (ushort)sum;

            cpu.Registers.Sign             = result.IsNegative();
            cpu.Registers.Zero             = result == 0;
            cpu.Registers.HalfCarry        = halfCarry != 0;
            cpu.Registers.ParityOrOverflow = overflow != 0;
            cpu.Registers.Subtract         = subtract;
            cpu.Registers.Carry            = carry != 0;
            cpu.Registers.HL = result;
        }
Esempio n. 5
0
        public static int JP_cc_nn(IZ80CPU cpu, byte[] instruction)
        {
            var condition  = instruction[0].ExtractBits(3, 3);
            var shouldJump = false;

            switch (condition)
            {
            case 0b000: shouldJump = !cpu.Registers.Zero; break;

            case 0b001: shouldJump = cpu.Registers.Zero; break;

            case 0b010: shouldJump = !cpu.Registers.Carry; break;

            case 0b011: shouldJump = cpu.Registers.Carry; break;

            case 0b100: shouldJump = !cpu.Registers.ParityOrOverflow; break;

            case 0b101: shouldJump = cpu.Registers.ParityOrOverflow; break;

            case 0b110: shouldJump = !cpu.Registers.Sign; break;

            case 0b111: shouldJump = cpu.Registers.Sign; break;

            default: throw new InvalidOperationException();
            }

            if (shouldJump)
            {
                cpu.Registers.PC = Utilities.LETo16Bit(instruction[1], instruction[2]);
            }
            return(10);
        }
Esempio n. 6
0
        private static void SubBytes(IZ80CPU cpu, byte a, byte b, bool useCarryFlag = false)
        {
            var carryFlagValue = ((byte)(useCarryFlag ? 1 : 0)).TwosComplement();

            b = b.TwosComplement();
            AddMultipleBytesAndSetConditionBits(cpu, true, a, b, carryFlagValue);
        }
Esempio n. 7
0
        public static int ADD_IY_pp(IZ80CPU cpu, byte[] instruction)
        {
            cpu.InsertWaitMachineCycle(4);
            ushort val = 0;

            switch (instruction[1])
            {
            case 0x09: val = cpu.Registers.BC; break;

            case 0x19: val = cpu.Registers.DE; break;

            case 0x29: val = cpu.Registers.IY; break;

            case 0x39: val = cpu.Registers.SP; break;

            default: throw new InvalidOperationException();
            }

            var upperReg = val.GetUpperByte();
            var upperIY  = cpu.Registers.IXUpper;

            cpu.Registers.IY       += val;
            cpu.Registers.HalfCarry = upperIY.WillHalfCarry(upperReg);
            cpu.Registers.Subtract  = false;
            cpu.Registers.Carry     = upperIY.WillCarry(upperReg);

            cpu.InsertWaitMachineCycle(3);
            return(15);
        }
Esempio n. 8
0
        public static int CPDR(IZ80CPU cpu, byte[] instruction)
        {
            var data = cpu.ReadMemory(cpu.Registers.HL);
            var cmp  = cpu.Registers.A - data;

            cpu.Registers.HL--;
            cpu.Registers.BC--;

            cpu.Registers.Sign             = cmp < 0;
            cpu.Registers.Zero             = cmp == 0;
            cpu.Registers.HalfCarry        = cpu.Registers.A.WillHalfCarry(data);
            cpu.Registers.Subtract         = true;
            cpu.Registers.ParityOrOverflow = cpu.Registers.BC != 0;

            cpu.InsertWaitMachineCycle(5);

            if (cpu.Registers.Zero || cpu.Registers.BC == 0)
            {
                return(16);
            }

            cpu.Registers.PC -= 2;
            cpu.InsertWaitMachineCycle(5);
            return(21);
        }
Esempio n. 9
0
        public static int RET(IZ80CPU cpu, byte[] instruction)
        {
            cpu.Registers.PC = cpu.Registers.PC.SetLowerByte(cpu.PopByte());
            cpu.Registers.PC = cpu.Registers.PC.SetUpperByte(cpu.PopByte());

            return(10);
        }
Esempio n. 10
0
        public static int DJNZ_e(IZ80CPU cpu, byte[] instruction)
        {
            // FIXME: The opcode fetch has the tick after it, then the memory read for the operand
            cpu.ControlLines.SystemClock.Tick();

            cpu.Registers.B--;

            if (cpu.Registers.B == 0)
            {
                return(8);
            }

            var offset = (int)instruction[1];

            offset += 2;

            if (offset < 0)
            {
                cpu.Registers.PC -= (ushort)Math.Abs(offset);
            }
            else
            {
                cpu.Registers.PC += (ushort)offset;
            }

            cpu.InsertWaitMachineCycle(5);
            return(13);
        }
Esempio n. 11
0
        public static int CALL_nn(IZ80CPU cpu, byte[] instruction)
        {
            cpu.PushWord(cpu.Registers.PC, 1);
            cpu.Registers.PC = Utilities.LETo16Bit(instruction[1], instruction[2]);

            return(17);
        }
Esempio n. 12
0
        public static int POP_IY(IZ80CPU cpu, byte[] instruction)
        {
            cpu.Registers.IYLower = cpu.PopByte();
            cpu.Registers.IYUpper = cpu.PopByte();

            return(14);
        }
Esempio n. 13
0
 private static byte RotateByteLeft(IZ80CPU cpu, byte val)
 {
     cpu.Registers.HalfCarry = false;
     cpu.Registers.Subtract  = false;
     cpu.Registers.Carry     = cpu.Registers.A.GetBit(7);
     return((byte)((cpu.Registers.A << 1) | (cpu.Registers.A.GetBitAsByte(7) >> 7)));
 }
Esempio n. 14
0
        public static int LD_IY_plus_d_mem_n(IZ80CPU cpu, byte[] instruction)
        {
            cpu.ControlLines.SystemClock.TickMultiple(2);
            cpu.WriteMemory(cpu.Registers.IX.CalculateIndex(instruction[2]), instruction[3]);

            return(19);
        }
Esempio n. 15
0
        public static int DEC_IX(IZ80CPU cpu, byte[] instruction)
        {
            cpu.ControlLines.SystemClock.TickMultiple(2);
            cpu.Registers.IX--;

            return(10);
        }
Esempio n. 16
0
        public static int LD_nn_mem_A(IZ80CPU cpu, byte[] instruction)
        {
            var addr = Utilities.LETo16Bit(instruction[1], instruction[2]);

            cpu.WriteMemory(addr, cpu.Registers.A);
            return(13);
        }
Esempio n. 17
0
        public static int LD_A_nn_mem(IZ80CPU cpu, byte[] instruction)
        {
            var addr = Utilities.LETo16Bit(instruction[1], instruction[2]);

            cpu.Registers.A = cpu.ReadMemory(addr);
            return(13);
        }
Esempio n. 18
0
        public static int EI(IZ80CPU cpu, byte[] instruction)
        {
            cpu.Registers.IFF1 = true;
            cpu.Registers.IFF2 = true;

            return(4);
        }
Esempio n. 19
0
        public static int LD_SP_IY(IZ80CPU cpu, byte[] instruction)
        {
            cpu.ControlLines.SystemClock.TickMultiple(2);

            cpu.Registers.SP = cpu.Registers.IY;
            return(10);
        }
Esempio n. 20
0
        public static int LD_r_n(IZ80CPU cpu, byte[] instruction)
        {
            var dst = instruction[0].ExtractBits(3, 3);

            WriteByteToCpuRegister(cpu, dst, instruction[1]);

            return(7);
        }
Esempio n. 21
0
        public static int RST_p(IZ80CPU cpu, byte[] instruction)
        {
            cpu.ControlLines.SystemClock.Tick();
            cpu.PushWord(cpu.Registers.PC);
            cpu.Registers.PC = (ushort)(instruction[0].ExtractBits(3, 3) * 8);

            return(11);
        }
Esempio n. 22
0
        public static int LD_HL_nn_mem(IZ80CPU cpu, byte[] instruction)
        {
            var nn = Utilities.LETo16Bit(instruction[1], instruction[2]);

            cpu.Registers.HL = cpu.ReadWord(nn);

            return(16);
        }
Esempio n. 23
0
        public static int LD_IY_nn(IZ80CPU cpu, byte[] instruction)
        {
            var nn = Utilities.LETo16Bit(instruction[2], instruction[3]);

            cpu.Registers.IY = nn;

            return(14);
        }
Esempio n. 24
0
        public static int LD_R_A(IZ80CPU cpu, byte[] instruction)
        {
            cpu.ControlLines.SystemClock.Tick();

            cpu.Registers.R = cpu.Registers.A;

            return(9);
        }
Esempio n. 25
0
        public static int RETI(IZ80CPU cpu, byte[] instruction)
        {
            cpu.Registers.PC = cpu.Registers.PC.SetLowerByte(cpu.PopByte());
            cpu.Registers.PC = cpu.Registers.PC.SetUpperByte(cpu.PopByte());

            cpu.InterruptsBeingServiced.Pop();
            return(14);
        }
Esempio n. 26
0
        public static int LD_nn_mem_IY(IZ80CPU cpu, byte[] instruction)
        {
            var addr = Utilities.LETo16Bit(instruction[2], instruction[3]);

            cpu.WriteWord(addr, cpu.Registers.IY);

            return(20);
        }
Esempio n. 27
0
        public static int ADC_A_n(IZ80CPU cpu, byte[] instruction)
        {
            var data = instruction[1];

            AddBytes(cpu, cpu.Registers.A, data, true);

            return(7);
        }
Esempio n. 28
0
        public static int ADC_A_HL_mem(IZ80CPU cpu, byte[] instruction)
        {
            var data = cpu.ReadMemory(cpu.Registers.HL);

            AddBytes(cpu, cpu.Registers.A, data, true);

            return(7);
        }
Esempio n. 29
0
        public static int LD_nn_mem_HL(IZ80CPU cpu, byte[] instruction)
        {
            var addr = Utilities.LETo16Bit(instruction[1], instruction[2]);

            cpu.WriteWord(addr, cpu.Registers.HL);

            return(16);
        }
Esempio n. 30
0
        public static int SCF(IZ80CPU cpu, byte[] instruction)
        {
            cpu.Registers.HalfCarry = false;
            cpu.Registers.Subtract  = false;
            cpu.Registers.Carry     = true;

            return(4);
        }