/* 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 alone */ if (op == 21) return 1; if (op == 23) return 0; if (op == 22) { static const char lead[] = ""; 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++); }