diff options
| author | user <user@clank> | 2026-07-15 23:44:28 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-15 23:44:28 +0200 |
| commit | de725da74db5cba0f9bfd0755269e1683423d87b (patch) | |
| tree | dc39eca9fbd290393ed51de31eee5e4bd6af8375 /src/sched.asm | |
| download | gbos-de725da74db5cba0f9bfd0755269e1683423d87b.tar.gz gbos-de725da74db5cba0f9bfd0755269e1683423d87b.tar.xz gbos-de725da74db5cba0f9bfd0755269e1683423d87b.zip | |
gbos scaffold: working cooperative microkernel (verified ABAB in emulator)
- fix ClearKernelRAM clobbering the kernel stack (only clear $C000-$CBFF)
- fix SyscallTrap clobbering DE (buffer arg) during table dispatch
- README: run via ~/dev/gbc --headless; note bring-up bugs
Diffstat (limited to 'src/sched.asm')
| -rw-r--r-- | src/sched.asm | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/sched.asm b/src/sched.asm new file mode 100644 index 0000000..c871f7a --- /dev/null +++ b/src/sched.asm @@ -0,0 +1,75 @@ +; ============================================================================= +; sched.asm - round-robin scheduler + yield + timer stub +; ============================================================================= +INCLUDE "include/gbos.inc" + +SECTION "sched", ROM0 + +; ----------------------------------------------------------------------------- +; SchedInit - prime the round-robin cursor so the first pick lands on slot 0. +; ----------------------------------------------------------------------------- +SchedInit:: + ld a, MAX_PROCS - 1 + ld [wSchedNext], a + ret + +; ----------------------------------------------------------------------------- +; SchedRunFirst - hand control to the first runnable task. Never returns; the +; kernel-init context is saved into wKernelPCB and simply abandoned. +; ----------------------------------------------------------------------------- +SchedRunFirst:: + ld hl, wKernelPCB + ld a, l + ld [wCurProc], a + ld a, h + ld [wCurProc+1], a + call FindNextReady ; DE = &first ready PCB + jp hSwitchTo + +; ----------------------------------------------------------------------------- +; SchedYield - cooperative switch to the next runnable task. Returns to the +; caller when this task is eventually rescheduled. +; ----------------------------------------------------------------------------- +SchedYield:: + call FindNextReady ; DE = &next PCB + call hSwitchTo + ret + +; ----------------------------------------------------------------------------- +; FindNextReady - round-robin from wSchedNext. out: DE = &PCB (updates cursor) +; Scaffold: assumes at least one PS_READY task exists. +; ----------------------------------------------------------------------------- +FindNextReady:: + ld a, [wSchedNext] + ld b, MAX_PROCS +.scan + inc a + cp MAX_PROCS + jr c, .nowrap + xor a +.nowrap + push af ; save candidate slot + call PcbPtr ; DE = &PCB[slot] (preserves BC) + ld a, [de] ; state + cp PS_READY + jr z, .found + pop af ; restore candidate slot + dec b + jr nz, .scan + ; nothing ready: fall back to slot 0 (idle behavior) + xor a + call PcbPtr + ret +.found + pop af ; A = chosen slot + ld [wSchedNext], a + call PcbPtr ; DE = &PCB + ret + +; ----------------------------------------------------------------------------- +; TimerISR - preemption hook (TODO). A real preemptive switch must save the +; interrupted context and call hSwitchTo from here. For now the demo is +; cooperative (tasks call SYS_YIELD), so we just acknowledge and return. +; ----------------------------------------------------------------------------- +TimerISR:: + reti |
