1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 07:38:06 +11:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Virgil Dupras
f3992ed598 basic: begin an implementation from sratch
Let's see where it will lead us...
2019-11-13 15:28:16 -05:00
Virgil Dupras
1ae51bea3a tests: remove instr blacklist
Because scas isn't used as a reference anymore, no need to blacklist its bugs
anymore.
2019-11-12 20:47:09 -05:00
9 changed files with 134 additions and 15 deletions

View File

@ -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.

16
apps/basic/README.md Normal file
View File

@ -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.

17
apps/basic/glue.asm Normal file
View File

@ -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"

87
apps/basic/main.asm Normal file
View File

@ -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

View File

@ -4,4 +4,5 @@
/*/*-bin.h /*/*-bin.h
/cfsin/zasm /cfsin/zasm
/cfsin/ed /cfsin/ed
/cfsin/basic
/cfsin/user.h /cfsin/user.h

View File

@ -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

View File

@ -65,6 +65,7 @@ ADD IY, DE
ADD IY, IY ADD IY, IY
ADD IY, SP ADD IY, SP
AND (HL) AND (HL)
AND (IX)
AND (IX+1) AND (IX+1)
AND (IX-1) AND (IX-1)
AND (IX+10) AND (IX+10)
@ -73,6 +74,7 @@ AND (IX+100)
AND (IX-100) AND (IX-100)
AND (IX+127) AND (IX+127)
AND (IX-127) AND (IX-127)
AND (IY)
AND (IY+1) AND (IY+1)
AND (IY-1) AND (IY-1)
AND (IY+10) AND (IY+10)

View File

@ -6,12 +6,6 @@
import sys import sys
# Those lines below are improperly assembled by scas and are skipped by tests.
BLACKLIST = {
"AND (IX)",
"AND (IY)",
}
argspecTbl = { argspecTbl = {
'A': "A", 'A': "A",
'B': "B", 'B': "B",
@ -124,11 +118,6 @@ def eargs(args):
newargs = ['$+'+s for s in args[:-1]] newargs = ['$+'+s for s in args[:-1]]
return newargs + ['$-'+s for s in args[:-1]] return newargs + ['$-'+s for s in args[:-1]]
def p(line):
if line not in BLACKLIST:
print(line)
def main(): def main():
asmfile = sys.argv[1] asmfile = sys.argv[1]
with open(asmfile, 'rt') as fp: with open(asmfile, 'rt') as fp:
@ -164,11 +153,11 @@ def main():
if n in {'JR', 'DJNZ'} and a2 == 'n': if n in {'JR', 'DJNZ'} and a2 == 'n':
args2 = eargs(args2) args2 = eargs(args2)
for arg2 in args2: for arg2 in args2:
p(f"{n} {arg1}, {arg2}") print(f"{n} {arg1}, {arg2}")
else: else:
p(f"{n} {arg1}") print(f"{n} {arg1}")
else: else:
p(n) print(n)
pass pass
if __name__ == '__main__': if __name__ == '__main__':