diff options
| author | 2026-10-12 08:46:23 +0330 | |
|---|---|---|
| committer | 2026-10-12 08:46:23 +0330 | |
| commit | ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch) | |
| tree | 70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /src/micro/micro_port.h | |
a
Diffstat (limited to 'src/micro/micro_port.h')
| -rw-r--r-- | src/micro/micro_port.h | 89 |
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 |
