Beispiel #1
0
        //Extract adress according to register offset specification
        int DecodeRegisterOffset()
        {
            char Rm       = (char)ExtractBits(code, 0, 3);
            char Sh       = (char)ExtractBits(code, 5, 6);
            int  shiftVal = ExtractBits(code, 7, 11);

            shiftVal *= U ? 1 : -1;

            stringValue = ", " + (shiftVal == 0 ? (U ? "" : "-") : "") + "r" + (int)Rm;

            int regval = Regs.ReadWord(GetReg(Rm));

            if (Rm == 15)
            {
                regval += 8;
            }

            if (shiftVal != 0)
            {
                stringValue += ", " + BarrelShifter.CodeToString(Sh) + " #" + shiftVal;
            }
            else if (!U)
            {
                regval *= -1;
            }

            return(BarrelShifter.ShiftByCode(regval, shiftVal, Sh));
        }
Beispiel #2
0
        //fire the interrupt
        //Interrupts are special. They get special access to the inner guts of the program...
        public override void Execute()
        {
            if (swiType == 0x11)
            {
                Flags[SysFlag.Running]     = false;
                Flags[SysFlag.Unsteppable] = true;
                return;
            }

            Regs.WriteWord(Reg.LR_SVC, Regs.ReadWord(Reg.R15));
            Regs.WriteWord(Reg.SPSR_SVC, Regs.ReadWord(Reg.CPSR));

            int cpsr = Regs.ReadWord(Reg.CPSR) & 0b1111111111111111111111111100000;

            Regs.WriteWord(Reg.CPSR, cpsr | Mode.Supervisor); //switch to superviser

            if (swiType == 0x0)
            {
                SetCPSRFlag(7, true);
            }
            else
            {
                SetCPSRFlag(7, false);
            }

            Regs.WriteWord(Reg.R15, 0x8);
        }
Beispiel #3
0
        //decode instruction based on 'code' parent variable and returns populated version of itself
        public override Instruction Decode()
        {
            IBit    = TestFlag(code, 25);
            P       = TestFlag(code, 24);
            U       = TestFlag(code, 23);
            S       = TestFlag(code, 22);
            W       = TestFlag(code, 21);
            L       = TestFlag(code, 20);
            Rn      = (char)ExtractBits(code, 16, 19);
            address = Regs.ReadWord(GetReg(Rn));

            regstr = "";
            bool first = true;

            for (int i = 0; i < regList.Length; i++)
            {
                regList[i] = TestFlag(code, i);
                if (regList[i])
                {
                    if (!first)
                    {
                        regstr += ", ";
                    }
                    regstr += "r" + i;
                    first   = false;
                }
            }
            return(this);
        }
Beispiel #4
0
 //stores the values in the active registers in reglist[] into the address pinted to by Rn
 //while decrementing the value Rn before the store process
 void Store() //push
 {
     for (int i = regList.Length - 1; i >= 0; i--)
     {
         if (regList[i])
         {
             address -= 4;
             RAM.WriteWord(address, Regs.ReadWord(GetReg(i)));
         }
     }
 }
Beispiel #5
0
        //Extract the operands op1, op2, op3 from the command
        void CalculateOperands()
        {
            opn = Regs.ReadWord(GetReg(Rn)); //What is stored in Rn
            if (Rn == 15)
            {
                opn += 8;
            }

            opd = Regs.ReadWord(GetReg(Rd)); //What is stored in Rd
            op3 = IBit ? CalulateImmediateOperand3() : CalculateRegisterOperand3();
        }
Beispiel #6
0
        //Transfers value from CPSR or SPSR of the current mode into a general purpose register
        public override void Execute()
        {
            int value = Regs.ReadWord(Reg.CPSR);
            if (RBit)
            {
                char mode = CheckMode();
                if (mode == 'V') //supervisor
                    value = Regs.ReadWord(Reg.LR_SVC);
                else if (mode == 'R') //irq
                    value = Regs.ReadWord(Reg.LR_IRQ);
            }

            Regs.WriteWord(GetReg(Rd), value);
        }
