public static ushort GetInstructionValue(Cpu8086 cpu, OpCodeManager.OpCodeFlag flag, Register segmentPrefix, int instruction, int instructionValue, int instructionDisplacement)
        {
            switch (instruction)
            {
            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:
                return(cpu.GetRegister((Register)instruction));

            case OpCodeManager.ARG_BYTE_REGISTER:
                return(cpu.GetRegisterU8((Register)instructionValue));

            case OpCodeManager.ARG_DEREFERENCE:
            case OpCodeManager.ARG_MEMORY:
                var address = GetInstructionRealAddress(cpu, segmentPrefix, instruction, instructionValue, instructionDisplacement);
                return(flag.Has(OpCodeManager.OpCodeFlag.Size8) ? cpu.ReadU8(address) : cpu.ReadU16(address));

            case OpCodeManager.ARG_CONSTANT:
                return((ushort)instructionValue);

            default:
                throw new NotImplementedException();
            }
        }
 public static void CalculateSubFlags(Cpu8086 cpu, OpCodeManager.OpCodeFlag flag, ushort value1, ushort value2, int result)
 {
     if (flag.Has(OpCodeManager.OpCodeFlag.Size8))
     {
         CalculateSubFlags8Bit(cpu, (byte)value1, (byte)value2, result);
     }
     else
     {
         CalculateSubFlags16Bit(cpu, value1, value2, result);
     }
 }
        public static void CalculateBitwiseFlags16Bit(Cpu8086 cpu, ushort value1, ushort value2, int result)
        {
            var truncResult = (ushort)result;
            var sign        = ((truncResult >> 15) & 1) == 1;
            var zero        = truncResult == 0;
            var parity      = ParityLookup[(byte)(result & 0xFF)];

            cpu.Flags &= ~(FlagsRegister.Carry | FlagsRegister.Parity | FlagsRegister.Zero | FlagsRegister.Sign | FlagsRegister.Overflow);
            cpu.Flags |= (parity ? FlagsRegister.Parity : 0) |
                         (zero ? FlagsRegister.Zero : 0) |
                         (sign ? FlagsRegister.Sign : 0);
        }
        public static ushort GetInstructionAddress(Cpu8086 cpu, int instruction, int instructionValue, int instructionDisplacement)
        {
            switch (instruction)
            {
            case OpCodeManager.ARG_DEREFERENCE:
                ushort address;
                switch (instructionValue)
                {
                case 0:
                    address = (ushort)(cpu.GetRegister(Register.BX) + cpu.GetRegister(Register.SI));
                    break;

                case 1:
                    address = (ushort)(cpu.GetRegister(Register.BX) + cpu.GetRegister(Register.DI));
                    break;

                case 2:
                    address = (ushort)(cpu.GetRegister(Register.BP) + cpu.GetRegister(Register.SI));
                    break;

                case 3:
                    address = (ushort)(cpu.GetRegister(Register.BP) + cpu.GetRegister(Register.DI));
                    break;

                case 4:
                    address = cpu.GetRegister(Register.SI);
                    break;

                case 5:
                    address = cpu.GetRegister(Register.DI);
                    break;

                case 6:
                    address = cpu.GetRegister(Register.BP);
                    break;

                case 7:
                    address = cpu.GetRegister(Register.BX);
                    break;

                default:
                    throw new NotImplementedException();
                }
                return((ushort)(address + instructionDisplacement));

            case OpCodeManager.ARG_MEMORY:
                return((ushort)instructionValue);

            default:
                throw new NotImplementedException();
            }
        }
        public static void CalculateDecFlags16Bit(Cpu8086 cpu, ushort value1, ushort value2, int result)
        {
            var truncResult = (ushort)result;
            var sign        = ((truncResult >> 15) & 1) == 1;
            var overflow    = ((truncResult ^ value1) & (value1 ^ value2) & 0x8000) == 0x8000;
            var auxiliary   = ((value1 ^ value2 ^ truncResult) & 0x10) != 0;
            var zero        = truncResult == 0;
            var parity      = ParityLookup[(byte)(result & 0xFF)];

            cpu.Flags &= ~(FlagsRegister.Parity | FlagsRegister.Auxiliary | FlagsRegister.Zero | FlagsRegister.Sign | FlagsRegister.Overflow);
            cpu.Flags |= (parity ? FlagsRegister.Parity : 0) |
                         (auxiliary ? FlagsRegister.Auxiliary : 0) |
                         (zero ? FlagsRegister.Zero : 0) |
                         (sign ? FlagsRegister.Sign : 0) |
                         (overflow ? FlagsRegister.Overflow : 0);
        }
        public static void CalculateAddFlags8Bit(Cpu8086 cpu, byte value1, byte value2, int result)
        {
            var truncResult = (byte)result;
            var carry       = (uint)result > 0xFF;
            var sign        = ((truncResult >> 7) & 1) == 1;
            var overflow    = ((truncResult ^ value1) & (truncResult ^ value2) & 0x80) == 0x80;
            var auxiliary   = ((value1 ^ value2 ^ truncResult) & 0x10) != 0;
            var zero        = truncResult == 0;
            var parity      = ParityLookup[(byte)(result & 0xFF)];

            cpu.Flags &= ~(FlagsRegister.Carry | FlagsRegister.Parity | FlagsRegister.Auxiliary | FlagsRegister.Zero | FlagsRegister.Sign | FlagsRegister.Overflow);
            cpu.Flags |= (carry ? FlagsRegister.Carry : 0) |
                         (parity ? FlagsRegister.Parity : 0) |
                         (auxiliary ? FlagsRegister.Auxiliary : 0) |
                         (zero ? FlagsRegister.Zero : 0) |
                         (sign ? FlagsRegister.Sign : 0) |
                         (overflow ? FlagsRegister.Overflow : 0);
        }
        public static uint GetInstructionRealAddress(Cpu8086 cpu, Register segmentPrefix, int instruction, int instructionValue, int instructionDisplacement)
        {
            switch (instruction)
            {
            case OpCodeManager.ARG_DEREFERENCE:
                if (segmentPrefix == Register.Invalid)
                {
                    segmentPrefix = instructionValue == 6 ? Register.SS : Register.DS;     // BP needs SS segment
                }
                var addr = GetInstructionAddress(cpu, instruction, instructionValue, instructionDisplacement);
                return(SegmentToAddress(cpu.GetRegister(segmentPrefix), addr));

            case OpCodeManager.ARG_MEMORY:
                if (segmentPrefix == Register.Invalid)
                {
                    segmentPrefix = Register.DS;
                }
                var address = GetInstructionAddress(cpu, instruction, instructionValue, instructionDisplacement);
                return(SegmentToAddress(cpu.GetRegister(segmentPrefix), address));

            default:
                throw new NotImplementedException();
            }
        }
Beispiel #8
0
 public Fetcher8086(Cpu8086 cpu)
 {
     _cpu     = cpu;
     _fetched = 0;
 }