Przeglądaj źródła

cvm: improve comments

They were a bit terse.
master
Virgil Dupras 3 lat temu
rodzic
commit
25f4312523
2 zmienionych plików z 28 dodań i 11 usunięć
  1. +15
    -0
      cvm/vm.c
  2. +13
    -11
      cvm/vm.h

+ 15
- 0
cvm/vm.c Wyświetl plik

@@ -21,6 +21,8 @@ static VM vm;
static uint64_t blkop = 0; // 5 bytes
static FILE *blkfp;

// Read single byte from I/O handler, if set. addr is a word only because of
// Forth's cell size, but can't actually address more than a byte-ful of ports.
static byte io_read(word addr)
{
addr &= 0xff;
@@ -44,6 +46,9 @@ static void io_write(word addr, byte val)
}
}

// I/O hook to read/write a chunk of 1024 byte to blkfs at specified blkid.
// This is used by EFS@ and EFS! in xcomp.fs.
// See comment above BLK_PORT define for poking convention.
static void iowr_blk(byte val)
{
blkop <<= 8;
@@ -62,29 +67,37 @@ static void iowr_blk(byte val)
}
}

// get/set word from/to memory
static word gw(word addr) { return vm.mem[addr+1] << 8 | vm.mem[addr]; }
static void sw(word addr, word val) {
vm.mem[addr] = val;
vm.mem[addr+1] = val >> 8;
}
// pop word from SP
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;
}
// push word to SP
static void push(word x) {
vm.SP -= 2; sw(vm.SP, x);
if (vm.SP < vm.minSP) { vm.minSP = vm.SP; }
}
// pop word from RS
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;
}
// push word to RS
static void pushRS(word val) {
vm.RS += 2; sw(vm.RS, val);
if (vm.RS > vm.maxRS) { vm.maxRS = vm.RS; }
}

// The functions below directly map to native forth words defined in the
// dictionary (B30)
static void execute(word wordref) {
byte wtype = vm.mem[wordref];
if (wtype == 0) { // native
@@ -242,6 +255,7 @@ static void MINUS2() { push(pop()-2); }
static void PLUS2() { push(pop()+2); }
static void RSHIFT() { word u = pop(); push(pop()>>u); }
static void LSHIFT() { word u = pop(); push(pop()<<u); }

static void native(NativeWord func) {
vm.nativew[vm.nativew_count++] = func;
}
@@ -284,6 +298,7 @@ VM* VM_init() {
vm.iowr[i] = NULL;
}
vm.iowr[BLK_PORT] = iowr_blk;
// Added in the same order as in xcomp.fs
native(EXIT);
native(_br_);
native(_cbr_);


+ 13
- 11
cvm/vm.h Wyświetl plik

@@ -14,28 +14,30 @@ typedef void (*NativeWord) ();
typedef byte (*IORD) ();
typedef void (*IOWR) (byte data);

/* Native word placement
Being a C VM, all actual native code is outside the VM's memory. However,
we have a stable ABI to conform to. VM_init() configures the memory by
placing references to stable words at proper offsets, and then add all other
native words next to it. This will result in a "boot binary" that is much
more compact than a real Collapse OS memory layout.
*/
typedef struct {
byte mem[0x10000];
word SP;
word RS;
word IP;
word SP; // parameter Stack Pointer
word RS; // Return Stack pointer
word IP; // Interpreter Pointer
// A list of native words' code. This is filled in VM_init() by calls to
// native(). The order is very important because we refer to these elements
// by index. For example, "0x42 CODE FOO" in Forth creates the native word
// FOO which, when executed, will call the code at index 0x42 in this array.
NativeWord nativew[0x100];
byte nativew_count;
// Array of 0x100 function pointers to IO read and write routines. Leave to
// NULL when IO port is unhandled.
IORD iord[0x100];
IOWR iowr[0x100];
word xcurrent; // only used during native bootstrap
// Used for keeping track of max RS and min SP during the lifetime of the
// program. Useful for debugging.
word maxRS;
word minSP;
bool running;
// Whether we're in stack underflow situation. Alters the behavior of some
// core action, notably popping. Doesn't stay set for more than a single
// execute cycle. The goal is to avoid over-popping in native words that
// pop more than once and thus corrupt memory.
bool uflw;
} VM;



Ładowanie…
Anuluj
Zapisz