BeRTOS
|
00001 00037 void asm_switch_context(void ** new_sp /* R2 */, void ** save_sp /* R3 */); 00038 asm void asm_switch_context(void ** new_sp, void ** save_sp) 00039 { 00040 lea (SP)+ 00041 00042 ; From the manual: 00043 ; The compiler uses page 0 address locations X: 0x0030 - 0x003F as register 00044 ; variables. Frequently accessed local variables are assigned to the page 0 00045 ; registers instead of to stack locations so that load and store instructions 00046 ; are shortened. Addresses X: 0x0030 - 0x0037 (page 0 registers MR0-MR7) are 00047 ; volatile registers and can be overwritten. The remaining registers (page 0 00048 ; registers MR8-MR15) are treated as non-volatile and, if used by a routine, 00049 ; must be saved on entry and restored on exit. 00050 ; 00051 ; So, register 0x30-0x37 are caller-save, while 0x38-0x3F are callee-save. 00052 move x:<$38,y1 00053 move y1,x:(SP)+ 00054 move x:<$39,y1 00055 move y1,x:(SP)+ 00056 move x:<$3A,y1 00057 move y1,x:(SP)+ 00058 move x:<$3B,y1 00059 move y1,x:(SP)+ 00060 move x:<$3C,y1 00061 move y1,x:(SP)+ 00062 move x:<$3D,y1 00063 move y1,x:(SP)+ 00064 move x:<$3E,y1 00065 move y1,x:(SP)+ 00066 move x:<$3F,y1 00067 move y1,x:(SP) 00068 00069 ; 00070 ; Switch stacks 00071 nop 00072 move SP, x:(R3) 00073 nop 00074 move x:(R2), SP 00075 nop 00076 00077 ; 00078 ; restore all saved registers 00079 ; 00080 pop y1 00081 move y1,x:<$3F 00082 pop y1 00083 move y1,x:<$3E 00084 pop y1 00085 move y1,x:<$3D 00086 pop y1 00087 move y1,x:<$3C 00088 pop y1 00089 move y1,x:<$3B 00090 pop y1 00091 move y1,x:<$3A 00092 pop y1 00093 move y1,x:<$39 00094 pop y1 00095 move y1,x:<$38 00096 00097 ; SR is already pushed on the stack (normal call context). Use RTI to restore 00098 ; it, so that interrupt status is preserved across the tasks. 00099 rti 00100 }