aboutsummaryrefslogtreecommitdiff
path: root/src/micro/port_stub.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /src/micro/port_stub.c
a
Diffstat (limited to 'src/micro/port_stub.c')
-rw-r--r--src/micro/port_stub.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/micro/port_stub.c b/src/micro/port_stub.c
new file mode 100644
index 0000000..7bc22a7
--- /dev/null
+++ b/src/micro/port_stub.c
@@ -0,0 +1,59 @@
+/* bare-metal sketch. link this instead of port_linux.c and call micro_run
+ from the reset handler, after bss is cleared.
+
+ point UART_TX at the transmit register. leave micro_getc returning -1 and
+ micro_eof returning 1 when the program arrives in the image and nothing
+ else is typed. micro_syscall returns -1 for every op, which the runtime
+ treats as failure (open fails, time is unavailable). the virt boards do
+ not use this file; their port is src/baremetal/port.c. */
+#include "micro_port.h"
+
+/* example, machine dependent: volatile unsigned char *const UART_TX = (volatile unsigned char *)0x10000000; */
+
+static void uart_putc(unsigned char c)
+{
+ (void)c;
+ /* *UART_TX = c; */
+}
+
+/* the machine's memory on this board: the arena below, which is the board's RAM as
+ memmap.h sizes it. a board's RAM is a fixed amount of hardware, so this is the one
+ place the port has a size; it returns NULL past it. */
+/* physical backing is separate from the vm's configurable growth limit. */
+#ifndef MICRO_PORT_WORDS
+#define MICRO_PORT_WORDS (HEAP_HI > PW ? HEAP_HI : PW)
+#endif
+static Cell arena[MICRO_PORT_WORDS];
+
+Cell *micro_mem_alloc(UCell words)
+{
+ if (words > MICRO_PORT_WORDS) return 0;
+ return arena;
+}
+
+int micro_getc(void) { return -1; }
+int micro_eof(void) { return 1; }
+void micro_putc(int c) { uart_putc((unsigned char)c); }
+
+Cell micro_syscall(Cell *mem, Cell op, Cell a, Cell b, Cell c)
+{
+ /* no command line and no environment here, so argv[0] is <eval> alone */
+ if (op == 21) return 1;
+ if (op == 23) return 0;
+ if (op == 22) {
+ static const char lead[] = "<eval>";
+ int i;
+ if (a != 0) return -1;
+ if (!b) return 6;
+ for (i = 0; i < 6; i++) mem[b + i] = (unsigned char)lead[i];
+ mem[b + 6] = 0;
+ return 6;
+ }
+ (void)mem; (void)op; (void)a; (void)b; (void)c;
+ return -1;
+}
+
+void micro_msg(const char *s)
+{
+ while (*s) uart_putc((unsigned char)*s++);
+}