//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); }
//All these operations are unique in their own ways and I cannot simplify them into one function, //they all need their own functions. They are also highly dependent on the same instance variables, therefore //making a utilities class would mean many unnecessary arguments. //All the operations: //move value of op3 into Rd void MOV() { Regs.WriteWord(GetReg(Rd), op3); if (SBit && Rd == 15) { SwitchBackMode(); } }
//loads the values in the address pointed to by Rn into the active registers //in reglist[] while incrementing the address in Rn after loading void Load() //pop { for (int i = 0; i < regList.Length; i++) { if (regList[i]) { Regs.WriteWord(GetReg(i), RAM.ReadWord(address)); address += 4; } } }
//Loads value pointed to by 'address' into register Rd void Load() { if (B) { Regs.WriteWord(GetReg(Rd), RAM.ReadByte(address)); } else { Regs.WriteWord(GetReg(Rd), RAM.ReadWord(address)); } }
//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); }
//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); }
//Executes instruction by either store or load public override void Execute() { if (L) { Load(); } else { Store(); } if (W) { Regs.WriteWord(GetReg(Rn), address); } }
//transfers the value of a general-purpose register or an //immediate constant to the CPSR or the SPSR of the current mode. public override void Execute() { if (RBit) { char mode = CheckMode(); if (mode == 'V') { //supervisor Regs.WriteWord(Reg.SPSR_SVC, value); } else if (mode == 'R') { //irq Regs.WriteWord(Reg.SPSR_IRQ, value); } } else { Regs.WriteWord(Reg.CPSR, value); } }
// rn logical OR op3 store in rd void ORR() { //rd = rn || op3 Regs.WriteWord(GetReg(Rd), opn | op3); }
//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)))); }
// Rn + op3 and store in Rd void ADD() { Regs.WriteWord(GetReg(Rd), op3 + opn); }
// move NOT op3 into rd void MVN() { Regs.WriteWord(GetReg(Rd), ~op3); }
// Rn AND op3 and store in Rd void AND() { Regs.WriteWord(GetReg(Rd), op3 & opn); }
//bit clear rd = rn & ~op3 void BIC() { Regs.WriteWord(GetReg(Rd), opn & ~op3); }
//Execute BX: jump to address stored in link register void ExecuteReturn() { Regs.WriteWord(Reg.R15, Regs.ReadWord(GetReg(Rm))); }
// op3 - Rn and store in Rd void RSB() { Regs.WriteWord(GetReg(Rd), op3 - opn); }
// Rn - op3 and store in Rd void SUB() { Regs.WriteWord(GetReg(Rd), opn - op3); }
// Rn EOR op3 and store in Rd void EOR() { Regs.WriteWord(GetReg(Rd), opn ^ op3); }