diff options
| author | user <user@clank> | 2026-07-16 00:04:09 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 00:04:09 +0200 |
| commit | 0a77a11e17f697bf797655c4ae87b927432b1f88 (patch) | |
| tree | 97cafaa103aec412f692daff9e068fc63f0496bf /src/programs.asm | |
| parent | kernel: implement fork() (diff) | |
| download | gbos-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.asm | 52 |
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 |
