diff options
| author | user <user@clank> | 2026-07-16 00:12:43 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 00:12:43 +0200 |
| commit | 19a2b63bab71b796ee456b3ae8bec1a2ab297158 (patch) | |
| tree | 49b1effd335d47e859002903caea337fea27e1b9 /src/programs.asm | |
| parent | kernel: implement exec() (diff) | |
| download | gbos-19a2b63bab71b796ee456b3ae8bec1a2ab297158.tar.gz gbos-19a2b63bab71b796ee456b3ae8bec1a2ab297158.tar.xz gbos-19a2b63bab71b796ee456b3ae8bec1a2ab297158.zip | |
kernel: complete the process lifecycle (exit/wait/reap + bank free list)
- exit(): zombie + status, reparent orphans to init, wake blocked parent,
schedule away forever (resources reclaimed by the reaper)
- wait(): scan for a zombie child; reap (free cart-RAM bank + PCB slot) and
return pid/code; block PS_BLOCKED + yield if children still live; $FF if none
- cart-RAM banks are now a free list (wBankUsed bitmap): AllocRamBank/FreeRamBank
- scheduler: FindNextReady returns carry when nothing runnable; yield idles
instead of blindly picking slot 0
- helpers: FindPcbByPid, ReparentToInit
- demo: init forks 3 workers -> exec -> exit(pid) -> wait/reap => wwwR2R3R4!
verified bank recycling with 6 workers over 3 banks (w2w3w4w5w6w7)
- README: document the lifecycle + syscall status
Diffstat (limited to '')
| -rw-r--r-- | src/programs.asm | 54 |
1 files changed, 19 insertions, 35 deletions
diff --git a/src/programs.asm b/src/programs.asm index a8d8b63..b5e4d8e 100644 --- a/src/programs.asm +++ b/src/programs.asm @@ -1,52 +1,36 @@ ; ============================================================================= ; programs.asm - userland program images (text-in-ROM model). ; -; Each program is linked to execute from the ROMX window ($4000-$7FFF) and -; lives in its own ROM bank. exec() maps the bank and jumps to the entry. -; -; To prove ROM banking really drives execution, both demo programs are ORG'd at -; the SAME address ($4000) in DIFFERENT banks - the only thing selecting which -; code runs is PROC_ROMB. They also read their message string out of the mapped -; bank, so the correct bank must be live when sys_write runs. -; -; Programs only ever talk to the kernel via `rst $30` (the trap + all kernel -; code live in ROM0, which is always mapped), so they never call kernel labels. +; Programs are linked to run from the ROMX window ($4000-$7FFF) and live in +; their own ROM banks. exec() maps the bank and jumps to the entry. Programs +; only talk to the kernel via `rst $30` (the trap + kernel live in ROM0, always +; mapped), so they never reference kernel labels. ; ============================================================================= INCLUDE "include/gbos.inc" -SECTION "prog_ping", ROMX[$4000], BANK[2] -ProgPing: -.loop - ld de, .msg - ld b, 1 - ld c, SYS_WRITE - rst $30 - ld c, SYS_YIELD - rst $30 - jr .loop -.msg - db "1" - -SECTION "prog_pong", ROMX[$4000], BANK[3] -ProgPong: -.loop +; ----------------------------------------------------------------------------- +; PROG_WORKER: announce with 'w', then exit() with a status equal to our pid. +; Exercises exec (runs from a ROM bank) + the exit/wait lifecycle. +; ----------------------------------------------------------------------------- +SECTION "prog_worker", ROMX[$4000], BANK[2] +ProgWorker: ld de, .msg ld b, 1 ld c, SYS_WRITE rst $30 - ld c, SYS_YIELD + ld c, SYS_GETPID rst $30 - jr .loop + ld b, a ; exit status = pid (so reaped codes are distinct) + ld c, SYS_EXIT + rst $30 ; never returns .msg - db "2" + db "w" ; ----------------------------------------------------------------------------- -; Program table (in ROM0, always mapped). Indexed by exec()'s program id. -; Entry layout: bank (2 bytes, MBC5 16-bit) then entry address (2 bytes). +; Program table (ROM0). Indexed by exec()'s program id. +; Entry: bank (2 bytes, MBC5 16-bit) then entry address (2 bytes). ; ----------------------------------------------------------------------------- SECTION "progtab", ROM0 ProgramTable:: - db LOW(BANK(ProgPing)), HIGH(BANK(ProgPing)) - dw ProgPing - db LOW(BANK(ProgPong)), HIGH(BANK(ProgPong)) - dw ProgPong + db LOW(BANK(ProgWorker)), HIGH(BANK(ProgWorker)) + dw ProgWorker |
