mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-23 21:28:06 +11:00
cvm: bootstraps itself!
This commit is contained in:
parent
fc3919863f
commit
8a7fa77163
3
cvm/.gitignore
vendored
Normal file
3
cvm/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/blkfs
|
||||||
|
/forth
|
||||||
|
/stage
|
@ -31,6 +31,7 @@ vm.o: vm.c blkfs
|
|||||||
.PHONY: updatebootstrap
|
.PHONY: updatebootstrap
|
||||||
updatebootstrap: stage xcomp.fs pack
|
updatebootstrap: stage xcomp.fs pack
|
||||||
./stage < xcomp.fs > new.bin
|
./stage < xcomp.fs > new.bin
|
||||||
|
mv new.bin forth.bin
|
||||||
|
|
||||||
.PHONY: pack
|
.PHONY: pack
|
||||||
pack:
|
pack:
|
||||||
|
BIN
cvm/forth.bin
Normal file
BIN
cvm/forth.bin
Normal file
Binary file not shown.
60
cvm/stage.c
Normal file
60
cvm/stage.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
VM *vm;
|
||||||
|
// 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) {
|
||||||
|
vm->running = false;
|
||||||
|
}
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
vm = VM_init();
|
||||||
|
if (vm == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
vm->iord[STDIO_PORT] = iord_stdio;
|
||||||
|
vm->iowr[STDIO_PORT] = iowr_stdio;
|
||||||
|
vm->iowr[HERE_PORT] = iowr_here;
|
||||||
|
while (VM_steps(1));
|
||||||
|
|
||||||
|
// We're done, now let's spit dict data
|
||||||
|
for (int i=start_here; i<end_here; i++) {
|
||||||
|
putchar(vm->mem[i]);
|
||||||
|
}
|
||||||
|
VM_printdbg();
|
||||||
|
VM_deinit();
|
||||||
|
return 0;
|
||||||
|
}
|
123
cvm/vm.c
123
cvm/vm.c
@ -238,18 +238,8 @@ static void MINUS2() { push(pop()-2); }
|
|||||||
static void PLUS2() { push(pop()+2); }
|
static void PLUS2() { push(pop()+2); }
|
||||||
static void RSHIFT() { word u = pop(); push(pop()>>u); }
|
static void RSHIFT() { word u = pop(); push(pop()>>u); }
|
||||||
static void LSHIFT() { word u = pop(); push(pop()<<u); }
|
static void LSHIFT() { word u = pop(); push(pop()<<u); }
|
||||||
// create a native word with a specific target offset. target is addr of
|
static void native(NativeWord func) {
|
||||||
// wordref.
|
|
||||||
static void create_native_t(word target, char *name, NativeWord func) {
|
|
||||||
int len = strlen(name);
|
|
||||||
strcpy(&vm.mem[target-len-3], name);
|
|
||||||
word prev_off = target - 3 - vm.xcurrent;
|
|
||||||
sw(target-3, prev_off);
|
|
||||||
vm.mem[target-1] = len;
|
|
||||||
vm.mem[target] = 0; // native word type
|
|
||||||
vm.mem[target+1] = vm.nativew_count;
|
|
||||||
vm.nativew[vm.nativew_count++] = func;
|
vm.nativew[vm.nativew_count++] = func;
|
||||||
vm.xcurrent = target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INITIAL BOOTSTRAP PLAN
|
/* INITIAL BOOTSTRAP PLAN
|
||||||
@ -299,63 +289,62 @@ VM* VM_init() {
|
|||||||
vm.iowr[i] = NULL;
|
vm.iowr[i] = NULL;
|
||||||
}
|
}
|
||||||
vm.iowr[BLK_PORT] = iowr_blk;
|
vm.iowr[BLK_PORT] = iowr_blk;
|
||||||
vm.xcurrent = 0x3f; // make EXIT's prev field 0
|
native(EXIT);
|
||||||
create_native_t(0x42, "EXIT", EXIT);
|
native(_br_);
|
||||||
create_native_t(0x53, "(br)", _br_);
|
native(_cbr_);
|
||||||
create_native_t(0x67, "(?br)", _cbr_);
|
native(_loop_);
|
||||||
create_native_t(0x80, "(loop)", _loop_);
|
native(SP_to_R_2);
|
||||||
create_native_t(0xa9, "2>R", SP_to_R_2);
|
native(nlit);
|
||||||
create_native_t(0xbf, "(n)", nlit);
|
native(slit);
|
||||||
create_native_t(0xd4, "(s)", slit);
|
|
||||||
// End of stable ABI
|
// End of stable ABI
|
||||||
create_native_t(0xe7, ">R", SP_to_R);
|
native(SP_to_R);
|
||||||
create_native_t(0xf4, "R>", R_to_SP);
|
native(R_to_SP);
|
||||||
create_native_t(0x102, "2R>", R_to_SP_2);
|
native(R_to_SP_2);
|
||||||
create_native_t(0x1d4, "EXECUTE", EXECUTE);
|
native(EXECUTE);
|
||||||
create_native_t(0x1e1, "ROT", ROT);
|
native(ROT);
|
||||||
create_native_t(0x1f4, "DUP", DUP);
|
native(DUP);
|
||||||
create_native_t(0x205, "?DUP", CDUP);
|
native(CDUP);
|
||||||
create_native_t(0x21a, "DROP", DROP);
|
native(DROP);
|
||||||
create_native_t(0x226, "SWAP", SWAP);
|
native(SWAP);
|
||||||
create_native_t(0x238, "OVER", OVER);
|
native(OVER);
|
||||||
create_native_t(0x24b, "PICK", PICK);
|
native(PICK);
|
||||||
create_native_t(0x26c, "(roll)", _roll_);
|
native(_roll_);
|
||||||
create_native_t(0x283, "2DROP", DROP2);
|
native(DROP2);
|
||||||
create_native_t(0x290, "2DUP", DUP2);
|
native(DUP2);
|
||||||
create_native_t(0x2a2, "S0", S0);
|
native(S0);
|
||||||
create_native_t(0x2af, "'S", Saddr);
|
native(Saddr);
|
||||||
create_native_t(0x2be, "AND", AND);
|
native(AND);
|
||||||
create_native_t(0x2d3, "OR", OR);
|
native(OR);
|
||||||
create_native_t(0x2e9, "XOR", XOR);
|
native(XOR);
|
||||||
create_native_t(0x2ff, "NOT", NOT);
|
native(NOT);
|
||||||
create_native_t(0x314, "+", PLUS);
|
native(PLUS);
|
||||||
create_native_t(0x323, "-", MINUS);
|
native(MINUS);
|
||||||
create_native_t(0x334, "*", MULT);
|
native(MULT);
|
||||||
create_native_t(0x358, "/MOD", DIVMOD);
|
native(DIVMOD);
|
||||||
create_native_t(0x37c, "!", STORE);
|
native(STORE);
|
||||||
create_native_t(0x389, "@", FETCH);
|
native(FETCH);
|
||||||
create_native_t(0x39a, "C!", CSTORE);
|
native(CSTORE);
|
||||||
create_native_t(0x3a6, "C@", CFETCH);
|
native(CFETCH);
|
||||||
create_native_t(0x3b8, "PC!", IO_OUT);
|
native(IO_OUT);
|
||||||
create_native_t(0x3c6, "PC@", IO_IN);
|
native(IO_IN);
|
||||||
create_native_t(0x3d7, "I", RI);
|
native(RI);
|
||||||
create_native_t(0x3e7, "I'", RI_);
|
native(RI_);
|
||||||
create_native_t(0x3f6, "J", RJ);
|
native(RJ);
|
||||||
create_native_t(0x407, "BYE", BYE);
|
native(BYE);
|
||||||
create_native_t(0x416, "(resSP)", _resSP_);
|
native(_resSP_);
|
||||||
create_native_t(0x427, "(resRS)", _resRS_);
|
native(_resRS_);
|
||||||
create_native_t(0x434, "S=", Seq);
|
native(Seq);
|
||||||
create_native_t(0x457, "CMP", CMP);
|
native(CMP);
|
||||||
create_native_t(0x476, "_find", _find);
|
native(_find);
|
||||||
create_native_t(0x4a4, "0", ZERO);
|
native(ZERO);
|
||||||
create_native_t(0x4b0, "1", ONE);
|
native(ONE);
|
||||||
create_native_t(0x4bd, "-1", MONE);
|
native(MONE);
|
||||||
create_native_t(0x4ca, "1+", PLUS1);
|
native(PLUS1);
|
||||||
create_native_t(0x4d9, "1-", MINUS1);
|
native(MINUS1);
|
||||||
create_native_t(0x4e8, "2+", PLUS2);
|
native(PLUS2);
|
||||||
create_native_t(0x4f8, "2-", MINUS2);
|
native(MINUS2);
|
||||||
create_native_t(0x50c, "RSHIFT", RSHIFT);
|
native(RSHIFT);
|
||||||
create_native_t(0x52a, "LSHIFT", LSHIFT);
|
native(LSHIFT);
|
||||||
vm.IP = gw(0x04) + 1; // BOOT
|
vm.IP = gw(0x04) + 1; // BOOT
|
||||||
sw(SYSVARS+0x02, gw(0x08)); // CURRENT
|
sw(SYSVARS+0x02, gw(0x08)); // CURRENT
|
||||||
sw(SYSVARS+0x04, gw(0x08)); // HERE
|
sw(SYSVARS+0x04, gw(0x08)); // HERE
|
||||||
|
104
cvm/xcomp.fs
Normal file
104
cvm/xcomp.fs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
0xe800 CONSTANT RAMSTART
|
||||||
|
0xff00 CONSTANT RS_ADDR
|
||||||
|
0xfffa CONSTANT PS_ADDR
|
||||||
|
: CODE ( natidx -- ) (entry) 0 C, C, ;
|
||||||
|
VARIABLE ORG
|
||||||
|
CREATE BIN( 0 ,
|
||||||
|
: PC H@ ORG @ - ;
|
||||||
|
262 LOAD ( xcomp )
|
||||||
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
|
H@ ORG !
|
||||||
|
ORG @ 0x3b + HERE !
|
||||||
|
," EXIT"
|
||||||
|
0 , ( prev ) 4 C,
|
||||||
|
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
||||||
|
0 C, 0 C,
|
||||||
|
ORG @ 0x4c + HERE !
|
||||||
|
0x01 CODE (br) ( 0x53 )
|
||||||
|
ORG @ 0x5f + HERE !
|
||||||
|
0x02 CODE (?br) ( 0x67 )
|
||||||
|
ORG @ 0x77 + HERE !
|
||||||
|
0x03 CODE (loop) ( 0x80 )
|
||||||
|
ORG @ 0xa3 + HERE !
|
||||||
|
0x04 CODE 2>R ( 0xa9 )
|
||||||
|
ORG @ 0xb9 + HERE !
|
||||||
|
0x05 CODE (n) ( 0xbf )
|
||||||
|
ORG @ 0xce + HERE !
|
||||||
|
0x06 CODE (s) ( 0xd4 )
|
||||||
|
( END OF STABLE ABI )
|
||||||
|
0x07 CODE >R
|
||||||
|
0x08 CODE R>
|
||||||
|
0x09 CODE 2R>
|
||||||
|
0x0a CODE EXECUTE
|
||||||
|
0x0b CODE ROT
|
||||||
|
0x0c CODE DUP
|
||||||
|
0x0d CODE ?DUP
|
||||||
|
0x0e CODE DROP
|
||||||
|
0x0f CODE SWAP
|
||||||
|
0x10 CODE OVER
|
||||||
|
0x11 CODE PICK
|
||||||
|
0x12 CODE (roll)
|
||||||
|
0x13 CODE 2DROP
|
||||||
|
0x14 CODE 2DUP
|
||||||
|
0x15 CODE S0
|
||||||
|
0x16 CODE 'S
|
||||||
|
0x17 CODE AND
|
||||||
|
0x18 CODE OR
|
||||||
|
0x19 CODE XOR
|
||||||
|
0x1a CODE NOT
|
||||||
|
0x1b CODE +
|
||||||
|
0x1c CODE -
|
||||||
|
0x1d CODE *
|
||||||
|
0x1e CODE /MOD
|
||||||
|
0x1f CODE !
|
||||||
|
0x20 CODE @
|
||||||
|
0x21 CODE C!
|
||||||
|
0x22 CODE C@
|
||||||
|
0x23 CODE PC!
|
||||||
|
0x24 CODE PC@
|
||||||
|
0x25 CODE I
|
||||||
|
0x26 CODE I'
|
||||||
|
0x27 CODE J
|
||||||
|
0x28 CODE BYE
|
||||||
|
0x29 CODE (resSP)
|
||||||
|
0x2a CODE (resRS)
|
||||||
|
0x2b CODE S=
|
||||||
|
0x2c CODE CMP
|
||||||
|
0x2d CODE _find
|
||||||
|
0x2e CODE 0
|
||||||
|
0x2f CODE 1
|
||||||
|
0x30 CODE -1
|
||||||
|
0x31 CODE 1+
|
||||||
|
0x32 CODE 1-
|
||||||
|
0x33 CODE 2+
|
||||||
|
0x34 CODE 2-
|
||||||
|
0x35 CODE RSHIFT
|
||||||
|
0x36 CODE LSHIFT
|
||||||
|
353 LOAD ( xcomp core low )
|
||||||
|
: (emit) 0 PC! ;
|
||||||
|
: (key) 0 PC@ ;
|
||||||
|
: EFS@
|
||||||
|
1 3 PC! ( read )
|
||||||
|
256 /MOD 3 PC! 3 PC! ( blkid )
|
||||||
|
BLK( 256 /MOD 3 PC! 3 PC! ( dest )
|
||||||
|
;
|
||||||
|
: EFS!
|
||||||
|
2 3 PC! ( write )
|
||||||
|
256 /MOD 3 PC! 3 PC! ( blkid )
|
||||||
|
BLK( 256 /MOD 3 PC! 3 PC! ( dest )
|
||||||
|
;
|
||||||
|
: COLS 80 ; : LINES 32 ;
|
||||||
|
: AT-XY 6 PC! ( y ) 5 PC! ( x ) ;
|
||||||
|
|
||||||
|
380 LOAD ( xcomp core high )
|
||||||
|
(entry) _
|
||||||
|
( Update LATEST )
|
||||||
|
PC ORG @ 8 + !
|
||||||
|
," CURRENT @ HERE ! "
|
||||||
|
," BLK$ "
|
||||||
|
," ' EFS@ BLK@* ! "
|
||||||
|
," ' EFS! BLK!* ! "
|
||||||
|
EOT,
|
||||||
|
ORG @ 256 /MOD 2 PC! 2 PC!
|
||||||
|
H@ 256 /MOD 2 PC! 2 PC!
|
Loading…
Reference in New Issue
Block a user