commit 9c9fa65864337e6a313be023e4266ee38b0ac389
parent 4a0851e9e5d28d9d9397b0e5cc5e21c29f5e4ba6
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Fri, 30 Sep 2022 08:48:16 -0400
app/cos: update cvm.c prototype
CC's design target changed in the last few commits, this means a change in
cvm.c's target code.
Diffstat:
M | fs/app/cos/cvm.c | | | 117 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 62 insertions(+), 55 deletions(-)
diff --git a/fs/app/cos/cvm.c b/fs/app/cos/cvm.c
@@ -1,4 +1,5 @@
// This doesn't compile. It's a prototype of what it will look like.
+// TODO: typedefs
// TODO: function pointer arrays (iord iowr).
// TODO: += -= &= |= %
// TODO: %s %x (4b hex) %w (2b hex) %b (1b hex) formatting
@@ -23,35 +24,41 @@
4 const BLKOP_CMD_SZ
]#
+typedef int Bool;
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef byte (*IORD) ();
+typedef void (*IOWR) (byte);
+
struct COSVM {
- unsigned char mem[ #[ MEMSIZE c]# ];
- unsigned short SP; /* parameter Stack Pointer */
- unsigned short RS; /* Return Stack pointer */
- unsigned short IP; /* Interpreter Pointer */
- unsigned short PC; /* Program Counter for HAL bytecode interpreter */
+ byte mem[ #[ MEMSIZE c]# ];
+ word SP; /* parameter Stack Pointer */
+ word RS; /* Return Stack pointer */
+ word IP; /* Interpreter Pointer */
+ word PC; /* Program Counter for HAL bytecode interpreter */
/* Array of 0x100 function pointers to IO read and write routines. Leave to
* NULL when IO port is unhandled. */
- unsigned char (*iord[0x100])();
- void (*iowr[0x100])(unsigned char);
+ IORD iord[0x100];
+ IOWR iowr[0x100];
/* Used for keeping track of max RS and min SP during the lifetime of the
* program. Useful for debugging. */
- unsigned short maxRS;
- unsigned short minSP;
- int running;
+ word maxRS;
+ word minSP;
+ Bool running;
};
static struct COSVM vm;
static struct File *blkfp;
/* Stores blkop command. Bytes flow from left (byte 0) to right (byte 3)
* We know we have a full command when last byte is nonzero. After
* processing the cmd, we reset blkop to 0. */
-static unsigned char blkop[ #[ BLKOP_CMD_SZ c]# ];
+static byte blkop[ #[ BLKOP_CMD_SZ c]# ];
/* 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-full of ports. */
-static unsigned char io_read(unsigned short addr)
+static byte io_read(word addr)
{
addr &= 0xff;
- unsigned char(*fn)() = vm.iord[addr];
+ IORD fn = vm.iord[addr];
if (fn != NULL) {
return fn();
} else {
@@ -60,10 +67,10 @@ static unsigned char io_read(unsigned short addr)
}
}
-static void io_write(unsigned short addr, unsigned char val)
+static void io_write(word addr, byte val)
{
addr &= 0xff;
- void (*fn)(unsigned char) = vm.iowr[addr];
+ IOWR fn = vm.iowr[addr];
if (fn != NULL) {
fn(val);
} else {
@@ -76,14 +83,14 @@ static void io_write(unsigned short addr, unsigned char 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(unsigned char val)
+static void iowr_blk(byte val)
{
- unsigned char rw = blkop[3];
+ byte rw = blkop[3];
if (rw) {
- unsigned short blkid =
- (unsigned short)blkop[2] << 8 | (unsigned short)blkop[1];
- unsigned short dest =
- (unsigned short)blkop[0] << 8 | (unsigned short)val;
+ word blkid =
+ (word)blkop[2] << 8 | (word)blkop[1];
+ word dest =
+ (word)blkop[0] << 8 | (word)val;
memset(blkop, 0, #[ BLKOP_CMD_SZ c]# );
fseek(blkid*1024, blkfp);
if (rw==2) { /* write */
@@ -98,46 +105,46 @@ static void iowr_blk(unsigned char val)
}
/* get/set word from/to memory */
-static unsigned short gw(unsigned short addr) {
+static word gw(word addr) {
return vm.mem[addr+1] << 8 | vm.mem[addr]; }
-static void sw(unsigned short addr, unsigned short val) {
+static void sw(word addr, word val) {
vm.mem[addr] = val;
vm.mem[addr+1] = val >> 8;
}
-static unsigned short peek() { return gw(vm.SP); }
+static word peek() { return gw(vm.SP); }
/* pop word from SP */
-static unsigned short pop() { unsigned short n = peek(); vm.SP+=2; return n; }
-unsigned short VM_PS_pop() { return pop(); }
+static word pop() { word n = peek(); vm.SP+=2; return n; }
+word VM_PS_pop() { return pop(); }
/* push word to SP */
-static void push(unsigned short x) {
+static void push(word x) {
vm.SP -= 2;
sw(vm.SP, x);
if (vm.SP < vm.minSP) { vm.minSP = vm.SP; }
}
-void VM_PS_push(unsigned short n) { push(n); }
+void VM_PS_push(word n) { push(n); }
/* pop word from RS */
-static unsigned short popRS() {
- unsigned short x = gw(vm.RS); vm.RS -= 2; return x;
+static word popRS() {
+ word x = gw(vm.RS); vm.RS -= 2; return x;
}
/* push word to RS */
-static void pushRS(unsigned short val) {
+static void pushRS(word val) {
vm.RS += 2;
sw(vm.RS, val);
if (vm.RS > vm.maxRS) { vm.maxRS = vm.RS; }
}
-static unsigned short pc16() {
- unsigned short n = gw(vm.PC); vm.PC+=2; return n; }
-static unsigned short pc8() {
- unsigned char b = vm.mem[vm.PC]; vm.PC++; return b; }
+static word pc16() {
+ word n = gw(vm.PC); vm.PC+=2; return n; }
+static word pc8() {
+ byte b = vm.mem[vm.PC]; vm.PC++; return b; }
/* Native words */
static void lblnext() { vm.PC = gw(vm.IP); vm.IP += 2; }
static void lblxt() { pushRS(vm.IP); vm.IP = pop(); lblnext(); }
static void lbldoes() { vm.PC = pop(); push(vm.PC+2); vm.PC = gw(vm.PC); }
static void lblval() {
- unsigned short a;
+ word a;
if (vm.mem[ #[ SYSVARS $18 + c]# ]) { // TO?
vm.mem[ #[ SYSVARS $18 + c]# ] = 0;
a = pop();
@@ -150,13 +157,13 @@ static void lblval() {
static void DUP() { push(peek()); }
static void DROP() { pop(); }
static void SWAP() {
- unsigned short a = pop(); unsigned short b = pop(); push(a); push(b); }
+ word a = pop(); word b = pop(); push(a); push(b); }
static void OVER() {
- unsigned short a = pop(); unsigned short b = peek(); push(a); push(b); }
+ word a = pop(); word b = peek(); push(a); push(b); }
static void ROT() {
- unsigned short c = pop();
- unsigned short b = pop();
- unsigned short a = pop();
+ word c = pop();
+ word b = pop();
+ word a = pop();
push(b); push(c); push(a); }
static void RS2PS() { push(popRS()); }
static void PS2RS() { pushRS(pop()); }
@@ -166,8 +173,8 @@ static void PUSHi() { push(pc16()); }
static void PUSHii() { push(gw(pc16())); }
static void CFETCH() { push(vm.mem[pop()]); }
static void FETCH() { push(gw(pop())); }
-static void CSTORE() { unsigned short a = pop(); vm.mem[a] = pop(); }
-static void STORE() { unsigned short a = pop(); sw(a, pop()); }
+static void CSTORE() { word a = pop(); vm.mem[a] = pop(); }
+static void STORE() { word a = pop(); sw(a, pop()); }
static void EXECUTE() { vm.PC = pop(); }
static void JMPi() { vm.PC = gw(vm.PC); }
static void JMPii() { vm.PC = gw(gw(vm.PC)); }
@@ -177,27 +184,27 @@ static void AND() { push(pop() & pop()); }
static void OR() { push(pop() | pop()); }
static void XOR() { push(pop() ^ pop()); }
static void PLUS() {
- unsigned short b = pop(); unsigned short a = pop(); push(a+b); }
+ word b = pop(); word a = pop(); push(a+b); }
static void SUB() {
- unsigned short b = pop(); unsigned short a = pop(); push(a-b); }
+ word b = pop(); word a = pop(); push(a-b); }
static void BR() {
- unsigned short off = vm.mem[vm.IP];
+ word off = vm.mem[vm.IP];
if (off > 0x7f) off |= 0xff00; vm.IP += off; }
-static void CBR() { if (pop()) { vm.IP++; } else { BR(); } }
+static void CBR() { if (pop()) vm.IP++; else BR(); }
static void NEXT() {
- unsigned short n = popRS()-1;
+ word n = popRS()-1;
if (n) { pushRS(n); BR(); }
else { vm.IP++; }
}
static void PCSTORE() {
- unsigned short a = pop(); unsigned short val = pop();
+ word a = pop(); word val = pop();
io_write(a, val);
}
static void PCFETCH() { push(io_read(pop())); }
static void MULT() {
- unsigned short b = pop(); unsigned short a = pop(); push(a * b); }
+ word b = pop(); word a = pop(); push(a * b); }
static void DIVMOD() {
- unsigned short b = pop(); unsigned short a = pop();
+ word b = pop(); word a = pop();
push(a % b); push(a / b);
}
static void QUIT() { vm.RS = #[ RS_ADDR c]# ; }
@@ -206,11 +213,11 @@ static void RCNT() { push((vm.RS - #[ RS_ADDR c]# ) / 2); }
static void SCNT() { push((#[ SP_ADDR c]# - vm.SP) / 2); }
static void BYE() { vm.running = 0; }
static void EXIT() { vm.IP = popRS(); }
-static void CDUP() { unsigned short a = peek(); if (a) push(a); }
+static void CDUP() { word a = peek(); if (a) push(a); }
static void LIT8() { push(vm.mem[vm.IP++]); }
static void LIT16() { push(gw(vm.IP)); vm.IP+=2; }
static void LT() {
- unsigned short b = pop(); unsigned short a = pop(); push(a<b); }
+ word b = pop(); word a = pop(); push(a<b); }
#[ 67 const OPCNT ]#
static void (*ops[ #[ OPCNT c]# ])() = {
@@ -223,7 +230,7 @@ static void (*ops[ #[ OPCNT c]# ])() = {
RFETCH, RS2PS, PS2RS, CFETCH, FETCH, STORE, CSTORE
};
-static void opexec(unsigned char op) {
+static void opexec(byte op) {
if (op < #[ OPCNT c]# ) {
ops[op]();
} else {
@@ -274,7 +281,7 @@ void COSVM_deinit()
fclose(blkfp);
}
-int COSVM_steps(int n) {
+Bool COSVM_steps(int n) {
if (!vm.running) {
fprintf("machine halted!\n", ConsoleOut());
return 0;