duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit f6985c0591295e6d2d573e7f2599fe95cb86ea6a
parent d76f086cea6d03802dcc9df7c9bd3ccab550e928
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed,  3 Aug 2022 16:43:47 -0400

cvm: Helloworld!

Diffstat:
Aposix/tmpboot.fs | 1+
Mposix/vm.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/posix/tmpboot.fs b/posix/tmpboot.fs @@ -0,0 +1 @@ +Hello world! diff --git a/posix/vm.c b/posix/vm.c @@ -21,7 +21,8 @@ The VM is little endian. #define HERE SYSVARS #define CURRENT HERE+4 #define COMPILING CURRENT+4 -#define CURWORD COMPILING+4 +#define INRD COMPILING+4 +#define CURWORD INRD+4 #define HEREMAX SYSVARS @@ -34,7 +35,6 @@ struct VM { dword RSP; dword PC; // when PC >= MEMSZ, machine is halted dword toptr; - dword bootptr; dword areg; byte mem[MEMSZ]; }; @@ -43,6 +43,7 @@ struct VM { static dword lblmain = 0; static struct VM vm = {0}; +static FILE *bootfp; // Utilities static byte gb(dword addr) { return vm.mem[addr]; } @@ -92,6 +93,7 @@ static void callwr(dword a) { cwrite(0x01); dwrite(a); } +static void callword(dword addr); // forward declaration // Operations @@ -199,7 +201,7 @@ static void NEXT() { // op: 0f } static void BOOTRD() { // op: 10 - ppush(gb(vm.bootptr++)); + ppush(fgetc(bootfp)); } static void EMIT() { // op: 11 @@ -506,7 +508,41 @@ static void STACKCHK() { // op: 4d } } -#define OPCNT 0x4e +static void MAYBEWORD() { // op: 4e + dword c, a; + // save toptr so that it doesn't mess in<, which could be calling a word + // with to semantics + dword toptr = vm.toptr; + vm.toptr = 0; + do { + callword(gd(INRD)); + c = ppop(); + if (c >> 31) { // EOF + vm.toptr = toptr; + ppush(0); + return; + } + } while (c <= ' '); + a = CURWORD+1; + do { + sb(a++, c); + callword(gd(INRD)); + c = ppop(); + } while (!(c >> 31) && (c > ' ')); + vm.toptr = toptr; + sb(CURWORD, a-CURWORD-1); // len + ppush(CURWORD); +} + +static void WORD() { // op: 4f + MAYBEWORD(); + if (!ppeek()) { + printf("word expected"); + ABORT(); + } +} + +#define OPCNT 0x50 static void (*ops[OPCNT])() = { BR, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT, EXECUTE, CELL, VAL, ALIAS, DOES, SLIT, CBR, NEXT, @@ -517,7 +553,7 @@ static void (*ops[OPCNT])() = { CSTORE, CWRITE, WFETCH, WSTORE, FETCH, STORE, ADDSTORE, WRITE, ADD, SUB, MUL, DIVMOD, AND, OR, XOR, BOOL, NOT, LT, SHLC, SHRC, LSHIFT, RSHIFT, LITN, EXECUTEWR, - EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK}; + EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD}; static char *opnames[OPCNT] = { "(br)", NULL, NULL, NULL, "bye", "bytefail", "quit", "(abort)", @@ -529,7 +565,28 @@ static char *opnames[OPCNT] = { "c!", "c,", "w@", "w!", "@", "!", "+!", ",", "+", "-", "*", "/mod", "and", "or", "xor", "bool", "not", "<", "<<c", ">>c", "lshift", "rshift", "litn", "execute,", - "exit,", "move", "move,", "rtype", "(wnf)", "stack?"}; + "exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word"}; + +static void oprun1() { // run next op + byte opcode = vm.mem[vm.PC++]; + if (opcode >= OPCNT) { + printf("Illegal opcode %02x at PC %08x\n", opcode, vm.PC-1); + BYEFAIL(); + } else { + ops[opcode](); + } +} + +static void callword(dword addr) { + dword oldPC; + // We push a special "0" marker to RS. This way, when PC is 0, we know that + // it's time to return from our callword(). + rpush(0); + oldPC = vm.PC; + vm.PC = addr; + while (vm.PC && (vm.PC < MEMSZ)) oprun1(); + vm.PC = oldPC; +} // Dictionary building static void entry(char *name) { @@ -546,6 +603,14 @@ static void opentry(byte op) { cwrite(op); } +static void sysalias(char *name, dword addr) { + entry(name); + litwr(addr); + cwrite(0x34); // @ + cwrite(0x08); // execute + retwr(); +} + static void buildsysdict() { sd(HERE, 0); sd(CURRENT, 0); @@ -560,31 +625,37 @@ static void buildsysdict() { for (int i=0x09; i<0x0b; i++) { opentry(i); retwr(); } for (int i=0x0b; i<0x10; i++) opentry(i); for (int i=0x10; i<OPCNT; i++) { opentry(i); retwr(); } + sysalias("in<", INRD); + sd(INRD, find("boot<")); lblmain = here(); sd(0x01, lblmain); - litwr('X'); + callwr(find("word")); callwr(find("dup")); callwr(find("1+")); - callwr(find("(emit)")); - callwr(find("(emit)")); + callwr(find("swap")); + callwr(find("c@")); + callwr(find("rtype")); + callwr(find("word")); + callwr(find("dup")); + callwr(find("1+")); + callwr(find("swap")); + callwr(find("c@")); + callwr(find("rtype")); callwr(find("bye")); } // Interpret loop int main() { - byte opcode; vm.PC = 0; vm.PSP = PSTOP; vm.RSP = RSTOP; - buildsysdict(); - while (vm.PC < MEMSZ) { - opcode = vm.mem[vm.PC++]; - if (opcode >= OPCNT) { - printf("Illegal opcode %02x at PC %08x\n", opcode, vm.PC-1); - BYEFAIL(); - } else { - ops[opcode](); - } + bootfp = fopen("posix/tmpboot.fs", "r"); + if (!bootfp) { + printf("Can't open boot file.\n"); + return 1; } + buildsysdict(); + while (vm.PC < MEMSZ) oprun1(); + fclose(bootfp); return MEMSZ - vm.PC; }