From 72d2a8f07323d04284878f158c4261c0686fb3c2 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Tue, 14 May 2019 15:26:29 -0400 Subject: [PATCH] zasm: add support for + expressions --- apps/zasm/directive.asm | 4 ++-- apps/zasm/expr.asm | 35 +++++++++++++++++++++++++++++++++++ apps/zasm/instr.asm | 4 ++-- apps/zasm/main.asm | 1 + apps/zasm/tests/test5.asm | 2 ++ parts/z80/core.asm | 14 ++++++++++---- 6 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 apps/zasm/expr.asm create mode 100644 apps/zasm/tests/test5.asm diff --git a/apps/zasm/directive.asm b/apps/zasm/directive.asm index 1b544ce..29c1e9a 100644 --- a/apps/zasm/directive.asm +++ b/apps/zasm/directive.asm @@ -39,7 +39,7 @@ handleDW: call toWord call readWord ld hl, scratchpad - call parseNumberOrSymbol + call parseExpr ld a, ixl ld (direcData), a ld a, ixh @@ -74,7 +74,7 @@ handleEQU: call toWord call readWord ld hl, scratchpad - call parseNumberOrSymbol + call parseExpr jr nz, .error ld hl, DIREC_SCRATCHPAD ld d, ixh diff --git a/apps/zasm/expr.asm b/apps/zasm/expr.asm new file mode 100644 index 0000000..82ec38b --- /dev/null +++ b/apps/zasm/expr.asm @@ -0,0 +1,35 @@ +; Parse expression in string at (HL) and returns the result in IX. +; We expect (HL) to be disposable: we mutate it to avoid having to make a copy. +; Sets Z on success, unset on error. +parseExpr: + push hl + ld a, '+' + call JUMP_FINDCHAR + jr nz, .noExpr + ; Alright, we have a + and we're pointing at it. Let's advance HL and + ; recurse. But first, let's change this + into a null char. It will be + ; handy later. + xor a + ld (hl), a ; + changed to \0 + + inc hl + call parseExpr + ; Whether parseExpr was successful or not, we pop hl right now + pop hl + ret nz ; return immediately if error + ; Now we have parsed everything to the right and we have its result in + ; IX. the pop hl brought us back to the beginning of the string. Our + ; + was changed to a 0. Let's save IX somewhere and parse this. + push de + ld d, ixh + ld e, ixl + call parseNumberOrSymbol + jr nz, .end ; error + ; Good! let's do the math! + add ix, de +.end: + pop de + ret +.noExpr: + pop hl + jp parseNumberOrSymbol diff --git a/apps/zasm/instr.asm b/apps/zasm/instr.asm index bb0d46f..0f60f65 100644 --- a/apps/zasm/instr.asm +++ b/apps/zasm/instr.asm @@ -153,7 +153,7 @@ parseArg: call enterParens jr z, .withParens ; (HL) has no parens - call parseNumberOrSymbol + call parseExpr jr nz, .nomatch ; We have a proper number in no parens. Number in IX. ld a, 'N' @@ -177,7 +177,7 @@ parseArg: .notY: ld c, 'x' .parseNumberInParens: - call parseNumberOrSymbol + call parseExpr jr nz, .nomatch ; We have a proper number in parens. Number in IX ld a, c ; M, x, or y diff --git a/apps/zasm/main.asm b/apps/zasm/main.asm index 4b9ea69..0440e23 100644 --- a/apps/zasm/main.asm +++ b/apps/zasm/main.asm @@ -47,6 +47,7 @@ jp zasmMain #include "io.asm" #include "tok.asm" #include "parse.asm" +#include "expr.asm" #include "instr.asm" .equ DIREC_RAMSTART IO_RAMEND #include "directive.asm" diff --git a/apps/zasm/tests/test5.asm b/apps/zasm/tests/test5.asm new file mode 100644 index 0000000..3343e41 --- /dev/null +++ b/apps/zasm/tests/test5.asm @@ -0,0 +1,2 @@ +; test expressions +ld a, 'A'+3 diff --git a/parts/z80/core.asm b/parts/z80/core.asm index 8703deb..546ae2c 100644 --- a/parts/z80/core.asm +++ b/parts/z80/core.asm @@ -108,6 +108,7 @@ fill: ; iterated in A. ; If a null char is encountered before we find A, processing is stopped in the ; same way as if we found our char (so, we look for A *or* 0) +; Set Z if the character is found. Unsets it if not findchar: push bc ld c, a ; let's use C as our cp target @@ -116,15 +117,20 @@ findchar: .loop: ld a, (hl) cp c - jr z, .end - cp 0 - jr z, .end + jr z, .match + or a ; cp 0 + jr z, .nomatch inc hl djnz .loop -.end: +.nomatch: + call unsetZ + jr .end +.match: ; We ran 0xff-B loops. That's the result that goes in A. ld a, 0xff sub a, b + cp a ; ensure Z +.end: pop bc ret