/// <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