commit 508a18b8d4a3d5f044187ebf3150f2c193d98cf5
parent 54bad5ff45ecd33fe462358ffae2956f13446b37
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 13 Aug 2022 14:38:37 -0400
cvm: add the ability to mount any file on the host has a drive
For example, if you want to mount "pc.img" as a FAT, you would do:
S" pc.img" mountImage mountFATvolume value myfat
0 S" init.fs" myfat FAT :child value myid
myid myfat FAT :open value myhdl
40 myhdl FATFile :readbuf rtype
And it will yield something like:
\ Initialization for PC
: ARCH S" i386" ok
Diffstat:
2 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/posix/glue.fs b/posix/glue.fs
@@ -7,3 +7,6 @@ create _POSIXFS
' abort ,
_POSIXFS ' activefs rebind
+
+: mountImage ( imgname -- drv )
+ _mountdrv here 512 , ['] _drv@ , ['] _drv! , ;
diff --git a/posix/vm.c b/posix/vm.c
@@ -49,7 +49,7 @@ struct VM {
};
static struct VM vm = {0};
-static FILE *bootfp;
+static FILE *fp;
// Utilities
static void vmabort() { vm.PC = MEMSZ + 1; }
@@ -256,7 +256,7 @@ static void _TO_() { // op: 12
}
static void BOOTRD() { // op: 13
- ppush(fgetc(bootfp));
+ ppush(fgetc(fp));
}
static void STDOUT() { // op: 14
@@ -830,7 +830,7 @@ static void FREADBUF () { // op: 5f
ppush((dword)res);
}
-static void FCLOSE () { // op: 60
+static void FCLOSE() { // op: 60
dword hdl = ppop();
int fd = getfiledesc(hdl);
if (fd) {
@@ -840,7 +840,43 @@ static void FCLOSE () { // op: 60
}
}
-#define OPCNT 0x61
+// ( imgname -- )
+static void MOUNTDRV() { // op: 61
+ char buf[64] = {0};
+ dword str = ppop();
+ byte slen = gb(str++);
+ memcpy(buf, &vm.mem[str], slen);
+ if (fp) {
+ fclose(fp);
+ fp = NULL;
+ }
+ fp = fopen(buf, "r+");
+ if (!fp) {
+ printf("Can't open %s.\n", buf);
+ BYEFAIL();
+ }
+}
+
+#define SECSZ 512
+// ( sec dst drv -- )
+static void DRVRD() { // op: 62
+ DROP();
+ dword dst = ppop();
+ dword sec = ppop();
+ fseek(fp, SECSZ * sec, SEEK_SET);
+ fread(&vm.mem[dst], SECSZ, 1, fp);
+}
+
+// ( sec src drv -- )
+static void DRVWR() { // op: 63
+ DROP();
+ dword src = ppop();
+ dword sec = ppop();
+ fseek(fp, SECSZ * sec, SEEK_SET);
+ fread(&vm.mem[src], SECSZ, 1, fp);
+}
+
+#define OPCNT 0x64
static void (*ops[OPCNT])() = {
JUMP, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT_,
EXECUTE, CELL, VAL, ALIAS, DOES, SLIT, BR, CBR,
@@ -854,7 +890,7 @@ static void (*ops[OPCNT])() = {
RSHIFT, LITN, EXECUTEWR, EXITWR, MOVE, MOVEWR, RTYPE, WNF,
STACKCHK, MAYBEWORD, WORD, PARSE, REQ, FIND, APOS, COMPILING,
SWR, STARTCOMP, STOPCOMP, RUNWORD, EXIT, FCHILD, FOPEN, FREADBUF,
- FCLOSE};
+ FCLOSE, MOUNTDRV, DRVRD, DRVWR};
static char *opnames[OPCNT] = {
NULL, NULL, NULL, NULL, "bye", "byefail", "quit", "(abort)",
@@ -869,7 +905,7 @@ static char *opnames[OPCNT] = {
"rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)",
"stack?", "maybeword", "word", "parse", "[]=", "find", "'", "compiling",
",\"", "]", "[", "runword", "exit", "_fchild", "_fopen", "_freadbuf",
- "_fclose"};
+ "_fclose", "_mountdrv", "_drv@", "_drv!"};
static void oprun1() { // run next op
if (!memchk(vm.PC)) return;
@@ -959,15 +995,15 @@ static void buildsysdict() {
// Interpret loop
int main() {
strcpy(fsids[0], "fs"); // Set FS root path
- bootfp = fopen("posix/boot.fs", "r");
- if (!bootfp) {
+ fp = fopen("posix/boot.fs", "r");
+ if (!fp) {
printf("Can't open boot file.\n");
return 1;
}
buildsysdict();
vm.PC = find("(abort)");
while (vm.PC < MEMSZ) oprun1();
- fclose(bootfp);
+ if (fp) fclose(fp);
if (vm.PC > MEMSZ) {
fprintf(stderr, "Dumping memory to memdump.\n");
FILE *fp = fopen("memdump", "w");