Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        public static int SBC_HL_ss(IZ80CPU cpu, byte[] instruction)
        {
            var src  = instruction[0].ExtractBits(4, 2);
            var data = ReadWordFromCpuRegister_BC_DE_HL_SP(cpu, src);

            cpu.InsertWaitMachineCycle(4);

            AddWordsWithCarryAndSetConditionBits(cpu, true, data);

            cpu.InsertWaitMachineCycle(3);

            return(15);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        public static int ADD_A_IY_plus_d_mem(IZ80CPU cpu, byte[] instruction)
        {
            var data = cpu.ReadMemory(cpu.Registers.IY.CalculateIndex(instruction[2]), 2);

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

            cpu.InsertWaitMachineCycle(3);
            return(19);
        }
Exemplo n.º 6
0
        public static int CP_IX_plus_d_mem(IZ80CPU cpu, byte[] instruction)
        {
            var data = cpu.ReadMemory(cpu.Registers.IX.CalculateIndex(instruction[2]), 2);

            CompareBytes(cpu, data);

            cpu.InsertWaitMachineCycle(3);
            return(19);
        }
Exemplo n.º 7
0
        public static int ADD_HL_ss(IZ80CPU cpu, byte[] instruction)
        {
            var src  = instruction[0].ExtractBits(4, 2);
            var data = ReadWordFromCpuRegister_BC_DE_HL_SP(cpu, src);

            cpu.InsertWaitMachineCycle(4);

            var upperReg = data.GetUpperByte();
            var upperHL  = cpu.Registers.H;

            cpu.Registers.HL       += data;
            cpu.Registers.HalfCarry = upperHL.WillHalfCarry(upperReg);
            cpu.Registers.Subtract  = false;
            cpu.Registers.Carry     = upperHL.WillCarry(upperReg);

            cpu.InsertWaitMachineCycle(3);

            return(11);
        }
Exemplo n.º 8
0
        public static int LD_IY_plus_d_mem_r(IZ80CPU cpu, byte[] instruction)
        {
            cpu.InsertWaitMachineCycle(5);

            var src  = instruction[1].ExtractBits(0, 3);
            var data = ReadByteFromCpuRegister(cpu, src);

            cpu.WriteMemory(cpu.Registers.IY.CalculateIndex(instruction[2]), data);

            return(19);
        }
Exemplo n.º 9
0
        public static int LD_r_IY_plus_d_mem(IZ80CPU cpu, byte[] instruction)
        {
            cpu.InsertWaitMachineCycle(5);

            var dst  = instruction[0].ExtractBits(3, 3);
            var data = cpu.ReadMemory(cpu.Registers.IY.CalculateIndex(instruction[2]));

            WriteByteToCpuRegister(cpu, dst, data);

            return(19);
        }
Exemplo n.º 10
0
        public static int DEC_IY_plus_d_mem(IZ80CPU cpu, byte[] instruction)
        {
            cpu.InsertWaitMachineCycle(5);

            var addr = cpu.Registers.IY.CalculateIndex(instruction[2]);
            var data = cpu.ReadMemory(addr);

            data--;
            cpu.WriteMemory(addr, data, 1);

            DecrementByteSetConditionBits(cpu, data);

            return(23);
        }
Exemplo n.º 11
0
        public static int LDD(IZ80CPU cpu, byte[] instruction)
        {
            var data = cpu.ReadMemory(cpu.Registers.HL);

            cpu.WriteMemory(cpu.Registers.DE, data, waitAfter: 2);
            cpu.Registers.HL--;
            cpu.Registers.DE--;
            cpu.Registers.BC--;
            cpu.Registers.HalfCarry        = false;
            cpu.Registers.ParityOrOverflow = cpu.Registers.BC != 0;
            cpu.Registers.Subtract         = false;

            cpu.InsertWaitMachineCycle(5);
            return(16);
        }
Exemplo n.º 12
0
        public static int JR_e(IZ80CPU cpu, byte[] instruction)
        {
            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(12);
        }
Exemplo n.º 13
0
        public static int RRD(IZ80CPU cpu, byte[] instruction)
        {
            var data   = cpu.ReadMemory(cpu.Registers.HL);
            var lowerA = cpu.Registers.A.GetLowerNibble();
            var acc    = cpu.Registers.A.SetLowerNibble(data.GetLowerNibble());

            data = data.SetLowerNibble(data.GetUpperNibble());
            data = data.SetUpperNibble(lowerA);

            cpu.Registers.A                = acc;
            cpu.Registers.Sign             = acc.IsNegative();
            cpu.Registers.Zero             = acc == 0;
            cpu.Registers.HalfCarry        = false;
            cpu.Registers.ParityOrOverflow = acc.IsParityEven();
            cpu.Registers.Subtract         = false;

            cpu.InsertWaitMachineCycle(4);
            cpu.WriteMemory(cpu.Registers.HL, data);

            return(18);
        }
Exemplo n.º 14
0
        public static int INDR(IZ80CPU cpu, byte[] instruction)
        {
            var portAddr = Utilities.LETo16Bit(cpu.Registers.C, cpu.Registers.B);
            var data     = cpu.ReadFromPort(portAddr, 1);

            cpu.WriteMemory(cpu.Registers.HL, data);
            cpu.Registers.B--;
            cpu.Registers.HL--;
            cpu.Registers.Zero     = true;
            cpu.Registers.Subtract = true;

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

            cpu.Registers.PC -= 2;
            cpu.InsertWaitMachineCycle(5);

            return(21);
        }
Exemplo n.º 15
0
        public static int JR_cc_e(IZ80CPU cpu, byte[] instruction)
        {
            var condition  = instruction[0].ExtractBits(3, 2);
            var shouldJump = false;

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

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

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

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

            default: throw new InvalidOperationException();
            }

            if (!shouldJump)
            {
                return(7);
            }

            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(12);
        }