예제 #1
0
        /// <summary>
        ///     Change Processor State.
        /// </summary>
        private void ARM_CPS()
        {
            ARMMode Mode = (ARMMode)(Opcode & 0x1f);
            bool    mmod = IsOpcodeBitSet(17);
            uint    imod = (Opcode >> 18) & 3;

            if ((imod & 2) != 0)
            {
                bool Value = (imod & 1) != 0;
                if (IsOpcodeBitSet(6))
                {
                    Registers.SetFlag(ARMFlag.FIQDisable, Value);
                }
                if (IsOpcodeBitSet(7))
                {
                    Registers.SetFlag(ARMFlag.IRQDisable, Value);
                }
                if (IsOpcodeBitSet(8))
                {
                    Registers.SetFlag(ARMFlag.AbortDisable, Value);
                }
            }
            else
            if (mmod)
            {
                Registers.Mode = Mode;
            }
        }
예제 #2
0
        /// <summary>
        ///     Store Multiple.
        /// </summary>
        private void ARM_STM()
        {
            ushort RegisterList = (ushort)(Opcode & 0xffff);
            int    Rn           = (int)((Opcode >> 16) & 0xf);
            bool   W            = IsOpcodeBitSet(21);
            bool   S            = IsOpcodeBitSet(22);
            bool   U            = IsOpcodeBitSet(23);
            bool   P            = IsOpcodeBitSet(24);

            uint Address;

            if (U)
            {
                Address = Registers[Rn] + (uint)(P ? 4 : 0);
            }
            else
            {
                Address = Registers[Rn] + (uint)(P ? 0 : 4);
                for (int Index = 0; Index < 16; Index++)
                {
                    if ((RegisterList & (1 << Index)) != 0)
                    {
                        Address -= 4;
                    }
                }
            }

            uint    Count   = 0;
            ARMMode OldMode = Registers.Mode;

            if (S)
            {
                Registers.Mode = ARMMode.User;
            }
            for (int Index = 0; Index < 16; Index++)
            {
                if ((RegisterList & (1 << Index)) != 0)
                {
                    WriteUInt32E(Address + Count, Registers[Index]);
                    Count += 4;
                }
            }
            Registers.Mode = OldMode;

            if (W)
            {
                if (U)
                {
                    Registers[Rn] += Count;
                }
                else
                {
                    Registers[Rn] -= Count;
                }
            }
        }
예제 #3
0
        /// <summary>
        ///     Store Return State.
        /// </summary>
        private void ARM_SRS()
        {
            uint Address = ARM_GetSRSAddress();

            ARMMode OldMode = Registers.Mode;

            Registers.Mode = (ARMMode)(Opcode & 0x1f);

            WriteUInt32E(Address, Registers[14]);
            WriteUInt32E(Address + 4, Registers.SPSR);

            Registers.Mode = OldMode;
        }
예제 #4
0
        /// <summary>
        ///     Load Multiple.
        /// </summary>
        private void ARM_LDM()
        {
            ushort RegisterList = (ushort)(Opcode & 0xffff);
            bool   PC           = (RegisterList & 0x8000) != 0;
            int    Rn           = (int)((Opcode >> 16) & 0xf);
            bool   W            = IsOpcodeBitSet(21);
            bool   S            = IsOpcodeBitSet(22);

            ARMMode OldMode = Registers.Mode;

            if (S && !PC)
            {
                Registers.Mode = ARMMode.User;
            }
            uint Address = ARM_GetLoadAndStoreMultipleAddress() & 0xfffffffc;

            for (int Index = 0; Index < 15; Index++)
            {
                if ((RegisterList & (1 << Index)) != 0)
                {
                    Registers[Index] = ReadUInt32E(Address);
                    Address         += 4;
                }
            }
            Registers.Mode = OldMode;

            if (PC)
            {
                uint Value = ReadUInt32E(Address);
                Registers[15] = Value & 0xfffffffe;
                Registers.SetFlag(ARMFlag.Thumb, (Value & 1) != 0);
                if (S)
                {
                    Registers.CPSR = Registers.SPSR;
                }
            }
        }
예제 #5
0
        /// <summary>
        ///     Gets the Address used for the general Load and Store instructions.
        /// </summary>
        /// <returns>The Base Address to Load or Store</returns>
        private uint ARM_GetLoadAndStoreAddress()
        {
            int  Rn = (int)((Opcode >> 16) & 0xf);
            bool W  = IsOpcodeBitSet(21);
            bool U  = IsOpcodeBitSet(23);
            bool P  = IsOpcodeBitSet(24);
            bool I  = IsOpcodeBitSet(25);

            ARMMode OldMode = Registers.Mode;

            if (!P && W)
            {
                Registers.Mode = ARMMode.User;
            }
            uint Offset = 0;

            if (I) //Register
            {
                int  Rm             = (int)(Opcode & 0xf);
                uint Shift          = (Opcode >> 5) & 3;
                int  ShiftImmediate = (int)((Opcode >> 7) & 0x1f);

                switch (Shift)
                {
                case 0: Offset = Registers[Rm] << ShiftImmediate; break;                           //LSL

                case 1: Offset = ShiftImmediate != 0 ? Registers[Rm] >> ShiftImmediate : 0; break; //LSR

                case 2:                                                                            //ASR
                    if (ShiftImmediate == 0)
                    {
                        Offset = (Registers[Rm] & 0x80000000) != 0 ? 0xffffffff : 0;
                    }
                    else
                    {
                        Offset = Registers[Rm] >> ShiftImmediate;
                    }
                    break;

                case 3:     //ROR
                    if (ShiftImmediate == 0)
                    {
                        Offset = (Registers[Rm] >> 1) | (Registers.IsFlagSet(ARMFlag.Carry) ? 0x80000000 : 0);
                    }
                    else
                    {
                        Offset = ROR(Registers[Rm], ShiftImmediate);
                    }
                    break;
                }
            }
            else //Immediate
            {
                Offset = Opcode & 0xfff;
            }

            uint Address = 0;

            if (P)
            {
                if (W) //Pre-Indexed
                {
                    if (U)
                    {
                        Registers[Rn] += Offset;
                    }
                    else
                    {
                        Registers[Rn] -= Offset;
                    }

                    Address = Registers[Rn];
                }
                else //Offset
                {
                    Address = U ? Registers[Rn] + Offset : Registers[Rn] - Offset;
                }
            }
            else
            {
                if (!W) //Post-Indexed
                {
                    Address = Registers[Rn];

                    if (U)
                    {
                        Registers[Rn] += Offset;
                    }
                    else
                    {
                        Registers[Rn] -= Offset;
                    }
                }
            }

            Registers.Mode = OldMode;
            return(Address);
        }