Beispiel #7
0
        //caculated and returns the reister operand
        int CalulateRegValue()
        {
            char Rm = (char)ExtractBits(code, 0, 3);

            int val = Regs.ReadWord(GetReg(Rm));

            if (Rm == 15)
            {
                val += 8;
            }

            strVal = "r" + (int)Rm;
            return(val);
        }
Beispiel #8
0
        //Change the value of the program counter,
        //if L is true, store previous PC value in R14
        public override void Execute()
        {
            if (isRet)
            {
                ExecuteReturn();
                return;
            }

            if (link)
            {
                Regs.WriteWord(GetReg(14), Regs.ReadWord(Reg.R15));
            }
            Regs.WriteWord(Reg.R15, address);
        }
Beispiel #9
0
        //Calculate the address to jump to relative to PC
        void ProcessBranchAddress()
        {
            int pc = Regs.ReadWord(Reg.R15);

            link = TestFlag(code, 24);
            sign = TestFlag(code, 23);

            offset = ExtractBits(code, 0, 22);

            if (sign)
            {
                uint mask = 0xFFF00000;
                offset |= (int)mask; //mask to convert to signed FF000000
            }
            offset <<= 2;
            address  = pc + 8 + offset;
        }
Beispiel #10
0
        //Stores value from register Rd in 'address'
        void Store()
        {
            if (B)
            {
                int storeVal = Regs.ReadWord(GetReg(Rd));
                if (Rd == 15)
                {
                    storeVal += 8;
                }
                RAM.WriteByte(address, (byte)storeVal);
            }
            else
            {
                int storeVal = Regs.ReadWord(GetReg(Rd));
                if (Rd == 15)
                {
                    storeVal += 8;
                }

                RAM.WriteWord(address, storeVal);
            }
        }
Beispiel #11
0
        //Calcultes and returns the register shift operand
        int CalculateRegisterOperand3()
        {
            int shiftVal;

            Rm = (char)ExtractBits(code, 0, 3);
            char Sh   = (char)ExtractBits(code, 5, 6);
            bool bit4 = TestFlag(code, 4);
            char Rs   = '0';

            strShift = "r" + (int)Rm;

            if (!bit4)
            {
                shiftVal = ExtractBits(code, 7, 11);
            }
            else
            {
                Rs       = (char)ExtractBits(code, 8, 11);
                shiftVal = Regs.ReadWord(GetReg(Rs));
                if (Rs == 15)
                {
                    shiftVal += 8;
                }
            }
            if (shiftVal != 0)
            {
                strShift += ", " + BarrelShifter.CodeToString(Sh) + (bit4 ? " r" + (int)Rs : " #" + shiftVal);
            }

            int val = Regs.ReadWord(GetReg(Rm));

            if (Rm == 15)
            {
                val += 8;
            }

            return(BarrelShifter.ShiftByCode(val, shiftVal, Sh));
        }
Beispiel #12
0
        //Decodes loadstore instruction for 'code' parent variable and returns
        //itself as a fully populated instruction ready for execution
        public override Instruction Decode()
        {
            IBit = TestFlag(code, 25);
            P    = TestFlag(code, 24);
            U    = TestFlag(code, 23);
            B    = TestFlag(code, 22);
            W    = TestFlag(code, 21);
            L    = TestFlag(code, 20);
            Rn   = (char)ExtractBits(code, 16, 19);
            Rd   = (char)ExtractBits(code, 12, 15);

            int regContent = Regs.ReadWord(GetReg(Rn));

            if (Rn == 15)
            {
                regContent += 8;
            }

            offset = !IBit?DecodeImmediateOffset() : DecodeRegisterOffset();

            address = P ? regContent + offset : regContent;

            return(this);
        }
Beispiel #13
0
 //performs the special case for the multiplication instruction,
 //multiplies the values in Rm and Rn and stores their results in Rd
 void ExecMUL()
 {
     Regs.WriteWord(GetReg(Rd), (Regs.ReadWord(GetReg(Rn)) * Regs.ReadWord(GetReg(Rm))));
 }
Beispiel #14
0
 //Execute BX: jump to address stored in link register
 void ExecuteReturn()
 {
     Regs.WriteWord(Reg.R15, Regs.ReadWord(GetReg(Rm)));
 }