void NewContext(int* SP) { // SP for next task to go (arg #1) goes into HL SP; FunctionArgToReg(H, L); // Restores usermode status SetStackPointerASM(_OldSP); ExchangeRegs(); ReloadIndexes(); SaveContext(); // Switches to the process with stack in SP ExchangeRegs(); GetStackPointerASM(_TempSP); SetStackPointerREG(HL); *CurrentSP=TempSP; ExchangeRegs(); LoadContext(); if(ControlRequests==0) Halt("ISR IN USER MODE"); ControlRequests--; IntsOn(); ImmediateReturn(); }
/// Switches CPU context to that of the specified thread void SwitchContext(Thread* t) { Thread* cur = GetCurrentThread(); // Save context for current thread if (cur) { SaveContext(cur->context); if (cur->IsRunning()) { ChangeReadyState(cur, true); } } // Load context of new thread if (t) { SetCurrentThread(t); ChangeReadyState(t, false); t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; t->wait_type = WAITTYPE_NONE; LoadContext(t->context); } else { SetCurrentThread(nullptr); } }
/*** Stack: VAR offset($fp) absolute $sp ------------ local 3 16 56 local 2 12 52 local 1 8 48 ret addr 4 44 pre $fp 0 40 $fp ------------ args3 -4 36 args2 -8 32 args1 -12 28 old local 4 -16 24 old local 3 -20 20 old local 2 -24 16 old local 1 -28 12 old ret value -32 8 old ret addr -36 4 olc pre $fp -40 0 pre $fp ------------- */ void MipsCode::BeginToMips(MiddleInstr* middle) { SaveContext(); }