예제 #1
0
파일: BCD.cs 프로젝트: cryogen/VM86CS
        public void DecimalAdjustAfterAddition()
        {
            Operand tempOp = new Operand();

            if (((AL & 0xf) > 9) || AF)
            {
                bool carry = false;

                var temp = (ushort)(AL + 6);
                if (temp > byte.MaxValue)
                    carry = true;

                CF = (CF | carry);

                AF = true;
                AL += 6;
            }
            else
                AF = false;

            if (((AL & 0xf0) > 0x90) || CF)
            {
                AL += 0x60;
                CF = true;
            }
            else
                CF = false;

            tempOp.Size = 8;
            tempOp.Value = AL;
            SetCPUFlags(tempOp);
        }
예제 #2
0
파일: Logic.cs 프로젝트: cryogen/VM86CS
        private void SetCPUFlags(Operand operand)
        {
            SF = operand.MSB;

            ZF = operand.Value == 0;
            PF = (((((byte)operand.Value * 0x0101010101010101UL) & 0x8040201008040201UL) % 0x1FF) & 1) == 0;
        }
예제 #3
0
파일: CPU.cs 프로젝트: cryogen/VM86CS
        public CPU()
        {
            PMode = false;
            segments = new Segment[6];
            registers = new Register[9];
            controlRegisters = new uint[5];
            idtRegister = new TableRegister();
            gdtRegister = new TableRegister();
            disasm = new Disassembler(DisassemblerRead);

            disasm.CodeSize = codeSize;
            ProcessOperations();
            realModeEntry = new GDTEntry
                                {
                                    BaseAddress = 0,
                                    Is32Bit = false,
                                    IsAccessed = true,
                                    IsCode = false,
                                    Limit = 0xffff,
                                    IsWritable = true
                                };

            Halted = false;

            interruptOperand = new Operand();
            interruptOperand.Size = 8;
            interruptOperand.Type = OperandType.Immediate;

            Reset();
        }
예제 #4
0
        public void CallFarMemory(Operand dest)
        {
            dest.Value = SegRead(dest.Memory.Segment, dest.Memory.Address + 2, 16);
            dest.Address = SegRead(dest.Memory.Segment, dest.Memory.Address, (int)dest.Size);

            CallFar(dest);
        }
예제 #5
0
파일: BitByte.cs 프로젝트: cryogen/VM86CS
 public void Test(Operand dest, Operand source)
 {
     dest.Value = dest.Value & source.Value;
     SetCPUFlags(dest);
     CF = false;
     OF = false;
 }
예제 #6
0
파일: Strings.cs 프로젝트: cryogen/VM86CS
        public void StringIOWrite(Operand dest, Operand source)
        {
            uint count = GetCount();
            int size = (int)(source.Size / 8);

            while (count > 0)
            {
                uint addr;

                if (addressSize == 32)
                    addr = ESI;
                else
                    addr = SI;

                uint value = SegRead(source.Memory.Segment, addr, (int)source.Size);
                IOWrite((ushort)dest.Value, value, (int)source.Size);
                if (DF)
                {
                    if (addressSize == 32)
                        ESI = (uint)(ESI - size);
                    else
                        SI = (ushort)(SI - size);
                }
                else
                {
                    if (addressSize == 32)
                        ESI = (uint)(ESI + size);
                    else
                        SI = (ushort)(SI + size);
                }

                count--;
            }
            SetCount(count);
        }
예제 #7
0
파일: Strings.cs 프로젝트: cryogen/VM86CS
        public void StringIORead(Operand dest, Operand source)
        {
            uint count = GetCount();
            int size = (int)(dest.Size / 8);

            while (count > 0)
            {
                uint addr;

                if (addressSize == 32)
                    addr = EDI;
                else
                    addr = DI;

                uint value = IORead((ushort)source.Value, (int)dest.Size);
                SegWrite(SegmentRegister.ES, addr, value, (int)dest.Size);
                if (DF)
                {
                    if (addressSize == 32)
                        EDI = (uint)(EDI - size);
                    else
                        DI = (ushort)(DI - size);
                }
                else
                {
                    if (addressSize == 32)
                        EDI = (uint)(EDI + size);
                    else
                        DI = (ushort)(DI + size);
                }

                count--;
            }
            SetCount(count);
        }
예제 #8
0
        public void RotateCarryRight(Operand dest, Operand source)
        {
            byte tempCount;
            byte tempCF;

            switch (dest.Size)
            {
                case 8:
                    tempCount = (byte)((source.Value & 0x1f) % 9);
                    break;
                case 16:
                    tempCount = (byte)((source.Value & 0x1f) % 17);
                    break;
                default:
                    tempCount = (byte)((source.Value & 0x1f));
                    break;
            }

            if(source.Value == 1)
                OF = dest.MSB ^ CF;

            while (tempCount != 0)
            {
                tempCF = (byte)(dest.Value & 0x1);
                dest.Value = (uint)((dest.Value / 2) + ((CF ? 1 : 0) << (int)(dest.Size - 1)));
                CF = tempCF != 0;
                tempCount--;
            }

            SetCPUFlags(dest);
            WriteOperand(dest);
        }
