diff --git a/cvm/Makefile b/cvm/Makefile index 6b29eaa..880fddf 100644 --- a/cvm/Makefile +++ b/cvm/Makefile @@ -1,4 +1,4 @@ -TARGETS = forth +TARGETS = forth stage OBJS = vm.o BLKPACK = ../tools/blkpack BLKUNPACK = ../tools/blkunpack @@ -18,17 +18,19 @@ stage: stage.c $(OBJS) blkfs blkfs: $(BLKPACK) $(BLKPACK) ../blk > $@ -forth: forth.c $(OBJS) blkfs +forth: forth.c $(OBJS) $(CC) forth.c $(OBJS) -lncurses -o $@ -vm.o: vm.c +stage: stage.c $(OBJS) + $(CC) stage.c $(OBJS) -lncurses -o $@ + +vm.o: vm.c blkfs $(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" -c -o vm.o vm.c .PHONY: updatebootstrap updatebootstrap: stage xcomp.fs pack ./stage < xcomp.fs > new.bin - mv new.bin forth.bin .PHONY: pack pack: diff --git a/cvm/vm.c b/cvm/vm.c index 68167e9..d159efe 100644 --- a/cvm/vm.c +++ b/cvm/vm.c @@ -67,12 +67,20 @@ static void sw(word addr, word val) { vm.mem[addr] = val; vm.mem[addr+1] = val >> 8; } -static word pop() { return vm.mem[vm.SP++] | vm.mem[vm.SP++] << 8; } +static word pop() { + if (vm.uflw) return 0; + if (vm.SP >= SP_ADDR) { vm.uflw = true; } + return vm.mem[vm.SP++] | vm.mem[vm.SP++] << 8; +} static void push(word x) { vm.SP -= 2; sw(vm.SP, x); if (vm.SP < vm.minSP) { vm.minSP = vm.SP; } } -static word popRS() { word x = gw(vm.RS); vm.RS -= 2; return x; } +static word popRS() { + if (vm.uflw) return 0; + if (vm.RS <= RS_ADDR) { vm.uflw = true; } + word x = gw(vm.RS); vm.RS -= 2; return x; +} static void pushRS(word val) { vm.RS += 2; sw(vm.RS, val); if (vm.RS > vm.maxRS) { vm.maxRS = vm.RS; } @@ -351,6 +359,7 @@ VM* VM_init() { vm.IP = gw(0x04) + 1; // BOOT sw(SYSVARS+0x02, gw(0x08)); // CURRENT sw(SYSVARS+0x04, gw(0x08)); // HERE + vm.uflw = false; vm.running = true; return &vm; } @@ -369,6 +378,10 @@ bool VM_steps(int n) { word wordref = gw(vm.IP); vm.IP += 2; execute(wordref); + if (vm.uflw) { + vm.uflw = false; + execute(gw(0x06)); /* uflw */ + } n--; } return vm.running; diff --git a/cvm/vm.h b/cvm/vm.h index 5d80abc..b0c7c62 100644 --- a/cvm/vm.h +++ b/cvm/vm.h @@ -36,6 +36,7 @@ typedef struct { word maxRS; word minSP; bool running; + bool uflw; } VM; VM* VM_init();