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/proc.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/proc.asm')
| -rw-r--r-- | src/proc.asm | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/proc.asm b/src/proc.asm index 058881f..114cc9c 100644 --- a/src/proc.asm +++ b/src/proc.asm @@ -368,3 +368,56 @@ sys_fork:: ld sp, hl ld a, $FF ret + +; ============================================================================= +; sys_exec(B = program id) - replace the current process image. Never returns. +; +; Looks up ProgramTable[B] = (ROM bank, entry). Points PROC_ROMB at the program +; text bank, maps it live into $4000-$7FFF, resets the stack to the top of the +; task's (already mapped) cart-RAM bank, and jumps to the entry. The task keeps +; its RAM bank; a fuller exec would also copy .data from ROM and zero .bss, but +; our demo programs keep no pre-initialized RAM. +; ============================================================================= +sys_exec:: + ; HL = &ProgramTable[B] = ProgramTable + B*4 + ld hl, ProgramTable + ld a, b + add a ; *2 + add a ; *4 (program id < 64) + add l + ld l, a + jr nc, .nc + inc h +.nc + ld a, [hl+] ; bank lo + ld b, a + ld a, [hl+] ; bank hi + ld c, a + ld a, [hl+] ; entry lo + ld e, a + ld a, [hl] ; entry hi + ld d, a ; DE = entry, BC = bank(lo,hi) + + ; PROC_ROMB = BC + ld a, [wCurProc] + add PROC_ROMB + ld l, a + ld a, [wCurProc+1] + adc 0 + ld h, a + ld a, b + ld [hl+], a + ld a, c + ld [hl], a + + ; map the program's ROM bank into $4000-$7FFF + ld a, b + ld [MBC5_ROMB_LO], a + ld a, c + ld [MBC5_ROMB_HI], a + + ; fresh empty stack at the top of the task's cart-RAM bank, then enter + ld sp, TASK_RAM_TOP ; $C000; first push lands at $BFFF + ld h, d + ld l, e + jp hl ; jump to program entry ($4000) |
