aboutsummaryrefslogtreecommitdiff
path: root/src/micro/micro_port.h
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/micro_port.h
a
Diffstat (limited to 'src/micro/micro_port.h')
-rw-r--r--src/micro/micro_port.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/micro/micro_port.h b/src/micro/micro_port.h
new file mode 100644
index 0000000..9f77987
--- /dev/null
+++ b/src/micro/micro_port.h
@@ -0,0 +1,89 @@
+/* host port for the microcore.
+ micro.c calls only these. a bare-metal port is the five functions below:
+ the uart replaces getc/putc, and every syscall returns -1. port_stub.c is
+ the empty shape the freestanding compile check links. src/baremetal/port.c is
+ the one that boots: a 16550 on riscv virt, a PL011 on aarch64 virt.
+ port_linux.c is the hosted one the test suite runs.
+
+ the core does not use stdio, malloc, or the string routines. it does need
+ a 64-bit C compiler (division is the compiler's own runtime, not libc) and
+ a zeroed bss before micro_run. memory starts at MICRO_MW_INIT words of 64
+ bits and grows through micro_mem_alloc when the heap asks for more. */
+#ifndef MICRO_PORT_H
+#define MICRO_PORT_H
+#include <stdint.h>
+#include "memmap.h"
+
+typedef int64_t Cell;
+typedef uint64_t UCell;
+#ifndef MICRO_MW_LIMIT
+#define MICRO_MW_LIMIT 0x7fffffff
+#endif
+/* configure initial words and the growth limit before micro_run. */
+int micro_memory_config(UCell initial, UCell limit);
+/* the machine starts at this many words and grows on demand through micro_mem_alloc.
+ the map's initial heap (HEAP_HI) on a growing map, the whole map (MW) otherwise.
+ there is no fixed ceiling: a run that needs more memory asks the port for it. */
+#ifndef MICRO_MW_INIT
+#if HEAP_GROW
+#define MICRO_MW_INIT HEAP_HI
+#else
+#define MICRO_MW_INIT MW
+#endif
+#endif
+
+/* the machine's memory, in words, from the port. micro_mem_alloc(words) returns a
+ zeroed base with at least words words that stays valid until the next call; the
+ port keeps what it already holds, so a grow keeps the contents. NULL when the port
+ has no more memory. micro_mem_words is the size micro.c has mapped now. */
+Cell *micro_mem_alloc(UCell words);
+UCell micro_mem_words(void);
+
+/* next input byte, 0..255, or -1 at end of input. does not report whether
+ another byte follows; micro_eof does that, and the core asks after each read. */
+int micro_getc(void);
+
+/* 1 when the next micro_getc would return -1, 0 when a byte is waiting.
+ must not consume the byte. called once before the first instruction. */
+int micro_eof(void);
+
+/* streaming input: micro_getc returns MICRO_WAIT when no byte is waiting yet but
+ more may come (micro_eof then says 0). the run then returns MICRO_SUSPENDED,
+ and the port calls micro_resume once it has bytes. the browser and the
+ extension use this for the language server; a port with blocking input never
+ needs it. micro_run and micro_resume return what run returns, MICRO_SUSPENDED
+ included. */
+#define MICRO_WAIT (-2)
+#define MICRO_SUSPENDED 3
+int micro_run(void);
+int micro_resume(void);
+
+/* write the low 8 bits. */
+void micro_putc(int c);
+
+/* a store of op to SYSGATE (ZFP+2; 0xA0002 on the default map). a, b, c are the three words after the gate.
+ mem is the whole machine. return the result, or -1 if op is unsupported.
+ 1 open(path, 0 read | 1 create/truncate) -> fd
+ 2 close(fd)
+ 3 read(fd, buf, n) 4 write(fd, buf, n) one byte per word
+ 5 getenv(name, buf, cap) -> length, or -1
+ 6 time. unix seconds on a hosted port; a hardware counter on bare metal
+ 7 exit(status). does not return
+ 8 a random word, never -1 when the port has a source
+ 9 memory: a = 0 words now, 1 HEAP_LO, 2 HEAP_HI, 3 bytes now, 4 grow to b words
+ 10 bopen(byte_addr, mode) 11 bread(fd, byte_addr, n)
+ 12 bwrite(fd, byte_addr, n) 13 bgetenv(name_byte_addr, dst_byte_addr, cap)
+ ops 1..5 and the names they take are one character per word, 0 terminated.
+ ops 10..13 are packed bytes, 0 terminated, the same layout as a b"..."
+ payload. the bare-metal port keeps files in RAM and answers
+ getenv("BOARD"). the stub returns -1. */
+Cell micro_syscall(Cell *mem, Cell op, Cell a, Cell b, Cell c);
+
+/* a short diagnostic, usually the stack-overflow lines. not program output.
+ may be a no-op. */
+void micro_msg(const char *s);
+
+/* copy the linked genome in and run from its entry. 0 on halt, 2 on a
+ stack overflow (after a message). */
+int micro_run(void);
+#endif