diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c78ba938..c83b8aad 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -68,7 +68,7 @@ jobs:
run: (cd tests/kvm-unit-tests && ./configure && make x86/realmode.flat)
- name: Run kvm-unit-test
- run: tests/kvm-unit-tests/run.js tests/kvm-unit-tests/x86/realmode.flat
+ run: tests/kvm-unit-tests/run.mjs tests/kvm-unit-tests/x86/realmode.flat
- name: Fetch namsmtests cache
uses: actions/cache@v4
diff --git a/Makefile b/Makefile
index 263da6d7..74d887f3 100644
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ CARGO_FLAGS_SAFE=\
CARGO_FLAGS=$(CARGO_FLAGS_SAFE) -C target-feature=+bulk-memory -C target-feature=+multivalue -C target-feature=+simd128
-CORE_FILES=const.js config.js io.js main.js lib.js buffer.js ide.js pci.js floppy.js \
+CORE_FILES=cjs.js const.js config.js io.js main.js lib.js buffer.js ide.js pci.js floppy.js \
memory.js dma.js pit.js vga.js ps2.js rtc.js uart.js \
acpi.js apic.js ioapic.js \
state.js ne2k.js sb16.js virtio.js virtio_console.js virtio_net.js virtio_balloon.js \
@@ -151,7 +151,7 @@ build/libv86.mjs: $(CLOSURE) src/*.js lib/*.js src/browser/*.js
$(CLOSURE_FLAGS)\
--compilation_level SIMPLE\
--jscomp_off=missingProperties\
- --output_wrapper ';let module = {exports:{}}; %output%; export default module.exports.V86;'\
+ --output_wrapper ';let module = {exports:{}}; %output%; export default module.exports.V86; export let {V86, CPU} = module.exports;'\
--js $(CORE_FILES)\
--js $(BROWSER_FILES)\
--js $(LIB_FILES)\
@@ -257,6 +257,7 @@ clean:
-rm build/libv86.js
-rm build/libv86.mjs
-rm build/libv86-debug.js
+ -rm build/libv86-debug.mjs
-rm build/v86_all.js
-rm build/v86.wasm
-rm build/v86-debug.wasm
@@ -299,45 +300,45 @@ tests: build/libv86-debug.js build/v86-debug.wasm build/integration-test-fs/fs.j
tests-release: build/libv86.js build/v86.wasm build/integration-test-fs/fs.json
TEST_RELEASE_BUILD=1 ./tests/full/run.js
-nasmtests: build/libv86-debug.js build/v86-debug.wasm
+nasmtests: build/libv86-debug.mjs build/v86-debug.wasm
$(NASM_TEST_DIR)/create_tests.js
$(NASM_TEST_DIR)/gen_fixtures.js
$(NASM_TEST_DIR)/run.js
-nasmtests-force-jit: build/libv86-debug.js build/v86-debug.wasm
+nasmtests-force-jit: build/libv86-debug.mjs build/v86-debug.wasm
$(NASM_TEST_DIR)/create_tests.js
$(NASM_TEST_DIR)/gen_fixtures.js
$(NASM_TEST_DIR)/run.js --force-jit
-jitpagingtests: build/libv86-debug.js build/v86-debug.wasm
+jitpagingtests: build/libv86-debug.mjs build/v86-debug.wasm
$(MAKE) -C tests/jit-paging test-jit
./tests/jit-paging/run.js
-qemutests: build/libv86-debug.js build/v86-debug.wasm
+qemutests: build/libv86-debug.mjs build/v86-debug.wasm
$(MAKE) -C tests/qemu test-i386
LOG_LEVEL=3 ./tests/qemu/run.js build/qemu-test-result
./tests/qemu/run-qemu.js > build/qemu-test-reference
diff build/qemu-test-result build/qemu-test-reference
-qemutests-release: build/libv86.js build/v86.wasm
+qemutests-release: build/libv86.mjs build/v86.wasm
$(MAKE) -C tests/qemu test-i386
TEST_RELEASE_BUILD=1 time ./tests/qemu/run.js build/qemu-test-result
./tests/qemu/run-qemu.js > build/qemu-test-reference
diff build/qemu-test-result build/qemu-test-reference
-kvm-unit-test: build/libv86-debug.js build/v86-debug.wasm
+kvm-unit-test: build/libv86-debug.mjs build/v86-debug.wasm
(cd tests/kvm-unit-tests && ./configure && make x86/realmode.flat)
- tests/kvm-unit-tests/run.js tests/kvm-unit-tests/x86/realmode.flat
+ tests/kvm-unit-tests/run.mjs tests/kvm-unit-tests/x86/realmode.flat
-kvm-unit-test-release: build/libv86.js build/v86.wasm
+kvm-unit-test-release: build/libv86.mjs build/v86.wasm
(cd tests/kvm-unit-tests && ./configure && make x86/realmode.flat)
- TEST_RELEASE_BUILD=1 tests/kvm-unit-tests/run.js tests/kvm-unit-tests/x86/realmode.flat
+ TEST_RELEASE_BUILD=1 tests/kvm-unit-tests/run.mjs tests/kvm-unit-tests/x86/realmode.flat
-expect-tests: build/libv86-debug.js build/v86-debug.wasm build/libwabt.js
+expect-tests: build/libv86-debug.mjs build/v86-debug.wasm build/libwabt.cjs
make -C tests/expect/tests
./tests/expect/run.js
-devices-test: build/libv86-debug.js build/v86-debug.wasm
+devices-test: build/libv86-debug.mjs build/v86-debug.wasm
./tests/devices/virtio_9p.js
./tests/devices/virtio_console.js
./tests/devices/fetch_network.js
@@ -352,7 +353,7 @@ rust-test: $(RUST_FILES)
rust-test-intensive:
QUICKCHECK_TESTS=100000000 make rust-test
-api-tests: build/libv86-debug.js build/v86-debug.wasm
+api-tests: build/libv86-debug.mjs build/v86-debug.wasm
./tests/api/clean-shutdown.js
./tests/api/state.js
./tests/api/reset.js
@@ -375,10 +376,11 @@ build/capstone-x86.min.js:
mkdir -p build
wget -nv -P build https://github.com/AlexAltea/capstone.js/releases/download/v3.0.5-rc1/capstone-x86.min.js
-build/libwabt.js:
+build/libwabt.cjs:
mkdir -p build
wget -nv -P build https://github.com/WebAssembly/wabt/archive/1.0.6.zip
unzip -j -d build/ build/1.0.6.zip wabt-1.0.6/demo/libwabt.js
+ mv build/libwabt.js build/libwabt.cjs
rm build/1.0.6.zip
build/xterm.js:
diff --git a/debug.html b/debug.html
index 88105a4a..e752317e 100644
--- a/debug.html
+++ b/debug.html
@@ -4,58 +4,12 @@
v86 (debug)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 7f21000a..47f86752 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -1,5 +1,56 @@
+
export default [
{
+ "languageOptions": {
+ "globals": {
+ "process": "readonly",
+ "window": "writable",
+ "navigator": "writable",
+ "location": "writable",
+ "document": "readonly",
+ "console": "readonly",
+ "crypto": "readonly",
+ "alert": "readonly",
+ "performance": "readonly",
+ "URL": "readonly",
+ "WebAssembly": "readonly",
+
+ "setTimeout": "readonly",
+ "setInterval": "readonly",
+ "clearTimeout": "readonly",
+ "clearInterval": "readonly",
+ "requestAnimationFrame": "readonly",
+ "cancelAnimationFrame": "readonly",
+
+ "Buffer": "readonly",
+ "FileReader": "readonly",
+ "TextEncoder": "readonly",
+ "TextDecoder": "readonly",
+ "fetch": "readonly",
+ "Headers": "readonly",
+ "Response": "readonly",
+ "WebSocket": "readonly",
+ "Blob": "readonly",
+ "Blob": "readonly",
+ "File": "readonly",
+ "XMLHttpRequest": "readonly",
+ "URLSearchParams": "readonly",
+ "ImageData": "readonly",
+ "Image": "readonly",
+ "OffscreenCanvas": "readonly",
+ "BroadcastChannel": "readonly",
+
+ "AudioContext": "readonly",
+ "AudioWorkletProcessor": "readonly",
+ "webkitAudioContext": "readonly",
+ "AudioWorkletNode": "readonly",
+ "Worker": "readonly",
+ "postMessage": "readonly",
+ "importScripts": "readonly",
+
+ "DEBUG": "writable"
+ }
+ },
rules: {
"eol-last": "error",
//"no-extra-parens": "error",
@@ -69,7 +120,7 @@ export default [
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-this-before-super": "error",
- //"no-undef": "error",
+ "no-undef": "error",
"no-unexpected-multiline": "error",
//"no-unreachable": "error",
"no-unsafe-finally": "error",
diff --git a/examples/nodejs.js b/examples/nodejs.js
index c2ec8246..98b4fd8b 100755
--- a/examples/nodejs.js
+++ b/examples/nodejs.js
@@ -1,8 +1,11 @@
#!/usr/bin/env node
"use strict";
-var fs = require("fs");
-var V86 = require("../build/libv86.js").V86;
+import fs from "node:fs";
+import url from "node:url";
+import { V86 } from "../build/libv86.js";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
function readfile(path)
{
diff --git a/examples/nodejs_state.js b/examples/nodejs_state.js
index 229f2c14..63f5df25 100755
--- a/examples/nodejs_state.js
+++ b/examples/nodejs_state.js
@@ -1,8 +1,10 @@
#!/usr/bin/env node
"use strict";
-var fs = require("fs");
-var V86 = require("../build/libv86.js").V86;
+import fs from "node:fs";
+import url from "node:url";
+var V86 = await import("../build/libv86.js").V86;
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
function readfile(path)
{
diff --git a/examples/worker.js b/examples/worker.js
index 90760064..b438d49e 100644
--- a/examples/worker.js
+++ b/examples/worker.js
@@ -1,5 +1,7 @@
importScripts("../build/libv86.js");
+/* global V86 */
+
var emulator = new V86({
wasm_path: "../build/v86.wasm",
memory_size: 32 * 1024 * 1024,
diff --git a/gen/generate_analyzer.js b/gen/generate_analyzer.js
index de31a8c3..103e2a31 100755
--- a/gen/generate_analyzer.js
+++ b/gen/generate_analyzer.js
@@ -1,13 +1,16 @@
#!/usr/bin/env node
"use strict";
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
-const x86_table = require("./x86_table");
-const rust_ast = require("./rust_ast");
-const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util");
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import x86_table from "./x86_table.js";
+const rust_ast = await import("./rust_ast.js");
+const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = await import("./util.js");
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/");
mkdirpSync(OUT_DIR);
diff --git a/gen/generate_interpreter.js b/gen/generate_interpreter.js
index 8c09eddf..8015d0da 100755
--- a/gen/generate_interpreter.js
+++ b/gen/generate_interpreter.js
@@ -1,13 +1,16 @@
#!/usr/bin/env node
"use strict";
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
-const x86_table = require("./x86_table");
-const rust_ast = require("./rust_ast");
-const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util");
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import x86_table from "./x86_table.js";
+const rust_ast = await import("./rust_ast.js");
+const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = await import("./util.js");
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/");
mkdirpSync(OUT_DIR);
diff --git a/gen/generate_jit.js b/gen/generate_jit.js
index 104f0598..b237a368 100755
--- a/gen/generate_jit.js
+++ b/gen/generate_jit.js
@@ -1,15 +1,17 @@
#!/usr/bin/env node
"use strict";
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
-const x86_table = require("./x86_table");
-const rust_ast = require("./rust_ast");
-const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util");
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import x86_table from "./x86_table.js";
+const rust_ast = await import("./rust_ast.js");
+const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = await import("./util.js");
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/");
-
mkdirpSync(OUT_DIR);
const table_arg = get_switch_value("--table");
diff --git a/gen/rust_ast.js b/gen/rust_ast.js
index fb4f2e98..7d50cd55 100644
--- a/gen/rust_ast.js
+++ b/gen/rust_ast.js
@@ -1,13 +1,13 @@
"use strict";
-const assert = require("assert").strict;
+import assert from "node:assert/strict";
function indent(lines, how_much)
{
return lines.map(line => " ".repeat(how_much) + line);
}
-function print_syntax_tree(statements)
+export function print_syntax_tree(statements)
{
let code = [];
@@ -77,7 +77,3 @@ function print_syntax_tree(statements)
return code;
}
-
-module.exports = {
- print_syntax_tree,
-};
diff --git a/gen/util.js b/gen/util.js
index 9325428c..a01a8eda 100644
--- a/gen/util.js
+++ b/gen/util.js
@@ -1,14 +1,13 @@
"use strict";
-const assert = require("assert");
-const fs = require("fs");
-const path = require("path");
-const process = require("process");
-const child_process = require("child_process");
+import fs from "node:fs";
+import path from "node:path";
+import process from "node:process";
+
const CYAN_FMT = "\x1b[36m%s\x1b[0m";
-function hex(n, pad)
+export function hex(n, pad)
{
pad = pad || 0;
let s = n.toString(16).toUpperCase();
@@ -16,12 +15,12 @@ function hex(n, pad)
return s;
}
-function mkdirpSync(dir)
+export function mkdirpSync(dir)
{
fs.mkdirSync(dir, { recursive: true });
}
-function get_switch_value(arg_switch)
+export function get_switch_value(arg_switch)
{
const argv = process.argv;
const switch_i = argv.indexOf(arg_switch);
@@ -33,22 +32,14 @@ function get_switch_value(arg_switch)
return null;
}
-function get_switch_exist(arg_switch)
+export function get_switch_exist(arg_switch)
{
return process.argv.includes(arg_switch);
}
-function finalize_table_rust(out_dir, name, contents)
+export function finalize_table_rust(out_dir, name, contents)
{
const file_path = path.join(out_dir, name);
fs.writeFileSync(file_path, contents);
console.log(CYAN_FMT, `[+] Wrote table ${name}.`);
}
-
-module.exports = {
- hex,
- mkdirpSync,
- get_switch_value,
- get_switch_exist,
- finalize_table_rust,
-};
diff --git a/gen/x86_table.js b/gen/x86_table.js
index e6663a0c..5325b4f6 100644
--- a/gen/x86_table.js
+++ b/gen/x86_table.js
@@ -1,6 +1,6 @@
"use strict";
-const { hex } = require("./util");
+const { hex } = await import("./util.js");
// http://ref.x86asm.net/coder32.html
@@ -875,4 +875,5 @@ encodings.sort((e1, e2) => {
return o1 - o2 || e1.fixed_g - e2.fixed_g;
});
-module.exports = Object.freeze(encodings.map(entry => Object.freeze(entry)));
+const result = Object.freeze(encodings.map(entry => Object.freeze(entry)));
+export default result;
diff --git a/lib/9p.js b/lib/9p.js
index 27b39836..c988d43d 100644
--- a/lib/9p.js
+++ b/lib/9p.js
@@ -6,6 +6,21 @@
"use strict";
+import { TRACK_FILENAMES } from "../src/config.js";
+import { VirtIO, VIRTIO_F_VERSION_1, VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_RING_INDIRECT_DESC } from "../src/virtio.js";
+import { S_IFREG, S_IFDIR, STATUS_UNLINKED } from "./filesystem.js";
+import { hex8, message } from "./jor1k.js";
+import { marshall, texten } from "./marshall.js";
+import { range } from "../src/lib.js";
+import { dbg_assert } from "../src/log.js";
+
+
+// For Types Only
+import { CPU } from "../src/cpu.js";
+import { BusConnector } from "../src/bus.js";
+import { FS } from "./filesystem.js";
+
+
// Feature bit (bit position) for mount tag.
const VIRTIO_9P_F_MOUNT_TAG = 0;
// Assumed max tag length in bytes.
@@ -16,13 +31,13 @@ const MAX_REPLYBUFFER_SIZE = 16 * 1024 * 1024;
// TODO
// flush
-var EPERM = 1; /* Operation not permitted */
-var ENOENT = 2; /* No such file or directory */
-var EEXIST = 17; /* File exists */
-var EINVAL = 22; /* Invalid argument */
-var EOPNOTSUPP = 95; /* Operation is not supported */
-var ENOTEMPTY = 39; /* Directory not empty */
-var EPROTO = 71; /* Protocol error */
+export const EPERM = 1; /* Operation not permitted */
+export const ENOENT = 2; /* No such file or directory */
+export const EEXIST = 17; /* File exists */
+export const EINVAL = 22; /* Invalid argument */
+export const EOPNOTSUPP = 95; /* Operation is not supported */
+export const ENOTEMPTY = 39; /* Directory not empty */
+export const EPROTO = 71; /* Protocol error */
var P9_SETATTR_MODE = 0x00000001;
var P9_SETATTR_UID = 0x00000002;
@@ -49,18 +64,18 @@ var P9_STAT_MODE_SETUID = 0x00080000;
var P9_STAT_MODE_SETGID = 0x00040000;
var P9_STAT_MODE_SETVTX = 0x00010000;
-const P9_LOCK_TYPE_RDLCK = 0;
-const P9_LOCK_TYPE_WRLCK = 1;
-const P9_LOCK_TYPE_UNLCK = 2;
+export const P9_LOCK_TYPE_RDLCK = 0;
+export const P9_LOCK_TYPE_WRLCK = 1;
+export const P9_LOCK_TYPE_UNLCK = 2;
const P9_LOCK_TYPES = ["shared", "exclusive", "unlock"];
const P9_LOCK_FLAGS_BLOCK = 1;
const P9_LOCK_FLAGS_RECLAIM = 2;
-const P9_LOCK_SUCCESS = 0;
-const P9_LOCK_BLOCKED = 1;
-const P9_LOCK_ERROR = 2;
-const P9_LOCK_GRACE = 3;
+export const P9_LOCK_SUCCESS = 0;
+export const P9_LOCK_BLOCKED = 1;
+export const P9_LOCK_ERROR = 2;
+export const P9_LOCK_GRACE = 3;
var FID_NONE = -1;
var FID_INODE = 1;
@@ -72,7 +87,7 @@ var FID_XATTR = 2;
* @param {FS} filesystem
* @param {CPU} cpu
*/
-function Virtio9p(filesystem, cpu, bus) {
+export function Virtio9p(filesystem, cpu, bus) {
/** @type {FS} */
this.fs = filesystem;
@@ -156,7 +171,7 @@ function Virtio9p(filesystem, cpu, bus) {
read: () => this.configspace_taglen,
write: data => { /* read only */ },
},
- ].concat(v86util.range(VIRTIO_9P_MAX_TAGLEN).map(index =>
+ ].concat(range(VIRTIO_9P_MAX_TAGLEN).map(index =>
({
bytes: 1,
name: "mount tag name " + index,
diff --git a/lib/filesystem.js b/lib/filesystem.js
index 46856e01..486f53d6 100644
--- a/lib/filesystem.js
+++ b/lib/filesystem.js
@@ -5,14 +5,25 @@
"use strict";
-var S_IRWXUGO = 0x1FF;
-var S_IFMT = 0xF000;
-var S_IFSOCK = 0xC000;
-var S_IFLNK = 0xA000;
-var S_IFREG = 0x8000;
-var S_IFBLK = 0x6000;
-var S_IFDIR = 0x4000;
-var S_IFCHR = 0x2000;
+import { LOG_9P } from "../src/const.js";
+import { h } from "../src/lib.js";
+import { dbg_assert, dbg_log } from "../src/log.js";
+import { marshall, texten } from "../lib/marshall.js";
+import { message } from "./jor1k.js";
+import { EEXIST, ENOTEMPTY, ENOENT, EPERM } from "./9p.js";
+import { P9_LOCK_SUCCESS, P9_LOCK_BLOCKED, P9_LOCK_TYPE_UNLCK, P9_LOCK_TYPE_WRLCK, P9_LOCK_TYPE_RDLCK } from "./9p.js";
+
+// For Types Only
+import { FileStorageInterface } from "../src/browser/filestorage.js";
+
+export const S_IRWXUGO = 0x1FF;
+export const S_IFMT = 0xF000;
+export const S_IFSOCK = 0xC000;
+export const S_IFLNK = 0xA000;
+export const S_IFREG = 0x8000;
+export const S_IFBLK = 0x6000;
+export const S_IFDIR = 0x4000;
+export const S_IFCHR = 0x2000;
//var S_IFIFO 0010000
//var S_ISUID 0004000
@@ -24,11 +35,11 @@ var O_WRONLY = 0x0001; // open for writing only
var O_RDWR = 0x0002; // open for reading and writing
var O_ACCMODE = 0x0003; // mask for above modes
-var STATUS_INVALID = -0x1;
-var STATUS_OK = 0x0;
-var STATUS_ON_STORAGE = 0x2;
-var STATUS_UNLINKED = 0x4;
-var STATUS_FORWARDING = 0x5;
+export const STATUS_INVALID = -0x1;
+export const STATUS_OK = 0x0;
+export const STATUS_ON_STORAGE = 0x2;
+export const STATUS_UNLINKED = 0x4;
+export const STATUS_FORWARDING = 0x5;
/** @const */ var JSONFS_VERSION = 3;
@@ -49,7 +60,7 @@ var STATUS_FORWARDING = 0x5;
* @param {!FileStorageInterface} storage
* @param {{ last_qidnumber: number }=} qidcounter Another fs's qidcounter to synchronise with.
*/
-function FS(storage, qidcounter) {
+export function FS(storage, qidcounter) {
/** @type {Array.} */
this.inodes = [];
this.events = [];
diff --git a/lib/jor1k.js b/lib/jor1k.js
index 1b27112b..6114e13a 100644
--- a/lib/jor1k.js
+++ b/lib/jor1k.js
@@ -1,5 +1,10 @@
"use strict";
+import { LOG_9P } from "../src/const.js";
+import { h } from "../src/lib.js";
+import { dbg_log } from "../src/log.js";
+
+
// jor1k compatibility
var VIRTIO_MAGIC_REG = 0x0;
@@ -29,12 +34,12 @@ var VRING_DESC_F_WRITE = 2; /* This marks a buffer as write-only (otherwise
var VRING_DESC_F_INDIRECT = 4; /* This means the buffer contains a list of buffer descriptors. */
-function hex8(n)
+export function hex8(n)
{
return h(n);
}
-var message = {};
+export var message = {};
/** @param {...string} log */
message.Debug = function(log)
@@ -92,7 +97,7 @@ else
LoadBinaryResource = function(url, OnSuccess, OnError)
{
//console.log(url);
- require("fs")["readFile"](url, function(err, data)
+ import("node:" + "fs").then(fs => fs["readFile"](url, function(err, data)
{
if(err)
{
@@ -102,6 +107,6 @@ else
{
OnSuccess(data.buffer);
}
- });
+ }));
};
}
diff --git a/lib/marshall.js b/lib/marshall.js
index 17fc0c46..926ba5af 100644
--- a/lib/marshall.js
+++ b/lib/marshall.js
@@ -5,10 +5,12 @@
"use strict";
-var marshall = {};
+import { message } from "./jor1k.js";
-const textde = new TextDecoder();
-const texten = new TextEncoder();
+export var marshall = {};
+
+export const textde = new TextDecoder();
+export const texten = new TextEncoder();
// Inserts data from an array to a byte aligned struct in memory
marshall.Marshall = function(typelist, input, struct, offset) {
diff --git a/nodejs-loader.mjs b/nodejs-loader.mjs
index 1694d9d9..8e05d6e5 100644
--- a/nodejs-loader.mjs
+++ b/nodejs-loader.mjs
@@ -1,97 +1,5 @@
-import vm from "node:vm";
-import url from "node:url";
-import fs from "node:fs";
-import path from "node:path";
-import crypto from "node:crypto";
-import perf_hooks from "node:perf_hooks";
-const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
-
-let files = [
- "src/const.js",
- "src/config.js",
- "src/log.js",
- "src/cpu.js",
- "src/debug.js",
- "src/io.js",
- "src/main.js",
- "src/lib.js",
- "src/buffer.js",
- "src/ide.js",
- "src/pci.js",
- "src/floppy.js",
- "src/memory.js",
- "src/dma.js",
- "src/pit.js",
- "src/vga.js",
- "src/ps2.js",
-
- "src/rtc.js",
- "src/uart.js",
-
- "src/acpi.js",
- "src/apic.js",
- "src/ioapic.js",
-
- "src/state.js",
- "src/ne2k.js",
- "src/sb16.js",
- "src/virtio.js",
- "src/virtio_console.js",
- "src/virtio_net.js",
- "src/virtio_balloon.js",
- "src/bus.js",
-
- "src/debug.js",
- "src/elf.js",
- "src/kernel.js",
-
- "lib/9p.js",
- "lib/filesystem.js",
- "lib/jor1k.js",
- "lib/marshall.js",
-
- "src/browser/screen.js",
- "src/browser/keyboard.js",
- "src/browser/mouse.js",
- "src/browser/speaker.js",
- "src/browser/serial.js",
- "src/browser/network.js",
- "src/browser/fake_network.js",
- "src/browser/fetch_network.js",
- "src/browser/starter.js",
- "src/browser/worker_bus.js",
- "src/browser/dummy_screen.js",
- "src/browser/print_stats.js",
- "src/browser/filestorage.js"
-];
-
-
-let globals = Object.create(globalThis);
-let v86 = {};
-
-let ctx = vm.createContext(globals);
-globals.DEBUG = false;
-globals.module = {exports:v86};
-Object.defineProperty(globals, "crypto", {value: crypto});
-globals.require = (what) => {
- return ({
- perf_hooks,
- fs
- })[what];
-};
-
-for( let f of files ) {
- vm.runInContext(fs.readFileSync(path.join(__dirname, f), "utf8"), ctx, {
- filename: f
- });
-}
-
-export let {
- FetchNetworkAdapter,
- MemoryFileStorage,
- ServerFileStorageWrapper,
-} = globals;
-
-export default globals.V86;
+globalThis.DEBUG = true;
+var V86 = await import("./src/browser/starter.js");
+export default V86.V86;
diff --git a/package.json b/package.json
index 733a00f4..fc4415b5 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"build/*.mjs",
"build/v86*.wasm"
],
- "main": "build/libv86.js",
- "repository": "github:copy/v86"
+ "main": "build/libv86.mjs",
+ "repository": "github:copy/v86",
+ "type": "module"
}
diff --git a/src/acpi.js b/src/acpi.js
index daace1df..00106e48 100644
--- a/src/acpi.js
+++ b/src/acpi.js
@@ -2,14 +2,22 @@
// http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf
+import { v86 } from "./main.js";
+import { LOG_ACPI } from "../src/const.js";
+import { h } from "./lib.js";
+import { dbg_log, dbg_assert } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+
/** @const */
-var PMTIMER_FREQ_SECONDS = 3579545;
+export const PMTIMER_FREQ_SECONDS = 3579545;
/**
* @constructor
* @param {CPU} cpu
*/
-function ACPI(cpu)
+export function ACPI(cpu)
{
/** @type {CPU} */
this.cpu = cpu;
diff --git a/src/apic.js b/src/apic.js
index df2561ec..564face7 100644
--- a/src/apic.js
+++ b/src/apic.js
@@ -2,9 +2,18 @@
// See Intel's System Programming Guide
+import { v86 } from "./main.js";
+import { LOG_APIC } from "../src/const.js";
+import { APIC_TIMER_FREQ } from "./config.js";
+import { h, int_log2 } from "./lib.js";
+import { dbg_assert, dbg_log, dbg_trace } from "./log.js";
+import { IOAPIC_CONFIG_MASKED, IOAPIC_DELIVERY_INIT, IOAPIC_DELIVERY_NMI, IOAPIC_DELIVERY_FIXED } from "./ioapic.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
/** @const */
-var APIC_LOG_VERBOSE = false;
+export const APIC_LOG_VERBOSE = false;
/** @const */
var APIC_ADDRESS = 0xFEE00000;
@@ -23,7 +32,7 @@ var APIC_TIMER_MODE_TSC = 2 << 17;
/** @const */
-var DELIVERY_MODES = [
+export const DELIVERY_MODES = [
"Fixed (0)",
"Lowest Prio (1)",
"SMI (2)",
@@ -35,13 +44,14 @@ var DELIVERY_MODES = [
];
/** @const */
-var DESTINATION_MODES = ["physical", "logical"];
+export const DESTINATION_MODES = ["physical", "logical"];
/**
* @constructor
* @param {CPU} cpu
*/
+export
function APIC(cpu)
{
/** @type {CPU} */
@@ -640,7 +650,7 @@ APIC.prototype.register_get_highest_bit = function(v)
if(word)
{
- return v86util.int_log2(word >>> 0) | i << 5;
+ return int_log2(word >>> 0) | i << 5;
}
}
diff --git a/src/browser/dummy_screen.js b/src/browser/dummy_screen.js
index 405dd818..6039d961 100644
--- a/src/browser/dummy_screen.js
+++ b/src/browser/dummy_screen.js
@@ -1,9 +1,11 @@
"use strict";
+import { dbg_assert } from "../log.js";
+
/**
* @constructor
*/
-function DummyScreenAdapter()
+export function DummyScreenAdapter()
{
var
graphic_image_data,
diff --git a/src/browser/fake_network.js b/src/browser/fake_network.js
index eee37e6c..8b1290e3 100644
--- a/src/browser/fake_network.js
+++ b/src/browser/fake_network.js
@@ -1,5 +1,9 @@
"use strict";
+import { LOG_FETCH } from "../const.js";
+import { h } from "../lib.js";
+import { dbg_assert, dbg_log } from "../log.js";
+
// https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
const ETHERTYPE_IPV4 = 0x0800;
const ETHERTYPE_ARP = 0x0806;
@@ -23,17 +27,17 @@ const V86_ASCII = [118, 56, 54];
*
* State TIME_WAIT is not needed, we can skip it and transition directly to CLOSED instead.
*/
-const TCP_STATE_CLOSED = "closed";
-const TCP_STATE_SYN_RECEIVED = "syn-received";
-const TCP_STATE_SYN_SENT = "syn-sent";
-const TCP_STATE_SYN_PROBE = "syn-probe";
+export const TCP_STATE_CLOSED = "closed";
+export const TCP_STATE_SYN_RECEIVED = "syn-received";
+export const TCP_STATE_SYN_SENT = "syn-sent";
+export const TCP_STATE_SYN_PROBE = "syn-probe";
//const TCP_STATE_LISTEN = "listen";
-const TCP_STATE_ESTABLISHED = "established";
-const TCP_STATE_FIN_WAIT_1 = "fin-wait-1";
-const TCP_STATE_CLOSE_WAIT = "close-wait";
-const TCP_STATE_FIN_WAIT_2 = "fin-wait-2";
-const TCP_STATE_LAST_ACK = "last-ack";
-const TCP_STATE_CLOSING = "closing";
+export const TCP_STATE_ESTABLISHED = "established";
+export const TCP_STATE_FIN_WAIT_1 = "fin-wait-1";
+export const TCP_STATE_CLOSE_WAIT = "close-wait";
+export const TCP_STATE_FIN_WAIT_2 = "fin-wait-2";
+export const TCP_STATE_LAST_ACK = "last-ack";
+export const TCP_STATE_CLOSING = "closing";
//const TCP_STATE_TIME_WAIT = "time-wait";
// source: RFC6335, 6. Port Number Ranges
@@ -158,7 +162,7 @@ class GrowableRingbuffer
}
}
-function create_eth_encoder_buf()
+export function create_eth_encoder_buf()
{
const eth_frame = new Uint8Array(ETH_FRAME_SIZE);
const buffer = eth_frame.buffer;
@@ -445,7 +449,7 @@ function handle_fake_dhcp(packet, adapter) {
adapter.receive(make_packet(adapter.eth_encoder_buf, reply));
}
-function handle_fake_networking(data, adapter) {
+export function handle_fake_networking(data, adapter) {
let packet = {};
parse_eth(data, packet);
@@ -974,7 +978,7 @@ function write_tcp(spec, out) {
return total_length;
}
-function fake_tcp_connect(dport, adapter)
+export function fake_tcp_connect(dport, adapter)
{
const vm_ip_str = adapter.vm_ip.join(".");
const router_ip_str = adapter.router_ip.join(".");
@@ -1003,7 +1007,7 @@ function fake_tcp_connect(dport, adapter)
return conn;
}
-function fake_tcp_probe(dport, adapter) {
+export function fake_tcp_probe(dport, adapter) {
return new Promise((res, rej) => {
let handle = fake_tcp_connect(dport, adapter);
handle.state = TCP_STATE_SYN_PROBE;
@@ -1014,7 +1018,7 @@ function fake_tcp_probe(dport, adapter) {
/**
* @constructor
*/
-function TCPConnection()
+export function TCPConnection()
{
this.state = TCP_STATE_CLOSED;
this.net = null; // The adapter is stored here
diff --git a/src/browser/fetch_network.js b/src/browser/fetch_network.js
index ecfdc92d..250d144b 100644
--- a/src/browser/fetch_network.js
+++ b/src/browser/fetch_network.js
@@ -1,5 +1,21 @@
"use strict";
+import { LOG_FETCH } from "../const.js";
+import { h } from "../lib.js";
+import { dbg_log } from "../log.js";
+
+import {
+ create_eth_encoder_buf,
+ handle_fake_networking,
+ TCPConnection,
+ TCP_STATE_SYN_RECEIVED,
+ fake_tcp_connect,
+ fake_tcp_probe
+} from "./fake_network.js";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* @constructor
*
@@ -7,7 +23,7 @@
* @param {*=} config
* @export
*/
-function FetchNetworkAdapter(bus, config)
+export function FetchNetworkAdapter(bus, config)
{
config = config || {};
this.bus = bus;
diff --git a/src/browser/filestorage.js b/src/browser/filestorage.js
index 773cb69e..2cfd8fdd 100644
--- a/src/browser/filestorage.js
+++ b/src/browser/filestorage.js
@@ -1,7 +1,11 @@
"use strict";
+
+import { dbg_assert } from "../log.js";
+import { load_file } from "../lib.js";
+
/** @interface */
-function FileStorageInterface() {}
+export function FileStorageInterface() {}
/**
* Read a portion of a file.
@@ -31,7 +35,7 @@ FileStorageInterface.prototype.uncache = function(sha256sum) {};
* @constructor
* @implements {FileStorageInterface}
*/
-function MemoryFileStorage()
+export function MemoryFileStorage()
{
/**
* From sha256sum to file data.
@@ -83,7 +87,7 @@ MemoryFileStorage.prototype.uncache = function(sha256sum)
* @param {FileStorageInterface} file_storage
* @param {string} baseurl
*/
-function ServerFileStorageWrapper(file_storage, baseurl)
+export function ServerFileStorageWrapper(file_storage, baseurl)
{
dbg_assert(baseurl, "ServerMemoryFileStorage: baseurl should not be empty");
@@ -104,7 +108,7 @@ ServerFileStorageWrapper.prototype.load_from_server = function(sha256sum)
{
return new Promise((resolve, reject) =>
{
- v86util.load_file(this.baseurl + sha256sum, { done: async buffer =>
+ load_file(this.baseurl + sha256sum, { done: async buffer =>
{
const data = new Uint8Array(buffer);
await this.cache(sha256sum, data);
diff --git a/src/browser/inbrowser_network.js b/src/browser/inbrowser_network.js
index 90541430..9144eef1 100644
--- a/src/browser/inbrowser_network.js
+++ b/src/browser/inbrowser_network.js
@@ -1,5 +1,9 @@
"use strict";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* Network adapter "inbrowser" which connects the emulated NIC
* to a shared in-browser BroadcastChannel.
@@ -16,7 +20,7 @@
* @param {BusConnector} bus
* @param {*=} config
*/
-function InBrowserNetworkAdapter(bus, config)
+export function InBrowserNetworkAdapter(bus, config)
{
const id = config.id || 0;
diff --git a/src/browser/keyboard.js b/src/browser/keyboard.js
index 0ef6e073..1f47bf2e 100644
--- a/src/browser/keyboard.js
+++ b/src/browser/keyboard.js
@@ -1,5 +1,8 @@
"use strict";
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/** @const */
var SHIFT_SCAN_CODE = 0x2A;
@@ -14,7 +17,7 @@ const PLATFOM_WINDOWS = typeof window !== "undefined" && window.navigator.platfo
*
* @param {BusConnector} bus
*/
-function KeyboardAdapter(bus)
+export function KeyboardAdapter(bus)
{
var
/**
diff --git a/src/browser/main.js b/src/browser/main.js
index b1d5bbb3..0ac1db1a 100644
--- a/src/browser/main.js
+++ b/src/browser/main.js
@@ -1,7 +1,14 @@
"use strict";
-(function()
-{
+import { V86 } from "./starter.js";
+import { LOG_NAMES } from "../const.js";
+import { LOG_LEVEL, setLogLevel } from "../config.js";
+import { print_stats } from "./print_stats.js";
+import { SyncFileBuffer } from "../buffer.js";
+import { pad0, pads, hex_dump, dump_file, download, round_up_to_next_power_of_2 } from "../lib.js";
+import { log_data } from "../log.js";
+
+
const ON_LOCALHOST = !location.hostname.endsWith("copy.sh");
const DEFAULT_NETWORKING_PROXIES = ["wss://relay.widgetry.org/", "ws://localhost:8080/"];
@@ -29,13 +36,13 @@
}
else if(time < 3600)
{
- return (time / 60 | 0) + "m " + v86util.pad0(time % 60, 2) + "s";
+ return (time / 60 | 0) + "m " + pad0(time % 60, 2) + "s";
}
else
{
return (time / 3600 | 0) + "h " +
- v86util.pad0((time / 60 | 0) % 60, 2) + "m " +
- v86util.pad0(time % 60, 2) + "s";
+ pad0((time / 60 | 0) % 60, 2) + "m " +
+ pad0(time % 60, 2) + "s";
}
}
@@ -1659,7 +1666,7 @@
}
input.mask = mask;
- label.append(input, v86util.pads(name, 4) + " ");
+ label.append(input, pads(name, 4) + " ");
log_levels.appendChild(label);
if(i === Math.floor(LOG_NAMES.length / 2))
@@ -1675,11 +1682,11 @@
if(target.checked)
{
- LOG_LEVEL |= mask;
+ setLogLevel(LOG_LEVEL | mask);
}
else
{
- LOG_LEVEL &= ~mask;
+ setLogLevel(LOG_LEVEL & ~mask);
}
target.blur();
@@ -1765,7 +1772,7 @@
if(chunk_size >= 0)
{
chunk_size = Math.min(4 * 1024 * 1024, Math.max(512, chunk_size));
- chunk_size = v86util.round_up_to_next_power_of_2(chunk_size);
+ chunk_size = round_up_to_next_power_of_2(chunk_size);
}
else
{
@@ -2384,6 +2391,9 @@
// $("memory_dump_dmp").blur();
//};
+ /**
+ * @this HTMLElement
+ */
$("capture_network_traffic").onclick = function()
{
this.value = "0 packets";
@@ -2427,6 +2437,9 @@
$("load_state").blur();
};
+ /**
+ * @this HTMLElement
+ */
$("load_state_input").onchange = async function()
{
var file = this.files[0];
@@ -2501,6 +2514,9 @@
$("alttab").blur();
};
+ /**
+ * @this HTMLElement
+ */
$("scale").onchange = function()
{
var n = parseFloat(this.value);
@@ -2627,11 +2643,14 @@
{
$("filesystem_panel").style.display = "block";
+ /**
+ * @this HTMLElement
+ */
$("filesystem_send_file").onchange = function()
{
Array.prototype.forEach.call(this.files, function(file)
{
- var loader = new v86util.SyncFileBuffer(file);
+ var loader = new SyncFileBuffer(file);
loader.onload = function()
{
loader.get_buffer(async function(buffer)
@@ -2646,6 +2665,9 @@
this.blur();
};
+ /**
+ * @this HTMLElement
+ */
$("filesystem_get_file").onkeypress = async function(e)
{
if(e.which !== 13)
@@ -2731,5 +2753,3 @@
window.history.pushState({ search }, "", search);
}
}
-
-})();
diff --git a/src/browser/mouse.js b/src/browser/mouse.js
index d4f5c9cb..eb071ae2 100644
--- a/src/browser/mouse.js
+++ b/src/browser/mouse.js
@@ -1,11 +1,17 @@
"use strict";
+
+import { dbg_log } from "../log.js";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* @constructor
*
* @param {BusConnector} bus
*/
-function MouseAdapter(bus, screen_container)
+export function MouseAdapter(bus, screen_container)
{
/** @const */
var SPEED_FACTOR = 0.15;
diff --git a/src/browser/network.js b/src/browser/network.js
index 22d58f26..4ee59d6d 100644
--- a/src/browser/network.js
+++ b/src/browser/network.js
@@ -1,5 +1,8 @@
"use strict";
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* An ethernet-through-websocket adapter, to be used with
* https://github.com/benjamincburns/websockproxy
@@ -12,7 +15,7 @@
* @param {BusConnector} bus
* @param {number} [id=0] id
*/
-function NetworkAdapter(url, bus, id)
+export function NetworkAdapter(url, bus, id)
{
this.bus = bus;
this.socket = undefined;
diff --git a/src/browser/print_stats.js b/src/browser/print_stats.js
index 4a5f3dc7..033cbe48 100644
--- a/src/browser/print_stats.js
+++ b/src/browser/print_stats.js
@@ -1,9 +1,11 @@
"use strict";
+import { pads } from "../lib.js";
+
/**
* @export
*/
-const print_stats = {
+export const print_stats = {
stats_to_string: function(cpu)
{
return print_stats.print_misc_stats(cpu) +
@@ -251,7 +253,7 @@ const print_stats = {
for(let i = 0; i < 0x100; i++)
{
- text += i.toString(16).padStart(2, "0") + ":" + v86util.pads(Math.round(per_opcode[i] / factor), pad_length);
+ text += i.toString(16).padStart(2, "0") + ":" + pads(Math.round(per_opcode[i] / factor), pad_length);
if(i % 16 === 15)
text += "\n";
@@ -264,7 +266,7 @@ const print_stats = {
for(let i = 0; i < 0x100; i++)
{
- text += (i & 0xFF).toString(16).padStart(2, "0") + ":" + v86util.pads(Math.round(per_opcode0f[i] / factor), pad_length);
+ text += (i & 0xFF).toString(16).padStart(2, "0") + ":" + pads(Math.round(per_opcode0f[i] / factor), pad_length);
if(i % 16 === 15)
text += "\n";
diff --git a/src/browser/screen.js b/src/browser/screen.js
index d207d443..3b963e67 100644
--- a/src/browser/screen.js
+++ b/src/browser/screen.js
@@ -1,11 +1,14 @@
"use strict";
+import { DEBUG_SCREEN_LAYERS } from "../config.js";
+import { dbg_assert } from "../log.js";
+
/**
* Adapter to use visual screen in browsers (in contrast to node)
* @constructor
* @param {Object} options
*/
-function ScreenAdapter(options, screen_fill_buffer)
+export function ScreenAdapter(options, screen_fill_buffer)
{
const screen_container = options.container;
this.screen_fill_buffer = screen_fill_buffer;
diff --git a/src/browser/serial.js b/src/browser/serial.js
index c5c59422..4d804195 100644
--- a/src/browser/serial.js
+++ b/src/browser/serial.js
@@ -1,11 +1,16 @@
"use strict";
+import { dbg_assert, dbg_log } from "../log.js";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* @constructor
*
* @param {BusConnector} bus
*/
-function SerialAdapter(element, bus)
+export function SerialAdapter(element, bus)
{
var serial = this;
@@ -216,7 +221,7 @@ function SerialRecordingAdapter(bus)
* @constructor
* @param {BusConnector} bus
*/
-function SerialAdapterXtermJS(element, bus)
+export function SerialAdapterXtermJS(element, bus)
{
this.element = element;
diff --git a/src/browser/speaker.js b/src/browser/speaker.js
index 44ab448c..2d29c10e 100644
--- a/src/browser/speaker.js
+++ b/src/browser/speaker.js
@@ -1,5 +1,18 @@
"use strict";
+import {
+ MIXER_CHANNEL_BOTH, MIXER_CHANNEL_LEFT, MIXER_CHANNEL_RIGHT,
+ MIXER_SRC_PCSPEAKER, MIXER_SRC_DAC, MIXER_SRC_MASTER,
+} from "../const.js";
+import { dbg_assert, dbg_log } from "../log.js";
+import { OSCILLATOR_FREQ } from "../pit.js";
+import { dump_file } from "../lib.js";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
+/* global registerProcessor, sampleRate */
+
/** @const */
var DAC_QUEUE_RESERVE = 0.2;
@@ -10,7 +23,7 @@ var AUDIOBUFFER_MINIMUM_SAMPLING_RATE = 8000;
* @constructor
* @param {!BusConnector} bus
*/
-function SpeakerAdapter(bus)
+export function SpeakerAdapter(bus)
{
if(typeof window === "undefined")
{
diff --git a/src/browser/starter.js b/src/browser/starter.js
index 22591bd5..d7ad9a23 100644
--- a/src/browser/starter.js
+++ b/src/browser/starter.js
@@ -1,5 +1,36 @@
"use strict";
+import { v86 } from "../main.js";
+import { LOG_CPU, WASM_TABLE_OFFSET, WASM_TABLE_SIZE } from "../const.js";
+import { setLogLevel } from "../config.js";
+import { get_rand_int, load_file, read_sized_string_from_mem } from "../lib.js";
+import { dbg_assert, dbg_trace, dbg_log } from "../log.js";
+import { print_stats } from "./print_stats.js";
+import { Bus } from "../bus.js";
+import { BOOT_ORDER_FD_FIRST, BOOT_ORDER_HD_FIRST, BOOT_ORDER_CD_FIRST } from "../rtc.js";
+
+import { SpeakerAdapter } from "./speaker.js";
+import { NetworkAdapter } from "./network.js";
+import { FetchNetworkAdapter } from "./fetch_network.js";
+import { WispNetworkAdapter } from "./wisp_network.js";
+import { KeyboardAdapter } from "./keyboard.js";
+import { MouseAdapter } from "./mouse.js";
+import { ScreenAdapter } from "./screen.js";
+import { DummyScreenAdapter } from "./dummy_screen.js";
+import { SerialAdapter, SerialAdapterXtermJS } from "./serial.js";
+import { InBrowserNetworkAdapter } from "./inbrowser_network.js";
+
+import { MemoryFileStorage, ServerFileStorageWrapper } from "./filestorage.js";
+import { SyncBuffer, buffer_from_object } from "../buffer.js";
+import { FS } from "../../lib/filesystem.js";
+import { EEXIST, ENOENT } from "../../lib/9p.js";
+
+
+// Decorates CPU
+import "../debug.js";
+import "../memory.js";
+import "../state.js";
+
/**
* Constructor for emulator instances.
*
@@ -107,12 +138,12 @@
* @constructor
* @export
*/
-function V86(options)
+export function V86(options)
{
if(typeof options.log_level === "number")
{
// XXX: Shared between all emulator instances
- LOG_LEVEL = options.log_level;
+ setLogLevel(options.log_level);
}
//var worker = new Worker("src/browser/worker.js");
@@ -136,7 +167,7 @@ function V86(options)
"cpu_event_halt": () => { this.emulator_bus.send("cpu-event-halt"); },
"abort": function() { dbg_assert(false); },
"microtick": v86.microtick,
- "get_rand_int": function() { return v86util.get_rand_int(); },
+ "get_rand_int": function() { return get_rand_int(); },
"apic_acknowledge_irq": function() { return cpu.devices.apic.acknowledge_irq(); },
"stop_idling": function() { return cpu.stop_idling(); },
@@ -159,11 +190,11 @@ function V86(options)
},
"log_from_wasm": function(offset, len) {
- const str = v86util.read_sized_string_from_mem(wasm_memory, offset, len);
+ const str = read_sized_string_from_mem(wasm_memory, offset, len);
dbg_log(str, LOG_CPU);
},
"console_log_from_wasm": function(offset, len) {
- const str = v86util.read_sized_string_from_mem(wasm_memory, offset, len);
+ const str = read_sized_string_from_mem(wasm_memory, offset, len);
console.error(str);
},
"dbg_trace_from_wasm": function() {
@@ -185,6 +216,8 @@ function V86(options)
{
wasm_fn = env =>
{
+ /* global __dirname */
+
return new Promise(resolve => {
let v86_bin = DEBUG ? "v86-debug.wasm" : "v86.wasm";
let v86_bin_fallback = "v86-fallback.wasm";
@@ -207,7 +240,7 @@ function V86(options)
v86_bin_fallback = "build/" + v86_bin_fallback;
}
- v86util.load_file(v86_bin, {
+ load_file(v86_bin, {
done: async bytes =>
{
try
@@ -218,7 +251,7 @@ function V86(options)
}
catch(err)
{
- v86util.load_file(v86_bin_fallback, {
+ load_file(v86_bin_fallback, {
done: async bytes => {
const { instance } = await WebAssembly.instantiate(bytes, env);
this.wasm_source = bytes;
@@ -471,7 +504,7 @@ V86.prototype.continue_init = async function(emulator, options)
{
files_to_load.push({
name,
- loadable: v86util.buffer_from_object(file, this.zstd_decompress_worker.bind(this)),
+ loadable: buffer_from_object(file, this.zstd_decompress_worker.bind(this)),
});
}
};
@@ -552,7 +585,7 @@ V86.prototype.continue_init = async function(emulator, options)
}
else
{
- v86util.load_file(f.url, {
+ load_file(f.url, {
done: function(result)
{
if(f.url.endsWith(".zst") && f.name !== "initial_state")
@@ -561,7 +594,7 @@ V86.prototype.continue_init = async function(emulator, options)
result = this.zstd_decompress(f.size, new Uint8Array(result));
}
- put_on_settings.call(this, f.name, f.as_json ? result : new v86util.SyncBuffer(result));
+ put_on_settings.call(this, f.name, f.as_json ? result : new SyncBuffer(result));
cont(index + 1);
}.bind(this),
progress: function progress(e)
@@ -618,8 +651,8 @@ V86.prototype.continue_init = async function(emulator, options)
settings.fs9p.read_file(initrd_path),
settings.fs9p.read_file(bzimage_path),
]);
- put_on_settings.call(this, "initrd", new v86util.SyncBuffer(initrd.buffer));
- put_on_settings.call(this, "bzimage", new v86util.SyncBuffer(bzimage.buffer));
+ put_on_settings.call(this, "initrd", new SyncBuffer(initrd.buffer));
+ put_on_settings.call(this, "bzimage", new SyncBuffer(bzimage.buffer));
}
}
else
@@ -947,16 +980,16 @@ V86.prototype.set_fda = async function(file)
{
if(file.url && !file.async)
{
- v86util.load_file(file.url, {
+ load_file(file.url, {
done: result =>
{
- this.v86.cpu.devices.fdc.set_fda(new v86util.SyncBuffer(result));
+ this.v86.cpu.devices.fdc.set_fda(new SyncBuffer(result));
},
});
}
else
{
- const image = v86util.buffer_from_object(file, this.zstd_decompress_worker.bind(this));
+ const image = buffer_from_object(file, this.zstd_decompress_worker.bind(this));
image.onload = () =>
{
this.v86.cpu.devices.fdc.set_fda(image);
@@ -1470,3 +1503,11 @@ function FileNotFoundError(message)
this.message = message || "File not found";
}
FileNotFoundError.prototype = Error.prototype;
+
+/* global module */
+
+if(typeof module !== "undefined" && typeof module.exports !== "undefined")
+{
+ module.exports["V86"] = V86;
+ module.exports["print_stats"] = print_stats;
+}
diff --git a/src/browser/wisp_network.js b/src/browser/wisp_network.js
index 2d07783f..99240b45 100644
--- a/src/browser/wisp_network.js
+++ b/src/browser/wisp_network.js
@@ -1,5 +1,18 @@
"use strict";
+import { LOG_NET } from "../const.js";
+import { dbg_log } from "../log.js";
+
+import {
+ create_eth_encoder_buf,
+ handle_fake_networking,
+ TCPConnection,
+ TCP_STATE_SYN_RECEIVED,
+} from "./fake_network.js";
+
+// For Types Only
+import { BusConnector } from "../bus.js";
+
/**
* @constructor
*
@@ -7,7 +20,7 @@
* @param {BusConnector} bus
* @param {*=} config
*/
-function WispNetworkAdapter(wisp_url, bus, config)
+export function WispNetworkAdapter(wisp_url, bus, config)
{
this.register_ws(wisp_url);
this.last_stream = 1;
diff --git a/src/browser/worker_bus.js b/src/browser/worker_bus.js
index 23577231..3564d7c9 100644
--- a/src/browser/worker_bus.js
+++ b/src/browser/worker_bus.js
@@ -1,9 +1,9 @@
"use strict";
-var WorkerBus = {};
+import { dbg_assert } from "../log.js";
/** @constructor */
-WorkerBus.Connector = function(pair)
+export var Connector = function(pair)
{
this.listeners = {};
this.pair = pair;
@@ -22,7 +22,7 @@ WorkerBus.Connector = function(pair)
};
-WorkerBus.Connector.prototype.register = function(name, fn, this_value)
+Connector.prototype.register = function(name, fn, this_value)
{
var listeners = this.listeners[name];
@@ -44,7 +44,7 @@ WorkerBus.Connector.prototype.register = function(name, fn, this_value)
* @param {*=} value
* @param {*=} transfer_list
*/
-WorkerBus.Connector.prototype.send = function(name, value, transfer_list)
+Connector.prototype.send = function(name, value, transfer_list)
{
dbg_assert(arguments.length >= 1);
@@ -57,7 +57,7 @@ WorkerBus.Connector.prototype.send = function(name, value, transfer_list)
};
-WorkerBus.init = function(worker)
+export var init = function(worker)
{
- return new WorkerBus.Connector(worker);
+ return new Connector(worker);
};
diff --git a/src/buffer.js b/src/buffer.js
index 3d4382c2..403ad42a 100644
--- a/src/buffer.js
+++ b/src/buffer.js
@@ -1,14 +1,8 @@
"use strict";
-(function()
-{
- v86util.SyncBuffer = SyncBuffer;
- v86util.AsyncXHRBuffer = AsyncXHRBuffer;
- v86util.AsyncXHRPartfileBuffer = AsyncXHRPartfileBuffer;
- v86util.AsyncFileBuffer = AsyncFileBuffer;
- v86util.SyncFileBuffer = SyncFileBuffer;
-
- v86util.buffer_from_object = buffer_from_object;
+import { CPU } from "./cpu.js";
+import { load_file } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
// The smallest size the emulated hardware can emit
const BLOCK_SIZE = 256;
@@ -19,7 +13,7 @@
* Synchronous access to ArrayBuffer
* @constructor
*/
- function SyncBuffer(buffer)
+ export function SyncBuffer(buffer)
{
dbg_assert(buffer instanceof ArrayBuffer);
@@ -208,7 +202,7 @@
requested_length = Math.ceil((offset - requested_start + len) / this.fixed_chunk_size) * this.fixed_chunk_size;
}
- v86util.load_file(this.filename, {
+ load_file(this.filename, {
done: function done(buffer)
{
var block = new Uint8Array(buffer);
@@ -383,7 +377,7 @@
* @param {number|undefined} fixed_chunk_size
* @param {boolean|undefined} partfile_alt_format
*/
- function AsyncXHRPartfileBuffer(filename, size, fixed_chunk_size, partfile_alt_format, zstd_decompress)
+ export function AsyncXHRPartfileBuffer(filename, size, fixed_chunk_size, partfile_alt_format, zstd_decompress)
{
const parts = filename.match(/\.[^\.]+(\.zst)?$/);
@@ -484,7 +478,7 @@
}
else
{
- v86util.load_file(part_filename, {
+ load_file(part_filename, {
done: async function done(buffer)
{
let block = new Uint8Array(buffer);
@@ -512,7 +506,7 @@
{
const part_filename = this.basename + offset + "-" + (offset + len) + this.extension;
- v86util.load_file(part_filename, {
+ load_file(part_filename, {
done: function done(buffer)
{
dbg_assert(buffer.byteLength === len);
@@ -537,7 +531,7 @@
*
* @constructor
*/
- function SyncFileBuffer(file)
+ export function SyncFileBuffer(file)
{
this.file = file;
this.byteLength = file.size;
@@ -608,7 +602,7 @@
*
* @constructor
*/
- function AsyncFileBuffer(file)
+ export function AsyncFileBuffer(file)
{
this.file = file;
this.byteLength = file.size;
@@ -703,11 +697,12 @@
return file;
};
+ var determine_size;
if(typeof XMLHttpRequest === "undefined")
{
- var determine_size = function(path, cb)
+ determine_size = function(path, cb)
{
- require("fs")["stat"](path, (err, stats) =>
+ import("node:" + "fs").then(fs => fs["stat"](path, (err, stats) =>
{
if(err)
{
@@ -717,14 +712,14 @@
{
cb(null, stats.size);
}
- });
+ }));
};
}
else
{
- var determine_size = function(url, cb)
+ determine_size = function(url, cb)
{
- v86util.load_file(url, {
+ load_file(url, {
done: (buffer, http) =>
{
var header = http.getResponseHeader("Content-Range") || "";
@@ -748,13 +743,13 @@
};
}
- function buffer_from_object(obj, zstd_decompress_worker)
+ export function buffer_from_object(obj, zstd_decompress_worker)
{
// TODO: accept Uint8Array, ArrayBuffer, File, url rather than { url }
if(obj.buffer instanceof ArrayBuffer)
{
- return new v86util.SyncBuffer(obj.buffer);
+ return new SyncBuffer(obj.buffer);
}
else if(typeof File !== "undefined" && obj.buffer instanceof File)
{
@@ -776,11 +771,11 @@
if(is_async)
{
- return new v86util.AsyncFileBuffer(obj.buffer);
+ return new AsyncFileBuffer(obj.buffer);
}
else
{
- return new v86util.SyncFileBuffer(obj.buffer);
+ return new SyncFileBuffer(obj.buffer);
}
}
else if(obj.url)
@@ -789,11 +784,11 @@
if(obj.use_parts)
{
- return new v86util.AsyncXHRPartfileBuffer(obj.url, obj.size, obj.fixed_chunk_size, false, zstd_decompress_worker);
+ return new AsyncXHRPartfileBuffer(obj.url, obj.size, obj.fixed_chunk_size, false, zstd_decompress_worker);
}
else
{
- return new v86util.AsyncXHRBuffer(obj.url, obj.size, obj.fixed_chunk_size);
+ return new AsyncXHRBuffer(obj.url, obj.size, obj.fixed_chunk_size);
}
}
else
@@ -801,4 +796,3 @@
dbg_log("Ignored file: url=" + obj.url + " buffer=" + obj.buffer);
}
}
-})();
diff --git a/src/bus.js b/src/bus.js
index da718756..07ce172b 100644
--- a/src/bus.js
+++ b/src/bus.js
@@ -1,9 +1,11 @@
"use strict";
-var Bus = {};
+import { dbg_assert } from "./log.js";
+
+export var Bus = {};
/** @constructor */
-function BusConnector()
+export function BusConnector()
{
this.listeners = {};
this.pair = undefined;
diff --git a/src/cjs.js b/src/cjs.js
new file mode 100644
index 00000000..845072c4
--- /dev/null
+++ b/src/cjs.js
@@ -0,0 +1,27 @@
+"use strict";
+
+/* global module, self */
+
+var goog = goog || {};
+goog.exportSymbol = function(name, sym) {
+ if(typeof module !== "undefined" && typeof module.exports !== "undefined")
+ {
+ module.exports[name] = sym;
+ }
+ else if(typeof window !== "undefined")
+ {
+ window[name] = sym;
+ }
+ else if(typeof importScripts === "function")
+ {
+ // web worker
+ self[name] = sym;
+ }
+};
+goog.exportProperty = function() {};
+
+/**
+ * @define {boolean}
+ * Overridden for production by closure compiler
+ */
+ var DEBUG = true;
diff --git a/src/config.js b/src/config.js
index 888a6fc5..a0ae8e12 100644
--- a/src/config.js
+++ b/src/config.js
@@ -3,51 +3,54 @@
* Compile time configuration, some only relevant for debug mode
*/
-/**
- * @define {boolean}
- * Overridden for production by closure compiler
- */
-var DEBUG = true;
+import {
+ LOG_ALL, LOG_PS2, LOG_PIT, LOG_9P, LOG_PIC, LOG_DMA, LOG_NET, LOG_FLOPPY, LOG_DISK,
+ LOG_SERIAL, LOG_VGA, LOG_SB16, LOG_VIRTIO
+} from "./const.js";
/** @const */
-var LOG_TO_FILE = false;
+export var LOG_TO_FILE = false;
/**
* @const
* Enables logging all IO port reads and writes. Very verbose
*/
-var LOG_ALL_IO = false;
+export var LOG_ALL_IO = false;
/**
* @const
*/
-var DUMP_GENERATED_WASM = false;
+export var DUMP_GENERATED_WASM = false;
/**
* @const
*/
-var DUMP_UNCOMPILED_ASSEMBLY = false;
+export var DUMP_UNCOMPILED_ASSEMBLY = false;
/**
* @const
* More accurate filenames in 9p debug messages at the cost of performance.
*/
-var TRACK_FILENAMES = false;
+export var TRACK_FILENAMES = false;
-var LOG_LEVEL = LOG_ALL & ~LOG_PS2 & ~LOG_PIT & ~LOG_VIRTIO & ~LOG_9P & ~LOG_PIC &
+export var LOG_LEVEL = LOG_ALL & ~LOG_PS2 & ~LOG_PIT & ~LOG_VIRTIO & ~LOG_9P & ~LOG_PIC &
~LOG_DMA & ~LOG_SERIAL & ~LOG_NET & ~LOG_FLOPPY & ~LOG_DISK & ~LOG_VGA & ~LOG_SB16;
+
+export function setLogLevel(level) {
+ LOG_LEVEL = level;
+}
/**
* @const
* Draws entire buffer and visualizes the layers that would be drawn
*/
-var DEBUG_SCREEN_LAYERS = DEBUG && false;
+export var DEBUG_SCREEN_LAYERS = DEBUG && false;
/**
* @const
* How many ticks the TSC does per millisecond
*/
-var TSC_RATE = 1 * 1000 * 1000;
+export var TSC_RATE = 1 * 1000 * 1000;
/** @const */
-var APIC_TIMER_FREQ = TSC_RATE;
+export var APIC_TIMER_FREQ = TSC_RATE;
diff --git a/src/const.js b/src/const.js
index 775dada4..8d60ab33 100644
--- a/src/const.js
+++ b/src/const.js
@@ -1,6 +1,6 @@
"use strict";
-var
+export const
/** @const */ LOG_ALL = -1,
/** @const */ LOG_NONE = 0,
@@ -35,7 +35,7 @@ var
* @const
* @type {Array>}
*/
-var LOG_NAMES = [
+export const LOG_NAMES = [
[1, ""],
[LOG_CPU, "CPU"],
[LOG_DISK, "DISK"],
@@ -62,7 +62,7 @@ var LOG_NAMES = [
[LOG_FETCH, "FETC"],
];
-var
+export const
// flags register bitflags
/** @const */ FLAG_CARRY = 1,
@@ -108,7 +108,7 @@ FLAGS_DEFAULT = 1 << 1,
/** @const */ REG_LDTR = 7; // local descriptor table register
-var
+export const
/**
* The minimum number of bytes that can be memory-mapped
* by one device.
@@ -122,45 +122,45 @@ var
MMAP_MAX = 0x100000000;
/** @const */
-var CR0_PG = 1 << 31;
+export const CR0_PG = 1 << 31;
/** @const */
-var CR4_PAE = 1 << 5;
+export const CR4_PAE = 1 << 5;
// https://github.com/qemu/seabios/blob/14221cd86eadba82255fdc55ed174d401c7a0a04/src/fw/paravirt.c#L205-L219
-/** @const */ var FW_CFG_SIGNATURE = 0x00;
-/** @const */ var FW_CFG_ID = 0x01;
-/** @const */ var FW_CFG_RAM_SIZE = 0x03;
-/** @const */ var FW_CFG_NB_CPUS = 0x05;
-/** @const */ var FW_CFG_MAX_CPUS = 0x0F;
-/** @const */ var FW_CFG_NUMA = 0x0D;
-/** @const */ var FW_CFG_FILE_DIR = 0x19;
+/** @const */ export const FW_CFG_SIGNATURE = 0x00;
+/** @const */ export const FW_CFG_ID = 0x01;
+/** @const */ export const FW_CFG_RAM_SIZE = 0x03;
+/** @const */ export const FW_CFG_NB_CPUS = 0x05;
+/** @const */ export const FW_CFG_MAX_CPUS = 0x0F;
+/** @const */ export const FW_CFG_NUMA = 0x0D;
+/** @const */ export const FW_CFG_FILE_DIR = 0x19;
-/** @const */ var FW_CFG_CUSTOM_START = 0x8000;
+/** @const */ export const FW_CFG_CUSTOM_START = 0x8000;
// This value is specific to v86, choosen to hopefully not collide with other indexes
-/** @const */ var FW_CFG_FILE_START = 0xC000;
+/** @const */ export const FW_CFG_FILE_START = 0xC000;
-/** @const */ var FW_CFG_SIGNATURE_QEMU = 0x554D4551;
+/** @const */ export const FW_CFG_SIGNATURE_QEMU = 0x554D4551;
// See same constant in jit.rs
/** @const */
-var WASM_TABLE_SIZE = 900;
+export const WASM_TABLE_SIZE = 900;
/** @const */
-var WASM_TABLE_OFFSET = 1024;
+export const WASM_TABLE_OFFSET = 1024;
/** @const */
-var MIXER_CHANNEL_LEFT = 0;
+export const MIXER_CHANNEL_LEFT = 0;
/** @const */
-var MIXER_CHANNEL_RIGHT = 1;
+export const MIXER_CHANNEL_RIGHT = 1;
/** @const */
-var MIXER_CHANNEL_BOTH = 2;
+export const MIXER_CHANNEL_BOTH = 2;
/** @const */
-var MIXER_SRC_MASTER = 0;
+export const MIXER_SRC_MASTER = 0;
/** @const */
-var MIXER_SRC_PCSPEAKER = 1;
+export const MIXER_SRC_PCSPEAKER = 1;
/** @const */
-var MIXER_SRC_DAC = 2;
+export const MIXER_SRC_DAC = 2;
diff --git a/src/cpu.js b/src/cpu.js
index 70e18cd1..29b6089f 100644
--- a/src/cpu.js
+++ b/src/cpu.js
@@ -1,5 +1,58 @@
"use strict";
+import {
+ LOG_CPU, REG_CS,
+ FW_CFG_SIGNATURE, FW_CFG_SIGNATURE_QEMU,
+ WASM_TABLE_SIZE, WASM_TABLE_OFFSET, FW_CFG_ID,
+ FW_CFG_RAM_SIZE, FW_CFG_NB_CPUS, FW_CFG_MAX_CPUS,
+ FW_CFG_NUMA, FW_CFG_FILE_DIR, FW_CFG_FILE_START,
+ FW_CFG_CUSTOM_START, REG_EAX, REG_EBX, FLAGS_DEFAULT,
+ MMAP_BLOCK_BITS, MMAP_BLOCK_SIZE, MMAP_MAX
+} from "./const.js";
+import { DUMP_GENERATED_WASM, DUMP_UNCOMPILED_ASSEMBLY } from "./config.js";
+import { h, view, Bitmap } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+import { SB16 } from "./sb16.js";
+import { IOAPIC } from "./ioapic.js";
+import { APIC, APIC_LOG_VERBOSE } from "./apic.js";
+import { ACPI } from "./acpi.js";
+import { PIT } from "./pit.js";
+import { DMA } from "./dma.js";
+import { UART } from "./uart.js";
+import { Ne2k } from "./ne2k.js";
+import { IO } from "./io.js";
+import { VirtioConsole } from "./virtio_console.js";
+import { PCI } from "./pci.js";
+import { PS2 } from "./ps2.js";
+import { read_elf } from "./elf.js";
+
+import { FloppyController } from "./floppy.js";
+import { IDEDevice } from "./ide.js";
+import { VirtioNet } from "./virtio_net.js";
+import { VGAScreen } from "./vga.js";
+import { VirtioBalloon } from "./virtio_balloon.js";
+import { Virtio9p } from "../lib/9p.js";
+
+import { load_kernel } from "./kernel.js";
+
+
+import {
+ RTC,
+ CMOS_EQUIPMENT_INFO, CMOS_BIOS_SMP_COUNT,
+ CMOS_MEM_HIGHMEM_HIGH, CMOS_MEM_HIGHMEM_MID, CMOS_MEM_HIGHMEM_LOW,
+ CMOS_DISK_DATA, CMOS_BIOS_DISKTRANSFLAG, CMOS_FLOPPY_DRIVE_TYPE,
+ BOOT_ORDER_CD_FIRST, CMOS_BIOS_BOOTFLAG1, CMOS_BIOS_BOOTFLAG2,
+ CMOS_MEM_BASE_LOW, CMOS_MEM_BASE_HIGH,
+ CMOS_MEM_OLD_EXT_LOW, CMOS_MEM_OLD_EXT_HIGH, CMOS_MEM_EXTMEM_LOW,
+ CMOS_MEM_EXTMEM_HIGH, CMOS_MEM_EXTMEM2_LOW, CMOS_MEM_EXTMEM2_HIGH
+} from "./rtc.js";
+
+
+// For Types Only
+
+import { BusConnector } from "./bus.js";
+
// Resources:
// https://pdos.csail.mit.edu/6.828/2006/readings/i386/toc.htm
// https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
@@ -7,7 +60,7 @@
/** @constructor */
-function CPU(bus, wm, stop_idling)
+export function CPU(bus, wm, stop_idling)
{
this.stop_idling = stop_idling;
this.wm = wm;
@@ -18,91 +71,91 @@ function CPU(bus, wm, stop_idling)
this.wasm_memory = memory;
- this.memory_size = v86util.view(Uint32Array, memory, 812, 1);
+ this.memory_size = view(Uint32Array, memory, 812, 1);
this.mem8 = new Uint8Array(0);
this.mem32s = new Int32Array(this.mem8.buffer);
- this.segment_is_null = v86util.view(Uint8Array, memory, 724, 8);
- this.segment_offsets = v86util.view(Int32Array, memory, 736, 8);
- this.segment_limits = v86util.view(Uint32Array, memory, 768, 8);
- this.segment_access_bytes = v86util.view(Uint8Array, memory, 512, 8);
+ this.segment_is_null = view(Uint8Array, memory, 724, 8);
+ this.segment_offsets = view(Int32Array, memory, 736, 8);
+ this.segment_limits = view(Uint32Array, memory, 768, 8);
+ this.segment_access_bytes = view(Uint8Array, memory, 512, 8);
/**
* Wheter or not in protected mode
*/
- this.protected_mode = v86util.view(Int32Array, memory, 800, 1);
+ this.protected_mode = view(Int32Array, memory, 800, 1);
- this.idtr_size = v86util.view(Int32Array, memory, 564, 1);
- this.idtr_offset = v86util.view(Int32Array, memory, 568, 1);
+ this.idtr_size = view(Int32Array, memory, 564, 1);
+ this.idtr_offset = view(Int32Array, memory, 568, 1);
/**
* global descriptor table register
*/
- this.gdtr_size = v86util.view(Int32Array, memory, 572, 1);
- this.gdtr_offset = v86util.view(Int32Array, memory, 576, 1);
+ this.gdtr_size = view(Int32Array, memory, 572, 1);
+ this.gdtr_offset = view(Int32Array, memory, 576, 1);
- this.tss_size_32 = v86util.view(Int32Array, memory, 1128, 1);
+ this.tss_size_32 = view(Int32Array, memory, 1128, 1);
/*
* whether or not a page fault occured
*/
- this.page_fault = v86util.view(Uint32Array, memory, 540, 8);
+ this.page_fault = view(Uint32Array, memory, 540, 8);
- this.cr = v86util.view(Int32Array, memory, 580, 8);
+ this.cr = view(Int32Array, memory, 580, 8);
// current privilege level
- this.cpl = v86util.view(Uint8Array, memory, 612, 1);
+ this.cpl = view(Uint8Array, memory, 612, 1);
// current operand/address size
- this.is_32 = v86util.view(Int32Array, memory, 804, 1);
+ this.is_32 = view(Int32Array, memory, 804, 1);
- this.stack_size_32 = v86util.view(Int32Array, memory, 808, 1);
+ this.stack_size_32 = view(Int32Array, memory, 808, 1);
/**
* Was the last instruction a hlt?
*/
- this.in_hlt = v86util.view(Uint8Array, memory, 616, 1);
+ this.in_hlt = view(Uint8Array, memory, 616, 1);
- this.last_virt_eip = v86util.view(Int32Array, memory, 620, 1);
- this.eip_phys = v86util.view(Int32Array, memory, 624, 1);
+ this.last_virt_eip = view(Int32Array, memory, 620, 1);
+ this.eip_phys = view(Int32Array, memory, 624, 1);
- this.sysenter_cs = v86util.view(Int32Array, memory, 636, 1);
+ this.sysenter_cs = view(Int32Array, memory, 636, 1);
- this.sysenter_esp = v86util.view(Int32Array, memory, 640, 1);
+ this.sysenter_esp = view(Int32Array, memory, 640, 1);
- this.sysenter_eip = v86util.view(Int32Array, memory, 644, 1);
+ this.sysenter_eip = view(Int32Array, memory, 644, 1);
- this.prefixes = v86util.view(Int32Array, memory, 648, 1);
+ this.prefixes = view(Int32Array, memory, 648, 1);
- this.flags = v86util.view(Int32Array, memory, 120, 1);
+ this.flags = view(Int32Array, memory, 120, 1);
/**
* bitmap of flags which are not updated in the flags variable
* changed by arithmetic instructions, so only relevant to arithmetic flags
*/
- this.flags_changed = v86util.view(Int32Array, memory, 100, 1);
+ this.flags_changed = view(Int32Array, memory, 100, 1);
/**
* enough infos about the last arithmetic operation to compute eflags
*/
- this.last_op_size = v86util.view(Int32Array, memory, 96, 1);
- this.last_op1 = v86util.view(Int32Array, memory, 104, 1);
- this.last_result = v86util.view(Int32Array, memory, 112, 1);
+ this.last_op_size = view(Int32Array, memory, 96, 1);
+ this.last_op1 = view(Int32Array, memory, 104, 1);
+ this.last_result = view(Int32Array, memory, 112, 1);
- this.current_tsc = v86util.view(Uint32Array, memory, 960, 2); // 64 bit
+ this.current_tsc = view(Uint32Array, memory, 960, 2); // 64 bit
/** @type {!Object} */
this.devices = {};
- this.instruction_pointer = v86util.view(Int32Array, memory, 556, 1);
- this.previous_ip = v86util.view(Int32Array, memory, 560, 1);
+ this.instruction_pointer = view(Int32Array, memory, 556, 1);
+ this.previous_ip = view(Int32Array, memory, 560, 1);
// configured by guest
- this.apic_enabled = v86util.view(Uint8Array, memory, 548, 1);
+ this.apic_enabled = view(Uint8Array, memory, 548, 1);
// configured when the emulator starts (changes bios initialisation)
- this.acpi_enabled = v86util.view(Uint8Array, memory, 552, 1);
+ this.acpi_enabled = view(Uint8Array, memory, 552, 1);
// managed in io.js
/** @const */ this.memory_map_read8 = [];
@@ -119,47 +172,47 @@ function CPU(bus, wm, stop_idling)
vga: null,
};
- this.instruction_counter = v86util.view(Uint32Array, memory, 664, 1);
+ this.instruction_counter = view(Uint32Array, memory, 664, 1);
// registers
- this.reg32 = v86util.view(Int32Array, memory, 64, 8);
+ this.reg32 = view(Int32Array, memory, 64, 8);
- this.fpu_st = v86util.view(Int32Array, memory, 1152, 4 * 8);
+ this.fpu_st = view(Int32Array, memory, 1152, 4 * 8);
- this.fpu_stack_empty = v86util.view(Uint8Array, memory, 816, 1);
+ this.fpu_stack_empty = view(Uint8Array, memory, 816, 1);
this.fpu_stack_empty[0] = 0xFF;
- this.fpu_stack_ptr = v86util.view(Uint8Array, memory, 1032, 1);
+ this.fpu_stack_ptr = view(Uint8Array, memory, 1032, 1);
this.fpu_stack_ptr[0] = 0;
- this.fpu_control_word = v86util.view(Uint16Array, memory, 1036, 1);
+ this.fpu_control_word = view(Uint16Array, memory, 1036, 1);
this.fpu_control_word[0] = 0x37F;
- this.fpu_status_word = v86util.view(Uint16Array, memory, 1040, 1);
+ this.fpu_status_word = view(Uint16Array, memory, 1040, 1);
this.fpu_status_word[0] = 0;
- this.fpu_ip = v86util.view(Int32Array, memory, 1048, 1);
+ this.fpu_ip = view(Int32Array, memory, 1048, 1);
this.fpu_ip[0] = 0;
- this.fpu_ip_selector = v86util.view(Int32Array, memory, 1052, 1);
+ this.fpu_ip_selector = view(Int32Array, memory, 1052, 1);
this.fpu_ip_selector[0] = 0;
- this.fpu_opcode = v86util.view(Int32Array, memory, 1044, 1);
+ this.fpu_opcode = view(Int32Array, memory, 1044, 1);
this.fpu_opcode[0] = 0;
- this.fpu_dp = v86util.view(Int32Array, memory, 1056, 1);
+ this.fpu_dp = view(Int32Array, memory, 1056, 1);
this.fpu_dp[0] = 0;
- this.fpu_dp_selector = v86util.view(Int32Array, memory, 1060, 1);
+ this.fpu_dp_selector = view(Int32Array, memory, 1060, 1);
this.fpu_dp_selector[0] = 0;
- this.reg_xmm32s = v86util.view(Int32Array, memory, 832, 8 * 4);
+ this.reg_xmm32s = view(Int32Array, memory, 832, 8 * 4);
- this.mxcsr = v86util.view(Int32Array, memory, 824, 1);
+ this.mxcsr = view(Int32Array, memory, 824, 1);
// segment registers, tr and ldtr
- this.sreg = v86util.view(Uint16Array, memory, 668, 8);
+ this.sreg = view(Uint16Array, memory, 668, 8);
// debug registers
- this.dreg = v86util.view(Int32Array, memory, 684, 8);
+ this.dreg = view(Int32Array, memory, 684, 8);
- this.reg_pdpte = v86util.view(Int32Array, memory, 968, 8);
+ this.reg_pdpte = view(Int32Array, memory, 968, 8);
- this.svga_dirty_bitmap_min_offset = v86util.view(Uint32Array, memory, 716, 1);
- this.svga_dirty_bitmap_max_offset = v86util.view(Uint32Array, memory, 720, 1);
+ this.svga_dirty_bitmap_min_offset = view(Uint32Array, memory, 716, 1);
+ this.svga_dirty_bitmap_max_offset = view(Uint32Array, memory, 720, 1);
this.fw_value = [];
this.fw_pointer = 0;
@@ -573,7 +626,7 @@ CPU.prototype.set_state = function(state)
this.fpu_dp_selector[0] = state[74];
this.fpu_opcode[0] = state[75];
- const bitmap = new v86util.Bitmap(state[78].buffer);
+ const bitmap = new Bitmap(state[78].buffer);
const packed_memory = state[77];
this.unpack_memory(bitmap, packed_memory);
@@ -636,7 +689,7 @@ CPU.prototype.pack_memory = function()
}
}
- const bitmap = new v86util.Bitmap(page_count);
+ const bitmap = new Bitmap(page_count);
const packed_memory = new Uint8Array(nonzero_pages.length << 12);
for(const [i, page] of nonzero_pages.entries())
@@ -720,8 +773,8 @@ CPU.prototype.create_memory = function(size, minimum_size)
const memory_offset = this.allocate_memory(size);
- this.mem8 = v86util.view(Uint8Array, this.wasm_memory, memory_offset, size);
- this.mem32s = v86util.view(Uint32Array, this.wasm_memory, memory_offset, size >> 2);
+ this.mem8 = view(Uint8Array, this.wasm_memory, memory_offset, size);
+ this.mem32s = view(Uint32Array, this.wasm_memory, memory_offset, size >> 2);
};
/**
diff --git a/src/debug.js b/src/debug.js
index a694d8ae..9292d661 100644
--- a/src/debug.js
+++ b/src/debug.js
@@ -1,5 +1,16 @@
"use strict";
+import {
+ LOG_BIOS, LOG_CPU,
+ REG_ESP, REG_EBP, REG_ESI, REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_EDI,
+ REG_CS, REG_DS, REG_ES, REG_FS, REG_GS, REG_SS, CR0_PG, CR4_PAE, REG_LDTR,
+ FLAG_VM, FLAG_INTERRUPT, FLAG_CARRY, FLAG_ADJUST, FLAG_ZERO, FLAG_SIGN, FLAG_TRAP,
+ FLAG_DIRECTION, FLAG_OVERFLOW, FLAG_PARITY
+} from "./const.js";
+import { h, pads } from "./lib.js";
+import { dbg_log } from "./log.js";
+import { CPU } from "./cpu.js";
+
CPU.prototype.debug_init = function()
{
var cpu = this;
@@ -560,6 +571,7 @@ CPU.prototype.debug_init = function()
{
if(cs === undefined)
{
+ /* global require */
if(typeof require === "function")
{
cs = require("./capstone-x86.min.js");
@@ -588,7 +600,7 @@ CPU.prototype.debug_init = function()
instructions.forEach(function (instr) {
dbg_log(h(instr.address >>> 0) + ": " +
- v86util.pads(instr.bytes.map(x => h(x, 2).slice(-2)).join(" "), 20) + " " +
+ pads(instr.bytes.map(x => h(x, 2).slice(-2)).join(" "), 20) + " " +
instr.mnemonic + " " + instr.op_str);
});
dbg_log("");
@@ -616,11 +628,12 @@ CPU.prototype.debug_init = function()
debug.dump_wasm = function(buffer)
{
+ /* global require */
if(wabt === undefined)
{
if(typeof require === "function")
{
- wabt = require("./libwabt.js");
+ wabt = require("./libwabt.cjs");
}
else
{
diff --git a/src/dma.js b/src/dma.js
index 4283bded..6ad6d710 100644
--- a/src/dma.js
+++ b/src/dma.js
@@ -1,10 +1,17 @@
"use strict";
+import { LOG_DMA } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+
/**
* @constructor
* @param {CPU} cpu
*/
-function DMA(cpu)
+export function DMA(cpu)
{
/** @const @type {CPU} */
this.cpu = cpu;
diff --git a/src/elf.js b/src/elf.js
index b2d9b3d7..50d561aa 100644
--- a/src/elf.js
+++ b/src/elf.js
@@ -1,5 +1,8 @@
"use strict";
+import { LOG_LEVEL } from "./config.js";
+import { dbg_log } from "./log.js";
+
// A minimal elf parser for loading 32 bit, x86, little endian, executable elf files
const ELF_MAGIC = 0x464C457F;
@@ -95,7 +98,7 @@ function create_struct(struct)
}
/** @param {ArrayBuffer} buffer */
-function read_elf(buffer)
+export function read_elf(buffer)
{
const view = new DataView(buffer);
diff --git a/src/floppy.js b/src/floppy.js
index 3fdde453..302e29b5 100644
--- a/src/floppy.js
+++ b/src/floppy.js
@@ -3,6 +3,18 @@
// https://www.isdaman.com/alsos/hardware/fdc/floppy.htm
// https://wiki.osdev.org/Floppy_Disk_Controller
+import { LOG_FLOPPY } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+import { CMOS_FLOPPY_DRIVE_TYPE } from "./rtc.js";
+import { SyncBuffer } from "./buffer.js";
+
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { DMA } from "./dma.js";
+import { IO } from "./io.js";
+
const DIR_DOOR = 0x80;
const ST1_NID = 1 << 0;
const ST1_NDAT = 1 << 2;
@@ -12,7 +24,7 @@ const ST1_NDAT = 1 << 2;
*
* @param {CPU} cpu
*/
-function FloppyController(cpu, fda_image, fdb_image)
+export function FloppyController(cpu, fda_image, fdb_image)
{
/** @const @type {IO|undefined} */
this.io = cpu.io;
@@ -110,7 +122,7 @@ FloppyController.prototype.set_fda = function(fda_image)
dbg_assert(fda_image.buffer && fda_image.buffer instanceof ArrayBuffer);
const new_image = new Uint8Array(floppy_size);
new_image.set(new Uint8Array(fda_image.buffer));
- fda_image = new v86util.SyncBuffer(new_image.buffer);
+ fda_image = new SyncBuffer(new_image.buffer);
dbg_log("Warning: Unkown floppy size: " + fda_image.byteLength + ", assuming " + floppy_size);
}
diff --git a/src/ide.js b/src/ide.js
index 24691156..ea4c97e7 100644
--- a/src/ide.js
+++ b/src/ide.js
@@ -1,5 +1,14 @@
"use strict";
+import { LOG_DISK } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+import { CMOS_BIOS_DISKTRANSFLAG, CMOS_DISK_DATA, CMOS_DISK_DRIVE1_CYL } from "./rtc.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
+
/** @const */
var CDROM_SECTOR_SIZE = 2048;
/** @const */
@@ -12,7 +21,7 @@ var HD_SECTOR_SIZE = 512;
* @param {number} nr
* @param {BusConnector} bus
* */
-function IDEDevice(cpu, master_buffer, slave_buffer, is_cd, nr, bus)
+export function IDEDevice(cpu, master_buffer, slave_buffer, is_cd, nr, bus)
{
this.master = new IDEInterface(this, cpu, master_buffer, is_cd, nr, 0, bus);
this.slave = new IDEInterface(this, cpu, slave_buffer, false, nr, 1, bus);
diff --git a/src/io.js b/src/io.js
index 1d0f1125..29ad137b 100644
--- a/src/io.js
+++ b/src/io.js
@@ -1,5 +1,14 @@
"use strict";
+import { LOG_IO, MMAP_BLOCK_BITS, MMAP_BLOCK_SIZE, MMAP_MAX } from "./const.js";
+import { LOG_ALL_IO } from "./config.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+
+// For Types Only
+import { CPU } from "./cpu.js";
+
/**
* The ISA IO bus
* Devices register their ports here
@@ -7,7 +16,7 @@
* @constructor
* @param {CPU} cpu
*/
-function IO(cpu)
+export function IO(cpu)
{
/** @const */
this.ports = [];
@@ -87,9 +96,9 @@ IO.prototype.empty_port_write = function(x)
/**
* @param {number} port_addr
* @param {Object} device
- * @param {function():number=} r8
- * @param {function():number=} r16
- * @param {function():number=} r32
+ * @param {function(number):number=} r8
+ * @param {function(number):number=} r16
+ * @param {function(number):number=} r32
*/
IO.prototype.register_read = function(port_addr, device, r8, r16, r32)
{
diff --git a/src/ioapic.js b/src/ioapic.js
index 793ff853..ab51b675 100644
--- a/src/ioapic.js
+++ b/src/ioapic.js
@@ -2,55 +2,64 @@
// http://download.intel.com/design/chipsets/datashts/29056601.pdf
-/** @const */
-var IOAPIC_ADDRESS = 0xFEC00000;
+import { LOG_APIC, MMAP_BLOCK_SIZE } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+import { DELIVERY_MODES, DESTINATION_MODES, APIC_LOG_VERBOSE } from "./apic.js";
-/** @const */
-var IOREGSEL = 0;
-
-/** @const */
-var IOWIN = 0x10;
-
-/** @const */
-var IOAPIC_IRQ_COUNT = 24;
-
-/** @const */
-var IOAPIC_ID = 0; // must match value in seabios
+// For Types Only
+import { CPU } from "./cpu.js";
/** @const */
-var IOAPIC_CONFIG_TRIGGER_MODE_LEVEL = 1 << 15;
+export const IOAPIC_ADDRESS = 0xFEC00000;
/** @const */
-var IOAPIC_CONFIG_MASKED = 1 << 16;
+export const IOREGSEL = 0;
/** @const */
-var IOAPIC_CONFIG_DELIVS = 1 << 12;
+export const IOWIN = 0x10;
/** @const */
-var IOAPIC_CONFIG_REMOTE_IRR = 1 << 14;
+export const IOAPIC_IRQ_COUNT = 24;
/** @const */
-var IOAPIC_CONFIG_READONLY_MASK = IOAPIC_CONFIG_REMOTE_IRR | IOAPIC_CONFIG_DELIVS | 0xFFFE0000;
+export const IOAPIC_ID = 0; // must match value in seabios
+
/** @const */
-var IOAPIC_DELIVERY_FIXED = 0;
+export const IOAPIC_CONFIG_TRIGGER_MODE_LEVEL = 1 << 15;
/** @const */
-var IOAPIC_DELIVERY_LOWEST_PRIORITY = 1;
+export const IOAPIC_CONFIG_MASKED = 1 << 16;
/** @const */
-var IOAPIC_DELIVERY_NMI = 4;
+export const IOAPIC_CONFIG_DELIVS = 1 << 12;
/** @const */
-var IOAPIC_DELIVERY_INIT = 5;
+export const IOAPIC_CONFIG_REMOTE_IRR = 1 << 14;
+
+/** @const */
+export const IOAPIC_CONFIG_READONLY_MASK = IOAPIC_CONFIG_REMOTE_IRR | IOAPIC_CONFIG_DELIVS | 0xFFFE0000;
+
+/** @const */
+export const IOAPIC_DELIVERY_FIXED = 0;
+
+/** @const */
+export const IOAPIC_DELIVERY_LOWEST_PRIORITY = 1;
+
+/** @const */
+export const IOAPIC_DELIVERY_NMI = 4;
+
+/** @const */
+export const IOAPIC_DELIVERY_INIT = 5;
/**
* @constructor
* @param {CPU} cpu
*/
-function IOAPIC(cpu)
+export function IOAPIC(cpu)
{
/** @type {CPU} */
this.cpu = cpu;
diff --git a/src/kernel.js b/src/kernel.js
index 16948540..0fdd0995 100644
--- a/src/kernel.js
+++ b/src/kernel.js
@@ -1,5 +1,9 @@
"use strict";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+
// https://www.kernel.org/doc/Documentation/x86/boot.txt
const LINUX_BOOT_HDR_SETUP_SECTS = 0x1F1;
@@ -37,7 +41,7 @@ const LINUX_BOOT_HDR_LOADFLAGS_KEEP_SEGMENTS = 1 << 6;
const LINUX_BOOT_HDR_LOADFLAGS_CAN_USE_HEAPS = 1 << 7;
-function load_kernel(mem8, bzimage, initrd, cmdline)
+export function load_kernel(mem8, bzimage, initrd, cmdline)
{
dbg_log("Trying to load kernel of size " + bzimage.byteLength);
diff --git a/src/lib.js b/src/lib.js
index 682c1031..441390ef 100644
--- a/src/lib.js
+++ b/src/lib.js
@@ -1,52 +1,34 @@
"use strict";
-var goog = goog || {};
-goog.exportSymbol = function(name, sym) {
- if(typeof module !== "undefined" && typeof module.exports !== "undefined")
- {
- module.exports[name] = sym;
- }
- else if(typeof window !== "undefined")
- {
- window[name] = sym;
- }
- else if(typeof importScripts === "function")
- {
- // web worker
- self[name] = sym;
- }
-};
-goog.exportProperty = function() {};
-
-var v86util = v86util || {};
+import { dbg_assert } from "./log.js";
// pad string with spaces on the right
-v86util.pads = function(str, len)
+export function pads(str, len)
{
str = (str || str === 0) ? str + "" : "";
return str.padEnd(len, " ");
-};
+}
// pad string with zeros on the left
-v86util.pad0 = function(str, len)
+export function pad0(str, len)
{
str = (str || str === 0) ? str + "" : "";
return str.padStart(len, "0");
-};
+}
// generates array given size with zeros
-v86util.zeros = function(size)
+export function zeros(size)
{
return Array(size).fill(0);
-};
+}
// generates [0, 1, 2, ..., size-1]
-v86util.range = function(size)
+export function range(size)
{
return Array.from(Array(size).keys());
-};
+}
-v86util.view = function(constructor, memory, offset, length)
+export var view = function(constructor, memory, offset, length)
{
dbg_assert(offset >= 0);
return new Proxy({},
@@ -78,7 +60,7 @@ v86util.view = function(constructor, memory, offset, length)
* @param {number=} len
* @return {string}
*/
-function h(n, len)
+export function h(n, len)
{
if(!n)
{
@@ -89,14 +71,14 @@ function h(n, len)
var str = n.toString(16);
}
- return "0x" + v86util.pad0(str.toUpperCase(), len || 1);
+ return "0x" + pad0(str.toUpperCase(), len || 1);
}
-function hex_dump(buffer)
+export function hex_dump(buffer)
{
function hex(n, len)
{
- return v86util.pad0(n.toString(16).toUpperCase(), len);
+ return pad0(n.toString(16).toUpperCase(), len);
}
const result = [];
@@ -144,11 +126,13 @@ function hex_dump(buffer)
return "\n" + result.join("\n") + "\n";
}
+/* global require */
+export var get_rand_int;
if(typeof crypto !== "undefined" && crypto.getRandomValues)
{
const rand_data = new Int32Array(1);
- v86util.get_rand_int = function()
+ get_rand_int = function()
{
crypto.getRandomValues(rand_data);
return rand_data[0];
@@ -159,34 +143,41 @@ else if(typeof require !== "undefined")
/** @type {{ randomBytes: Function }} */
const crypto = require("crypto");
- v86util.get_rand_int = function()
+ get_rand_int = function()
{
return crypto.randomBytes(4)["readInt32LE"](0);
};
}
+else if(typeof process !== "undefined")
+ {
+ import("node:" + "crypto").then(crypto => {
+ get_rand_int = function()
+ {
+ return crypto["randomBytes"](4)["readInt32LE"](0);
+ };
+ });
+ }
else
{
dbg_assert(false, "Unsupported platform: No cryptographic random values");
}
-(function()
+export var int_log2;
+
+if(typeof Math.clz32 === "function" && Math.clz32(0) === 32 && Math.clz32(0x12345) === 15 && Math.clz32(-1) === 0)
{
- if(typeof Math.clz32 === "function" && Math.clz32(0) === 32 && Math.clz32(0x12345) === 15 && Math.clz32(-1) === 0)
+ /**
+ * calculate the integer logarithm base 2
+ * @param {number} x
+ * @return {number}
+ */
+ int_log2 = function(x)
{
- /**
- * calculate the integer logarithm base 2
- * @param {number} x
- * @return {number}
- */
- v86util.int_log2 = function(x)
- {
- dbg_assert(x > 0);
+ dbg_assert(x > 0);
- return 31 - Math.clz32(x);
- };
-
- return;
- }
+ return 31 - Math.clz32(x);
+ };
+} else {
var int_log2_table = new Int8Array(256);
@@ -203,7 +194,7 @@ else
* @param {number} x
* @return {number}
*/
- v86util.int_log2 = function(x)
+ int_log2 = function(x)
{
x >>>= 0;
dbg_assert(x > 0);
@@ -236,28 +227,28 @@ else
}
}
};
-})();
+}
-v86util.round_up_to_next_power_of_2 = function(x)
+export const round_up_to_next_power_of_2 = function(x)
{
dbg_assert(x >= 0);
- return x <= 1 ? 1 : 1 << 1 + v86util.int_log2(x - 1);
+ return x <= 1 ? 1 : 1 << 1 + int_log2(x - 1);
};
if(DEBUG)
{
- dbg_assert(v86util.int_log2(1) === 0);
- dbg_assert(v86util.int_log2(2) === 1);
- dbg_assert(v86util.int_log2(7) === 2);
- dbg_assert(v86util.int_log2(8) === 3);
- dbg_assert(v86util.int_log2(123456789) === 26);
+ dbg_assert(int_log2(1) === 0);
+ dbg_assert(int_log2(2) === 1);
+ dbg_assert(int_log2(7) === 2);
+ dbg_assert(int_log2(8) === 3);
+ dbg_assert(int_log2(123456789) === 26);
- dbg_assert(v86util.round_up_to_next_power_of_2(0) === 1);
- dbg_assert(v86util.round_up_to_next_power_of_2(1) === 1);
- dbg_assert(v86util.round_up_to_next_power_of_2(2) === 2);
- dbg_assert(v86util.round_up_to_next_power_of_2(7) === 8);
- dbg_assert(v86util.round_up_to_next_power_of_2(8) === 8);
- dbg_assert(v86util.round_up_to_next_power_of_2(123456789) === 134217728);
+ dbg_assert(round_up_to_next_power_of_2(0) === 1);
+ dbg_assert(round_up_to_next_power_of_2(1) === 1);
+ dbg_assert(round_up_to_next_power_of_2(2) === 2);
+ dbg_assert(round_up_to_next_power_of_2(7) === 8);
+ dbg_assert(round_up_to_next_power_of_2(8) === 8);
+ dbg_assert(round_up_to_next_power_of_2(123456789) === 134217728);
}
/**
@@ -266,7 +257,7 @@ if(DEBUG)
* Queue wrapper around Uint8Array
* Used by devices such as the PS2 controller
*/
-function ByteQueue(size)
+export function ByteQueue(size)
{
var data = new Uint8Array(size),
start,
@@ -337,7 +328,7 @@ function ByteQueue(size)
* Queue wrapper around Float32Array
* Used by devices such as the sound blaster sound card
*/
-function FloatQueue(size)
+export function FloatQueue(size)
{
this.size = size;
this.data = new Float32Array(size);
@@ -465,7 +456,7 @@ CircularQueue.prototype.set = function(new_data)
this.index = 0;
};
-function dump_file(ab, name)
+export function dump_file(ab, name)
{
if(!Array.isArray(ab))
{
@@ -476,7 +467,7 @@ function dump_file(ab, name)
download(blob, name);
}
-function download(file_or_blob, name)
+export function download(file_or_blob, name)
{
var a = document.createElement("a");
a["download"] = name;
@@ -502,7 +493,7 @@ function download(file_or_blob, name)
* A simple 1d bitmap
* @constructor
*/
-v86util.Bitmap = function(length_or_buffer)
+export var Bitmap = function(length_or_buffer)
{
if(typeof length_or_buffer === "number")
{
@@ -514,11 +505,11 @@ v86util.Bitmap = function(length_or_buffer)
}
else
{
- dbg_assert(false, "v86util.Bitmap: Invalid argument");
+ dbg_assert(false, "Bitmap: Invalid argument");
}
};
-v86util.Bitmap.prototype.set = function(index, value)
+Bitmap.prototype.set = function(index, value)
{
const bit_index = index & 7;
const byte_index = index >> 3;
@@ -528,7 +519,7 @@ v86util.Bitmap.prototype.set = function(index, value)
value ? this.view[byte_index] | bit_mask : this.view[byte_index] & ~bit_mask;
};
-v86util.Bitmap.prototype.get = function(index)
+Bitmap.prototype.get = function(index)
{
const bit_index = index & 7;
const byte_index = index >> 3;
@@ -536,19 +527,20 @@ v86util.Bitmap.prototype.get = function(index)
return this.view[byte_index] >> bit_index & 1;
};
-v86util.Bitmap.prototype.get_buffer = function()
+Bitmap.prototype.get_buffer = function()
{
return this.view.buffer;
};
+export var load_file;
if(typeof XMLHttpRequest === "undefined")
{
- v86util.load_file = load_file_nodejs;
+ load_file = load_file_nodejs;
}
else
{
- v86util.load_file = load_file;
+ load_file = _load_file;
}
/**
@@ -556,7 +548,7 @@ else
* @param {Object} options
* @param {number=} n_tries
*/
-function load_file(filename, options, n_tries)
+function _load_file(filename, options, n_tries)
{
var http = new XMLHttpRequest();
@@ -656,13 +648,11 @@ function load_file(filename, options, n_tries)
function load_file_nodejs(filename, options)
{
- const fs = require("fs");
-
if(options.range)
{
dbg_assert(!options.as_json);
- fs["open"](filename, "r", (err, fd) =>
+ import("node:" + "fs").then(fs => fs["open"](filename, "r", (err, fd) =>
{
if(err) throw err;
@@ -680,7 +670,7 @@ function load_file_nodejs(filename, options)
if(err) throw err;
});
});
- });
+ }));
}
else
{
@@ -688,7 +678,7 @@ function load_file_nodejs(filename, options)
encoding: options.as_json ? "utf-8" : null,
};
- fs["readFile"](filename, o, function(err, data)
+ import("node:" + "fs").then(fs => fs["readFile"](filename, o, function(err, data)
{
if(err)
{
@@ -709,14 +699,14 @@ function load_file_nodejs(filename, options)
options.done(result);
}
- });
+ }));
}
}
// Reads len characters at offset from Memory object mem as a JS string
-v86util.read_sized_string_from_mem = function read_sized_string_from_mem(mem, offset, len)
+export function read_sized_string_from_mem(mem, offset, len)
{
offset >>>= 0;
len >>>= 0;
return String.fromCharCode(...new Uint8Array(mem.buffer, offset, len));
-};
+}
diff --git a/src/log.js b/src/log.js
index 277316a2..d170266a 100644
--- a/src/log.js
+++ b/src/log.js
@@ -1,6 +1,10 @@
"use strict";
-var log_data = [];
+import { LOG_NAMES } from "./const.js";
+import { LOG_TO_FILE, LOG_LEVEL } from "./config.js";
+import { pad0, pads } from "./lib.js";
+
+export var log_data = [];
function do_the_log(message)
{
@@ -18,7 +22,7 @@ function do_the_log(message)
* @type {function((string|number), number=)}
* @const
*/
-var dbg_log = (function()
+export var dbg_log = (function()
{
if(!DEBUG)
{
@@ -47,7 +51,7 @@ var dbg_log = (function()
if(level & LOG_LEVEL)
{
var level_name = dbg_names[level] || "",
- message = "[" + v86util.pads(level_name, 4) + "] " + stuff;
+ message = "[" + pads(level_name, 4) + "] " + stuff;
if(message === log_last_message)
{
@@ -60,10 +64,10 @@ var dbg_log = (function()
}
var now = new Date();
- var time_str = v86util.pad0(now.getHours(), 2) + ":" +
- v86util.pad0(now.getMinutes(), 2) + ":" +
- v86util.pad0(now.getSeconds(), 2) + "+" +
- v86util.pad0(now.getMilliseconds(), 3) + " ";
+ var time_str = pad0(now.getHours(), 2) + ":" +
+ pad0(now.getMinutes(), 2) + ":" +
+ pad0(now.getSeconds(), 2) + "+" +
+ pad0(now.getMilliseconds(), 3) + " ";
if(log_message_repetitions)
{
@@ -90,7 +94,7 @@ var dbg_log = (function()
/**
* @param {number=} level
*/
-function dbg_trace(level)
+export function dbg_trace(level)
{
if(!DEBUG) return;
@@ -102,7 +106,7 @@ function dbg_trace(level)
* @param {string=} msg
* @param {number=} level
*/
-function dbg_assert(cond, msg, level)
+export function dbg_assert(cond, msg, level)
{
if(!DEBUG) return;
@@ -113,7 +117,7 @@ function dbg_assert(cond, msg, level)
}
-function dbg_assert_failed(msg)
+export function dbg_assert_failed(msg)
{
debugger;
console.trace();
diff --git a/src/main.js b/src/main.js
index 34a2f255..140197f3 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,10 +1,12 @@
"use strict";
+import { CPU } from "./cpu.js";
+
/**
* @constructor
* @param {Object=} wasm
*/
-function v86(bus, wasm)
+export function v86(bus, wasm)
{
/** @type {boolean} */
this.running = false;
@@ -98,6 +100,7 @@ if(typeof process !== "undefined")
{
v86.prototype.yield = function(t, tick)
{
+ /* global global */
if(t < 1)
{
global.setImmediate(tick => this.yield_callback(tick), tick);
@@ -205,7 +208,7 @@ v86.prototype.restore_state = function(state)
return this.cpu.restore_state(state);
};
-
+/* global require */
if(typeof performance === "object" && performance.now)
{
v86.microtick = performance.now.bind(performance);
diff --git a/src/memory.js b/src/memory.js
index 60445e4f..521ec189 100644
--- a/src/memory.js
+++ b/src/memory.js
@@ -1,5 +1,9 @@
"use strict";
+import { MMAP_BLOCK_BITS } from "./const.js";
+import { CPU } from "./cpu.js";
+import { dbg_assert } from "./log.js";
+
CPU.prototype.mmap_read8 = function(addr)
{
diff --git a/src/ne2k.js b/src/ne2k.js
index 5a944af7..6f5a94b3 100644
--- a/src/ne2k.js
+++ b/src/ne2k.js
@@ -1,5 +1,14 @@
"use strict";
+import { LOG_NET } from "./const.js";
+import { h, hex_dump } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { PCI } from "./pci.js";
+import { BusConnector } from "./bus.js";
+
// http://www.ethernut.de/pdf/8019asds.pdf
const NE2K_LOG_VERBOSE = false;
@@ -226,7 +235,7 @@ function translate_mac_address(packet, search_mac, replacement_mac)
}
}
-function format_mac(mac)
+export function format_mac(mac)
{
return [
mac[0].toString(16).padStart(2, "0"),
@@ -288,7 +297,7 @@ function dump_packet(packet, prefix)
* @param {Boolean} mac_address_translation
* @param {number} [id=0] id
*/
-function Ne2k(cpu, bus, preserve_mac_from_state_image, mac_address_translation, id)
+export function Ne2k(cpu, bus, preserve_mac_from_state_image, mac_address_translation, id)
{
/** @const @type {CPU} */
this.cpu = cpu;
diff --git a/src/pci.js b/src/pci.js
index f708f7c7..de0c16f2 100644
--- a/src/pci.js
+++ b/src/pci.js
@@ -1,8 +1,16 @@
"use strict";
+import { LOG_PCI } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+
+
// http://wiki.osdev.org/PCI
-var
+export const
/** @const */ PCI_CONFIG_ADDRESS = 0xCF8,
/** @const */ PCI_CONFIG_DATA = 0xCFC;
@@ -10,7 +18,7 @@ var
* @constructor
* @param {CPU} cpu
*/
-function PCI(cpu)
+export function PCI(cpu)
{
this.pci_addr = new Uint8Array(4);
this.pci_value = new Uint8Array(4);
diff --git a/src/pit.js b/src/pit.js
index f7813c15..272b36c7 100644
--- a/src/pit.js
+++ b/src/pit.js
@@ -1,17 +1,26 @@
"use strict";
+import { v86 } from "./main.js";
+import { LOG_PIT } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+
+
/**
* @const
* In kHz
*/
-var OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz
+export const OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz
/**
* @constructor
*
* Programmable Interval Timer
*/
-function PIT(cpu, bus)
+export function PIT(cpu, bus)
{
/** @const @type {CPU} */
this.cpu = cpu;
diff --git a/src/ps2.js b/src/ps2.js
index bfee804b..3e8b96d0 100644
--- a/src/ps2.js
+++ b/src/ps2.js
@@ -1,5 +1,14 @@
"use strict";
+import { LOG_PS2 } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
+import { ByteQueue } from "./lib.js";
+
/** @const */
const PS2_LOG_VERBOSE = false;
@@ -8,7 +17,7 @@ const PS2_LOG_VERBOSE = false;
* @param {CPU} cpu
* @param {BusConnector} bus
*/
-function PS2(cpu, bus)
+export function PS2(cpu, bus)
{
/** @const @type {CPU} */
this.cpu = cpu;
diff --git a/src/rtc.js b/src/rtc.js
index e4c03feb..e0fd43f8 100644
--- a/src/rtc.js
+++ b/src/rtc.js
@@ -1,56 +1,67 @@
"use strict";
-/** @const */ var CMOS_RTC_SECONDS = 0x00;
-/** @const */ var CMOS_RTC_SECONDS_ALARM = 0x01;
-/** @const */ var CMOS_RTC_MINUTES = 0x02;
-/** @const */ var CMOS_RTC_MINUTES_ALARM = 0x03;
-/** @const */ var CMOS_RTC_HOURS = 0x04;
-/** @const */ var CMOS_RTC_HOURS_ALARM = 0x05;
-/** @const */ var CMOS_RTC_DAY_WEEK = 0x06;
-/** @const */ var CMOS_RTC_DAY_MONTH = 0x07;
-/** @const */ var CMOS_RTC_MONTH = 0x08;
-/** @const */ var CMOS_RTC_YEAR = 0x09;
-/** @const */ var CMOS_STATUS_A = 0x0a;
-/** @const */ var CMOS_STATUS_B = 0x0b;
-/** @const */ var CMOS_STATUS_C = 0x0c;
-/** @const */ var CMOS_STATUS_D = 0x0d;
-/** @const */ var CMOS_RESET_CODE = 0x0f;
+import { v86 } from "./main.js";
+import { LOG_RTC } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
-/** @const */ var CMOS_FLOPPY_DRIVE_TYPE = 0x10;
-/** @const */ var CMOS_DISK_DATA = 0x12;
-/** @const */ var CMOS_EQUIPMENT_INFO = 0x14;
-/** @const */ var CMOS_MEM_BASE_LOW = 0x15;
-/** @const */ var CMOS_MEM_BASE_HIGH = 0x16;
-/** @const */ var CMOS_MEM_OLD_EXT_LOW = 0x17;
-/** @const */ var CMOS_MEM_OLD_EXT_HIGH = 0x18;
-/** @const */ var CMOS_DISK_DRIVE1_TYPE = 0x19;
-/** @const */ var CMOS_DISK_DRIVE2_TYPE = 0x1a;
-/** @const */ var CMOS_DISK_DRIVE1_CYL = 0x1b;
-/** @const */ var CMOS_DISK_DRIVE2_CYL = 0x24;
-/** @const */ var CMOS_MEM_EXTMEM_LOW = 0x30;
-/** @const */ var CMOS_MEM_EXTMEM_HIGH = 0x31;
-/** @const */ var CMOS_CENTURY = 0x32;
-/** @const */ var CMOS_MEM_EXTMEM2_LOW = 0x34;
-/** @const */ var CMOS_MEM_EXTMEM2_HIGH = 0x35;
-/** @const */ var CMOS_CENTURY2 = 0x37;
-/** @const */ var CMOS_BIOS_BOOTFLAG1 = 0x38;
-/** @const */ var CMOS_BIOS_DISKTRANSFLAG = 0x39;
-/** @const */ var CMOS_BIOS_BOOTFLAG2 = 0x3d;
-/** @const */ var CMOS_MEM_HIGHMEM_LOW = 0x5b;
-/** @const */ var CMOS_MEM_HIGHMEM_MID = 0x5c;
-/** @const */ var CMOS_MEM_HIGHMEM_HIGH = 0x5d;
-/** @const */ var CMOS_BIOS_SMP_COUNT = 0x5f;
+// For Types Only
+import { CPU } from "./cpu.js";
+import { DMA } from "./dma.js";
+
+
+/** @const */ export const CMOS_RTC_SECONDS = 0x00;
+/** @const */ export const CMOS_RTC_SECONDS_ALARM = 0x01;
+/** @const */ export const CMOS_RTC_MINUTES = 0x02;
+/** @const */ export const CMOS_RTC_MINUTES_ALARM = 0x03;
+/** @const */ export const CMOS_RTC_HOURS = 0x04;
+/** @const */ export const CMOS_RTC_HOURS_ALARM = 0x05;
+/** @const */ export const CMOS_RTC_DAY_WEEK = 0x06;
+/** @const */ export const CMOS_RTC_DAY_MONTH = 0x07;
+/** @const */ export const CMOS_RTC_MONTH = 0x08;
+/** @const */ export const CMOS_RTC_YEAR = 0x09;
+/** @const */ export const CMOS_STATUS_A = 0x0a;
+/** @const */ export const CMOS_STATUS_B = 0x0b;
+/** @const */ export const CMOS_STATUS_C = 0x0c;
+/** @const */ export const CMOS_STATUS_D = 0x0d;
+/** @const */ export const CMOS_RESET_CODE = 0x0f;
+
+/** @const */ export const CMOS_FLOPPY_DRIVE_TYPE = 0x10;
+/** @const */ export const CMOS_DISK_DATA = 0x12;
+/** @const */ export const CMOS_EQUIPMENT_INFO = 0x14;
+/** @const */ export const CMOS_MEM_BASE_LOW = 0x15;
+/** @const */ export const CMOS_MEM_BASE_HIGH = 0x16;
+/** @const */ export const CMOS_MEM_OLD_EXT_LOW = 0x17;
+/** @const */ export const CMOS_MEM_OLD_EXT_HIGH = 0x18;
+/** @const */ export const CMOS_DISK_DRIVE1_TYPE = 0x19;
+/** @const */ export const CMOS_DISK_DRIVE2_TYPE = 0x1a;
+/** @const */ export const CMOS_DISK_DRIVE1_CYL = 0x1b;
+/** @const */ export const CMOS_DISK_DRIVE2_CYL = 0x24;
+/** @const */ export const CMOS_MEM_EXTMEM_LOW = 0x30;
+/** @const */ export const CMOS_MEM_EXTMEM_HIGH = 0x31;
+/** @const */ export const CMOS_CENTURY = 0x32;
+/** @const */ export const CMOS_MEM_EXTMEM2_LOW = 0x34;
+/** @const */ export const CMOS_MEM_EXTMEM2_HIGH = 0x35;
+/** @const */ export const CMOS_CENTURY2 = 0x37;
+/** @const */ export const CMOS_BIOS_BOOTFLAG1 = 0x38;
+/** @const */ export const CMOS_BIOS_DISKTRANSFLAG = 0x39;
+/** @const */ export const CMOS_BIOS_BOOTFLAG2 = 0x3d;
+/** @const */ export const CMOS_MEM_HIGHMEM_LOW = 0x5b;
+/** @const */ export const CMOS_MEM_HIGHMEM_MID = 0x5c;
+/** @const */ export const CMOS_MEM_HIGHMEM_HIGH = 0x5d;
+/** @const */ export const CMOS_BIOS_SMP_COUNT = 0x5f;
// see CPU.prototype.fill_cmos
-const BOOT_ORDER_CD_FIRST = 0x123;
-const BOOT_ORDER_HD_FIRST = 0x312;
-const BOOT_ORDER_FD_FIRST = 0x321;
+export const BOOT_ORDER_CD_FIRST = 0x123;
+export const BOOT_ORDER_HD_FIRST = 0x312;
+export const BOOT_ORDER_FD_FIRST = 0x321;
/**
* RTC (real time clock) and CMOS
* @constructor
* @param {CPU} cpu
*/
+export
function RTC(cpu)
{
/** @const @type {CPU} */
diff --git a/src/sb16.js b/src/sb16.js
index 43007644..0c2bc263 100644
--- a/src/sb16.js
+++ b/src/sb16.js
@@ -1,5 +1,21 @@
"use strict";
+import {
+ LOG_SB16,
+ MIXER_CHANNEL_BOTH, MIXER_CHANNEL_LEFT, MIXER_CHANNEL_RIGHT,
+ MIXER_SRC_PCSPEAKER, MIXER_SRC_DAC, MIXER_SRC_MASTER,
+} from "./const.js";
+import { h } from "./lib.js";
+import { dbg_log } from "./log.js";
+import { SyncBuffer } from "./buffer.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { DMA } from "./dma.js";
+import { IO } from "./io.js";
+import { BusConnector } from "./bus.js";
+import { ByteQueue, FloatQueue } from "./lib.js";
+
// Useful documentation, articles, and source codes for reference:
// ===============================================================
//
@@ -92,7 +108,7 @@ var FM_HANDLERS = [];
* @param {CPU} cpu
* @param {BusConnector} bus
*/
-function SB16(cpu, bus)
+export function SB16(cpu, bus)
{
/** @const @type {CPU} */
this.cpu = cpu;
@@ -150,7 +166,7 @@ function SB16(cpu, bus)
this.dma_buffer_uint8 = new Uint8Array(this.dma_buffer);
this.dma_buffer_int16 = new Int16Array(this.dma_buffer);
this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer);
- this.dma_syncbuffer = new v86util.SyncBuffer(this.dma_buffer);
+ this.dma_syncbuffer = new SyncBuffer(this.dma_buffer);
this.dma_waiting_transfer = false;
this.dma_paused = false;
this.sampling_rate = 22050;
@@ -399,7 +415,7 @@ SB16.prototype.set_state = function(state)
this.dma_buffer_int8 = new Int8Array(this.dma_buffer);
this.dma_buffer_int16 = new Int16Array(this.dma_buffer);
this.dma_buffer_uint16 = new Uint16Array(this.dma_buffer);
- this.dma_syncbuffer = new v86util.SyncBuffer(this.dma_buffer);
+ this.dma_syncbuffer = new SyncBuffer(this.dma_buffer);
if(this.dma_paused)
{
diff --git a/src/state.js b/src/state.js
index 133d5872..524cf1af 100644
--- a/src/state.js
+++ b/src/state.js
@@ -1,5 +1,9 @@
"use strict";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+import { CPU } from "./cpu.js";
+
/** @const */
var STATE_VERSION = 6;
diff --git a/src/uart.js b/src/uart.js
index a85c5c19..c8078861 100644
--- a/src/uart.js
+++ b/src/uart.js
@@ -1,5 +1,13 @@
"use strict";
+import { LOG_SERIAL } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
+
/*
* Serial ports
* http://wiki.osdev.org/UART
@@ -44,7 +52,7 @@ var DLAB = 0x80;
* @param {number} port
* @param {BusConnector} bus
*/
-function UART(cpu, port, bus)
+export function UART(cpu, port, bus)
{
/** @const @type {BusConnector} */
this.bus = bus;
diff --git a/src/vga.js b/src/vga.js
index 0d85da06..61b0d605 100644
--- a/src/vga.js
+++ b/src/vga.js
@@ -1,5 +1,16 @@
"use strict";
+import { LOG_VGA } from "./const.js";
+import { h } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { ScreenAdapter } from "./browser/screen.js";
+import { BusConnector } from "./bus.js";
+import { DummyScreenAdapter } from "./browser/dummy_screen.js";
+import { round_up_to_next_power_of_2, view } from "./lib.js";
+
// Always 64k
const VGA_BANK_SIZE = 64 * 1024;
@@ -51,7 +62,7 @@ const VGA_HOST_MEMORY_SPACE_SIZE = Uint32Array.from([
* @param {ScreenAdapter|DummyScreenAdapter} screen
* @param {number} vga_memory_size
*/
-function VGAScreen(cpu, bus, screen, vga_memory_size)
+export function VGAScreen(cpu, bus, screen, vga_memory_size)
{
this.cpu = cpu;
@@ -216,7 +227,7 @@ function VGAScreen(cpu, bus, screen, vga_memory_size)
else
{
// required for pci code
- this.vga_memory_size = v86util.round_up_to_next_power_of_2(this.vga_memory_size);
+ this.vga_memory_size = round_up_to_next_power_of_2(this.vga_memory_size);
}
dbg_log("effective vga memory size: " + this.vga_memory_size, LOG_VGA);
@@ -356,7 +367,7 @@ function VGAScreen(cpu, bus, screen, vga_memory_size)
const vga_offset = cpu.svga_allocate_memory(this.vga_memory_size) >>> 0;
- this.svga_memory = v86util.view(Uint8Array, cpu.wasm_memory, vga_offset, this.vga_memory_size);
+ this.svga_memory = view(Uint8Array, cpu.wasm_memory, vga_offset, this.vga_memory_size);
this.diff_addr_min = this.vga_memory_size;
this.diff_addr_max = 0;
diff --git a/src/virtio.js b/src/virtio.js
index e7bd6709..26be9836 100644
--- a/src/virtio.js
+++ b/src/virtio.js
@@ -1,5 +1,13 @@
"use strict";
+import { LOG_VIRTIO } from "./const.js";
+import { h, zeros, int_log2 } from "./lib.js";
+import { dbg_assert, dbg_log } from "./log.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { PCI } from "./pci.js";
+
// http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html
const VIRTIO_PCI_VENDOR_ID = 0x1AF4;
@@ -32,9 +40,9 @@ const VIRTIO_ISR_DEVICE_CFG = 2;
// Feature bits (bit positions).
-const VIRTIO_F_RING_INDIRECT_DESC = 28;
-const VIRTIO_F_RING_EVENT_IDX = 29;
-const VIRTIO_F_VERSION_1 = 32;
+export const VIRTIO_F_RING_INDIRECT_DESC = 28;
+export const VIRTIO_F_RING_EVENT_IDX = 29;
+export const VIRTIO_F_VERSION_1 = 32;
// Queue struct sizes.
@@ -153,7 +161,7 @@ var VirtIO_Options;
* @param {CPU} cpu
* @param {VirtIO_Options} options
*/
-function VirtIO(cpu, options)
+export function VirtIO(cpu, options)
{
const io = cpu.io;
@@ -224,7 +232,7 @@ function VirtIO(cpu, options)
];
// Prevent sparse arrays by preallocating.
- this.pci_space = this.pci_space.concat(v86util.zeros(256 - this.pci_space.length));
+ this.pci_space = this.pci_space.concat(zeros(256 - this.pci_space.length));
// Remaining PCI space is appended by capabilities further below.
this.pci_id = options.pci_id;
@@ -480,7 +488,7 @@ VirtIO.prototype.create_common_capability = function(options)
dbg_log("Warning: dev<" + this.name +"> " +
"Given queue size was not a power of 2. " +
"Rounding up to next power of 2.", LOG_VIRTIO);
- data = 1 << (v86util.int_log2(data - 1) + 1);
+ data = 1 << (int_log2(data - 1) + 1);
}
if(data > this.queue_selected.size_supported)
{
@@ -727,7 +735,7 @@ VirtIO.prototype.init_capabilities = function(capabilities)
// Round up to next power of 2,
// Minimum 16 bytes for its size to be detectable in general (esp. mmio).
- bar_size = bar_size < 16 ? 16 : 1 << (v86util.int_log2(bar_size - 1) + 1);
+ bar_size = bar_size < 16 ? 16 : 1 << (int_log2(bar_size - 1) + 1);
dbg_assert((cap.port & (bar_size - 1)) === 0,
"VirtIO device<" + this.name + "> capability port should be aligned to pci bar size");
diff --git a/src/virtio_balloon.js b/src/virtio_balloon.js
index 5880b55e..07ff3763 100644
--- a/src/virtio_balloon.js
+++ b/src/virtio_balloon.js
@@ -2,6 +2,15 @@
// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003
+import { LOG_PCI } from "./const.js";
+import { dbg_log } from "./log.js";
+import { VirtIO, VIRTIO_F_VERSION_1 } from "./virtio.js";
+import { marshall } from "../lib/marshall.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
+
const VIRTIO_BALLOON_F_MUST_TELL_HOST = 0;
const VIRTIO_BALLOON_F_STATS_VQ = 1;
const VIRTIO_BALLOON_F_DEFLATE_ON_OOM = 2;
@@ -25,7 +34,7 @@ const STAT_NAMES = [
* @param {CPU} cpu
* @param {BusConnector} bus
*/
-function VirtioBalloon(cpu, bus)
+export function VirtioBalloon(cpu, bus)
{
/** @const @type {BusConnector} */
this.bus = bus;
diff --git a/src/virtio_console.js b/src/virtio_console.js
index 4cae265e..c55c783e 100644
--- a/src/virtio_console.js
+++ b/src/virtio_console.js
@@ -1,7 +1,16 @@
"use strict";
+import { dbg_assert } from "./log.js";
+import { VirtIO, VIRTIO_F_VERSION_1 } from "./virtio.js";
+import { marshall } from "../lib/marshall.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
+
// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003
+
const VIRTIO_CONSOLE_DEVICE_READY = 0;
const VIRTIO_CONSOLE_DEVICE_ADD = 1;
const VIRTIO_CONSOLE_DEVICE_REMOVE = 2;
@@ -20,7 +29,7 @@ const VIRTIO_CONSOLE_F_EMERG_WRITE = 2;
*
* @param {CPU} cpu
*/
-function VirtioConsole(cpu, bus)
+export function VirtioConsole(cpu, bus)
{
/** @const @type {BusConnector} */
this.bus = bus;
diff --git a/src/virtio_net.js b/src/virtio_net.js
index 886aa763..2d0829f7 100644
--- a/src/virtio_net.js
+++ b/src/virtio_net.js
@@ -2,6 +2,14 @@
// https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003
+import { dbg_assert } from "./log.js";
+import { VirtIO, VIRTIO_F_VERSION_1 } from "./virtio.js";
+import { format_mac } from "./ne2k.js";
+import { marshall } from "../lib/marshall.js";
+
+// For Types Only
+import { CPU } from "./cpu.js";
+import { BusConnector } from "./bus.js";
const VIRTIO_NET_F_MAC = 5;
const VIRTIO_NET_F_CTRL_VQ = 17;
@@ -19,7 +27,7 @@ const VIRTIO_NET_CTRL_MAC_ADDR_SET = 1;
* @param {BusConnector} bus
* @param {Boolean} preserve_mac_from_state_image
*/
-function VirtioNet(cpu, bus, preserve_mac_from_state_image)
+export function VirtioNet(cpu, bus, preserve_mac_from_state_image)
{
/** @const @type {BusConnector} */
this.bus = bus;
diff --git a/tests/api/clean-shutdown.js b/tests/api/clean-shutdown.js
index f645d822..a9b080f2 100755
--- a/tests/api/clean-shutdown.js
+++ b/tests/api/clean-shutdown.js
@@ -1,13 +1,15 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
// This test checks that calling emulator.destroy() will remove all event
// listeners, so that the nodejs process cleanly and automatically exits.
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const fs = require("fs");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
diff --git a/tests/api/floppy-insert-eject.js b/tests/api/floppy-insert-eject.js
index f6536e6c..176609be 100755
--- a/tests/api/floppy-insert-eject.js
+++ b/tests/api/floppy-insert-eject.js
@@ -1,11 +1,14 @@
#!/usr/bin/env node
"use strict";
+import {setTimeout as pause} from "timers/promises";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const pause = require("timers/promises").setTimeout;
-const fs = require("fs");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
diff --git a/tests/api/pic.js b/tests/api/pic.js
index a148352f..69131158 100755
--- a/tests/api/pic.js
+++ b/tests/api/pic.js
@@ -1,10 +1,12 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const fs = require("fs");
-const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+import fs from "node:fs";
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
const root_path = __dirname + "/../..";
diff --git a/tests/api/reboot.js b/tests/api/reboot.js
index 03b454d8..2fc33f07 100755
--- a/tests/api/reboot.js
+++ b/tests/api/reboot.js
@@ -1,10 +1,13 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const fs = require("fs");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
@@ -30,7 +33,7 @@ let did_reboot = false;
let serial_text = "";
const timeout = setTimeout(() => {
- console.log(serial_data);
+ console.log(serial_text);
throw new Error("Timeout");
}, 120 * 1000);
diff --git a/tests/api/reset.js b/tests/api/reset.js
index 630d2abc..651c7491 100755
--- a/tests/api/reset.js
+++ b/tests/api/reset.js
@@ -1,12 +1,15 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
// This test checks that reset works
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const fs = require("fs");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
diff --git a/tests/api/serial.js b/tests/api/serial.js
index d9e1e45e..63728201 100755
--- a/tests/api/serial.js
+++ b/tests/api/serial.js
@@ -1,12 +1,15 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+import assert from "node:assert/strict";
+import crypto from "node:crypto";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const assert = require("assert").strict;
-const fs = require("fs");
-const crypto = require("crypto");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
diff --git a/tests/api/state.js b/tests/api/state.js
index 152e2136..a6b992bb 100755
--- a/tests/api/state.js
+++ b/tests/api/state.js
@@ -1,13 +1,15 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-const assert = require("assert").strict;
-var fs = require("fs");
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
const config_async_cdrom = {
bios: { url: __dirname + "/../../bios/seabios.bin" },
diff --git a/tests/api/test.js b/tests/api/test.js
index 1b12dcb4..b354ac5b 100755
--- a/tests/api/test.js
+++ b/tests/api/test.js
@@ -1,10 +1,12 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const fs = require("fs");
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
process.on("unhandledRejection", exn => { throw exn; });
diff --git a/tests/benchmark/arch-bytemark.js b/tests/benchmark/arch-bytemark.js
index a9d13c9b..51d815ad 100755
--- a/tests/benchmark/arch-bytemark.js
+++ b/tests/benchmark/arch-bytemark.js
@@ -1,10 +1,13 @@
#!/usr/bin/env node
"use strict";
+import path from "node:path";
+import url from "node:url";
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
const BENCH_COLLECT_STATS = +process.env.BENCH_COLLECT_STATS;
-const { V86, print_stats } = require(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`);
-const path = require("path");
+const { V86, print_stats } = await import(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`);
const V86_ROOT = path.join(__dirname, "../..");
diff --git a/tests/benchmark/arch-python.js b/tests/benchmark/arch-python.js
index 1d16a104..e587660a 100755
--- a/tests/benchmark/arch-python.js
+++ b/tests/benchmark/arch-python.js
@@ -1,10 +1,13 @@
#!/usr/bin/env node
"use strict";
+import path from "node:path";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const BENCH_COLLECT_STATS = +process.env.BENCH_COLLECT_STATS;
-const { V86, print_stats } = require(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`);
-const path = require("path");
+const { V86, print_stats } = await import(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`);
const V86_ROOT = path.join(__dirname, "../..");
diff --git a/tests/benchmark/linux-boot.js b/tests/benchmark/linux-boot.js
index 81529d76..883f2dc2 100755
--- a/tests/benchmark/linux-boot.js
+++ b/tests/benchmark/linux-boot.js
@@ -1,12 +1,15 @@
#!/usr/bin/env node
"use strict";
-const BENCH_COLLECT_STATS = +process.env.BENCH_COLLECT_STATS;
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
+const BENCH_COLLECT_STATS = +process.env.BENCH_COLLECT_STATS;
+const { V86, print_stats } = await import(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`).V86;
-const V86 = require(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`).V86;
-const print_stats = require("../../build/libv86.js").print_stats;
-const fs = require("fs");
-const path = require("path");
const V86_ROOT = path.join(__dirname, "../..");
const LOG_SERIAL = true;
diff --git a/tests/benchmark/snapshot.js b/tests/benchmark/snapshot.js
index ab19cb4e..db53b814 100755
--- a/tests/benchmark/snapshot.js
+++ b/tests/benchmark/snapshot.js
@@ -1,12 +1,14 @@
#!/usr/bin/env node
"use strict";
+import path from "node:path";
+import url from "node:url";
+
const BENCH_COLLECT_STATS = +process.env.BENCH_COLLECT_STATS;
-const V86 = require(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`).V86;
-const print_stats = require("../../build/libv86.js").print_stats;
-const fs = require("fs");
-const path = require("path");
+let { V86, print_stats } = await import(`../../build/${BENCH_COLLECT_STATS ? "libv86-debug" : "libv86"}.js`);
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const V86_ROOT = path.join(__dirname, "../..");
const LOG_SERIAL = true;
diff --git a/tests/devices/fetch_network.js b/tests/devices/fetch_network.js
index fc001950..b62b1f37 100755
--- a/tests/devices/fetch_network.js
+++ b/tests/devices/fetch_network.js
@@ -1,14 +1,16 @@
#!/usr/bin/env node
"use strict";
+import assert from "assert/strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
const USE_VIRTIO = !!process.env.USE_VIRTIO;
-const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-
-const assert = require("assert").strict;
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
const SHOW_LOGS = false;
function wait(time) {
diff --git a/tests/devices/virtio_9p.js b/tests/devices/virtio_9p.js
index 88bad53b..1dba5edf 100755
--- a/tests/devices/virtio_9p.js
+++ b/tests/devices/virtio_9p.js
@@ -1,14 +1,16 @@
#!/usr/bin/env node
"use strict";
+import url from "node:url";
+import fs from "node:fs";
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-const fs = require("fs");
-const testfsjson = require("./testfs.json");
+const testfsjson = JSON.parse(fs.readFileSync(__dirname + "/testfs.json", "utf-8"));
const SHOW_LOGS = false;
const STOP_ON_FIRST_FAILURE = false;
diff --git a/tests/devices/virtio_balloon.js b/tests/devices/virtio_balloon.js
index f53e6eeb..89474aa0 100755
--- a/tests/devices/virtio_balloon.js
+++ b/tests/devices/virtio_balloon.js
@@ -1,13 +1,15 @@
#!/usr/bin/env node
"use strict";
+import assert from "assert/strict";
+import url from "node:url";
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
-const assert = require("assert").strict;
const SHOW_LOGS = false;
function wait(time) {
diff --git a/tests/devices/virtio_console.js b/tests/devices/virtio_console.js
index 91d20b40..c7efefd4 100755
--- a/tests/devices/virtio_console.js
+++ b/tests/devices/virtio_console.js
@@ -1,13 +1,17 @@
#!/usr/bin/env node
"use strict";
+import assert from "assert/strict";
+import fs from "node:fs";
+import url from "node:url";
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
const SHOW_LOGS = false;
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-const fs = require("fs");
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
+
const emulator = new V86({
bios: { url: __dirname + "/../../bios/seabios.bin" },
diff --git a/tests/devices/wisp_network.js b/tests/devices/wisp_network.js
index f8bad868..dadd5836 100755
--- a/tests/devices/wisp_network.js
+++ b/tests/devices/wisp_network.js
@@ -1,13 +1,16 @@
#!/usr/bin/env -S node --experimental-websocket
"use strict";
+import assert from "assert/strict";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
-const assert = require("assert").strict;
const SHOW_LOGS = false;
const tests =
diff --git a/tests/expect/run.js b/tests/expect/run.js
index 9b96072b..83888911 100755
--- a/tests/expect/run.js
+++ b/tests/expect/run.js
@@ -1,17 +1,23 @@
#!/usr/bin/env node
"use strict";
+import fs from "node:fs";
+import path from "node:path";
+import assert from "node:assert/strict";
+import url from "node:url";
+import wabtfactory from "../../build/libwabt.cjs";
+
+
+import { spawnSync } from "node:child_process";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
-const { spawnSync } = require("child_process");
-
-const libwabt = require("../../build/libwabt.js")();
+const libwabt = wabtfactory();
try {
- var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+ var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
}
catch(e) {
console.error(e);
diff --git a/tests/full/run.js b/tests/full/run.js
index c65986d3..c2e8f319 100755
--- a/tests/full/run.js
+++ b/tests/full/run.js
@@ -1,6 +1,14 @@
#!/usr/bin/env node
"use strict";
+import assert from "node:assert/strict";
+import cluster from "node:cluster";
+import os from "node:os";
+import fs from "node:fs";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
process.on("unhandledRejection", exn => { throw exn; });
var TIMEOUT_EXTRA_FACTOR = +process.env.TIMEOUT_EXTRA_FACTOR || 1;
@@ -14,7 +22,7 @@ const LOG_SCREEN = false;
try
{
- var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+ var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
}
catch(e)
{
@@ -22,10 +30,6 @@ catch(e)
process.exit(1);
}
-const assert = require("assert").strict;
-var cluster = require("cluster");
-var os = require("os");
-var fs = require("fs");
var root_path = __dirname + "/../..";
var SCREEN_WIDTH = 80;
@@ -79,7 +83,7 @@ function send_work_to_worker(worker, message)
}
}
-if(cluster.isMaster)
+if(cluster.isPrimary)
{
var tests = [
{
@@ -918,7 +922,6 @@ if(cluster.isMaster)
var worker = cluster.fork();
worker.on("message", send_work_to_worker.bind(null, worker));
- worker.on("online", send_work_to_worker.bind(null, worker));
worker.on("exit", function(code, signal)
{
@@ -949,6 +952,7 @@ else
process.send("I'm done");
});
});
+ process.send("up");
}
function bytearray_starts_with(arr, search)
diff --git a/tests/jit-paging/run.js b/tests/jit-paging/run.js
index 4bdc903c..fc4396a7 100755
--- a/tests/jit-paging/run.js
+++ b/tests/jit-paging/run.js
@@ -1,12 +1,15 @@
#!/usr/bin/env node
"use strict";
+import fs from "node:fs";
+import url from "node:url";
process.on("unhandledRejection", exn => { throw exn; });
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-var fs = require("fs");
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
+
var test_executable = new Uint8Array(fs.readFileSync(__dirname + "/test-jit"));
diff --git a/tests/kvm-unit-tests/run.js b/tests/kvm-unit-tests/run.mjs
similarity index 83%
rename from tests/kvm-unit-tests/run.js
rename to tests/kvm-unit-tests/run.mjs
index ed683b3a..f8f64d46 100755
--- a/tests/kvm-unit-tests/run.js
+++ b/tests/kvm-unit-tests/run.mjs
@@ -1,12 +1,17 @@
#!/usr/bin/env node
"use strict";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
-var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
-var fs = require("fs");
+var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
function readfile(path)
{
diff --git a/tests/nasm/create_tests.js b/tests/nasm/create_tests.js
index 05d50470..9967955d 100755
--- a/tests/nasm/create_tests.js
+++ b/tests/nasm/create_tests.js
@@ -1,6 +1,20 @@
#!/usr/bin/env node
"use strict";
+import fs from "node:fs";
+import fse from "node:fs/promises";
+import path from "node:path";
+import assert from "node:assert/strict";
+import util from "node:util";
+import url from "node:url";
+import { execFile as execFileAsync } from "node:child_process";
+
+import encodings from "../../gen/x86_table.js";
+import Rand from "./rand.js";
+
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
// number of tests per instruction
const NUMBER_TESTS = 5;
// arithmetic tests
@@ -19,14 +33,7 @@ const OF = 1 << 11;
const BUILD_DIR = __dirname + "/build/";
const LOG_VERBOSE = false;
-const assert = require("assert").strict;
-const fs = require("fs");
-const fse = require("fs/promises");
-const path = require("path");
-const encodings = require("../../gen/x86_table.js");
-const util = require("util");
-const execFile = util.promisify(require("child_process").execFile);
-const Rand = require("./rand.js");
+const execFile = util.promisify(execFileAsync);
const header = fs.readFileSync(path.join(__dirname, "header.inc"));
const footer = fs.readFileSync(path.join(__dirname, "footer.inc"));
diff --git a/tests/nasm/gen_fixtures.js b/tests/nasm/gen_fixtures.js
index 9e5302c8..36922117 100755
--- a/tests/nasm/gen_fixtures.js
+++ b/tests/nasm/gen_fixtures.js
@@ -1,11 +1,14 @@
#!/usr/bin/env node
"use strict";
-const assert = require("assert").strict;
-const fs = require("fs");
-const os = require("os");
-const path = require("path");
-const { spawn, spawnSync } = require("child_process");
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import assert from "node:assert/strict";
+import os from "node:os";
+import { spawn, spawnSync } from "node:child_process";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const DEBUG = process.env.DEBUG || false;
// Maximum number of gdb processes to spawn in parallel
diff --git a/tests/nasm/rand.js b/tests/nasm/rand.js
index eae47778..66076e49 100644
--- a/tests/nasm/rand.js
+++ b/tests/nasm/rand.js
@@ -1,5 +1,4 @@
"use strict";
-const assert = require("assert");
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagøe , 2010
@@ -25,7 +24,7 @@ function Mash() {
}
// From http://baagoe.com/en/RandomMusings/javascript/
-function KISS07() {
+export default function KISS07() {
return (function(args) {
// George Marsaglia, 2007-06-23
//http://groups.google.com/group/comp.lang.fortran/msg/6edb8ad6ec5421a5
@@ -100,5 +99,3 @@ function KISS07() {
};
} (Array.prototype.slice.call(arguments)));
}
-
-module.exports = KISS07;
diff --git a/tests/nasm/run.js b/tests/nasm/run.js
index 04a5ade9..8926a824 100755
--- a/tests/nasm/run.js
+++ b/tests/nasm/run.js
@@ -1,6 +1,15 @@
#!/usr/bin/env node
"use strict";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import assert from "node:assert/strict";
+import os from "node:os";
+import cluster from "node:cluster";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
process.on("unhandledRejection", exn => { throw exn; });
// Mapping between signals and x86 exceptions:
@@ -15,12 +24,6 @@ process.on("unhandledRejection", exn => { throw exn; });
// A #UD might indicate a bug in the test generation
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
-const os = require("os");
-const cluster = require("cluster");
-
const MAX_PARALLEL_TESTS = +process.env.MAX_PARALLEL_TESTS || 99;
const TEST_NAME = new RegExp(process.env.TEST_NAME || "", "i");
const SINGLE_TEST_TIMEOUT = 10000;
@@ -29,6 +32,7 @@ const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
const TEST_DIR = __dirname + "/build/";
const DONE_MSG = "DONE";
const TERMINATE_MSG = "DONE";
+const READY_MSG = "READY";
const BSS = 0x100000;
const STACK_TOP = 0x102000;
@@ -47,7 +51,7 @@ const FPU_STATUS_MASK = 0xFFFF & ~(1 << 9 | 1 << 5 | 1 << 3 | 1 << 1); // bits t
const FP_COMPARISON_SIGNIFICANT_DIGITS = 7;
try {
- var V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
+ var { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
}
catch(e) {
console.error(e);
@@ -202,14 +206,12 @@ if(cluster.isMaster)
let worker = cluster.fork();
worker.on("message", function(message) {
- if(message !== DONE_MSG) {
+ if(message !== DONE_MSG && message !== READY_MSG) {
failed_tests.push(message);
}
send_work_to_worker(this);
});
- worker.on("online", send_work_to_worker.bind(null, worker));
-
worker.on("exit", function(code, signal) {
if(code !== 0 && code !== null) {
console.log("Worker error code:", code);
@@ -548,4 +550,6 @@ else {
run_test(message);
}
});
+
+ process.send(READY_MSG);
}
diff --git a/tests/qemu/run-qemu.js b/tests/qemu/run-qemu.js
index 6e54a45b..ce477bc3 100755
--- a/tests/qemu/run-qemu.js
+++ b/tests/qemu/run-qemu.js
@@ -1,12 +1,15 @@
#!/usr/bin/env node
"use strict";
-const QEMU = "qemu-system-x86_64";
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import assert from "node:assert/strict";
+import { spawn, spawnSync } from "node:child_process";
-const assert = require("assert").strict;
-const fs = require("fs");
-const { spawn, spawnSync } = require("child_process");
-const path = require("path");
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
+const QEMU = "qemu-system-x86_64";
const share_dir_9p = fs.mkdtempSync("/tmp/v86-test-qemu-9p");
diff --git a/tests/qemu/run.js b/tests/qemu/run.js
index 44d540d3..877d4061 100755
--- a/tests/qemu/run.js
+++ b/tests/qemu/run.js
@@ -10,7 +10,7 @@ import path from "path";
import fs from "fs";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
-const { default: { V86 } } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`);
+const { V86 } = await import(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.mjs`);
var test_executable = new Uint8Array(fs.readFileSync(__dirname + "/test-i386"));
diff --git a/tests/rust/verify-wasmgen-dummy-output.js b/tests/rust/verify-wasmgen-dummy-output.js
index e8612e2a..85494334 100755
--- a/tests/rust/verify-wasmgen-dummy-output.js
+++ b/tests/rust/verify-wasmgen-dummy-output.js
@@ -1,11 +1,15 @@
#!/usr/bin/env node
"use strict";
-process.on("unhandledRejection", exn => { throw exn; });
-const assert = require("assert").strict;
-const fs = require("fs");
-const path = require("path");
+import fs from "node:fs";
+import path from "node:path";
+import url from "node:url";
+import assert from "node:assert/strict";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
+process.on("unhandledRejection", exn => { throw exn; });
const DUMMY_MODULE_PATH = path.resolve(__dirname, "../../build/dummy_output.wasm");
const dummy_module = fs.readFileSync(DUMMY_MODULE_PATH);
diff --git a/tools/docker/alpine/build-state.js b/tools/docker/alpine/build-state.js
index fd866b9b..616622dc 100755
--- a/tools/docker/alpine/build-state.js
+++ b/tools/docker/alpine/build-state.js
@@ -1,11 +1,14 @@
#!/usr/bin/env node
"use strict";
+import path from "node:path";
+import fs from "node:fs";
+import url from "node:url";
+
console.log("Don't forget to run `make all` before running this script");
-const path = require("path");
-const fs = require("fs");
-const V86 = require("./../../../build/libv86.js").V86;
+const { V86 } = await import("./../../../build/libv86.js");
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const V86_ROOT = path.join(__dirname, "../../..");
const OUTPUT_FILE = path.join(V86_ROOT, "images/alpine-state.bin");