示例#1
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement);
            var memory  = cpu.ReadU16(address);
            var segment = cpu.ReadU16(address + 2);

            cpu.SetRegister(_register, segment);
            switch ((Register)instruction.Argument1)
            {
            case Register.AX:
            case Register.CX:
            case Register.DX:
            case Register.BX:
            case Register.SP:
            case Register.BP:
            case Register.SI:
            case Register.DI:
            case Register.IP:
            case Register.CS:
            case Register.DS:
            case Register.ES:
            case Register.SS:
                cpu.SetRegister((Register)instruction.Argument1, memory);
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#2
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            var prefix = instruction.SegmentPrefix;

            if (prefix == Register.Invalid)
            {
                prefix = Register.DS;
            }
            var sourceAddress = InstructionHelper.SegmentToAddress(cpu.GetRegister(prefix), cpu.GetRegister(Register.SI));

            byte size;

            if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8))
            {
                cpu.SetRegisterU8(Register.AL, cpu.ReadU8(sourceAddress));
                size = 1;
            }
            else
            {
                cpu.SetRegister(Register.AX, cpu.ReadU16(sourceAddress));
                size = 2;
            }

            if (!cpu.GetFlags().Has(FlagsRegister.Direction))
            {
                cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) + size));
            }
            else
            {
                cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) - size));
            }
        }
示例#3
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            ushort value1;
            ushort value2;
            byte   size;

            if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8))
            {
                value1 = cpu.GetRegisterU8(Register.AL);
                value2 = cpu.ReadU8(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI)));
                size   = 1;
            }
            else
            {
                value1 = cpu.GetRegister(Register.AX);
                value2 = cpu.ReadU16(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI)));
                size   = 2;
            }
            var result = value1 - value2;

            InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, value1, value2, result);

            if (!cpu.GetFlags().Has(FlagsRegister.Direction))
            {
                cpu.IncRegister(Register.DI, size);
            }
            else
            {
                cpu.DecRegister(Register.DI, size);
            }
        }
示例#4
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            switch (instruction.Argument1)
            {
            case (int)Register.SP:
            // 8086 has a bug where it pushes SP after it has been modified
            // cpu.registers[(int)Register.SP] -= 2;
            // cpu.WriteU16(SegmentToAddress(cpu.GetRegister(Register.SS), cpu.GetRegister(Register.SP)), cpu.GetRegister(Register.SP));
            // break;
            case (int)Register.AX:
            case (int)Register.CX:
            case (int)Register.DX:
            case (int)Register.BX:
            case (int)Register.BP:
            case (int)Register.SI:
            case (int)Register.DI:
            case (int)Register.IP:
            case (int)Register.CS:
            case (int)Register.DS:
            case (int)Register.ES:
            case (int)Register.SS:
            case unchecked ((int)Register.FLAGS):
                cpu.Push(cpu.GetRegister((Register)instruction.Argument1));
                break;

            case OpCodeManager.ARG_DEREFERENCE:
            case OpCodeManager.ARG_MEMORY:
                var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement);
                cpu.Push(cpu.ReadU16(address));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#5
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            switch (instruction.Argument1)
            {
            case OpCodeManager.ARG_FAR_MEMORY:
                cpu.SetRegister(Register.CS, (ushort)((uint)instruction.Argument1Value >> 16));
                cpu.SetRegister(Register.IP, (ushort)(instruction.Argument1Value & 0xFFFF));
                break;

            case OpCodeManager.ARG_DEREFERENCE:
            case OpCodeManager.ARG_MEMORY:
                var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument1, instruction.Argument1Value, instruction.Argument1Displacement);
                cpu.SetRegister(Register.CS, cpu.ReadU16(address + 2));
                cpu.SetRegister(Register.IP, cpu.ReadU16(address));
                break;

            default:
                throw new InvalidOperationException();
            }
        }