예제 #9
0
        public void DoIOWrite(Operand dest, Operand source)
        {
            WriteCallback ioWrite = IOWrite;

            if (ioWrite != null)
                ioWrite((ushort)dest.Value, source.Value, (int)source.Size);
        }
예제 #10
0
파일: Logic.cs 프로젝트: cryogen/VM86CS
 public void Or(Operand dest, Operand source)
 {
     dest.Value = dest.Value | source.Value;
     SetCPUFlags(dest);
     CF = false;
     OF = false;
     WriteOperand(dest);
 }
예제 #11
0
        public void SegmentLoadDS(Operand dest, Operand source)
        {
            ushort segment;
            uint offset;

            GetSegmentAndOffset(source, out segment, out offset);
            DS = segment;
            dest.Value = offset;

            WriteOperand(dest);
        }
예제 #12
0
        public void Exchange(Operand dest, Operand source)
        {
            Operand temp;

            temp = dest;
            dest.Value = source.Value;
            source.Value = temp.Value;

            WriteOperand(source);
            WriteOperand(dest);
        }
예제 #13
0
        public void DoIORead(Operand dest, Operand source)
        {
            ReadCallback ioRead = IORead;

            if (ioRead != null)
                dest.Value = ioRead((ushort)source.Value, (int)dest.Size);
            else
                dest.Value = 0;

            WriteOperand(dest);
        }
예제 #14
0
파일: System.cs 프로젝트: cryogen/VM86CS
 public void LoadIDT(Operand dest)
 {
     if (opSize == 16)
     {
         idtRegister.Limit = SegReadWord(dest.Memory.Segment, dest.Memory.Address);
         idtRegister.Base = SegReadDWord(dest.Memory.Segment, dest.Memory.Address + 2) & 0x00ffffff;
     }
     else
     {
         idtRegister.Limit = SegReadWord(dest.Memory.Segment, dest.Memory.Address);
         idtRegister.Base = SegReadDWord(dest.Memory.Segment, dest.Memory.Address + 2);
     }
 }
예제 #15
0
 public void Call(Operand dest)
 {
     if (opSize == 32)
     {
         StackPush(EIP);
         EIP = (uint)(EIP + dest.SignedValue);
     }
     else
     {
         StackPush((ushort)EIP);
         EIP = (ushort)(EIP + dest.SignedValue);
     }
 }
예제 #16
0
        public void Decrement(Operand dest)
        {
            Operand result = dest;

            result.Value--;
            SetCPUFlags(result);
            if ((1 > 0 && dest.SignedValue < dest.SignedMin + 1))
                OF = true;
            else
                OF = false;

            WriteOperand(result);
        }
예제 #17
0
 public void CallAbsolute(Operand dest)
 {
     if (opSize == 16)
     {
         StackPush(IP);
         EIP = (ushort)dest.Value;
     }
     else
     {
         StackPush(EIP);
         EIP = dest.Value;
     }
 }
예제 #18
0
파일: System.cs 프로젝트: cryogen/VM86CS
 public void StoreIDT(Operand dest)
 {
     if (opSize == 16)
     {
         SegWriteWord(dest.Memory.Segment, dest.Memory.Address, idtRegister.Limit);
         SegWriteDWord(dest.Memory.Segment, dest.Memory.Address + 2, idtRegister.Base & 0x00ffffff);
     }
     else
     {
         SegWriteWord(dest.Memory.Segment, dest.Memory.Address, idtRegister.Limit);
         SegWriteDWord(dest.Memory.Segment, dest.Memory.Address + 2, idtRegister.Base);
     }
 }
예제 #19
0
        public void Compare(Operand dest, Operand source)
        {
            Operand result = dest;

            result.Value = dest.Value - source.Value;
            SetCPUFlags(result);

            if ((source.SignedValue > 0 && dest.SignedValue < dest.SignedMin + source.SignedValue) ||
                (source.SignedValue < 0 && dest.SignedValue > dest.SignedMax + source.SignedValue))
                OF = true;
            else
                OF = false;

            CF = dest.Value < source.Value;
        }
예제 #20
0
        public void Add(Operand dest, Operand source)
        {
            Operand result = dest;

            result.Value = dest.Value + source.Value;
            SetCPUFlags(result);
            CF = result.Value < dest.Value;
            if (((source.SignedValue > 0) && (dest.SignedValue > (dest.SignedMax - source.SignedValue))) ||
                ((source.SignedValue < 0) && (dest.SignedValue < (dest.SignedMin - source.SignedValue))))
                OF = true;
            else
                OF = false;

            WriteOperand(result);
        }
