diff --git a/recipes/sms/romasm/.gitignore b/recipes/sms/romasm/.gitignore new file mode 100644 index 0000000..2e334fc --- /dev/null +++ b/recipes/sms/romasm/.gitignore @@ -0,0 +1 @@ +user.h diff --git a/recipes/sms/romasm/Makefile b/recipes/sms/romasm/Makefile new file mode 100644 index 0000000..8be033e --- /dev/null +++ b/recipes/sms/romasm/Makefile @@ -0,0 +1,18 @@ +ZASM = ../../../tools/zasm.sh +KERNEL = ../../../kernel +APPS = ../../../apps + +.PHONY: all +all: os.sms ed.bin + +ed.bin: $(APPS)/ed/glue.asm + echo ".equ USER_CODE ED_CODE" | cat user-tmpl.h - > user.h + $(ZASM) $(KERNEL) $(APPS) user.h < $< > $@ + +zasm.bin: $(APPS)/zasm/glue.asm + echo ".equ USER_CODE ZASM_CODE" | cat user-tmpl.h - > user.h + $(ZASM) $(KERNEL) $(APPS) user.h < $< > $@ + +os.sms: glue.asm ed.bin zasm.bin + $(ZASM) $(KERNEL) ed.bin zasm.bin < $< > $@ + diff --git a/recipes/sms/romasm/README.md b/recipes/sms/romasm/README.md new file mode 100644 index 0000000..b66a8c4 --- /dev/null +++ b/recipes/sms/romasm/README.md @@ -0,0 +1,15 @@ +# zasm and ed from ROM + +SMS' RAM is much tighter than in the RC2014, which makes the idea of loading +apps like zasm and ed in memory before using it a bit wasteful. In this recipe, +we'll include zasm and ed code directly in the kernel and expose them as shell +commands. + +Moreover, we'll carve ourselves a little 1K memory map to put a filesystem in +there. This will give us a nice little system that can edit small source files +compile them and run them. + +## Gathering parts + +* A SMS that can run Collapse OS. +* A [PS/2 keyboard adapter](../kbd/README.md) diff --git a/recipes/sms/romasm/glue.asm b/recipes/sms/romasm/glue.asm new file mode 100644 index 0000000..1caf235 --- /dev/null +++ b/recipes/sms/romasm/glue.asm @@ -0,0 +1,151 @@ +; 8K of onboard RAM +.equ RAMSTART 0xc000 +; Memory register at the end of RAM. Must not overwrite +.equ RAMEND 0xddd0 + + jp init + +; *** JUMP TABLE *** + jp strncmp + jp addDE + jp addHL + jp upcase + jp unsetZ + jp intoDE + jp intoHL + jp writeHLinDE + jp findchar + jp parseHex + jp parseHexPair + jp blkSel + jp blkSet + jp fsFindFN + jp fsOpen + jp fsGetC + jp fsPutC + jp fsSetSize + jp cpHLDE + jp parseArgs + jp printstr + jp _blkGetC + jp _blkPutC + jp _blkSeek + jp _blkTell + jp printcrlf + jp stdioPutC + jp stdioReadLine + +.fill 0x66-$ + retn + +#include "err.h" +#include "core.asm" +#include "parse.asm" + +#include "sms/kbd.asm" +.equ KBD_RAMSTART RAMSTART +.equ KBD_FETCHKC smskbdFetchKCB +#include "kbd.asm" + +.equ VDP_RAMSTART KBD_RAMEND +#include "sms/vdp.asm" + +.equ STDIO_RAMSTART VDP_RAMEND +#include "stdio.asm" + +.equ MMAP_START 0xd800 +#include "mmap.asm" + +.equ BLOCKDEV_RAMSTART STDIO_RAMEND +.equ BLOCKDEV_COUNT 3 +#include "blockdev.asm" +; List of devices +.dw mmapGetC, mmapPutC +.dw f0GetC, f0PutC +.dw f1GetC, f1PutC + +#include "blockdev_cmds.asm" + +.equ FS_RAMSTART BLOCKDEV_RAMEND +.equ FS_HANDLE_COUNT 2 +#include "fs.asm" +#include "fs_cmds.asm" + +.equ SHELL_RAMSTART FS_RAMEND +.equ SHELL_EXTRA_CMD_COUNT 11 +#include "shell.asm" +.dw edCmd, zasmCmd, fnewCmd, fdelCmd, fopnCmd, flsCmd, fsOnCmd, blkBselCmd +.dw blkSeekCmd, blkLoadCmd, blkSaveCmd + +init: + di + im 1 + + ld sp, RAMEND + + ; init a FS in mmap + ld hl, MMAP_START + ld a, 'C' + ld (hl), a + inc hl + ld a, 'F' + ld (hl), a + inc hl + ld a, 'S' + ld (hl), a + call fsInit + xor a + call blkSel + + call kbdInit + call vdpInit + + ld hl, kbdGetC + ld de, vdpPutC + call stdioInit + call shellInit + jp shellLoop + +f0GetC: + ld ix, FS_HANDLES + jp fsGetC + +f0PutC: + ld ix, FS_HANDLES + jp fsPutC + +f1GetC: + ld ix, FS_HANDLES+FS_HANDLE_SIZE + jp fsGetC + +f1PutC: + ld ix, FS_HANDLES+FS_HANDLE_SIZE + jp fsPutC + +edCmd: + .db "eded", 0b1001, 0, 0 + push hl \ pop ix + ld l, (ix) + ld h, (ix+1) + jp 0x1800 + +zasmCmd: + .db "zasm", 0b1001, 0, 0 + push hl \ pop ix + ld l, (ix) + ld h, (ix+1) + jp 0x1c00 + +; last time I checked, PC at this point was 0x175a. Let's give us a nice margin +; for the start of ed. +.fill 0x1800-$ +.bin "ed.bin" + +; Last check: 0x1b4e +.fill 0x1c00-$ +.bin "zasm.bin" + +.fill 0x7ff0-$ +.db "TMR SEGA", 0x00, 0x00, 0xfb, 0x68, 0x00, 0x00, 0x00, 0x4c + + diff --git a/recipes/sms/romasm/user-tmpl.h b/recipes/sms/romasm/user-tmpl.h new file mode 100644 index 0000000..1f9e8fa --- /dev/null +++ b/recipes/sms/romasm/user-tmpl.h @@ -0,0 +1,37 @@ +; USER_CODE is filled in on-the-fly with either ED_CODE or ZASM_CODE +.equ ED_CODE 0x1800 +.equ ZASM_CODE 0x1c00 +.equ USER_RAMSTART 0xc200 +.equ FS_HANDLE_SIZE 6 +.equ BLOCKDEV_SIZE 8 + +; *** JUMP TABLE *** +.equ strncmp 0x03 +.equ addDE 0x06 +.equ addHL 0x09 +.equ upcase 0x0c +.equ unsetZ 0x0f +.equ intoDE 0x12 +.equ intoHL 0x15 +.equ writeHLinDE 0x18 +.equ findchar 0x1b +.equ parseHex 0x1e +.equ parseHexPair 0x21 +.equ blkSel 0x24 +.equ blkSet 0x27 +.equ fsFindFN 0x2a +.equ fsOpen 0x2d +.equ fsGetC 0x30 +.equ fsPutC 0x33 +.equ fsSetSize 0x36 +.equ cpHLDE 0x39 +.equ parseArgs 0x3c +.equ printstr 0x3f +.equ _blkGetC 0x42 +.equ _blkPutC 0x45 +.equ _blkSeek 0x48 +.equ _blkTell 0x4b +.equ printcrlf 0x4e +.equ stdioPutC 0x51 +.equ stdioReadLine 0x54 +