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/proc.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/proc.asm')
| -rw-r--r-- | src/proc.asm | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/proc.asm b/src/proc.asm new file mode 100644 index 0000000..762b30e --- /dev/null +++ b/src/proc.asm @@ -0,0 +1,159 @@ +; ============================================================================= +; proc.asm - process table management, task creation, fork/exec (stubs) +; ============================================================================= +INCLUDE "include/gbos.inc" + +SECTION "proc", ROM0 + +; ----------------------------------------------------------------------------- +; ProcInit - table already zeroed by ClearKernelRAM (PS_FREE=0). Seed pids. +; ----------------------------------------------------------------------------- +ProcInit:: + ld a, 1 + ld [wNextPid], a + ret + +; ----------------------------------------------------------------------------- +; PcbPtr - slot -> PCB pointer. in: A=slot out: DE=&PCB. preserves BC. +; ----------------------------------------------------------------------------- +PcbPtr:: + push bc + ld hl, wProcTable + ld bc, PROC_SIZE + and a + jr z, .done +.mul + add hl, bc + dec a + jr nz, .mul +.done + ld d, h + ld e, l + pop bc + ret + +; ----------------------------------------------------------------------------- +; ProcCreate - allocate a PCB and build an initial (runnable) task. +; in: HL = task entry, B = cart-RAM bank, C = SVBK u-area bank +; out: A = pid, or 0 if the table is full +; ----------------------------------------------------------------------------- +ProcCreate:: + ; stash params + ld a, l + ld [wTmpEntry], a + ld a, h + ld [wTmpEntry+1], a + ld a, b + ld [wTmpRamB], a + ld a, c + ld [wTmpWramB], a + + ; find a free slot + ld c, 0 +.find + ld a, c + call PcbPtr ; DE = &PCB[c] + ld a, [de] + cp PS_FREE + jr z, .found + inc c + ld a, c + cp MAX_PROCS + jr c, .find + xor a ; table full + ret + +.found + ld a, c + ld [wTmpSlot], a + + ; fill fields; HL walks the PCB + ld h, d + ld l, e + ld a, PS_READY + ld [hl+], a ; PROC_STATE + ld a, [wNextPid] + ld [hl+], a ; PROC_PID + ld [wTmpPid], a + inc a + ld [wNextPid], a + inc hl ; skip PROC_SP (filled below) + inc hl + ld a, 1 + ld [hl+], a ; PROC_ROMB lo (placeholder text bank) + xor a + ld [hl+], a ; PROC_ROMB hi + ld a, [wTmpRamB] + ld [hl+], a ; PROC_RAMB + ld a, [wTmpWramB] + ld [hl+], a ; PROC_WRAMB + xor a + ld [hl+], a ; PROC_PARENT + ld [hl], a ; PROC_EXIT + + ; build the initial stack frame in the task's RAM bank + ld a, [wTmpEntry] + ld l, a + ld a, [wTmpEntry+1] + ld h, a ; HL = entry + ld a, [wTmpRamB] + ld b, a ; B = RAM bank + call ProcSetupStack ; out: HL = initial SP + ld a, l + ld [wTmpSP], a + ld a, h + ld [wTmpSP+1], a + + ; store SP into PCB.PROC_SP + ld a, [wTmpSlot] + call PcbPtr ; DE = &PCB + ld a, e + add PROC_SP + ld l, a + ld a, d + adc 0 + ld h, a ; HL = &PROC_SP + ld a, [wTmpSP] + ld [hl+], a + ld a, [wTmpSP+1] + ld [hl], a + + ld a, [wTmpPid] + ret + +; ----------------------------------------------------------------------------- +; ProcSetupStack - lay a fresh switch-in frame at the top of a task RAM bank. +; in: HL = entry, B = cart-RAM bank +; out: HL = initial SP (points at the saved-HL slot) +; The frame matches hSwitchTo's restore sequence: +; [SP+0..1]=hl [+2..3]=de [+4..5]=bc [+6]=f [+7]=a [+8..9]=entry (ret target) +; ----------------------------------------------------------------------------- +ProcSetupStack:: + ld a, b + ld [MBC5_RAMB], a ; map task's RAM bank into $A000-$BFFF + push hl ; save entry + ld hl, TASK_STACK_TOP - 9 ; frame base = $BFF6 + xor a + ld [hl+], a ; hl_lo + ld [hl+], a ; hl_hi + ld [hl+], a ; de_lo + ld [hl+], a ; de_hi + ld [hl+], a ; bc_lo + ld [hl+], a ; bc_hi + ld [hl+], a ; f + ld [hl+], a ; a + pop de ; DE = entry + ld a, e + ld [hl+], a ; entry lo (ret target) + ld a, d + ld [hl], a ; entry hi + ld hl, TASK_STACK_TOP - 9 ; initial SP + ret + +; ----------------------------------------------------------------------------- +; sys_fork / sys_exec - TODO. Plan: +; fork: alloc slot, copy parent's 8 KiB RAM bank -> child bank, dup u-area, +; patch child's saved-A to 0 (child return), parent gets child pid. +; exec: point PROC_ROMB at a flashed program image, reset RAM-bank layout +; (copy .data from ROM, zero .bss, fresh heap/stack), longjmp in. +; ----------------------------------------------------------------------------- |
