aboutsummaryrefslogtreecommitdiff
path: root/src/micro/port_stub.c
blob: 7bc22a7361856d2aadd51117edb3e669046be231 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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++);
}