mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-03 00:30:55 +11:00
Compare commits
No commits in common. "62138b12cf4080ba02971d82ad0232239ab713c0" and "f5b04fc02fc90c9e143201a3ef57c140fa980080" have entirely different histories.
62138b12cf
...
f5b04fc02f
27
CODE.md
27
CODE.md
@ -51,25 +51,6 @@ Therefore, shadow registers should only be used in code that doesn't call
|
|||||||
routines or that call a routine that explicitly states that it preserves
|
routines or that call a routine that explicitly states that it preserves
|
||||||
shadow registers.
|
shadow registers.
|
||||||
|
|
||||||
Another important note is that routines returning success with Z generally don't
|
|
||||||
preserve AF: too complicated. But otherwise, AF is often preserved. For example,
|
|
||||||
register fiddling routines in core try to preserve AF.
|
|
||||||
|
|
||||||
## Z for success
|
|
||||||
|
|
||||||
The vast majority of routines use the Z flag to indicate success. When Z is set,
|
|
||||||
it indicates success. When Z is unset, it indicates error. This follows the
|
|
||||||
tradition of a zero indicating success and a nonzero indicating error.
|
|
||||||
|
|
||||||
Important note: only Z indicate success. Many routines return a meaningful
|
|
||||||
nonzero value in A and still set Z to indicate success.
|
|
||||||
|
|
||||||
In error conditions, however, most of the time A is set to an error code.
|
|
||||||
|
|
||||||
In many routines, this is specified verbosely, but it's repeated so often that
|
|
||||||
I started writing it in short form, "Z for success", which means what is
|
|
||||||
described here.
|
|
||||||
|
|
||||||
## Stack management
|
## Stack management
|
||||||
|
|
||||||
Keeping the stack "balanced" is a big challenge when writing assembler code.
|
Keeping the stack "balanced" is a big challenge when writing assembler code.
|
||||||
@ -106,12 +87,4 @@ comments. Example:
|
|||||||
pop af ; <-- lvl 1
|
pop af ; <-- lvl 1
|
||||||
|
|
||||||
I think that this should do the trick, so I'll do this consistently from now on.
|
I think that this should do the trick, so I'll do this consistently from now on.
|
||||||
|
|
||||||
## String length
|
|
||||||
|
|
||||||
Pretty much every routine expecting a string have no provision for a string
|
|
||||||
that doesn't have null termination within 0xff bytes. Treat strings of such
|
|
||||||
lengths with extra precaution and distrust proper handling of existing routines
|
|
||||||
for those strings.
|
|
||||||
|
|
||||||
[zasm]: ../apps/zasm/README.md
|
[zasm]: ../apps/zasm/README.md
|
||||||
|
@ -14,17 +14,3 @@ 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,
|
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
|
not break anything, and have the wisdom to see when copy/pasting is a better
|
||||||
idea.
|
idea.
|
||||||
|
|
||||||
## Design goal
|
|
||||||
|
|
||||||
The reason for including a BASIC dialect in Collapse OS is to supply some form
|
|
||||||
of system administration swiss knife. zasm, ed and the shell can do
|
|
||||||
theoretically anything, but some tasks (which are difficult to predict) can
|
|
||||||
possibly be overly tedious. One can think, for example, about hardware
|
|
||||||
debugging. Poking and peeking around when not sure what we're looking for can
|
|
||||||
be a lot more effective with the help of variables, conditions and for-loops in
|
|
||||||
an interpreter.
|
|
||||||
|
|
||||||
Because the goal is not to provide a foundation for complex programs, I'm
|
|
||||||
planning on intentionally crippling this BASIC dialect for the sake of
|
|
||||||
simplicity.
|
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
; *** Consts ***
|
|
||||||
; maximum number of lines (line number maximum, however, is always 0xffff)
|
|
||||||
.equ BUF_MAXLINES 0x100
|
|
||||||
; Size of the string pool
|
|
||||||
.equ BUF_POOLSIZE 0x1000
|
|
||||||
|
|
||||||
; *** Variables ***
|
|
||||||
; A pointer to the first free line
|
|
||||||
.equ BUF_LFREE BUF_RAMSTART
|
|
||||||
; A pointer to the first free byte in the pool
|
|
||||||
.equ BUF_PFREE @+2
|
|
||||||
; The line index. Each record consists of 4 bytes: 2 for line number,
|
|
||||||
; 2 for pointer to string in pool. Kept in order of line numbers.
|
|
||||||
.equ BUF_LINES @+2
|
|
||||||
; The line pool. A list of null terminated strings. BUF_LINES records point
|
|
||||||
; to those strings.
|
|
||||||
.equ BUF_POOL @+BUF_MAXLINES*4
|
|
||||||
.equ BUF_RAMEND @+BUF_POOLSIZE
|
|
||||||
|
|
||||||
bufInit:
|
|
||||||
ld hl, BUF_LINES
|
|
||||||
ld (BUF_LFREE), hl
|
|
||||||
ld hl, BUF_POOL
|
|
||||||
ld (BUF_PFREE), hl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Add line at (HL) with line number DE to the buffer. The string at (HL) should
|
|
||||||
; not contain the line number prefix or the whitespace between the line number
|
|
||||||
; and the comment.
|
|
||||||
; Note that an empty string is *not* an error. It will be saved as a line.
|
|
||||||
; Z for success.
|
|
||||||
; Error conditions are:
|
|
||||||
; * not enough space in the pool
|
|
||||||
; * not enough space in the line index
|
|
||||||
bufAdd:
|
|
||||||
exx ; preserve HL and DE
|
|
||||||
; First step: do we have index space?
|
|
||||||
ld hl, (BUF_LFREE)
|
|
||||||
ld de, BUF_POOL
|
|
||||||
or a ; reset carry
|
|
||||||
sbc hl, de
|
|
||||||
exx ; restore
|
|
||||||
; no carry? HL >= BUF_POOL, error. Z already unset
|
|
||||||
ret nc
|
|
||||||
; Second step: see if we're within the pool's bounds
|
|
||||||
call strlen
|
|
||||||
inc a ; strlen doesn't include line termination
|
|
||||||
exx ; preserve HL and DE
|
|
||||||
ld hl, (BUF_PFREE)
|
|
||||||
call addHL
|
|
||||||
ld de, BUF_RAMEND
|
|
||||||
sbc hl, de
|
|
||||||
exx ; restore
|
|
||||||
; no carry? HL >= BUF_RAMEND, error. Z already unset
|
|
||||||
ret nc
|
|
||||||
; We have enough space.
|
|
||||||
; Third step: set line index data
|
|
||||||
push de ; --> lvl 1
|
|
||||||
push hl ; --> lvl 2
|
|
||||||
ld hl, (BUF_LFREE)
|
|
||||||
ld (hl), e
|
|
||||||
inc hl
|
|
||||||
ld (hl), d
|
|
||||||
inc hl
|
|
||||||
ld de, (BUF_PFREE)
|
|
||||||
ld (hl), e
|
|
||||||
inc hl
|
|
||||||
ld (hl), d
|
|
||||||
inc hl
|
|
||||||
ld (BUF_LFREE), hl
|
|
||||||
pop hl \ push hl ; <-- lvl 2, restore and preserve
|
|
||||||
|
|
||||||
; Fourth step: copy string to pool
|
|
||||||
ld de, (BUF_PFREE)
|
|
||||||
call strcpyM
|
|
||||||
ld (BUF_PFREE), de
|
|
||||||
pop hl ; <-- lvl 2
|
|
||||||
pop de ; <-- lvl 1
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Set IX to point to the beginning of the pool.
|
|
||||||
; Z set if (IX) is a valid line, unset if the pool is empty.
|
|
||||||
bufFirst:
|
|
||||||
ld ix, BUF_LINES
|
|
||||||
jp bufEOF
|
|
||||||
|
|
||||||
; Given a valid line record in IX, move IX to the next line.
|
|
||||||
; This routine doesn't check that IX is valid. Ensure IX validity before
|
|
||||||
; calling.
|
|
||||||
bufNext:
|
|
||||||
inc ix \ inc ix \ inc ix \ inc ix
|
|
||||||
jp bufEOF
|
|
||||||
|
|
||||||
; Returns whether line index at IX is past the end of file, that is,
|
|
||||||
; whether IX == (BUF_LFREE)
|
|
||||||
; Z is set when not EOF, unset when EOF.
|
|
||||||
bufEOF:
|
|
||||||
push hl
|
|
||||||
push de
|
|
||||||
push ix \ pop hl
|
|
||||||
ld de, (BUF_LFREE)
|
|
||||||
sbc hl, de
|
|
||||||
jr z, .empty
|
|
||||||
cp a ; ensure Z
|
|
||||||
.end:
|
|
||||||
pop de
|
|
||||||
pop hl
|
|
||||||
ret
|
|
||||||
.empty:
|
|
||||||
call unsetZ
|
|
||||||
jr .end
|
|
||||||
|
|
||||||
; Given a line index in (IX), set HL to its associated string pointer.
|
|
||||||
bufStr:
|
|
||||||
ld l, (ix+2)
|
|
||||||
ld h, (ix+3)
|
|
||||||
ret
|
|
@ -17,8 +17,6 @@
|
|||||||
.equ EXPR_PARSE parseLiteral
|
.equ EXPR_PARSE parseLiteral
|
||||||
.inc "lib/expr.asm"
|
.inc "lib/expr.asm"
|
||||||
.inc "basic/tok.asm"
|
.inc "basic/tok.asm"
|
||||||
.equ BUF_RAMSTART USER_RAMSTART
|
.equ BAS_RAMSTART USER_RAMSTART
|
||||||
.inc "basic/buf.asm"
|
|
||||||
.equ BAS_RAMSTART BUF_RAMEND
|
|
||||||
.inc "basic/main.asm"
|
.inc "basic/main.asm"
|
||||||
USER_RAMSTART:
|
USER_RAMSTART:
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
; *** Code ***
|
; *** Code ***
|
||||||
basStart:
|
basStart:
|
||||||
ld (BAS_INITSP), sp
|
ld (BAS_INITSP), sp
|
||||||
call bufInit
|
|
||||||
xor a
|
xor a
|
||||||
ld hl, .welcome
|
ld hl, .welcome
|
||||||
call printstr
|
call printstr
|
||||||
@ -33,13 +32,12 @@ basPrompt:
|
|||||||
call basDirect
|
call basDirect
|
||||||
jr basPrompt
|
jr basPrompt
|
||||||
.number:
|
.number:
|
||||||
push ix \ pop de
|
; do nothing for now, we only support direct mode.
|
||||||
call toWS
|
ld hl, .sNumber
|
||||||
call rdWS
|
call basPrintLn
|
||||||
call bufAdd
|
|
||||||
jp nz, basERR
|
|
||||||
call printcrlf
|
|
||||||
jr basPrompt
|
jr basPrompt
|
||||||
|
.sNumber:
|
||||||
|
.db "A number!", 0
|
||||||
.sPrompt:
|
.sPrompt:
|
||||||
.db "> ", 0
|
.db "> ", 0
|
||||||
|
|
||||||
@ -106,26 +104,6 @@ basBYE:
|
|||||||
.sBye:
|
.sBye:
|
||||||
.db "Goodbye!", 0
|
.db "Goodbye!", 0
|
||||||
|
|
||||||
basLIST:
|
|
||||||
call printcrlf
|
|
||||||
call bufFirst
|
|
||||||
ret nz
|
|
||||||
.loop:
|
|
||||||
ld e, (ix)
|
|
||||||
ld d, (ix+1)
|
|
||||||
ld hl, BAS_SCRATCHPAD
|
|
||||||
call fmtDecimal
|
|
||||||
call printstr
|
|
||||||
ld a, ' '
|
|
||||||
call stdioPutC
|
|
||||||
call bufStr
|
|
||||||
call printstr
|
|
||||||
call printcrlf
|
|
||||||
call bufNext
|
|
||||||
jr z, .loop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
basPRINT:
|
basPRINT:
|
||||||
call parseExpr
|
call parseExpr
|
||||||
jp nz, basERR
|
jp nz, basERR
|
||||||
@ -138,8 +116,6 @@ basPRINT:
|
|||||||
basCmds1:
|
basCmds1:
|
||||||
.dw basBYE
|
.dw basBYE
|
||||||
.db "bye", 0, 0, 0
|
.db "bye", 0, 0, 0
|
||||||
.dw basLIST
|
|
||||||
.db "list", 0, 0
|
|
||||||
; statements
|
; statements
|
||||||
basCmds2:
|
basCmds2:
|
||||||
.dw basPRINT
|
.dw basPRINT
|
||||||
|
@ -46,11 +46,3 @@ fnWSIdx:
|
|||||||
pop bc
|
pop bc
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Advance HL to the next whitespace or to the end of string.
|
|
||||||
toWS:
|
|
||||||
ld a, (hl)
|
|
||||||
call isSep
|
|
||||||
ret z
|
|
||||||
inc hl
|
|
||||||
jr toWS
|
|
||||||
|
Loading…
Reference in New Issue
Block a user