mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 15:08:05 +11:00
basic: allow multiple args in print
This commit is contained in:
parent
9c400ca642
commit
3f3dd9141e
@ -9,6 +9,10 @@
|
||||
|
||||
jp basStart
|
||||
|
||||
; RAM space used in different routines for short term processing.
|
||||
.equ SCRATCHPAD_SIZE 0x20
|
||||
.equ SCRATCHPAD USER_RAMSTART
|
||||
|
||||
.inc "core.asm"
|
||||
.inc "lib/util.asm"
|
||||
.inc "lib/ari.asm"
|
||||
@ -17,7 +21,7 @@
|
||||
.equ EXPR_PARSE parseLiteralOrVar
|
||||
.inc "lib/expr.asm"
|
||||
.inc "basic/tok.asm"
|
||||
.equ VAR_RAMSTART USER_RAMSTART
|
||||
.equ VAR_RAMSTART SCRATCHPAD+SCRATCHPAD_SIZE
|
||||
.inc "basic/var.asm"
|
||||
.equ BUF_RAMSTART VAR_RAMEND
|
||||
.inc "basic/buf.asm"
|
||||
|
@ -1,5 +1,3 @@
|
||||
; *** Constants ***
|
||||
.equ BAS_SCRATCHPAD_SIZE 0x20
|
||||
; *** Variables ***
|
||||
; Value of `SP` when basic was first invoked. This is where SP is going back to
|
||||
; on restarts.
|
||||
@ -9,8 +7,7 @@
|
||||
; Important note: this is **not** a line number, it's a pointer to a line index
|
||||
; in buffer. If it's not zero, its a valid pointer.
|
||||
.equ BAS_PNEXTLN @+2
|
||||
.equ BAS_SCRATCHPAD @+2
|
||||
.equ BAS_RAMEND @+BAS_SCRATCHPAD_SIZE
|
||||
.equ BAS_RAMEND @+2
|
||||
|
||||
; *** Code ***
|
||||
basStart:
|
||||
@ -18,11 +15,11 @@ basStart:
|
||||
call varInit
|
||||
call bufInit
|
||||
xor a
|
||||
ld (BAS_PNEXTLN), a
|
||||
ld (BAS_PNEXTLN+1), a
|
||||
ld hl, .welcome
|
||||
call printstr
|
||||
call printcrlf
|
||||
ld hl, 0 ; points to a zero word
|
||||
ld (BAS_PNEXTLN), hl
|
||||
jr basLoop
|
||||
|
||||
.welcome:
|
||||
@ -43,8 +40,8 @@ basLoop:
|
||||
jr basLoop
|
||||
.number:
|
||||
push ix \ pop de
|
||||
call toWS
|
||||
call rdWS
|
||||
call toSep
|
||||
call rdSep
|
||||
call bufAdd
|
||||
jp nz, basERR
|
||||
jr basLoop
|
||||
@ -55,16 +52,7 @@ basLoop:
|
||||
; If found, jump to it. If not found, unset Z. We expect commands to set Z
|
||||
; on success. Therefore, when calling basCallCmd results in NZ, we're not sure
|
||||
; where the error come from, but well...
|
||||
; Before being evaluated, (HL) is copied in BAS_SCRATCHPAD because some
|
||||
; evaluation routines (such as parseExpr) mutate the string it evaluates.
|
||||
; TODO: straighten this situation up. Mutating a string like this breaks
|
||||
; expectations.
|
||||
basCallCmd:
|
||||
push de ; --> lvl 1
|
||||
ld de, BAS_SCRATCHPAD
|
||||
call strcpy
|
||||
ex de, hl ; HL now points to scratchpad
|
||||
pop de ; <-- lvl 1
|
||||
; let's see if it's a variable assignment.
|
||||
call varTryAssign
|
||||
ret z ; Done!
|
||||
@ -95,17 +83,13 @@ basCallCmd:
|
||||
ex de, hl
|
||||
ld a, b ; cmd's length
|
||||
call addHL
|
||||
call rdWS
|
||||
call rdSep
|
||||
jp (ix)
|
||||
|
||||
|
||||
basPrintLn:
|
||||
call printstr
|
||||
jp printcrlf
|
||||
|
||||
basERR:
|
||||
ld hl, .sErr
|
||||
jr basPrintLn
|
||||
call printstr
|
||||
jp printcrlf
|
||||
.sErr:
|
||||
.db "ERR", 0
|
||||
|
||||
@ -118,7 +102,8 @@ basERR:
|
||||
; Commands are expected to set Z on success.
|
||||
basBYE:
|
||||
ld hl, .sBye
|
||||
call basPrintLn
|
||||
call printstr
|
||||
call printcrlf
|
||||
; To quit the loop, let's return the stack to its initial value and
|
||||
; then return.
|
||||
xor a
|
||||
@ -133,7 +118,7 @@ basLIST:
|
||||
.loop:
|
||||
ld e, (ix)
|
||||
ld d, (ix+1)
|
||||
ld hl, BAS_SCRATCHPAD
|
||||
ld hl, SCRATCHPAD
|
||||
call fmtDecimal
|
||||
call printstr
|
||||
ld a, ' '
|
||||
@ -169,7 +154,7 @@ basRUN:
|
||||
; Print line number, then return NZ (which will print ERR)
|
||||
ld e, (ix)
|
||||
ld d, (ix+1)
|
||||
ld hl, BAS_SCRATCHPAD
|
||||
ld hl, SCRATCHPAD
|
||||
call fmtDecimal
|
||||
call printstr
|
||||
ld a, ' '
|
||||
@ -191,15 +176,33 @@ basRUN:
|
||||
ret
|
||||
|
||||
basPRINT:
|
||||
ld de, SCRATCHPAD
|
||||
call rdWord
|
||||
push hl ; --> lvl 1
|
||||
ex de, hl
|
||||
call parseExpr
|
||||
ret nz
|
||||
push ix \ pop de
|
||||
ld hl, BAS_SCRATCHPAD
|
||||
ld hl, SCRATCHPAD
|
||||
call fmtDecimal
|
||||
call printstr
|
||||
pop hl ; <-- lvl 1
|
||||
; Do we have another arg?
|
||||
call rdSep
|
||||
jr z, .another
|
||||
; no, we can stop here
|
||||
cp a ; ensure Z
|
||||
jp basPrintLn
|
||||
jp printcrlf
|
||||
.another:
|
||||
; Before we jump to basPRINT, let's print a space
|
||||
ld a, ' '
|
||||
call stdioPutC
|
||||
jr basPRINT
|
||||
|
||||
basGOTO:
|
||||
ld de, SCRATCHPAD
|
||||
call rdWord
|
||||
ex de, hl
|
||||
call parseExpr
|
||||
ret nz
|
||||
push ix \ pop de
|
||||
|
@ -1,3 +1,12 @@
|
||||
; Sets Z is A is ' ' or '\t' (whitespace), or ',' (arg sep)
|
||||
isSep:
|
||||
cp ' '
|
||||
ret z
|
||||
cp 0x09
|
||||
ret z
|
||||
cp ','
|
||||
ret
|
||||
|
||||
; Expect at least one whitespace (0x20, 0x09) at (HL), and then advance HL
|
||||
; until a non-whitespace character is met.
|
||||
; HL is advanced to the first non-whitespace char.
|
||||
@ -5,7 +14,7 @@
|
||||
; Failure is either not having a first whitespace or reaching the end of the
|
||||
; string.
|
||||
; Sets Z if we found a non-whitespace char, unset if we found the end of string.
|
||||
rdWS:
|
||||
rdSep:
|
||||
ld a, (hl)
|
||||
call isSep
|
||||
ret nz ; failure
|
||||
@ -47,10 +56,32 @@ fnWSIdx:
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; Advance HL to the next whitespace or to the end of string.
|
||||
toWS:
|
||||
; Advance HL to the next separator or to the end of string.
|
||||
toSep:
|
||||
ld a, (hl)
|
||||
call isSep
|
||||
ret z
|
||||
inc hl
|
||||
jr toWS
|
||||
jr toSep
|
||||
|
||||
; Read (HL) until the next separator and copy it in (DE)
|
||||
; DE is preserved, but HL is advanced to the end of the read word.
|
||||
rdWord:
|
||||
push af
|
||||
push de
|
||||
.loop:
|
||||
ld a, (hl)
|
||||
call isSep
|
||||
jr z, .stop
|
||||
or a
|
||||
jr z, .stop
|
||||
ld (de), a
|
||||
inc hl
|
||||
inc de
|
||||
jr .loop
|
||||
.stop:
|
||||
xor a
|
||||
ld (de), a
|
||||
pop de
|
||||
pop af
|
||||
ret
|
||||
|
@ -44,29 +44,33 @@ varTryAssign:
|
||||
; We have a variable! Its table index is currently in A.
|
||||
push ix ; --> lvl 1
|
||||
push hl ; --> lvl 2
|
||||
push af ; --> lvl 3. save for later
|
||||
; Let's start by evaluating that expression
|
||||
push de ; --> lvl 3
|
||||
push af ; --> lvl 4. save for later
|
||||
; Let's put that expression to read in scratchpad
|
||||
inc hl \ inc hl
|
||||
ld de, SCRATCHPAD
|
||||
call rdWord
|
||||
ex de, hl
|
||||
; Now, evaluate that expression now in (HL)
|
||||
call parseExpr ; --> number in IX
|
||||
jr nz, .exprErr
|
||||
pop af ; <-- lvl 3
|
||||
pop af ; <-- lvl 4
|
||||
add a, a ; * 2 because each element is a word
|
||||
ld hl, VAR_TBL
|
||||
call addHL
|
||||
; HL placed, write number
|
||||
push de ; --> lvl 3
|
||||
push ix \ pop de
|
||||
ld (hl), e
|
||||
inc hl
|
||||
ld (hl), d
|
||||
pop de ; <-- lvl 3
|
||||
xor a ; ensure Z
|
||||
.end:
|
||||
pop de ; <-- lvl 3
|
||||
pop hl ; <-- lvl 2
|
||||
pop ix ; <-- lvl 1
|
||||
ret
|
||||
.exprErr:
|
||||
pop af ; <-- lvl 3
|
||||
pop af ; <-- lvl 4
|
||||
jr .end
|
||||
|
||||
; Check if value at (HL) is a variable. If yes, returns its associated value.
|
||||
|
@ -132,7 +132,7 @@ parseDecimal:
|
||||
pop hl
|
||||
ret z
|
||||
; A is not 0? Ok, but if it's a space, we're happy too.
|
||||
jp isSep
|
||||
jp isWS
|
||||
.error:
|
||||
pop hl
|
||||
jp unsetZ
|
||||
|
@ -1,5 +1,5 @@
|
||||
; Sets Z is A is ' ' or '\t'
|
||||
isSep:
|
||||
; Sets Z is A is ' ' or '\t' (whitespace)
|
||||
isWS:
|
||||
cp ' '
|
||||
ret z
|
||||
cp 0x09
|
||||
|
@ -31,7 +31,7 @@ isLineEnd:
|
||||
|
||||
; Sets Z is A is ' ', ',', ';', CR, LF, or null.
|
||||
isSepOrLineEnd:
|
||||
call isSep
|
||||
call isWS
|
||||
ret z
|
||||
jr isLineEndOrComment
|
||||
|
||||
@ -68,7 +68,7 @@ isLabel:
|
||||
; read char in A
|
||||
_eatWhitespace:
|
||||
call ioGetB
|
||||
call isSep
|
||||
call isWS
|
||||
ret nz
|
||||
jr _eatWhitespace
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user