aboutsummaryrefslogtreecommitdiffstats
path: root/src/programs.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 00:04:09 +0200
committeruser <user@clank>2026-07-16 00:04:09 +0200
commit0a77a11e17f697bf797655c4ae87b927432b1f88 (patch)
tree97cafaa103aec412f692daff9e068fc63f0496bf /src/programs.asm
parentkernel: implement fork() (diff)
downloadgbos-0a77a11e17f697bf797655c4ae87b927432b1f88.tar.gz
gbos-0a77a11e17f697bf797655c4ae87b927432b1f88.tar.xz
gbos-0a77a11e17f697bf797655c4ae87b927432b1f88.zip
kernel: implement exec()
- sys_exec(B=program id): look up ProgramTable, point PROC_ROMB at the program's ROM text bank, map it into $4000-$7FFF, reset stack, jp to entry (no return) - programs.asm: two demo programs (ping/pong) ORG'd at the SAME $4000 in banks 2 and 3 - proves execution is driven purely by PROC_ROMB - demo: init forks; parent execs PROG_PING (bank2, '1'), child execs PROG_PONG (bank3, '2') -> '1212...', 2000/2000 balanced, zero garbage - README: document exec + text-in-ROM model
Diffstat (limited to 'src/programs.asm')
-rw-r--r--src/programs.asm52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/programs.asm b/src/programs.asm
new file mode 100644
index 0000000..a8d8b63
--- /dev/null
+++ b/src/programs.asm
@@ -0,0 +1,52 @@
+; =============================================================================
+; 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.
+; =============================================================================
+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
+ ld de, .msg
+ ld b, 1
+ ld c, SYS_WRITE
+ rst $30
+ ld c, SYS_YIELD
+ rst $30
+ jr .loop
+.msg
+ db "2"
+
+; -----------------------------------------------------------------------------
+; 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).
+; -----------------------------------------------------------------------------
+SECTION "progtab", ROM0
+ProgramTable::
+ db LOW(BANK(ProgPing)), HIGH(BANK(ProgPing))
+ dw ProgPing
+ db LOW(BANK(ProgPong)), HIGH(BANK(ProgPong))
+ dw ProgPong