From ae6334906ceea201e4ff84c5bfdd26a427443321 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Wed, 18 Mar 2020 22:18:07 -0400 Subject: [PATCH] forth: inline kernel's core and str units --- apps/forth/glue.asm | 1 - apps/forth/util.asm | 69 ++++++++++++++++++++++++++++++++++++++++++++ emul/forth/glue0.asm | 2 -- emul/forth/glue1.asm | 3 -- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/apps/forth/glue.asm b/apps/forth/glue.asm index 32bcded..c268543 100644 --- a/apps/forth/glue.asm +++ b/apps/forth/glue.asm @@ -1,7 +1,6 @@ .inc "user.h" jp forthMain -.inc "core.asm" .equ FORTH_RAMSTART RAMSTART .inc "forth/main.asm" .inc "forth/util.asm" diff --git a/apps/forth/util.asm b/apps/forth/util.asm index 0c1e7cb..82c553b 100644 --- a/apps/forth/util.asm +++ b/apps/forth/util.asm @@ -6,6 +6,43 @@ ; give us an idea of Forth's compactness. ; These routines below are copy/paste from apps/lib. +; Ensures that Z is unset (more complicated than it sounds...) +; There are often better inline alternatives, either replacing rets with +; appropriate jmps, or if an 8 bit register is known to not be 0, an inc +; then a dec. If a is nonzero, 'or a' is optimal. +unsetZ: + or a ;if a nonzero, Z reset + ret nz + cp 1 ;if a is zero, Z reset + ret + +; copy (HL) into DE, then exchange the two, utilising the optimised HL instructions. +; ld must be done little endian, so least significant byte first. +intoHL: + push de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + pop de + ret + +intoDE: + ex de, hl + call intoHL + ex de, hl ; de preserved by intoHL, so no push/pop needed + ret + +; add the value of A into HL +; affects carry flag according to the 16-bit addition, Z, S and P untouched. +addHL: + push de + ld d, 0 + ld e, a + add hl, de + pop de + ret + ; make Z the opposite of what it is now toggleZ: jp z, unsetZ @@ -57,6 +94,38 @@ strcmp: ; early, set otherwise) ret +; Compares strings pointed to by HL and DE up to A count of characters. If +; equal, Z is set. If not equal, Z is reset. +strncmp: + push bc + push hl + push de + + ld b, a +.loop: + ld a, (de) + cp (hl) + jr nz, .end ; not equal? break early. NZ is carried out + ; to the called + cp 0 ; If our chars are null, stop the cmp + jr z, .end ; The positive result will be carried to the + ; caller + inc hl + inc de + djnz .loop + ; We went through all chars with success, but our current Z flag is + ; unset because of the cp 0. Let's do a dummy CP to set the Z flag. + cp a + +.end: + pop de + pop hl + pop bc + ; Because we don't call anything else than CP that modify the Z flag, + ; our Z value will be that of the last cp (reset if we broke the loop + ; early, set otherwise) + ret + ; Given a string at (HL), move HL until it points to the end of that string. strskip: push bc diff --git a/emul/forth/glue0.asm b/emul/forth/glue0.asm index 5291990..7731b34 100644 --- a/emul/forth/glue0.asm +++ b/emul/forth/glue0.asm @@ -15,8 +15,6 @@ jp init -.inc "core.asm" -.inc "str.asm" .equ STDIO_RAMSTART RAMSTART .equ STDIO_GETC emulGetC diff --git a/emul/forth/glue1.asm b/emul/forth/glue1.asm index 919e608..a03deea 100644 --- a/emul/forth/glue1.asm +++ b/emul/forth/glue1.asm @@ -6,9 +6,6 @@ jp init -.inc "core.asm" -.inc "str.asm" - .equ STDIO_RAMSTART RAMSTART .equ STDIO_GETC emulGetC .equ STDIO_PUTC emulPutC