예제 #21
0
파일: BCD.cs 프로젝트: cryogen/VM86CS
        public void ASCIIAdjustBeforeDivide(Operand source)
        {
            byte tempAL = AL;
            byte tempAH = AH;
            Operand tmp = new Operand();

            tmp.Size = 8;

            AL = (byte)((tempAL + (tempAH * source.Value)) & 0xff);
            AH = 0;

            tmp.Value = AL;

            SetCPUFlags(tmp);
        }
예제 #22
0
파일: BCD.cs 프로젝트: cryogen/VM86CS
        public void ASCIIAdjustAfterMultiply(Operand source)
        {
            Operand temp = new Operand();

            if (source.Value == 0)
                throw new Exception("Divide Error");

            byte tempAL = AL;
            AH = (byte)(tempAL / source.Value);
            AL = (byte)(tempAL % source.Value);

            temp.Size = 16;
            temp.Value = AH;

            SetCPUFlags(temp);
        }
예제 #23
0
        public void Enter(Operand size, Operand nesting)
        {
            byte nestingLevel = (byte)(nesting.Value % 32);
            uint frameTemp;

            if (opSize == 32)
            {
                StackPush(EBP);
                frameTemp = ESP;
            }
            else
            {
                StackPush(BP);
                frameTemp = SP;
            }

            if (nestingLevel > 0)
            {
                for (int i = 1; i < nestingLevel - 1; i++)
                {
                    if (opSize == 32)
                    {
                        EBP -= 4;
                        StackPush(EBP);
                    }
                    else
                    {
                        BP -= 2;
                        StackPush(BP);
                    }
                }
                StackPush(frameTemp);
            }

            if (opSize == 32)
            {
                EBP = frameTemp;
                ESP = EBP - size.Value;
            }
            else
            {
                BP = (ushort)frameTemp;
                SP = (ushort)(BP - size.Value);
            }
        }
예제 #24
0
        public void FarJump(Operand dest)
        {
            uint segment, offset;

            if (PMode == false && ((CR0 & 0x1) == 0x1))
                PMode = true;
            else if (PMode && ((CR0 & 0x1) == 0))
                PMode = false;

            segment = dest.Value;
            offset = (uint)dest.Address;

            CS = segment;
            if (opSize == 32)
                EIP = offset;
            else
                EIP = (ushort)offset;
        }
예제 #25
0
파일: Misc.cs 프로젝트: cryogen/VM86CS
 public void CpuID(Operand source)
 {
     switch (source.Value)
     {
         case 0:
             EAX = 2;
             EBX = 0x756e6547; /* "Genu" */
             EDX = 0x49656e69; /* "ineI" */
             ECX = 0x6c65746e; /* "ntel" */
             break;
         case 1:
             EAX = 0x0610;     /* Pentium Pro (ish) */
             EDX = 0x3ce4787; /* support some stuff, other stuff not so much (i will comment or move this to enums at some point)*/
             break;
         default:
             System.Diagnostics.Debugger.Break();
             break;
     }
 }
예제 #26
0
        public void AddWithCarry(Operand dest, Operand source)
        {
            Operand result = dest;
            ulong tmp;

            tmp = dest.Value + source.Value;
            if (CF)
                tmp++;

            result.Value = (uint)tmp;
            SetCPUFlags(result);
            if (((source.SignedValue > 0) && (dest.SignedValue > (dest.SignedMax - source.SignedValue))) ||
                ((source.SignedValue < 0) && (dest.SignedValue < (dest.SignedMin - source.SignedValue))))
                OF = true;
            else
                OF = false;
            CF = result.Value < tmp;

            WriteOperand(result);
        }
예제 #27
0
파일: BitByte.cs 프로젝트: cryogen/VM86CS
        public void BitScanReverse(Operand dest, Operand source)
        {
            uint temp;

            if (source.Value == 0)
            {
                ZF = true;
            }
            else
            {
                ZF = false;
                temp = dest.Size - 1;

                while ((source.Value & ((1 << (int)temp))) == 0)
                {
                    temp--;
                }
                dest.Value = temp;
            }
            WriteOperand(dest);
        }
예제 #28
0
파일: BitByte.cs 프로젝트: cryogen/VM86CS
        public void BitScanForward(Operand dest, Operand source)
        {
            uint temp;

            if (source.Value == 0)
            {
                ZF = true;
            }
            else
            {
                ZF = false;
                temp = 0;

                while ((source.Value & ((1 << (int)temp))) == 0)
                {
                    temp++;
                }
                dest.Value = temp;
            }
            WriteOperand(dest);
        }
예제 #29
0
        public void CallFar(Operand dest)
        {
            uint segment, offset;

            segment = dest.Value;
            offset = (uint)dest.Address;

            if (opSize == 16)
            {
                StackPush(CS);
                StackPush(IP);
                CS = segment;
                EIP = (ushort)offset;
            }
            else
            {
                StackPush(CS);
                StackPush(EIP);
                CS = segment;
                EIP = offset;
            }
        }
예제 #30
0
 public void Pop(Operand dest)
 {
     dest.Value = StackPop();
     WriteOperand(dest);
 }