mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-26 09:48:05 +11:00
Compare commits
2 Commits
e17dc1e1e1
...
1b01f13105
Author | SHA1 | Date | |
---|---|---|---|
|
1b01f13105 | ||
|
fd5b2ab856 |
@ -61,3 +61,38 @@ relevant parts of the app's glue unit in your kernel's glue unit. This is often
|
|||||||
simpler and more efficient. However, if your shell is a big program, it might
|
simpler and more efficient. However, if your shell is a big program, it might
|
||||||
run into zasm's limits. In that case, you'd have to assemble your shell
|
run into zasm's limits. In that case, you'd have to assemble your shell
|
||||||
separately.
|
separately.
|
||||||
|
|
||||||
|
## Common features
|
||||||
|
|
||||||
|
The folder `lib/` contains code shared in more than one apps and this has the
|
||||||
|
effect that some concepts are exactly the same in many application. They are
|
||||||
|
therefore sharing documentation, here.
|
||||||
|
|
||||||
|
### Number literals
|
||||||
|
|
||||||
|
There are decimal, hexadecimal and binary literals. A "straight" number is
|
||||||
|
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
|
||||||
|
Binary must be prefixed with `0b` (`0b01100110`).
|
||||||
|
|
||||||
|
Decimals and hexadecimal are "flexible". Whether they're written in a byte or
|
||||||
|
a word, you don't need to prefix them with zeroes. Watch out for overflow,
|
||||||
|
however.
|
||||||
|
|
||||||
|
Binary literals are also "flexible" (`0b110` is fine), but can't go over a byte.
|
||||||
|
|
||||||
|
There is also the char literal (`'X'`), that is, two quotes with a character in
|
||||||
|
the middle. The value of that character is interpreted as-is, without any
|
||||||
|
encoding involved. That is, whatever binary code is written in between those
|
||||||
|
two quotes, it's what is evaluated. Only a single byte at once can be evaluated
|
||||||
|
thus. There is no escaping. `'''` results in `0x27`. You can't express a newline
|
||||||
|
this way, it's going to mess with the parser.
|
||||||
|
|
||||||
|
### Expressions
|
||||||
|
|
||||||
|
An expression is a bunch of literals or symbols assembled by operators. For
|
||||||
|
now, only `+`, `-` and `*` operators are supported. No parenthesis yet.
|
||||||
|
|
||||||
|
Symbols have a different meaning depending on the application. In zasm, it's
|
||||||
|
labels and constants. In basic, it's variables.
|
||||||
|
|
||||||
|
Expressions can't contain spaces.
|
||||||
|
@ -49,12 +49,11 @@ by typing a whitespace.
|
|||||||
|
|
||||||
Only 16-bit integers (unsigned for now) are supported in this BASIC. When
|
Only 16-bit integers (unsigned for now) are supported in this BASIC. When
|
||||||
printed, they're printed in decimal form. When expressing number literals, you
|
printed, they're printed in decimal form. When expressing number literals, you
|
||||||
can do so either in decimal (`42`), hexadecimal (`0x2a`), binary (`0b101010`)
|
can do so either in multiple forms. . See "Number literals" in `apps/README.md`
|
||||||
or char ('a', resulting in number 97).
|
for details.
|
||||||
|
|
||||||
Expressions are accepted wherever a number is expected. For example,
|
Expressions are accepted wherever a number is expected. For example,
|
||||||
`print 2+3` will print `5`. Expressions can't have whitespace inside them and
|
`print 2+3` will print `5`. See "Expressions" in `apps/README.md`.
|
||||||
don't support (yet) parentheses. Supported operators are `+`, `-`, `*` and `/`.
|
|
||||||
|
|
||||||
Inside a `if` command, "truth" expressions are accepted (`=`, `<`, `>`, `<=`,
|
Inside a `if` command, "truth" expressions are accepted (`=`, `<`, `>`, `<=`,
|
||||||
`>=`). A thruth expression that doesn't contain a truth operator evaluates the
|
`>=`). A thruth expression that doesn't contain a truth operator evaluates the
|
||||||
|
@ -25,3 +25,20 @@ divide:
|
|||||||
sbc a, d
|
sbc a, d
|
||||||
ld h, a
|
ld h, a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; DE * BC -> DE (high) and HL (low)
|
||||||
|
multDEBC:
|
||||||
|
ld hl, 0
|
||||||
|
ld a, 0x10
|
||||||
|
.loop:
|
||||||
|
add hl, hl
|
||||||
|
rl e
|
||||||
|
rl d
|
||||||
|
jr nc, .noinc
|
||||||
|
add hl, bc
|
||||||
|
jr nc, .noinc
|
||||||
|
inc de
|
||||||
|
.noinc:
|
||||||
|
dec a
|
||||||
|
jr nz, .loop
|
||||||
|
ret
|
||||||
|
@ -23,16 +23,30 @@ parseExpr:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
_parseExpr:
|
_parseExpr:
|
||||||
ld a, '+'
|
ld de, exprTbl
|
||||||
|
.loop:
|
||||||
|
ld a, (de)
|
||||||
|
or a
|
||||||
|
jp z, EXPR_PARSE ; no operator, just parse the literal
|
||||||
|
push de ; --> lvl 1. save operator row
|
||||||
call _findAndSplit
|
call _findAndSplit
|
||||||
jp z, _applyPlus
|
jr z, .found
|
||||||
ld a, '-'
|
pop de ; <-- lvl 1
|
||||||
call _findAndSplit
|
inc de \ inc de \ inc de
|
||||||
jp z, _applyMinus
|
jr .loop
|
||||||
ld a, '*'
|
.found:
|
||||||
call _findAndSplit
|
; Operator found, string splitted. Left in (HL), right in (DE)
|
||||||
jp z, _applyMult
|
call _resolveLeftAndRight
|
||||||
jp EXPR_PARSE
|
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
|
||||||
|
; out, which contains our operator row. We pop it in HL because we
|
||||||
|
; don't need our string anymore. L-R numbers are parsed, and in DE and
|
||||||
|
; IX.
|
||||||
|
pop hl ; <-- lvl 1
|
||||||
|
ret nz
|
||||||
|
; Resolving left and right succeeded, proceed!
|
||||||
|
inc hl ; point to routine pointer
|
||||||
|
call intoHL
|
||||||
|
jp (hl)
|
||||||
|
|
||||||
; Given a string in (HL) and a separator char in A, return a splitted string,
|
; Given a string in (HL) and a separator char in A, return a splitted string,
|
||||||
; that is, the same (HL) string but with the found A char replaced by a null
|
; that is, the same (HL) string but with the found A char replaced by a null
|
||||||
@ -88,20 +102,25 @@ _resolveLeftAndRight:
|
|||||||
pop de ; numeric left expr result in DE
|
pop de ; numeric left expr result in DE
|
||||||
jp parseExpr
|
jp parseExpr
|
||||||
|
|
||||||
; Parse expr in (HL) and expr in (DE) and apply + operator to both sides.
|
; Routines in here all have the same signature: they take two numbers, DE (left)
|
||||||
; Put result in IX.
|
; and IX (right), apply the operator and put the resulting number in IX.
|
||||||
_applyPlus:
|
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
|
||||||
call _resolveLeftAndRight
|
; pointer.
|
||||||
ret nz
|
exprTbl:
|
||||||
; Good! let's do the math! IX has our right part, DE has our left one.
|
.db '+'
|
||||||
|
.dw .plus
|
||||||
|
.db '-'
|
||||||
|
.dw .minus
|
||||||
|
.db '*'
|
||||||
|
.dw .mult
|
||||||
|
.db 0 ; end of table
|
||||||
|
|
||||||
|
.plus:
|
||||||
add ix, de
|
add ix, de
|
||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Same as _applyPlus but with -
|
.minus:
|
||||||
_applyMinus:
|
|
||||||
call _resolveLeftAndRight
|
|
||||||
ret nz
|
|
||||||
push ix
|
push ix
|
||||||
pop hl
|
pop hl
|
||||||
ex de, hl
|
ex de, hl
|
||||||
@ -112,9 +131,7 @@ _applyMinus:
|
|||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
|
|
||||||
_applyMult:
|
.mult:
|
||||||
call _resolveLeftAndRight
|
|
||||||
ret nz
|
|
||||||
push ix \ pop bc
|
push ix \ pop bc
|
||||||
call multDEBC
|
call multDEBC
|
||||||
push hl \ pop ix
|
push hl \ pop ix
|
||||||
|
@ -73,20 +73,3 @@ strlen:
|
|||||||
pop hl
|
pop hl
|
||||||
pop bc
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; DE * BC -> DE (high) and HL (low)
|
|
||||||
multDEBC:
|
|
||||||
ld hl, 0
|
|
||||||
ld a, 0x10
|
|
||||||
.loop:
|
|
||||||
add hl, hl
|
|
||||||
rl e
|
|
||||||
rl d
|
|
||||||
jr nc, .noinc
|
|
||||||
add hl, bc
|
|
||||||
jr nc, .noinc
|
|
||||||
inc de
|
|
||||||
.noinc:
|
|
||||||
dec a
|
|
||||||
jr nz, .loop
|
|
||||||
ret
|
|
||||||
|
@ -28,28 +28,13 @@ The resulting `zasm` binary takes asm code in stdin and spits binary in stdout.
|
|||||||
|
|
||||||
## Literals
|
## Literals
|
||||||
|
|
||||||
There are decimal, hexadecimal and binary literals. A "straight" number is
|
See "Number literals" in `apps/README.md`.
|
||||||
parsed as a decimal. Hexadecimal literals must be prefixed with `0x` (`0xf4`).
|
|
||||||
Binary must be prefixed with `0b` (`0b01100110`).
|
|
||||||
|
|
||||||
Decimals and hexadecimal are "flexible". Whether they're written in a byte or
|
On top of common literal logic, zasm also has string literals. It's a chain of
|
||||||
a word, you don't need to prefix them with zeroes. Watch out for overflow,
|
characters surrounded by double quotes. Example: `"foo"`. This literal can only
|
||||||
however.
|
be used in the `.db` directive and is equivalent to each character being
|
||||||
|
single-quoted and separated by commas (`'f', 'o', 'o'`). No null char is
|
||||||
Binary literals are also "flexible" (`0b110` is fine), but can't go over a byte.
|
inserted in the resulting value (unlike what C does).
|
||||||
|
|
||||||
There is also the char literal (`'X'`), that is, two qutes with a character in
|
|
||||||
the middle. The value of that character is interpreted as-is, without any
|
|
||||||
encoding involved. That is, whatever binary code is written in between those
|
|
||||||
two quotes, it's what is evaluated. Only a single byte at once can be evaluated
|
|
||||||
thus. There is no escaping. `'''` results in `0x27`. You can't express a newline
|
|
||||||
this way, it's going to mess with the parser.
|
|
||||||
|
|
||||||
Then comes our last literal, the string literal. It's a chain of characters
|
|
||||||
surrounded by double quotes. Example: `"foo"`. This literal can only be used
|
|
||||||
in the `.db` directive and is equivalent to each character being single-quoted
|
|
||||||
and separated by commas (`'f', 'o', 'o'`). No null char is inserted in the
|
|
||||||
resulting value (unlike what C does).
|
|
||||||
|
|
||||||
## Labels
|
## Labels
|
||||||
|
|
||||||
@ -100,11 +85,7 @@ of declaration order.
|
|||||||
|
|
||||||
## Expressions
|
## Expressions
|
||||||
|
|
||||||
Wherever a constant is expected, an expression can be written. An expression
|
See "Expressions" in `apps/README.md`.
|
||||||
is a bunch of literals or symbols assembled by operators. For now, only `+`, `-`
|
|
||||||
and `*` operators are supported. No parenthesis yet.
|
|
||||||
|
|
||||||
Expressions can't contain spaces.
|
|
||||||
|
|
||||||
## The Program Counter
|
## The Program Counter
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ jp zasmMain
|
|||||||
.inc "core.asm"
|
.inc "core.asm"
|
||||||
.inc "zasm/const.asm"
|
.inc "zasm/const.asm"
|
||||||
.inc "lib/util.asm"
|
.inc "lib/util.asm"
|
||||||
|
.inc "lib/ari.asm"
|
||||||
.inc "lib/parse.asm"
|
.inc "lib/parse.asm"
|
||||||
.inc "lib/args.asm"
|
.inc "lib/args.asm"
|
||||||
.inc "zasm/util.asm"
|
.inc "zasm/util.asm"
|
||||||
|
@ -3,6 +3,7 @@ jp test
|
|||||||
.inc "core.asm"
|
.inc "core.asm"
|
||||||
.inc "str.asm"
|
.inc "str.asm"
|
||||||
.inc "lib/util.asm"
|
.inc "lib/util.asm"
|
||||||
|
.inc "lib/ari.asm"
|
||||||
.inc "lib/parse.asm"
|
.inc "lib/parse.asm"
|
||||||
.equ EXPR_PARSE parseLiteral
|
.equ EXPR_PARSE parseLiteral
|
||||||
.inc "lib/expr.asm"
|
.inc "lib/expr.asm"
|
||||||
|
@ -12,6 +12,7 @@ jp test
|
|||||||
.inc "core.asm"
|
.inc "core.asm"
|
||||||
.inc "str.asm"
|
.inc "str.asm"
|
||||||
.inc "lib/util.asm"
|
.inc "lib/util.asm"
|
||||||
|
.inc "lib/ari.asm"
|
||||||
.inc "zasm/util.asm"
|
.inc "zasm/util.asm"
|
||||||
.inc "zasm/const.asm"
|
.inc "zasm/const.asm"
|
||||||
.inc "lib/parse.asm"
|
.inc "lib/parse.asm"
|
||||||
|
35
tools/tests/unit/test_lib_ari.asm
Normal file
35
tools/tests/unit/test_lib_ari.asm
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
jp test
|
||||||
|
|
||||||
|
.inc "core.asm"
|
||||||
|
.inc "lib/ari.asm"
|
||||||
|
|
||||||
|
testNum: .db 1
|
||||||
|
|
||||||
|
test:
|
||||||
|
ld sp, 0xffff
|
||||||
|
|
||||||
|
ld de, 12
|
||||||
|
ld bc, 4
|
||||||
|
call multDEBC
|
||||||
|
ld a, l
|
||||||
|
cp 48
|
||||||
|
jp nz, fail
|
||||||
|
call nexttest
|
||||||
|
|
||||||
|
; success
|
||||||
|
xor a
|
||||||
|
halt
|
||||||
|
|
||||||
|
nexttest:
|
||||||
|
ld a, (testNum)
|
||||||
|
inc a
|
||||||
|
ld (testNum), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
fail:
|
||||||
|
ld a, (testNum)
|
||||||
|
halt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,14 +12,6 @@ test:
|
|||||||
ld hl, 0xffff
|
ld hl, 0xffff
|
||||||
ld sp, hl
|
ld sp, hl
|
||||||
|
|
||||||
ld de, 12
|
|
||||||
ld bc, 4
|
|
||||||
call multDEBC
|
|
||||||
ld a, l
|
|
||||||
cp 48
|
|
||||||
jp nz, fail
|
|
||||||
call nexttest
|
|
||||||
|
|
||||||
ld hl, sFoo
|
ld hl, sFoo
|
||||||
call strlen
|
call strlen
|
||||||
cp 3
|
cp 3
|
||||||
|
@ -4,6 +4,7 @@ jp runTests
|
|||||||
.inc "core.asm"
|
.inc "core.asm"
|
||||||
.inc "str.asm"
|
.inc "str.asm"
|
||||||
.inc "zasm/const.asm"
|
.inc "zasm/const.asm"
|
||||||
|
.inc "lib/ari.asm"
|
||||||
.inc "lib/util.asm"
|
.inc "lib/util.asm"
|
||||||
.inc "zasm/util.asm"
|
.inc "zasm/util.asm"
|
||||||
.inc "lib/parse.asm"
|
.inc "lib/parse.asm"
|
||||||
|
Loading…
Reference in New Issue
Block a user