示例#1
0
        /// <summary>
        /// Switches the CPU into one of 7 modes. Save the cspr to the spsr, switch to the new mode.
        /// </summary>
        /// <param name="cpuMode"></param>
        public void SwitchCPUMode(CPSR.CPUModeEnum cpuMode)
        {
            //save the current cspr register into the spsr table based on the current mode
            _spsr[(int)cpuMode] = Flags;

            //switch cpu to the new mode
            mCPUMode = new CPUMode(cpuMode);
        }//SetCPUMode
        //Set a register value. Valid register numbers are 0-15 only
        //Based on the cpu mode and the register number/

        /// <summary>
        /// Set a register value. Valid register numbers are 0-15 only.
        /// Based on the cpu mode and the register number
        /// </summary>
        /// <param name="reg">register number to set(0-15)</param>
        /// <param name="newValue">value to set</param>
        private void setRegister(uint reg, uint newValue)
        {
            //make sure register number is valid
            if (reg >= r_user.Length)
            {
                return;
            }

            //get the current cpu mode
            CPSR.CPUModeEnum cpuMode = _cpsr.Mode;

            //and perform register transfer according to mode
            switch (cpuMode)
            {
            //user and system mode use only the normal 16 gp registers
            case CPSR.CPUModeEnum.User:
            case CPSR.CPUModeEnum.System:
                r_user[reg] = newValue; break;

            //these modes have their own r13 and r14
            case CPSR.CPUModeEnum.Supervisor:
            case CPSR.CPUModeEnum.Abort:
            case CPSR.CPUModeEnum.Undefined:
            case CPSR.CPUModeEnum.IRQ:
                if (reg < 13 || reg == PCRegisterIndex)
                {
                    r_user[reg] = newValue;
                }
                else
                {
                    if (cpuMode == CPSR.CPUModeEnum.Supervisor)
                    {
                        r_svc[reg - 13] = newValue;
                    }
                    else if (cpuMode == CPSR.CPUModeEnum.Abort)
                    {
                        r_abt[reg - 13] = newValue;
                    }
                    else if (cpuMode == CPSR.CPUModeEnum.Undefined)
                    {
                        r_und[reg - 13] = newValue;
                    }
                    else
                    {
                        r_irq[reg - 13] = newValue;
                    }
                }
                break;

            //fiq mode has its own r8-r14
            case CPSR.CPUModeEnum.FIQ:
                if (reg < 8 || reg == PCRegisterIndex)
                {
                    r_user[reg] = newValue;
                }
                else
                {
                    r_fiq[reg - 8] = newValue;
                }
                break;
            }//switch

            //if the register changed handler is set, call it
            if (_registerChangedHandler != null)
            {
                _registerChangedHandler(reg);
            }
        } //setRegister
        } //setRegister

        /// <summary>
        /// Get a register value. Valid register numbers are 0-15 only.
        /// Based on the cpu mode and the register number
        /// </summary>
        /// <param name="reg"></param>
        /// <returns></returns>
        private uint getRegister(uint reg)
        {
            //make sure register number is valid
            if (reg >= r_user.Length)
            {
                return(0);
            }

            //get the current cpu mode
            CPSR.CPUModeEnum cpuMode = _cpsr.Mode;

            //and perform register transfer according to mode
            switch (cpuMode)
            {
            //user and system mode use only the normal 16 gp registers
            case CPSR.CPUModeEnum.User:
            case CPSR.CPUModeEnum.System:
                return(r_user[reg]);

            //these modes have their own r13 and r14
            case CPSR.CPUModeEnum.Supervisor:
            case CPSR.CPUModeEnum.Abort:
            case CPSR.CPUModeEnum.Undefined:
            case CPSR.CPUModeEnum.IRQ:
                if (reg < 13 || reg == PCRegisterIndex)
                {
                    return(r_user[reg]);
                }
                else
                {
                    if (cpuMode == CPSR.CPUModeEnum.Supervisor)
                    {
                        return(r_svc[reg - 13]);
                    }
                    else if (cpuMode == CPSR.CPUModeEnum.Abort)
                    {
                        return(r_abt[reg - 13]);
                    }
                    else if (cpuMode == CPSR.CPUModeEnum.Undefined)
                    {
                        return(r_und[reg - 13]);
                    }
                    else
                    {
                        return(r_irq[reg - 13]);
                    }
                }

            //fiq mode has its own r8-r14
            case CPSR.CPUModeEnum.FIQ:
                if (reg < 8 || reg == PCRegisterIndex)
                {
                    return(r_user[reg]);
                }
                else
                {
                    return(r_fiq[reg - 8]);
                }
            } //switch
            return(0);
        }     //getRegister