diff options
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 |