示例#6
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            var segment = Register.DS;

            if (instruction.SegmentPrefix != Register.Invalid)
            {
                segment = instruction.SegmentPrefix;
            }

            ushort value1;
            ushort value2;
            byte   size;

            if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8))
            {
                value1 = cpu.ReadU8(InstructionHelper.SegmentToAddress(cpu.GetRegister(segment), cpu.GetRegister(Register.SI)));
                value2 = cpu.ReadU8(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI)));
                size   = 1;
            }
            else
            {
                value1 = cpu.ReadU16(InstructionHelper.SegmentToAddress(cpu.GetRegister(segment), cpu.GetRegister(Register.SI)));
                value2 = cpu.ReadU16(InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI)));
                size   = 2;
            }
            var result = value1 - value2;

            InstructionHelper.CalculateSubFlags(cpu, instruction.Flag, value1, value2, result);

            if (!cpu.GetFlags().Has(FlagsRegister.Direction))
            {
                cpu.SetRegister(Register.DI, (ushort)(cpu.GetRegister(Register.DI) + size));
                cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) + size));
            }
            else
            {
                cpu.SetRegister(Register.DI, (ushort)(cpu.GetRegister(Register.DI) - size));
                cpu.SetRegister(Register.SI, (ushort)(cpu.GetRegister(Register.SI) - size));
            }
        }
示例#7
0
        private ushort ProcessExchangeSecond(Cpu8086 cpu, OpCodeManager.Instruction instruction, ushort value)
        {
            ushort tmp;

            switch (instruction.Argument2)
            {
            case (int)Register.AX:
            case (int)Register.CX:
            case (int)Register.DX:
            case (int)Register.BX:
            case (int)Register.SP:
            case (int)Register.BP:
            case (int)Register.SI:
            case (int)Register.DI:
            case (int)Register.IP:
            case (int)Register.CS:
            case (int)Register.DS:
            case (int)Register.ES:
            case (int)Register.SS:
                tmp = cpu.GetRegister((Register)instruction.Argument2);
                cpu.SetRegister((Register)instruction.Argument2, (byte)value);
                break;

            case OpCodeManager.ARG_BYTE_REGISTER:
                tmp = cpu.GetRegisterU8((Register)instruction.Argument2Value);
                cpu.SetRegisterU8((Register)instruction.Argument2Value, (byte)value);
                break;

            case OpCodeManager.ARG_DEREFERENCE:
            case OpCodeManager.ARG_MEMORY:
                var address = InstructionHelper.GetInstructionRealAddress(cpu, instruction.SegmentPrefix, instruction.Argument2, instruction.Argument2Value, instruction.Argument2Displacement);
                tmp = cpu.ReadU16(address);
                cpu.WriteU16(address, value);
                break;

            default:
                throw new NotImplementedException();
            }
            return(tmp);
        }
示例#8
0
        public void Dispatch(Cpu8086 cpu, OpCodeManager.Instruction instruction)
        {
            var segment = Register.DS;

            if (instruction.SegmentPrefix != Register.Invalid)
            {
                segment = instruction.SegmentPrefix;
            }

            var  sourceAddress = InstructionHelper.SegmentToAddress(cpu.GetRegister(segment), cpu.GetRegister(Register.SI));
            var  destAddress   = InstructionHelper.SegmentToAddress(cpu.GetRegister(Register.ES), cpu.GetRegister(Register.DI));
            byte size;

            if (instruction.Flag.Has(OpCodeManager.OpCodeFlag.Size8))
            {
                var value = cpu.ReadU8(sourceAddress);
                cpu.WriteU8(destAddress, value);
                size = 1;
            }
            else
            {
                var value = cpu.ReadU16(sourceAddress);
                cpu.WriteU16(destAddress, value);
                size = 2;
            }

            if (!cpu.GetFlags().Has(FlagsRegister.Direction))
            {
                cpu.IncRegister(Register.DI, size);
                cpu.IncRegister(Register.SI, size);
            }
            else
            {
                cpu.DecRegister(Register.DI, size);
                cpu.DecRegister(Register.SI, size);
            }
        }