mirror of
https://github.com/copy/v86.git
synced 2025-12-31 04:23:15 +00:00
Switch to es6 modules.
This commit is contained in:
parent
30be975d6a
commit
a9219613af
97 changed files with 1206 additions and 749 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
32
Makefile
32
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:
|
||||
|
|
|
|||
56
debug.html
56
debug.html
|
|
@ -4,58 +4,12 @@
|
|||
<title>v86 (debug)</title>
|
||||
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
|
||||
<script src="src/const.js"></script>
|
||||
<script src="src/config.js"></script>
|
||||
<script src="src/log.js"></script>
|
||||
<script src="src/lib.js"></script>
|
||||
<script src="src/buffer.js"></script>
|
||||
<script src="src/cpu.js"></script>
|
||||
<script src="src/debug.js"></script>
|
||||
<script src="src/io.js"></script>
|
||||
<script src="src/main.js"></script>
|
||||
<script src="src/ide.js"></script>
|
||||
<script src="src/pci.js"></script>
|
||||
<script src="src/floppy.js"></script>
|
||||
<script src="src/memory.js"></script>
|
||||
<script src="src/dma.js"></script>
|
||||
<script src="src/pit.js"></script>
|
||||
<script src="src/vga.js"></script>
|
||||
<script src="src/ps2.js"></script>
|
||||
<script src="src/rtc.js"></script>
|
||||
<script src="src/uart.js"></script>
|
||||
<script src="src/acpi.js"></script>
|
||||
<script src="src/apic.js"></script>
|
||||
<script src="src/ioapic.js"></script>
|
||||
<script src="src/sb16.js"></script>
|
||||
<script src="src/ne2k.js"></script>
|
||||
<script src="src/state.js"></script>
|
||||
<script src="src/virtio.js"></script>
|
||||
<script src="src/virtio_balloon.js"></script>
|
||||
<script src="src/virtio_console.js"></script>
|
||||
<script src="src/virtio_net.js"></script>
|
||||
<script src="src/bus.js"></script>
|
||||
<script src="src/elf.js"></script>
|
||||
<script src="src/kernel.js"></script>
|
||||
<script src="src/browser/main.js"></script>
|
||||
<script src="src/browser/screen.js"></script>
|
||||
<script src="src/browser/keyboard.js"></script>
|
||||
<script src="src/browser/mouse.js"></script>
|
||||
<script src="src/browser/speaker.js"></script>
|
||||
<script src="src/browser/serial.js"></script>
|
||||
<script src="src/browser/network.js"></script>
|
||||
<script src="src/browser/fake_network.js"></script>
|
||||
<script src="src/browser/fetch_network.js"></script>
|
||||
<script src="src/browser/wisp_network.js"></script>
|
||||
<script src="src/browser/starter.js"></script>
|
||||
<script src="src/browser/worker_bus.js"></script>
|
||||
<script src="src/browser/print_stats.js"></script>
|
||||
<script src="src/browser/filestorage.js"></script>
|
||||
<script src="lib/jor1k.js"></script>
|
||||
<script src="lib/9p.js"></script>
|
||||
<script src="lib/filesystem.js"></script>
|
||||
<script src="lib/marshall.js"></script>
|
||||
<script>
|
||||
var DEBUG = true;
|
||||
</script>
|
||||
<script src="build/capstone-x86.min.js"></script>
|
||||
<script src="build/libwabt.js"></script>
|
||||
<script src="build/libwabt.cjs"></script>
|
||||
<script type="module" src="./src/browser/main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="v86.css">
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
importScripts("../build/libv86.js");
|
||||
|
||||
/* global V86 */
|
||||
|
||||
var emulator = new V86({
|
||||
wasm_path: "../build/v86.wasm",
|
||||
memory_size: 32 * 1024 * 1024,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
27
gen/util.js
27
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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
47
lib/9p.js
47
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,
|
||||
|
|
|
|||
|
|
@ -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.<!Inode>} */
|
||||
this.inodes = [];
|
||||
this.events = [];
|
||||
|
|
|
|||
13
lib/jor1k.js
13
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);
|
||||
}
|
||||
});
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
12
src/acpi.js
12
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;
|
||||
|
|
|
|||
18
src/apic.js
18
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
import { dbg_assert } from "../log.js";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function DummyScreenAdapter()
|
||||
export function DummyScreenAdapter()
|
||||
{
|
||||
var
|
||||
graphic_image_data,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
27
src/cjs.js
Normal file
27
src/cjs.js
Normal file
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
48
src/const.js
48
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<Array<string|number>>}
|
||||
*/
|
||||
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;
|
||||
|
|
|
|||
167
src/cpu.js
167
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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
17
src/debug.js
17
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
11
src/ide.js
11
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);
|
||||
|
|
|
|||
17
src/io.js
17
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
140
src/lib.js
140
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,18 +143,27 @@ 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)
|
||||
{
|
||||
/**
|
||||
|
|
@ -178,15 +171,13 @@ else
|
|||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
v86util.int_log2 = function(x)
|
||||
int_log2 = function(x)
|
||||
{
|
||||
dbg_assert(x > 0);
|
||||
|
||||
return 31 - Math.clz32(x);
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
} 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));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
24
src/log.js
24
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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
13
src/ne2k.js
13
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;
|
||||
|
|
|
|||
12
src/pci.js
12
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);
|
||||
|
|
|
|||
13
src/pit.js
13
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;
|
||||
|
|
|
|||
11
src/ps2.js
11
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;
|
||||
|
|
|
|||
95
src/rtc.js
95
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} */
|
||||
|
|
|
|||
22
src/sb16.js
22
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
10
src/uart.js
10
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;
|
||||
|
|
|
|||
17
src/vga.js
17
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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
||||
|
|
|
|||
|
|
@ -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 + "/../..";
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -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; });
|
||||
|
||||
|
|
|
|||
|
|
@ -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, "../..");
|
||||
|
||||
|
|
|
|||
|
|
@ -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, "../..");
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
"use strict";
|
||||
const assert = require("assert");
|
||||
|
||||
// From http://baagoe.com/en/RandomMusings/javascript/
|
||||
// Johannes Baagøe <baagoe@baagoe.com>, 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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue