Let's see where it will lead us...pull/85/head
@@ -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, | The userspace application is expected to set A on return. 0 means success, | ||||
non-zero means error. | 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. |
@@ -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. |
@@ -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" |
@@ -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 |
@@ -4,4 +4,5 @@ | |||||
/*/*-bin.h | /*/*-bin.h | ||||
/cfsin/zasm | /cfsin/zasm | ||||
/cfsin/ed | /cfsin/ed | ||||
/cfsin/basic | |||||
/cfsin/user.h | /cfsin/user.h |
@@ -4,7 +4,7 @@ KERNEL = ../../kernel | |||||
APPS = ../../apps | APPS = ../../apps | ||||
ZASMBIN = zasm/zasm | ZASMBIN = zasm/zasm | ||||
ZASMSH = ../zasm.sh | ZASMSH = ../zasm.sh | ||||
SHELLAPPS = $(addprefix cfsin/, zasm ed) | |||||
SHELLAPPS = $(addprefix cfsin/, zasm ed basic) | |||||
CFSIN_CONTENTS = $(SHELLAPPS) cfsin/user.h | CFSIN_CONTENTS = $(SHELLAPPS) cfsin/user.h | ||||
.PHONY: all | .PHONY: all | ||||