From f3992ed59855f3cfcfa0e785765b7055997d380e Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Wed, 13 Nov 2019 15:28:16 -0500 Subject: [PATCH] basic: begin an implementation from sratch Let's see where it will lead us... --- apps/README.md | 7 +++++ apps/basic/README.md | 16 ++++++++++ apps/basic/glue.asm | 17 ++++++++++ apps/basic/main.asm | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/emul/.gitignore | 1 + tools/emul/Makefile | 2 +- 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 apps/basic/README.md create mode 100644 apps/basic/glue.asm create mode 100644 apps/basic/main.asm diff --git a/apps/README.md b/apps/README.md index 7be6e2e..f40fe27 100644 --- a/apps/README.md +++ b/apps/README.md @@ -18,3 +18,10 @@ HL to a pointer to unparsed arguments in string form, null terminated. The userspace application is expected to set A on return. 0 means success, non-zero means error. + +A userspace application can expect the `SP` pointer to be properly set. If it +moves it, it should take care of returning it where it was before returning +because otherwise, it will break the kernel. + +Apps in Collapse OS are design to be ROM-compatible, that is, they don't write +to addresses that are part of the code's address space. diff --git a/apps/basic/README.md b/apps/basic/README.md new file mode 100644 index 0000000..d2c38c2 --- /dev/null +++ b/apps/basic/README.md @@ -0,0 +1,16 @@ +# basic + +**Work in progress, not finished.** + +This is a BASIC interpreter which is being written from scratch for Collapse OS. +There are many existing z80 implementations around, some of them open source +and most of them good and efficient, but because a lot of that code overlaps +with code that has already been written for zasm, I believe that it's better to +reuse those bits of code. + +Integrating an existing BASIC to Collapse OS seemed a bigger challenge than +writing from scratch, so here I am, writing from scratch again... + +The biggest challenge here is to extract code from zasm, adapt it to fit BASIC, +not break anything, and have the wisdom to see when copy/pasting is a better +idea. diff --git a/apps/basic/glue.asm b/apps/basic/glue.asm new file mode 100644 index 0000000..e7216bc --- /dev/null +++ b/apps/basic/glue.asm @@ -0,0 +1,17 @@ +; *** Requirements *** +; addHL +; printstr +; printcrlf +; stdioReadLine +; strncmp +; +.inc "user.h" + +.inc "err.h" +.org USER_CODE + + jp basStart + +.inc "lib/parse.asm" +.equ BAS_RAMSTART USER_RAMSTART +.inc "basic/main.asm" diff --git a/apps/basic/main.asm b/apps/basic/main.asm new file mode 100644 index 0000000..e281716 --- /dev/null +++ b/apps/basic/main.asm @@ -0,0 +1,87 @@ +; *** Variables *** +; Value of `SP` when basic was first invoked. This is where SP is going back to +; on restarts. +.equ BAS_INITSP BAS_RAMSTART +; **Pointer** to current line number +.equ BAS_PCURLN @+2 +.equ BAS_RAMEND @+2 + +; *** Code *** +basStart: + ld (BAS_INITSP), sp + xor a + ld hl, .welcome + call printstr + call printcrlf + ld hl, .welcome+2 ; points to a zero word + ld (BAS_PCURLN), hl + jr basPrompt + +.welcome: + .db "OK", 0, 0 + +basPrompt: + ld hl, .sPrompt + call printstr + call stdioReadLine + call parseDecimal + jr z, .number + call basDirect + jr basPrompt +.number: + ; do nothing for now, we only support direct mode. + ld hl, .sNumber + call basPrintLn + jr basPrompt +.sNumber: + .db "A number!", 0 +.sPrompt: + .db "> ", 0 + +basDirect: + ex de, hl + ld hl, basCmds1 +.loop: + ld a, 4 + call strncmp + jr z, .found + ld a, 6 + call addHL + ld a, (hl) + cp 0xff + jr nz, .loop + ld hl, .sUnknown + jr basPrintLn + +.found: + inc hl \ inc hl \ inc hl \ inc hl + call intoHL + jp (hl) + +.sUnknown: + .db "Unknown command", 0 + +basPrintLn: + call printcrlf + call printstr + jp printcrlf + +; *** Commands *** +basBYE: + ld hl, .sBye + call basPrintLn + ; To quit the loop, let's return the stack to its initial value and + ; then return. + xor a + ld sp, (BAS_INITSP) + ret +.sBye: + .db "Goodbye!", 0 + +; direct only +basCmds1: + .db "bye", 0 + .dw basBYE +; statements +basCmds2: + .db 0xff ; end of table diff --git a/tools/emul/.gitignore b/tools/emul/.gitignore index cc529d7..d4bb0a3 100644 --- a/tools/emul/.gitignore +++ b/tools/emul/.gitignore @@ -4,4 +4,5 @@ /*/*-bin.h /cfsin/zasm /cfsin/ed +/cfsin/basic /cfsin/user.h diff --git a/tools/emul/Makefile b/tools/emul/Makefile index 69511f3..affef32 100644 --- a/tools/emul/Makefile +++ b/tools/emul/Makefile @@ -4,7 +4,7 @@ KERNEL = ../../kernel APPS = ../../apps ZASMBIN = zasm/zasm ZASMSH = ../zasm.sh -SHELLAPPS = $(addprefix cfsin/, zasm ed) +SHELLAPPS = $(addprefix cfsin/, zasm ed basic) CFSIN_CONTENTS = $(SHELLAPPS) cfsin/user.h .PHONY: all