aboutsummaryrefslogtreecommitdiffstats
path: root/src/proc.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/proc.asm')
-rw-r--r--src/proc.asm159
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.
+; -----------------------------------------------------------------------------