aboutsummaryrefslogtreecommitdiffstats
path: root/src/programs.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 00:12:43 +0200
committeruser <user@clank>2026-07-16 00:12:43 +0200
commit19a2b63bab71b796ee456b3ae8bec1a2ab297158 (patch)
tree49b1effd335d47e859002903caea337fea27e1b9 /src/programs.asm
parentkernel: implement exec() (diff)
downloadgbos-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.asm54
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