From be2b73fa7b0da33d96200c4f51b8c3f5f76130c3 Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Mon, 27 Jan 2025 14:13:14 -0500
Subject: more const; add msp430 PoC

---
 Makefile      |  3 ++-
 foci.c        | 37 +++++++++++++++++++------------------
 foci.h        | 40 ++++++++++++++++++++++++----------------
 main.c        |  3 ---
 msp430/main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 97 insertions(+), 38 deletions(-)
 create mode 100644 msp430/main.c

diff --git a/Makefile b/Makefile
index 4a31f2e..6057c1f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
-#CC := arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -DFOCI_ARM
 CC := gcc -DFOCI_X86_64
+#CC := arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -DFOCI_ARM
+#CC := msp430-elf-gcc -DFOCI_MSP430 -mmcu=msp430g2553
 CFLAGS := -O3 -ggdb -g3 -Wall -Wextra
 
 all: foci
diff --git a/foci.c b/foci.c
index a75669e..107d317 100644
--- a/foci.c
+++ b/foci.c
@@ -18,9 +18,9 @@
 
 #define END_OF(arr) ((arr) + (sizeof((arr)) / sizeof(*(arr))))
 
-static intptr_t dstack[16];
-static intptr_t **rstack[16];
-static intptr_t dict[1000] = {
+static intptr_t dstack[8];
+static intptr_t **rstack[8];
+static intptr_t dict[100] = {
     0, 10, 0
 };
 #define state  dict[0]
@@ -140,8 +140,8 @@ W(colon,  ":",      &w_align)   FTH(here), LIT(0), comma, FTH(latest), comma,
 I(semic,  ";",      &w_colon)   LIT(fexit), comma, LIT(&LATEST), poke, intr, END
 I(literal, "literal", &w_semic) LIT(push), comma, comma, END
 N(b,      "_b",     &w_literal) { ++pp; pp = (intptr_t **)*pp; NEXT; }
-N(bz,     "_bz",    &w_literal) { ++pp; if (!*sp++) { pp = (intptr_t **)*pp; } NEXT; }
-I(fif,    "if",     &w_b)       LIT(bz), comma, FTH(here), LIT(0), comma, END
+N(bz,     "_bz",    &w_b)       { ++pp; if (!*sp++) { pp = (intptr_t **)*pp; } NEXT; }
+I(fif,    "if",     &w_bz)      LIT(bz), comma, FTH(here), LIT(0), comma, END
 I(then,   "then",   &w_fif)     FTH(here), LIT(sizeof(intptr_t)), sub, swap, poke, END
 I(felse,  "else",   &w_then)    LIT(b), comma, FTH(here), LIT(0), comma, swap, FTH(then), END
 W(tick,   "\'",     &w_felse)   compname, drop, lookup, peek, END
@@ -153,7 +153,7 @@ N(dot,    ".",      &w_hex)     ;
 N(emit,   "emit",   &w_dot)     { foci_putchar(*sp++); NEXT; }
 #define LATEST_INIT &w_emit
 
-void enter_forth(void *ptr)
+void enter_forth(const void * const ptr)
 {
     STASH;
     sp = saved_sp;
@@ -170,19 +170,20 @@ void enter_forth(void *ptr)
 __attribute__((noinline))
 static void dotimpl(intptr_t n)
 {
-    static char dotbuf[16];
+    static const char dottbl[16] = "0123456789abcdef";
+    static char dotbuf[16] = {0};
+    int i;
 
-    char *s = dotbuf + sizeof(dotbuf);
-    int neg = n < 0;
-    if (neg) n *= -1;
-    *--s = '\0';
-
-    do *--s = "0123456789abcdef"[n % BASE];
-    while (n /= BASE);
-    if (neg)
+    if (n < 0) {
+        n *= -1;
         foci_putchar('-');
-    while (*s)
-        foci_putchar(*s++);
+    }
+
+    for (i = 0; n > 0; n /= 10)
+        dotbuf[i++] = dottbl[n % BASE];
+
+    while (--i >= 0)
+        foci_putchar(dotbuf[i]);
     foci_putchar(' ');
 }
 
@@ -254,7 +255,7 @@ static void parse_word(const char *start, const char *end)
 
 void interpret(void)
 {
-    static char buf[128];
+    static char buf[80];
     char *s = buf - 1;
 
     do *++s = foci_getchar();
diff --git a/foci.h b/foci.h
index c61e302..c7d6fcb 100644
--- a/foci.h
+++ b/foci.h
@@ -26,22 +26,22 @@
 #define ATTR_LEN        (0x3F)
 
 #define WORD(name, tname, prev, attr) \
-    extern const void *name##_body[]; \
+    extern const void * const name##_body[]; \
     const struct word_t w_##name = { \
         name##_body, prev, attr + sizeof(tname) - 1, tname \
     }; \
-    const void *name##_body[] = {
+    const void * const name##_body[] = {
 #define LIT(x)  push, (void *)(x)
 #define FTH(w)  enter, (w##_body)
 #define END    fexit, };
 #define NATIVE(name, tname, prev, attr) \
-    extern const void *name##_body[]; \
+    static const void * const name##_body[2]; \
     NAKED void name(void); \
-    const struct word_t w_##name = { \
+    static const struct word_t w_##name = { \
         name##_body, prev, \
         (attr | ATTR_NATIVE) + sizeof(tname) - 1, tname \
     }; \
-    const void *name##_body[] = { name, fexit }; \
+    static const void * const name##_body[2] = { name, fexit }; \
     NAKED void name(void)
 
 #define W(name, tname, prev) WORD(name, tname, prev, 0)
@@ -49,36 +49,44 @@
 #define N(name, tname, prev) NATIVE(name, tname, prev, 0)
 #define C(name, tname, prev) NATIVE(name, tname, prev, ATTR_IMMEDIATE)
 
-#define NEXT    { goto *(*++pp); }
-
 struct word_t
 {
-    const void **body;
+    const void * const *body;
     const struct word_t *prev;
     unsigned char attr;
     char name[];
 } __attribute__ ((packed));
 
 #ifdef FOCI_ARM
-// ARM Cortex-M:
-register intptr_t *   sp  asm("r0"); // pointer to stack cells
-register intptr_t *** rp  asm("r1"); // stack of pp
-register intptr_t **  pp  asm("r2"); // pointer to ip
-register intptr_t     tmp asm("r8");
-#define STASH             asm("push {r0-r2,r8}")
-#define RESTORE           asm("pop {r0-r2,r8}")
+register intptr_t *   sp  asm("r4"); // pointer to stack cells
+register intptr_t *** rp  asm("r5"); // stack of pp
+register intptr_t **  pp  asm("r6"); // pointer to ip
+register intptr_t     tmp asm("r7");
+#define STASH             asm("push {r4-r7}")
+#define RESTORE           asm("pop {r4-r7}")
+#define NEXT              goto *(*++pp)
 #endif // FOCI_ARM
 
 #ifdef FOCI_X86_64
-// x86_64
 register intptr_t *   sp  asm("r12"); // pointer to stack cells
 register intptr_t *** rp  asm("r13"); // stack of pp
 register intptr_t **  pp  asm("r14"); // pointer to ip
 register intptr_t     tmp asm("r15");
 #define STASH             asm("push %r12; push %r13; push %r14")
 #define RESTORE           asm("pop %r14; pop %r13; pop %r12")
+#define NEXT              goto *(*++pp)
 #endif // FOCI_X86_64
 
+#ifdef FOCI_MSP430
+register intptr_t *   sp  asm("r4"); // pointer to stack cells
+register intptr_t *** rp  asm("r5"); // stack of pp
+register intptr_t **  pp  asm("r6"); // pointer to ip
+register intptr_t     tmp asm("r7");
+#define STASH             asm("push r4; push r5; push r6")
+#define RESTORE           asm("pop r6; pop r5; pop r4")
+#define NEXT              asm("incd r6;\n br @r6")
+#endif // FOCI_MSP430
+
 extern void foci_putchar(int);
 extern int  foci_getchar(void);
 
diff --git a/main.c b/main.c
index 4429d2d..e6230de 100644
--- a/main.c
+++ b/main.c
@@ -16,10 +16,7 @@
 
 #include "foci.h"
 
-#include <ctype.h>
-#include <stdbool.h>
 #include <stdio.h>
-#include <string.h>
 
 void foci_putchar(int ch)
 {
diff --git a/msp430/main.c b/msp430/main.c
new file mode 100644
index 0000000..5c83c2e
--- /dev/null
+++ b/msp430/main.c
@@ -0,0 +1,52 @@
+#include <msp430.h>
+
+#define FOCI_MSP430
+#include "../foci.h"
+
+int main()
+{
+    WDTCTL = WDTPW | WDTHOLD;
+
+    DCOCTL = 0;
+    BCSCTL1 = CALBC1_1MHZ;
+    DCOCTL = CALDCO_1MHZ;
+
+    P1SEL = BIT1 | BIT2;  // P1.1 = RXD, P1.2=TXD
+    P1SEL2 = BIT1 | BIT2; // P1.1 = RXD, P1.2=TXD
+    UCA0CTL1 |= UCSSEL_2; // SMCLK
+    UCA0BR0 = 104;        // 1MHz 9600
+    UCA0BR1 = 0;          // 1MHz 9600
+    UCA0MCTL = UCBRS0;    // Modulation UCBRSx = 1
+    UCA0CTL1 &= ~UCSWRST;
+
+    init();
+
+    foci_putchar('o');
+    foci_putchar('k');
+    foci_putchar('\n');
+
+    for (;;) {
+        interpret();
+        foci_putchar('o');
+        foci_putchar('k');
+        foci_putchar('\n');
+        //printf(compiling() ? "compiled <%d>\n" : "ok <%d>\n", depth());
+    }
+}
+
+void foci_putchar(int ch)
+{
+    while (!(IFG2 & UCA0TXIFG));
+    UCA0TXBUF = ch;
+}
+
+int foci_getchar(void)
+{
+    int ch;
+
+    while (!(IFG2 & UCA0RXIFG));
+    ch = UCA0RXBUF;
+    foci_putchar(ch);
+    return ch;
+}
+
-- 
cgit v1.2.3