emul: build from "cvm" instead of from itself
The C VM now runs the show.
This commit is contained in:
parent
1312817117
commit
a65f674c74
@ -24,9 +24,10 @@ tools.
|
|||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Usage documentation is in-system, so access to documentation requires you to
|
Usage documentation is in-system, so access to documentation requires you to
|
||||||
run Collapse OS. Fortunately, doing so in an emulator is easy.
|
run Collapse OS. Fortunately, building and running Collapse OS on a POSIX
|
||||||
|
environment is easy.
|
||||||
|
|
||||||
See `/emul/README.md` for getting an emulated system running.
|
See `/cvm/README.md` for instructions.
|
||||||
|
|
||||||
Then, run `0 LIST` for an introduction, follow instructions from there.
|
Then, run `0 LIST` for an introduction, follow instructions from there.
|
||||||
|
|
||||||
|
47
cvm/README.md
Normal file
47
cvm/README.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# C VM
|
||||||
|
|
||||||
|
This is a C implementation of Collapse OS' native words. It allows Collapse OS
|
||||||
|
to run natively on any POSIX environment.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
You need `ncurses` to build the `forth` executable. In debian-based distros,
|
||||||
|
it's `libncurses5-dev`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Running `make` will yield `forth` and `stage` executables.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To play around Collapse OS, you'll want to run `./forth`. Type `0 LIST` for
|
||||||
|
help.
|
||||||
|
|
||||||
|
The program is a curses interface with a limited, fixed size so that it can
|
||||||
|
provide a AT-XY interface.
|
||||||
|
|
||||||
|
You can get a REPL by launching the program with [`rlwrap(1)`][rlwrap] like
|
||||||
|
this:
|
||||||
|
|
||||||
|
rlwrap -e '' -m -S '> ' ./forth /dev/stdin
|
||||||
|
|
||||||
|
## Problems?
|
||||||
|
|
||||||
|
If the `forth` executable works badly (hangs, spew garbage, etc.),
|
||||||
|
it's probably because you've broken your bootstrap binary. It's easy to
|
||||||
|
mistakenly break. To verify if you've done that, look at your git status. If
|
||||||
|
`forth.bin` is modified, try resetting it and then run `make clean all`. Things
|
||||||
|
should go better afterwards.
|
||||||
|
|
||||||
|
A modified `blkfs` can also break things (although even with a completely broken
|
||||||
|
blkfs, you should still get to prompt), you might want to run `make pack` to
|
||||||
|
ensure that the `blkfs` file is in sync with the contents of the `blk/` folder.
|
||||||
|
|
||||||
|
If that doesn't work, there's also the nuclear option of `git reset --hard`
|
||||||
|
and `git clean -fxd`.
|
||||||
|
|
||||||
|
If that still doesn't work, it might be because the current commit you're on
|
||||||
|
is broken, but that is rather rare: the repo on Github is plugged on Travis
|
||||||
|
and it checks that everything is smooth.
|
||||||
|
|
||||||
|
[rlwrap]: https://linux.die.net/man/1/rlwrap
|
4
emul/.gitignore
vendored
4
emul/.gitignore
vendored
@ -1,4 +1,2 @@
|
|||||||
/stage
|
|
||||||
/forth
|
/forth
|
||||||
/*-bin.h
|
/forth.bin
|
||||||
/blkfs
|
|
||||||
|
@ -1,47 +1,30 @@
|
|||||||
TARGETS = forth stage
|
TARGETS = forth
|
||||||
OBJS = emul.o libz80/libz80.o
|
OBJS = emul.o libz80/libz80.o
|
||||||
BLKPACK = ../tools/blkpack
|
CDIR = ../cvm
|
||||||
BLKUNPACK = ../tools/blkunpack
|
STAGE = $(CDIR)/stage
|
||||||
|
BLKFS = $(CDIR)/blkfs
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
$(BLKPACK):
|
forth: forth.c $(OBJS) $(CDIR)/blkfs
|
||||||
$(MAKE) -C ../tools
|
|
||||||
|
|
||||||
.PHONY: $(BLKUNPACK)
|
|
||||||
$(BLKUNPACK): $(BLKPACK)
|
|
||||||
|
|
||||||
stage: stage.c $(OBJS) blkfs
|
|
||||||
$(CC) stage.c $(OBJS) -o $@
|
|
||||||
|
|
||||||
blkfs: $(BLKPACK)
|
|
||||||
$(BLKPACK) ../blk > $@
|
|
||||||
|
|
||||||
forth: forth.c $(OBJS) blkfs
|
|
||||||
$(CC) forth.c $(OBJS) -lncurses -o $@
|
$(CC) forth.c $(OBJS) -lncurses -o $@
|
||||||
|
|
||||||
libz80/libz80.o: libz80/z80.c
|
libz80/libz80.o: libz80/z80.c
|
||||||
$(MAKE) -C libz80/codegen opcodes
|
$(MAKE) -C libz80/codegen opcodes
|
||||||
$(CC) -Wall -ansi -g -c -o libz80/libz80.o libz80/z80.c
|
$(CC) -Wall -ansi -g -c -o libz80/libz80.o libz80/z80.c
|
||||||
|
|
||||||
emul.o: emul.c
|
emul.o: emul.c forth.bin $(BLKFS)
|
||||||
$(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" -c -o emul.o emul.c
|
$(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/$(BLKFS)\" -c -o emul.o emul.c
|
||||||
|
|
||||||
|
forth.bin: xcomp.fs $(STAGE)
|
||||||
|
$(CDIR)/stage < xcomp.fs > $@
|
||||||
|
|
||||||
.PHONY: updatebootstrap
|
$(BLKFS): $(STAGE)
|
||||||
updatebootstrap: stage xcomp.fs pack
|
|
||||||
./stage < xcomp.fs > new.bin
|
|
||||||
mv new.bin forth.bin
|
|
||||||
|
|
||||||
.PHONY: pack
|
$(STAGE):
|
||||||
pack:
|
$(MAKE) -C $(CDIR) all
|
||||||
rm blkfs && $(MAKE) blkfs
|
|
||||||
|
|
||||||
.PHONY: unpack
|
|
||||||
unpack:
|
|
||||||
$(BLKUNPACK) ../blk < blkfs
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGETS) emul.o *-bin.h blkfs libz80/libz80.o
|
rm -f $(TARGETS) emul.o *.bin libz80/libz80.o
|
||||||
|
BIN
emul/forth.bin
BIN
emul/forth.bin
Binary file not shown.
80
emul/stage.c
80
emul/stage.c
@ -1,80 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "emul.h"
|
|
||||||
|
|
||||||
/* Staging binaries
|
|
||||||
|
|
||||||
The role of a stage executable is to compile definitions in a dictionary and
|
|
||||||
then spit the difference between the starting binary and the new binary.
|
|
||||||
|
|
||||||
That binary can then be grafted to an exiting Forth binary to augment its
|
|
||||||
dictionary.
|
|
||||||
|
|
||||||
We could, if we wanted, run only with the bootstrap binary and compile core
|
|
||||||
defs at runtime, but that would mean that those defs live in RAM. In may system,
|
|
||||||
RAM is much more constrained than ROM, so it's worth it to give ourselves the
|
|
||||||
trouble of compiling defs to binary.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RAMSTART 0
|
|
||||||
#define STDIO_PORT 0x00
|
|
||||||
// To know which part of RAM to dump, we listen to port 2, which at the end of
|
|
||||||
// its compilation process, spits its HERE addr to port 2 (MSB first)
|
|
||||||
#define HERE_PORT 0x02
|
|
||||||
|
|
||||||
static int running;
|
|
||||||
// We support double-pokes, that is, a first poke to tell where to start the
|
|
||||||
// dump and a second one to tell where to stop. If there is only one poke, it's
|
|
||||||
// then ending HERE and we start at sizeof(KERNEL).
|
|
||||||
static uint16_t start_here = 0;
|
|
||||||
static uint16_t end_here = 0;
|
|
||||||
|
|
||||||
static uint8_t iord_stdio()
|
|
||||||
{
|
|
||||||
int c = getc(stdin);
|
|
||||||
if (c == EOF) {
|
|
||||||
running = 0;
|
|
||||||
}
|
|
||||||
return (uint8_t)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iowr_stdio(uint8_t val)
|
|
||||||
{
|
|
||||||
// comment if you don't like verbose staging output
|
|
||||||
putc(val, stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iowr_here(uint8_t val)
|
|
||||||
{
|
|
||||||
start_here <<=8;
|
|
||||||
start_here |= (end_here >> 8);
|
|
||||||
end_here <<= 8;
|
|
||||||
end_here |= val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
Machine *m = emul_init();
|
|
||||||
if (m == NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
m->ramstart = RAMSTART;
|
|
||||||
m->iord[STDIO_PORT] = iord_stdio;
|
|
||||||
m->iowr[STDIO_PORT] = iowr_stdio;
|
|
||||||
m->iowr[HERE_PORT] = iowr_here;
|
|
||||||
// Run!
|
|
||||||
running = 1;
|
|
||||||
|
|
||||||
while (running && emul_step());
|
|
||||||
|
|
||||||
// We're done, now let's spit dict data
|
|
||||||
for (int i=start_here; i<end_here; i++) {
|
|
||||||
putchar(m->mem[i]);
|
|
||||||
}
|
|
||||||
emul_deinit();
|
|
||||||
emul_printdebug();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -4,11 +4,12 @@ git submodule init
|
|||||||
git submodule update
|
git submodule update
|
||||||
git clean -fxd
|
git clean -fxd
|
||||||
|
|
||||||
|
make -C cvm
|
||||||
make -C emul
|
make -C emul
|
||||||
make -C tests
|
make -C tests
|
||||||
|
|
||||||
# verify that forth.bin is stable
|
# verify that forth.bin is stable
|
||||||
cp emul/forth.bin ref.bin
|
cp cvm/forth.bin ref.bin
|
||||||
make -C emul updatebootstrap
|
make -C cvm updatebootstrap
|
||||||
cmp emul/forth.bin ref.bin
|
cmp cvm/forth.bin ref.bin
|
||||||
rm ref.bin
|
rm ref.bin
|
||||||
|
Loading…
Reference in New Issue
Block a user