Sik wrote:
On the flipside, no more self-modifying code. Should have done it this way from the beginning honestly, but I guess I was worried about the RTE instruction messing up when not inside an interrupt (since this isn't a traditional scheduler but manually yielding). Turns out that 68000 doesn't work that way, instead when it acknowledges the interrupt it simply modifies the IRQ mask in SR — there isn't any special "interrupt" flag, and RTE will pop whatever mask is left in the stack as-is regardless of what was in SR before. This means that executing RTE from a non-interrupt routine is safe as long as you build the stack frame properly (and you're in supervisor mode, of course).
Most CPUs work this way. They don't actually know whether you are inside of an interrupt or not, they just execute code. And the "return from exception" opcode does some things that might be helpful in interrupt mode, but it always does the same things.
Sik wrote:
When entering the scheduler interrupt:
Save all registers
Save stack frame
When re-entering the task:
Restore stack frame
Restore all registers
Return like an "interrupt"
Not entirely sure what you mean here. My system works like this: When entering an interrupt -
any interrupt - just save all registers. Just do it. It is easier. When returning from kernel mode to userspace, test the task flags to see if the task has a pending signal or needs scheduling. If so, handle these events. There is no scheduler "interrupt". There is a timer interrupt which sets the "needs scheduling" task flag.
The scheduler contains two task switch functions, a high level one and a low level one. The high level one is written in C and saves FPU context and debug registers (by calling the requisite assembler functions). The low level one is written in assembler and simply saves the non-volatile registers, switches stack frames, and restores the other task's registers (and sets the "current task" variable)
All tasks sleep in kernel mode. This is necessary to even just save their registers. But that means that waking up just means switching stacks. The other task knows what it has to restore.