|
|
1.1 ! root 1: #include "task.h" ! 2: ! 3: // VAX frame fudger ! 4: ! 5: // STACK GROWS DOWN ! 6: /* ! 7: #define FP(p) ((int*)(&p+1)) ! 8: #define OLD_AP(fp) (*(fp+2)) ! 9: #define OLD_FP(fp) (*(fp+3)) ! 10: #define OLD_PC(fp) (*(fp+4)) ! 11: */ ! 12: ! 13: /* ! 14: * fix a the frame so that when we return from it, all the registers will ! 15: * be restored. ! 16: * The idea is that task_fp points to the task::task() stack frame which ! 17: * contains all the saved registers. t_framep points to the My_task::Mytask() ! 18: * stack frame that contains the return address (and perhaps some registers). ! 19: * fill the frame pointed to by t_framep with the registers from task_fp. ! 20: * do this by copying the registers up from t_framep to task_fp, then ! 21: * copying the whole frame down and adjusting t_framep. ! 22: * see the VAX architecture reference manual for frame layout ! 23: * note we always use calls (not callg) and spa is always 0 ! 24: */ ! 25: void ! 26: task::fudge_return(register int* task_fp, int offset, task* next) ! 27: { ! 28: register int* this_fp = t_framep + offset; ! 29: task_fp += offset; // in case this is SHARED ! 30: // get masks of saved registers in the frames ! 31: unsigned short this_mask = *((short*)this_fp + 3); ! 32: unsigned short task_mask = *((short*)task_fp + 3); ! 33: // copy up the always fields ! 34: task_fp[0] = this_fp[0]; // condition handler (always zero?) ! 35: ((short*)task_fp)[2] = ((short*)this_fp)[2]; // psw but not mask ! 36: task_fp[2] = this_fp[2]; // saved argument pointer ! 37: task_fp[3] = this_fp[3]; // saved frame pointer ! 38: task_fp[4] = this_fp[4]; // saved program counter ! 39: // now copy up optional registers ! 40: register int* this_rp = this_fp + 5; ! 41: register int* task_rp = task_fp + 5; ! 42: for (register mask = 1; mask != 0x1000; mask <<= 1) { ! 43: if (mask & task_mask) ! 44: if (mask & this_mask) ! 45: *task_rp++ = *this_rp++; ! 46: else task_rp++; ! 47: else if (mask & this_mask) // task frame is supposed to save all ! 48: task_error(E_FUDGE); ! 49: } ! 50: // next copy the whole frame down ! 51: while (task_rp > task_fp) ! 52: *--this_rp = *--task_rp; ! 53: // finally fix t_framep to point to where the frame wound up ! 54: t_framep = this_rp - offset; ! 55: if (next) next->restore(); ! 56: } ! 57:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.