From caaba6b1fad44f9abbe22880ac877bf4386d2468 Mon Sep 17 00:00:00 2001 From: Taras Vozniuk Date: Wed, 2 Feb 2022 22:07:56 +0800 Subject: [PATCH 01/11] package.json and .npmrc for github package registry --- .npmrc | 1 + package.json | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .npmrc create mode 100644 package.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..48fce939e3 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@glasssh:registry=https://npm.pkg.github.com \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000000..ed49fc8bd1 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "@glasssh/v86", + "version": "0.1.0", + "description": "x86 virtualization in your browser, recompiling x86 to wasm on the fly", + "main": "build/libv86.js", + "directories": { + "doc": "docs", + "example": "examples", + "lib": "lib", + "test": "tests" + }, + "scripts": { + "build": "npm run build:all_debug & npm run build:all", + "build:all_debug": "make all-debug", + "build:all": "make all", + "build:release": "make build/libv86.js build/v86.wasm build/v86-fallback.wasm", + "test:prepare": "wget -nv -P images/ https://k.copy.sh/{linux.iso,linux3.iso,linux4.iso,buildroot-bzimage.bin,TinyCore-11.0.iso,oberon.img,msdos.img,openbsd-floppy.img,kolibri.img,windows101.img,os8.img,freedos722.img,mobius-fd-release5.img}", + "test": "make kvm-unit-test nasmtests nasmtests-force-jit expect-tests jitpagingtests qemutests qemutests-release rust-test tests" + }, + "dependencies": { + }, + "devDependencies": { + }, + "files": [ + "build/libv86.js", + "build/v86.wasm", + "build/v86-fallback.wasm" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/glasssh/v86.git" + }, + "keywords": [ + "x86", + "virtualization", + "emulator" + ], + "author": "Fabian Hemmer", + "license": "BSD-2-Clause", + "bugs": { + "url": "https://github.com/glasssh/v86/issues" + }, + "homepage": "https://github.com/glasssh/v86#readme" +} From 2b95862f13c6c1f1295b028a923f132b8dfa1c8c Mon Sep 17 00:00:00 2001 From: Taras Vozniuk Date: Sat, 5 Feb 2022 22:17:14 +0800 Subject: [PATCH 02/11] base typescript definitions --- types/index.d.ts | 560 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 560 insertions(+) create mode 100644 types/index.d.ts diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000000..da0ac2dacf --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,560 @@ +/** set when v86 is built with debug mode enabled */ +declare const DEBUG: boolean; + +declare type V86Image = + | { url: string } + | { buffer: ArrayBuffer } + | { url: string, async: false, size?: number } + | { url: string, async: true, size: number } + +/** + * A 9p filesystem is supported by the emulator, using a virtio transport. Using it, files can be exchanged with the guest OS + * If `basefs` and `baseurl` are omitted, an empty 9p filesystem is created. + */ +declare interface Filesystem9pOptions { + /** + * json file created using [fs2json](https://github.com/copy/v86/blob/master/tools/fs2json.py). + */ + baseurl?: string, + + /** + * The base url is the prefix of a url from which the files are available. + * For instance, if the 9p filesystem has a file `/bin/sh`, that file must be accessible from http://localhost/9p/base/bin/sh + */ + basefs?: string +} + +declare enum LogLevel { + LOG_ALL = -1, + LOG_NONE = 0, + LOG_OTHER = 0x000001, + LOG_CPU = 0x000002, + LOG_FPU = 0x000004, + LOG_MEM = 0x000008, + LOG_DMA = 0x000010, + LOG_IO = 0x000020, + LOG_PS2 = 0x000040, + LOG_PIC = 0x000080, + LOG_VGA = 0x000100, + LOG_PIT = 0x000200, + LOG_MOUSE = 0x000400, + LOG_PCI = 0x000800, + LOG_BIOS = 0x001000, + LOG_FLOPPY = 0x002000, + LOG_SERIAL = 0x004000, + LOG_DISK = 0x008000, + LOG_RTC = 0x010000, + LOG_HPET = 0x020000, + LOG_ACPI = 0x040000, + LOG_APIC = 0x080000, + LOG_NET = 0x100000, + LOG_VIRTIO = 0x200000, + LOG_9P = 0x400000, + LOG_SB16 = 0x800000 +} + +declare enum BootOrder { + CD_FLOPPY_HARDDISK = 0x213, + CD_HARDDISK_FLOPPY = 0x123, + FLOPPY_CD_HARDDISK = 0x231, + FLOPPY_HARDDISK_CD = 0x321, + HARDDISK_CD_FLOPPY = 0x132 +} + +declare class BusConnector { + constructor() + + /** + * @param {string} name + * @param {function(?)} fn + * @param {Object} this_value + */ + register(name: string, fn: Function, this_value: Object); + + /** + * Unregister one message with the given name and callback + * + * @param {string} name + * @param {function()} fn + */ + unregister(name: string, fn: Function) + + /** + * Send ("emit") a message + * + * @param {string} name + * @param {*=} value + * @param {*=} unused_transfer + */ + send(name: string, value: any, unused_transfer?: any) + + /** + * Send a message, guaranteeing that it is received asynchronously + * + * @param {string} name + * @param {Object=} value + */ + send_async(name: string, value: any) +} + +/** + * Custom emulated ethernet card adapter (pass in V86StarterOptions) + * @see https://github.com/copy/v86/blob/master/src/browser/network.js + */ +declare class NetworkAdapter { + constructor(bus: BusConnector) + + handle_message(event: any & { data: string | ArrayBufferLike | Blob | ArrayBufferView }): void + handle_close(event: any): void + handle_open(event: any): void + handle_error(event: any): void + destroy(event: any): void + connect(): void + send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void + change_proxy(url: string): void +} + +declare type V86AutomaticStep = + | { + /** wait for x seconds */ + sleep: number + } + | { + /** wait until vga_text is present on the screen */ + vga_text: string + } + | { + /** text or scancodes to send */ + keyboard_send: number[] | string + } + | { + /** callback to execute */ + call: () => void + } + +/** + * emulator instance constructor options. + */ +declare interface V86StarterOptions { + /** + * Path to v86 wasm artifact + * @default "build/v86.wasm" or "build/v86-debug.wasm" when debug mode enabled + */ + wasm_path?: string + + /** + * The memory size in bytes, should be a power of 2. + * @example 16 * 1024 * 1024 + * @default 64 * 1024 * 1024 + */ + memory_size?: number + + /** + * VGA memory size in bytes. + * @example 8 * 1024 * 1024 + * @default 8 * 1024 * 1024 + */ + vga_memory_size?: number + + /** + * If emulation should be started when emulator is ready. + * @default false + */ + autostart?: boolean + + /** + * If keyboard should be disabled. + * @default false + */ + disable_keyboard?: boolean + + /** + * If mouse should be disabled. + * @default false + */ + disable_mouse?: boolean + + /** + * If speaker should be disabled. + * @default false + */ + disable_speaker?: boolean + + /** + * The url of a server running websockproxy. See [networking.md](networking.md). Setting this will enable an emulated network card. + * @default undefined + */ + network_relay_url?: string + + /** + * Either a url pointing to a bios or an ArrayBuffer, see below. + * @default undefined + */ + bios?: V86Image + + /** + * VGA bios, see below. + * @default undefined + */ + vga_bios?: V86Image + + /** + * First hard disk, see below. + * @default undefined + */ + hda?: V86Image + + /** + * First floppy disk, see below. + * @default undefined + */ + fda?: V86Image + + /** + * cdrom + * @default undefined + */ + cdrom?: V86Image + + /** + * A Linux kernel image to boot (only bzimage format) + * @default undefined + */ + bzimage?: V86Image + + /** + * A Linux ramdisk image + * @default undefined + */ + initrd?: V86Image + + /** + * Automatically fetch bzimage and initrd from the specified `filesystem`. + */ + bzimage_initrd_from_filesystem?: boolean + + /** + * An initial state to load + * @default undefined + */ + initial_state?: V86Image + + /** + * A 9p filesystem + * @default undefined + */ + filesystem?: Filesystem9pOptions + + /** + * A textarea that will receive and send data to the emulated serial terminal. + * Alternatively the serial terminal can also be accessed programatically, see [serial.html](../examples/serial.html). + * @default undefined + */ + serial_container?: HTMLTextAreaElement + + /** + * Xtermjs serial terminal container. When set, serial_container option is ignored. + * @default undefined + */ + serial_container_xtermjs?: HTMLElement + + /** + * An HTMLElement. This should have a certain structure, see [basic.html](../examples/basic.html). + * @default undefined + */ + screen_container?: HTMLElement | null + + /** + * ACPI + * @default false + */ + acpi?: boolean + + /** + * log level + * @default LogLevel.LOG_NONE + */ + log_level?: LogLevel + + /** + * boot order + * @default BootOrder.CD_FLOPPY_HARDDISK + */ + boot_order?: BootOrder + + /** + * fast boot + * @default false + */ + fastboot?: boolean + + /** + * enables UART1 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart1?: boolean + + /** + * enables UART2 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart2?: boolean + + /** + * enables UART3 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart3?: boolean + + /** + * boot cmdline + */ + cmdline?: string + + /** + * Ne2k: should MAC be preserved from the state image + * @default undefined + */ + preserve_mac_from_state_image?: boolean + + /** + * custom network adapter + * @default undefined + */ + network_adapter?: NetworkAdapter + + /** + * enables screen dummy + * @default undefined + */ + screen_dummy?: boolean +} + +declare class V86Starter { + constructor(options?: V86StarterOptions) + + /** + * Start emulation. Do nothing if emulator is running already. Can be asynchronous. + */ + run(): void + + /** + * Stop emulation. Do nothing if emulator is not running. Can be asynchronous. + */ + stop(): void + destroy(): void + + /** + * Restart (force a reboot). + */ + restart(): void + + /** + * Add an event listener (the emulator is an event emitter). A list of events + * can be found at [events.md](events.md). + * + * The callback function gets a single argument which depends on the event. + * + * @param event Name of the event. + * @param listener The callback function. + */ + add_listener(event: string, listener: Function): void + + /** + * Remove an event listener. + * + * @param event + * @param listener + */ + remove_listener(event: string, listener: Function): void + + /** + * Restore the emulator state from the given state, which must be an + * ArrayBuffer returned by + * [`save_state`](#save_statefunctionobject-arraybuffer-callback). + * + * Note that the state can only be restored correctly if this constructor has + * been created with the same options as the original instance (e.g., same disk + * images, memory size, etc.). + * + * Different versions of the emulator might use a different format for the + * state buffer. + * + * @param state + */ + restore_state(state: ArrayBuffer): void + + /** + * Asynchronously save the current state of the emulator. The first argument to + * the callback is an Error object if something went wrong and is null + * otherwise. + * + * @param callback + */ + save_state(callback: (error: Object | null, state: ArrayBuffer) => void): void + + /** + * Return an object with several statistics. Return value looks similar to + * (but can be subject to change in future versions or different + * configurations, so use defensively): + * + * ```javascript + * { + * "cpu": { + * "instruction_counter": 2821610069 + * }, + * "hda": { + * "sectors_read": 95240, + * "sectors_written": 952, + * "bytes_read": 48762880, + * "bytes_written": 487424, + * "loading": false + * }, + * "cdrom": { + * "sectors_read": 0, + * "sectors_written": 0, + * "bytes_read": 0, + * "bytes_written": 0, + * "loading": false + * }, + * "mouse": { + * "enabled": true + * }, + * "vga": { + * "is_graphical": true, + * "res_x": 800, + * "res_y": 600, + * "bpp": 32 + * } + * } + * ``` + * + * @deprecated + */ + get_statistics(): Object + get_instruction_counter(): number + is_running(): boolean + + /** + * Send a sequence of scan codes to the emulated PS2 controller. A list of + * codes can be found at http://stanislavs.org/helppc/make_codes.html. + * Do nothing if there is no keyboard controller. + * + * @param codes + */ + keyboard_send_scancodes(codes: number[]): void + + /** + * Send translated keys + */ + keyboard_send_keys(codes: any[]): void + + /** + * Send text + */ + keyboard_send_text(string: string): void + + + /** + * Download a screenshot. + */ + screen_make_screenshot(): void + + /** + * Set the scaling level of the emulated screen. + * + * @param {number} sx + * @param {number} sy + * + * @ignore + * @export + */ + screen_set_scale(sx: number, sy: number): void + + /** + * Go fullscreen. + */ + screen_go_fullscreen(): void + + /** + * Lock the mouse cursor: It becomes invisble and is not moved out of the browser window. + */ + lock_mouse(): void + + /** + * Enable or disable sending mouse events to the emulated PS2 controller. + */ + mouse_set_status(enabled: boolean): void + + /** + * Enable or disable sending keyboard events to the emulated PS2 controller. + */ + keyboard_set_status(enabled: boolean): void + + /** + * Send a string to the first emulated serial terminal. + * + * @param data + */ + serial0_send(data: string): void + + /** + * Send bytes to a serial port (to be received by the emulated PC). + * + * @param serial the index of the serial port + * @param data + */ + serial_send_bytes(serial: number, data: Uint8Array) + + /** + * Mount another filesystem to the current filesystem. + * @param path Path for the mount point + * @param baseurl + * @param basefs As a JSON string + * @param callback + * @export + */ + mount_fs(path: string, baseurl?: string, basefs?: string, callback?: (error: Object | null) => void): void + + /** + * Write to a file in the 9p filesystem. Nothing happens if no filesystem has + * been initialized. First argument to the callback is an error object if + * something went wrong and null otherwise. + * + * @param file + * @param data + * @param callback + */ + create_file(file: string, data: Uint8Array, callback?: (error: Object | null) => void): void + + /** + * Runs a set of automatic steps + * @param steps + */ + automatically(steps: V86AutomaticStep[]): void + + /** + * Reads data from memory at specified offset. + * + * @param offset + * @param length + */ + read_memory(offset: number, length: number): Array | Uint8Array + + /** + * Writes data to memory at specified offset. + * + * @param {Array.|Uint8Array} blob + * @param {number} offset + */ + write_memory(blob: Array | Uint8Array, offset: number): void +} \ No newline at end of file From d7dafb61f2332be3b1ecfc72352f5557340faf5f Mon Sep 17 00:00:00 2001 From: Taras Vozniuk Date: Thu, 10 Feb 2022 20:50:20 +0800 Subject: [PATCH 03/11] expose bus --- types/index.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/types/index.d.ts b/types/index.d.ts index da0ac2dacf..f4385cdc17 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -342,6 +342,11 @@ declare interface V86StarterOptions { declare class V86Starter { constructor(options?: V86StarterOptions) + /** + * bus, use it when you must (there are a few wrappers on top of it in V86Starter that you might find helpful instead) + */ + bus: BusConnector + /** * Start emulation. Do nothing if emulator is running already. Can be asynchronous. */ From d65220d804f301772ab98d434dd59eb53b95ad4d Mon Sep 17 00:00:00 2001 From: ambientlight Date: Thu, 5 May 2022 00:53:26 +0800 Subject: [PATCH 04/11] include types in package.json --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ed49fc8bd1..490720f772 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,10 @@ "files": [ "build/libv86.js", "build/v86.wasm", - "build/v86-fallback.wasm" + "build/v86-fallback.wasm", + "types/index.d.ts" ], + "types": "types/index.d.ts", "repository": { "type": "git", "url": "git+https://github.com/glasssh/v86.git" From a49e2b5518a3b27b87aaf0ff7df691275bed004b Mon Sep 17 00:00:00 2001 From: ambientlight Date: Thu, 5 May 2022 01:01:08 +0800 Subject: [PATCH 05/11] add bios and debug bundled to files --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 490720f772..506a072872 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,11 @@ "devDependencies": { }, "files": [ + "bios/*.bin", "build/libv86.js", + "build/libv86-debug.js", "build/v86.wasm", + "build/v86-debug.wasm", "build/v86-fallback.wasm", "types/index.d.ts" ], From 7176ad23e9f0deef2ac17a298caf016fd701c263 Mon Sep 17 00:00:00 2001 From: ambientlight Date: Thu, 5 May 2022 01:21:22 +0800 Subject: [PATCH 06/11] remove github registry .npmrc, change links to @copy --- .npmrc | 1 - package.json | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 .npmrc diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 48fce939e3..0000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -@glasssh:registry=https://npm.pkg.github.com \ No newline at end of file diff --git a/package.json b/package.json index 506a072872..da2415b4a5 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@glasssh/v86", + "name": "@copy/v86", "version": "0.1.0", "description": "x86 virtualization in your browser, recompiling x86 to wasm on the fly", "main": "build/libv86.js", @@ -33,7 +33,7 @@ "types": "types/index.d.ts", "repository": { "type": "git", - "url": "git+https://github.com/glasssh/v86.git" + "url": "git+https://github.com/copy/v86.git" }, "keywords": [ "x86", @@ -43,7 +43,7 @@ "author": "Fabian Hemmer", "license": "BSD-2-Clause", "bugs": { - "url": "https://github.com/glasssh/v86/issues" + "url": "https://github.com/copy/v86/issues" }, - "homepage": "https://github.com/glasssh/v86#readme" + "homepage": "https://github.com/copy/v86#readme" } From af37e1d34bb1a0d77a3c2f13a97415e01a5406e2 Mon Sep 17 00:00:00 2001 From: ambientlight Date: Sat, 14 May 2022 13:49:38 +0800 Subject: [PATCH 07/11] check for commonjs first in exports statements, commonjs exports for v86,V86Starter,CPU,MemoryFileStorage,ServerFileStorageWrapper --- Makefile | 4 ++-- src/browser/filestorage.js | 12 ++++++------ src/browser/starter.js | 16 ++++++---------- src/cpu.js | 8 ++++---- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 983881fb95..e77fb2ca1a 100644 --- a/Makefile +++ b/Makefile @@ -133,7 +133,7 @@ build/libv86.js: $(CLOSURE) src/*.js lib/*.js src/browser/*.js --define=DEBUG=false\ $(CLOSURE_FLAGS)\ --compilation_level SIMPLE\ - --output_wrapper ';(function(){%output%}).call(this);'\ + --output_wrapper 'var v86=(function(){%output% return {v86,V86Starter,CPU,MemoryFileStorage,ServerFileStorageWrapper};}).call(this);if(typeof module !== "undefined" && typeof module.exports !== "undefined"){module.exports = v86;}'\ --js $(CORE_FILES)\ --js $(BROWSER_FILES)\ --js $(LIB_FILES) @@ -147,7 +147,7 @@ build/libv86-debug.js: $(CLOSURE) src/*.js lib/*.js src/browser/*.js $(CLOSURE_FLAGS)\ $(CLOSURE_READABLE)\ --compilation_level SIMPLE\ - --output_wrapper ';(function(){%output%}).call(this);'\ + --output_wrapper 'var v86=(function(){%output% return {v86,V86Starter,CPU,MemoryFileStorage,ServerFileStorageWrapper};}).call(this);if(typeof module !== "undefined" && typeof module.exports !== "undefined"){module.exports = v86;}'\ --js $(CORE_FILES)\ --js $(BROWSER_FILES)\ --js $(LIB_FILES) diff --git a/src/browser/filestorage.js b/src/browser/filestorage.js index 4d9297fe5b..ef2d5c4b4c 100644 --- a/src/browser/filestorage.js +++ b/src/browser/filestorage.js @@ -142,16 +142,16 @@ ServerFileStorageWrapper.prototype.uncache = function(sha256sum) }; // Closure Compiler's way of exporting -if(typeof window !== "undefined") -{ - window["MemoryFileStorage"] = MemoryFileStorage; - window["ServerFileStorageWrapper"] = ServerFileStorageWrapper; -} -else if(typeof module !== "undefined" && typeof module.exports !== "undefined") +if(typeof module !== "undefined" && typeof module.exports !== "undefined") { module.exports["MemoryFileStorage"] = MemoryFileStorage; module.exports["ServerFileStorageWrapper"] = ServerFileStorageWrapper; } +else if(typeof window !== "undefined") +{ + window["MemoryFileStorage"] = MemoryFileStorage; + window["ServerFileStorageWrapper"] = ServerFileStorageWrapper; +} else if(typeof importScripts === "function") { // web worker diff --git a/src/browser/starter.js b/src/browser/starter.js index 3977656264..cac0ef96a0 100644 --- a/src/browser/starter.js +++ b/src/browser/starter.js @@ -1349,19 +1349,15 @@ function FileNotFoundError(message) FileNotFoundError.prototype = Error.prototype; // Closure Compiler's way of exporting -if(typeof window !== "undefined") -{ - window["V86Starter"] = V86Starter; - window["V86"] = V86Starter; -} -else if(typeof module !== "undefined" && typeof module.exports !== "undefined") +if(typeof module !== "undefined" && typeof module.exports !== "undefined") { module.exports["V86Starter"] = V86Starter; module.exports["V86"] = V86Starter; -} -else if(typeof importScripts === "function") -{ +} else if(typeof window !== "undefined"){ + window["V86Starter"] = V86Starter; + window["V86"] = V86Starter; +} else if(typeof importScripts === "function") { // web worker self["V86Starter"] = V86Starter; self["V86"] = V86Starter; -} +} \ No newline at end of file diff --git a/src/cpu.js b/src/cpu.js index 9cb5c6d4d5..aa48e2c68e 100644 --- a/src/cpu.js +++ b/src/cpu.js @@ -1508,13 +1508,13 @@ CPU.prototype.device_lower_irq = function(i) }; // Closure Compiler's way of exporting -if(typeof window !== "undefined") +if(typeof module !== "undefined" && typeof module.exports !== "undefined") { - window["CPU"] = CPU; + module.exports["CPU"] = CPU; } -else if(typeof module !== "undefined" && typeof module.exports !== "undefined") +else if(typeof window !== "undefined") { - module.exports["CPU"] = CPU; + window["CPU"] = CPU; } else if(typeof importScripts === "function") { From 2e7686cd20c3d057c066c43a094906d494896a1e Mon Sep 17 00:00:00 2001 From: ambientlight Date: Sat, 14 May 2022 18:40:31 +0800 Subject: [PATCH 08/11] v86 module in typings --- types/index.d.ts | 1111 +++++++++++++++++++++++----------------------- 1 file changed, 557 insertions(+), 554 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index f4385cdc17..d086cbd198 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,565 +1,568 @@ -/** set when v86 is built with debug mode enabled */ -declare const DEBUG: boolean; - -declare type V86Image = - | { url: string } - | { buffer: ArrayBuffer } - | { url: string, async: false, size?: number } - | { url: string, async: true, size: number } - -/** - * A 9p filesystem is supported by the emulator, using a virtio transport. Using it, files can be exchanged with the guest OS - * If `basefs` and `baseurl` are omitted, an empty 9p filesystem is created. - */ -declare interface Filesystem9pOptions { - /** - * json file created using [fs2json](https://github.com/copy/v86/blob/master/tools/fs2json.py). - */ - baseurl?: string, - - /** - * The base url is the prefix of a url from which the files are available. - * For instance, if the 9p filesystem has a file `/bin/sh`, that file must be accessible from http://localhost/9p/base/bin/sh - */ - basefs?: string -} - -declare enum LogLevel { - LOG_ALL = -1, - LOG_NONE = 0, - LOG_OTHER = 0x000001, - LOG_CPU = 0x000002, - LOG_FPU = 0x000004, - LOG_MEM = 0x000008, - LOG_DMA = 0x000010, - LOG_IO = 0x000020, - LOG_PS2 = 0x000040, - LOG_PIC = 0x000080, - LOG_VGA = 0x000100, - LOG_PIT = 0x000200, - LOG_MOUSE = 0x000400, - LOG_PCI = 0x000800, - LOG_BIOS = 0x001000, - LOG_FLOPPY = 0x002000, - LOG_SERIAL = 0x004000, - LOG_DISK = 0x008000, - LOG_RTC = 0x010000, - LOG_HPET = 0x020000, - LOG_ACPI = 0x040000, - LOG_APIC = 0x080000, - LOG_NET = 0x100000, - LOG_VIRTIO = 0x200000, - LOG_9P = 0x400000, - LOG_SB16 = 0x800000 -} - -declare enum BootOrder { - CD_FLOPPY_HARDDISK = 0x213, - CD_HARDDISK_FLOPPY = 0x123, - FLOPPY_CD_HARDDISK = 0x231, - FLOPPY_HARDDISK_CD = 0x321, - HARDDISK_CD_FLOPPY = 0x132 -} - -declare class BusConnector { - constructor() - - /** - * @param {string} name - * @param {function(?)} fn - * @param {Object} this_value - */ - register(name: string, fn: Function, this_value: Object); - - /** - * Unregister one message with the given name and callback - * - * @param {string} name - * @param {function()} fn - */ - unregister(name: string, fn: Function) - - /** - * Send ("emit") a message - * - * @param {string} name - * @param {*=} value - * @param {*=} unused_transfer - */ - send(name: string, value: any, unused_transfer?: any) - - /** - * Send a message, guaranteeing that it is received asynchronously - * - * @param {string} name - * @param {Object=} value - */ - send_async(name: string, value: any) -} - -/** - * Custom emulated ethernet card adapter (pass in V86StarterOptions) - * @see https://github.com/copy/v86/blob/master/src/browser/network.js - */ -declare class NetworkAdapter { - constructor(bus: BusConnector) - - handle_message(event: any & { data: string | ArrayBufferLike | Blob | ArrayBufferView }): void - handle_close(event: any): void - handle_open(event: any): void - handle_error(event: any): void - destroy(event: any): void - connect(): void - send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void - change_proxy(url: string): void -} - -declare type V86AutomaticStep = - | { - /** wait for x seconds */ - sleep: number - } - | { - /** wait until vga_text is present on the screen */ - vga_text: string - } - | { - /** text or scancodes to send */ - keyboard_send: number[] | string - } - | { - /** callback to execute */ - call: () => void +declare module v86 { + + /** set when v86 is built with debug mode enabled */ + declare const DEBUG: boolean; + + declare type V86Image = + | { url: string } + | { buffer: ArrayBuffer } + | { url: string, async: false, size?: number } + | { url: string, async: true, size: number } + + /** + * A 9p filesystem is supported by the emulator, using a virtio transport. Using it, files can be exchanged with the guest OS + * If `basefs` and `baseurl` are omitted, an empty 9p filesystem is created. + */ + declare interface Filesystem9pOptions { + /** + * json file created using [fs2json](https://github.com/copy/v86/blob/master/tools/fs2json.py). + */ + baseurl?: string, + + /** + * The base url is the prefix of a url from which the files are available. + * For instance, if the 9p filesystem has a file `/bin/sh`, that file must be accessible from http://localhost/9p/base/bin/sh + */ + basefs?: string } -/** - * emulator instance constructor options. - */ -declare interface V86StarterOptions { - /** - * Path to v86 wasm artifact - * @default "build/v86.wasm" or "build/v86-debug.wasm" when debug mode enabled - */ - wasm_path?: string - - /** - * The memory size in bytes, should be a power of 2. - * @example 16 * 1024 * 1024 - * @default 64 * 1024 * 1024 - */ - memory_size?: number - - /** - * VGA memory size in bytes. - * @example 8 * 1024 * 1024 - * @default 8 * 1024 * 1024 - */ - vga_memory_size?: number - - /** - * If emulation should be started when emulator is ready. - * @default false - */ - autostart?: boolean - - /** - * If keyboard should be disabled. - * @default false - */ - disable_keyboard?: boolean - - /** - * If mouse should be disabled. - * @default false - */ - disable_mouse?: boolean - - /** - * If speaker should be disabled. - * @default false - */ - disable_speaker?: boolean - - /** - * The url of a server running websockproxy. See [networking.md](networking.md). Setting this will enable an emulated network card. - * @default undefined - */ - network_relay_url?: string - - /** - * Either a url pointing to a bios or an ArrayBuffer, see below. - * @default undefined - */ - bios?: V86Image - - /** - * VGA bios, see below. - * @default undefined - */ - vga_bios?: V86Image - - /** - * First hard disk, see below. - * @default undefined - */ - hda?: V86Image - - /** - * First floppy disk, see below. - * @default undefined - */ - fda?: V86Image - - /** - * cdrom - * @default undefined - */ - cdrom?: V86Image - - /** - * A Linux kernel image to boot (only bzimage format) - * @default undefined - */ - bzimage?: V86Image - - /** - * A Linux ramdisk image - * @default undefined - */ - initrd?: V86Image - - /** - * Automatically fetch bzimage and initrd from the specified `filesystem`. - */ - bzimage_initrd_from_filesystem?: boolean - - /** - * An initial state to load - * @default undefined - */ - initial_state?: V86Image - - /** - * A 9p filesystem - * @default undefined - */ - filesystem?: Filesystem9pOptions - - /** - * A textarea that will receive and send data to the emulated serial terminal. - * Alternatively the serial terminal can also be accessed programatically, see [serial.html](../examples/serial.html). - * @default undefined - */ - serial_container?: HTMLTextAreaElement - - /** - * Xtermjs serial terminal container. When set, serial_container option is ignored. - * @default undefined - */ - serial_container_xtermjs?: HTMLElement - - /** - * An HTMLElement. This should have a certain structure, see [basic.html](../examples/basic.html). - * @default undefined - */ - screen_container?: HTMLElement | null - - /** - * ACPI - * @default false - */ - acpi?: boolean - - /** - * log level - * @default LogLevel.LOG_NONE - */ - log_level?: LogLevel - - /** - * boot order - * @default BootOrder.CD_FLOPPY_HARDDISK - */ - boot_order?: BootOrder - - /** - * fast boot - * @default false - */ - fastboot?: boolean - - /** - * enables UART1 (Serial port) - * @see http://wiki.osdev.org/UART - * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js - * @see https://www.freebsd.org/doc/en/articles/serial-uart/ - * @default undefined - */ - uart1?: boolean + declare enum LogLevel { + LOG_ALL = -1, + LOG_NONE = 0, + LOG_OTHER = 0x000001, + LOG_CPU = 0x000002, + LOG_FPU = 0x000004, + LOG_MEM = 0x000008, + LOG_DMA = 0x000010, + LOG_IO = 0x000020, + LOG_PS2 = 0x000040, + LOG_PIC = 0x000080, + LOG_VGA = 0x000100, + LOG_PIT = 0x000200, + LOG_MOUSE = 0x000400, + LOG_PCI = 0x000800, + LOG_BIOS = 0x001000, + LOG_FLOPPY = 0x002000, + LOG_SERIAL = 0x004000, + LOG_DISK = 0x008000, + LOG_RTC = 0x010000, + LOG_HPET = 0x020000, + LOG_ACPI = 0x040000, + LOG_APIC = 0x080000, + LOG_NET = 0x100000, + LOG_VIRTIO = 0x200000, + LOG_9P = 0x400000, + LOG_SB16 = 0x800000 + } - /** - * enables UART2 (Serial port) - * @see http://wiki.osdev.org/UART - * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js - * @see https://www.freebsd.org/doc/en/articles/serial-uart/ - * @default undefined - */ - uart2?: boolean + declare enum BootOrder { + CD_FLOPPY_HARDDISK = 0x213, + CD_HARDDISK_FLOPPY = 0x123, + FLOPPY_CD_HARDDISK = 0x231, + FLOPPY_HARDDISK_CD = 0x321, + HARDDISK_CD_FLOPPY = 0x132 + } - /** - * enables UART3 (Serial port) - * @see http://wiki.osdev.org/UART - * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js - * @see https://www.freebsd.org/doc/en/articles/serial-uart/ - * @default undefined - */ - uart3?: boolean + declare class BusConnector { + constructor() + + /** + * @param {string} name + * @param {function(?)} fn + * @param {Object} this_value + */ + register(name: string, fn: Function, this_value: Object); + + /** + * Unregister one message with the given name and callback + * + * @param {string} name + * @param {function()} fn + */ + unregister(name: string, fn: Function) + + /** + * Send ("emit") a message + * + * @param {string} name + * @param {*=} value + * @param {*=} unused_transfer + */ + send(name: string, value: any, unused_transfer?: any) + + /** + * Send a message, guaranteeing that it is received asynchronously + * + * @param {string} name + * @param {Object=} value + */ + send_async(name: string, value: any) + } /** - * boot cmdline + * Custom emulated ethernet card adapter (pass in V86StarterOptions) + * @see https://github.com/copy/v86/blob/master/src/browser/network.js */ - cmdline?: string + declare class NetworkAdapter { + constructor(bus: BusConnector) - /** - * Ne2k: should MAC be preserved from the state image - * @default undefined - */ - preserve_mac_from_state_image?: boolean + handle_message(event: any & { data: string | ArrayBufferLike | Blob | ArrayBufferView }): void + handle_close(event: any): void + handle_open(event: any): void + handle_error(event: any): void + destroy(event: any): void + connect(): void + send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void + change_proxy(url: string): void + } - /** - * custom network adapter - * @default undefined - */ - network_adapter?: NetworkAdapter + declare type V86AutomaticStep = + | { + /** wait for x seconds */ + sleep: number + } + | { + /** wait until vga_text is present on the screen */ + vga_text: string + } + | { + /** text or scancodes to send */ + keyboard_send: number[] | string + } + | { + /** callback to execute */ + call: () => void + } + + /** + * emulator instance constructor options. + */ + declare interface V86StarterOptions { + /** + * Path to v86 wasm artifact + * @default "build/v86.wasm" or "build/v86-debug.wasm" when debug mode enabled + */ + wasm_path?: string + + /** + * The memory size in bytes, should be a power of 2. + * @example 16 * 1024 * 1024 + * @default 64 * 1024 * 1024 + */ + memory_size?: number + + /** + * VGA memory size in bytes. + * @example 8 * 1024 * 1024 + * @default 8 * 1024 * 1024 + */ + vga_memory_size?: number + + /** + * If emulation should be started when emulator is ready. + * @default false + */ + autostart?: boolean + + /** + * If keyboard should be disabled. + * @default false + */ + disable_keyboard?: boolean + + /** + * If mouse should be disabled. + * @default false + */ + disable_mouse?: boolean + + /** + * If speaker should be disabled. + * @default false + */ + disable_speaker?: boolean + + /** + * The url of a server running websockproxy. See [networking.md](networking.md). Setting this will enable an emulated network card. + * @default undefined + */ + network_relay_url?: string + + /** + * Either a url pointing to a bios or an ArrayBuffer, see below. + * @default undefined + */ + bios?: V86Image + + /** + * VGA bios, see below. + * @default undefined + */ + vga_bios?: V86Image + + /** + * First hard disk, see below. + * @default undefined + */ + hda?: V86Image + + /** + * First floppy disk, see below. + * @default undefined + */ + fda?: V86Image + + /** + * cdrom + * @default undefined + */ + cdrom?: V86Image + + /** + * A Linux kernel image to boot (only bzimage format) + * @default undefined + */ + bzimage?: V86Image + + /** + * A Linux ramdisk image + * @default undefined + */ + initrd?: V86Image + + /** + * Automatically fetch bzimage and initrd from the specified `filesystem`. + */ + bzimage_initrd_from_filesystem?: boolean + + /** + * An initial state to load + * @default undefined + */ + initial_state?: V86Image + + /** + * A 9p filesystem + * @default undefined + */ + filesystem?: Filesystem9pOptions + + /** + * A textarea that will receive and send data to the emulated serial terminal. + * Alternatively the serial terminal can also be accessed programatically, see [serial.html](../examples/serial.html). + * @default undefined + */ + serial_container?: HTMLTextAreaElement + + /** + * Xtermjs serial terminal container. When set, serial_container option is ignored. + * @default undefined + */ + serial_container_xtermjs?: HTMLElement + + /** + * An HTMLElement. This should have a certain structure, see [basic.html](../examples/basic.html). + * @default undefined + */ + screen_container?: HTMLElement | null + + /** + * ACPI + * @default false + */ + acpi?: boolean + + /** + * log level + * @default LogLevel.LOG_NONE + */ + log_level?: LogLevel + + /** + * boot order + * @default BootOrder.CD_FLOPPY_HARDDISK + */ + boot_order?: BootOrder + + /** + * fast boot + * @default false + */ + fastboot?: boolean + + /** + * enables UART1 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart1?: boolean + + /** + * enables UART2 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart2?: boolean + + /** + * enables UART3 (Serial port) + * @see http://wiki.osdev.org/UART + * @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js + * @see https://www.freebsd.org/doc/en/articles/serial-uart/ + * @default undefined + */ + uart3?: boolean + + /** + * boot cmdline + */ + cmdline?: string + + /** + * Ne2k: should MAC be preserved from the state image + * @default undefined + */ + preserve_mac_from_state_image?: boolean + + /** + * custom network adapter + * @default undefined + */ + network_adapter?: NetworkAdapter + + /** + * enables screen dummy + * @default undefined + */ + screen_dummy?: boolean + } - /** - * enables screen dummy - * @default undefined - */ - screen_dummy?: boolean + declare class V86Starter { + constructor(options?: V86StarterOptions) + + /** + * bus, use it when you must (there are a few wrappers on top of it in V86Starter that you might find helpful instead) + */ + bus: BusConnector + + /** + * Start emulation. Do nothing if emulator is running already. Can be asynchronous. + */ + run(): void + + /** + * Stop emulation. Do nothing if emulator is not running. Can be asynchronous. + */ + stop(): void + destroy(): void + + /** + * Restart (force a reboot). + */ + restart(): void + + /** + * Add an event listener (the emulator is an event emitter). A list of events + * can be found at [events.md](events.md). + * + * The callback function gets a single argument which depends on the event. + * + * @param event Name of the event. + * @param listener The callback function. + */ + add_listener(event: string, listener: Function): void + + /** + * Remove an event listener. + * + * @param event + * @param listener + */ + remove_listener(event: string, listener: Function): void + + /** + * Restore the emulator state from the given state, which must be an + * ArrayBuffer returned by + * [`save_state`](#save_statefunctionobject-arraybuffer-callback). + * + * Note that the state can only be restored correctly if this constructor has + * been created with the same options as the original instance (e.g., same disk + * images, memory size, etc.). + * + * Different versions of the emulator might use a different format for the + * state buffer. + * + * @param state + */ + restore_state(state: ArrayBuffer): void + + /** + * Asynchronously save the current state of the emulator. The first argument to + * the callback is an Error object if something went wrong and is null + * otherwise. + * + * @param callback + */ + save_state(callback: (error: Object | null, state: ArrayBuffer) => void): void + + /** + * Return an object with several statistics. Return value looks similar to + * (but can be subject to change in future versions or different + * configurations, so use defensively): + * + * ```javascript + * { + * "cpu": { + * "instruction_counter": 2821610069 + * }, + * "hda": { + * "sectors_read": 95240, + * "sectors_written": 952, + * "bytes_read": 48762880, + * "bytes_written": 487424, + * "loading": false + * }, + * "cdrom": { + * "sectors_read": 0, + * "sectors_written": 0, + * "bytes_read": 0, + * "bytes_written": 0, + * "loading": false + * }, + * "mouse": { + * "enabled": true + * }, + * "vga": { + * "is_graphical": true, + * "res_x": 800, + * "res_y": 600, + * "bpp": 32 + * } + * } + * ``` + * + * @deprecated + */ + get_statistics(): Object + get_instruction_counter(): number + is_running(): boolean + + /** + * Send a sequence of scan codes to the emulated PS2 controller. A list of + * codes can be found at http://stanislavs.org/helppc/make_codes.html. + * Do nothing if there is no keyboard controller. + * + * @param codes + */ + keyboard_send_scancodes(codes: number[]): void + + /** + * Send translated keys + */ + keyboard_send_keys(codes: any[]): void + + /** + * Send text + */ + keyboard_send_text(string: string): void + + + /** + * Download a screenshot. + */ + screen_make_screenshot(): void + + /** + * Set the scaling level of the emulated screen. + * + * @param {number} sx + * @param {number} sy + * + * @ignore + * @export + */ + screen_set_scale(sx: number, sy: number): void + + /** + * Go fullscreen. + */ + screen_go_fullscreen(): void + + /** + * Lock the mouse cursor: It becomes invisble and is not moved out of the browser window. + */ + lock_mouse(): void + + /** + * Enable or disable sending mouse events to the emulated PS2 controller. + */ + mouse_set_status(enabled: boolean): void + + /** + * Enable or disable sending keyboard events to the emulated PS2 controller. + */ + keyboard_set_status(enabled: boolean): void + + /** + * Send a string to the first emulated serial terminal. + * + * @param data + */ + serial0_send(data: string): void + + /** + * Send bytes to a serial port (to be received by the emulated PC). + * + * @param serial the index of the serial port + * @param data + */ + serial_send_bytes(serial: number, data: Uint8Array) + + /** + * Mount another filesystem to the current filesystem. + * @param path Path for the mount point + * @param baseurl + * @param basefs As a JSON string + * @param callback + * @export + */ + mount_fs(path: string, baseurl?: string, basefs?: string, callback?: (error: Object | null) => void): void + + /** + * Write to a file in the 9p filesystem. Nothing happens if no filesystem has + * been initialized. First argument to the callback is an error object if + * something went wrong and null otherwise. + * + * @param file + * @param data + * @param callback + */ + create_file(file: string, data: Uint8Array, callback?: (error: Object | null) => void): void + + /** + * Runs a set of automatic steps + * @param steps + */ + automatically(steps: V86AutomaticStep[]): void + + /** + * Reads data from memory at specified offset. + * + * @param offset + * @param length + */ + read_memory(offset: number, length: number): Array | Uint8Array + + /** + * Writes data to memory at specified offset. + * + * @param {Array.|Uint8Array} blob + * @param {number} offset + */ + write_memory(blob: Array | Uint8Array, offset: number): void + } } - -declare class V86Starter { - constructor(options?: V86StarterOptions) - - /** - * bus, use it when you must (there are a few wrappers on top of it in V86Starter that you might find helpful instead) - */ - bus: BusConnector - - /** - * Start emulation. Do nothing if emulator is running already. Can be asynchronous. - */ - run(): void - - /** - * Stop emulation. Do nothing if emulator is not running. Can be asynchronous. - */ - stop(): void - destroy(): void - - /** - * Restart (force a reboot). - */ - restart(): void - - /** - * Add an event listener (the emulator is an event emitter). A list of events - * can be found at [events.md](events.md). - * - * The callback function gets a single argument which depends on the event. - * - * @param event Name of the event. - * @param listener The callback function. - */ - add_listener(event: string, listener: Function): void - - /** - * Remove an event listener. - * - * @param event - * @param listener - */ - remove_listener(event: string, listener: Function): void - - /** - * Restore the emulator state from the given state, which must be an - * ArrayBuffer returned by - * [`save_state`](#save_statefunctionobject-arraybuffer-callback). - * - * Note that the state can only be restored correctly if this constructor has - * been created with the same options as the original instance (e.g., same disk - * images, memory size, etc.). - * - * Different versions of the emulator might use a different format for the - * state buffer. - * - * @param state - */ - restore_state(state: ArrayBuffer): void - - /** - * Asynchronously save the current state of the emulator. The first argument to - * the callback is an Error object if something went wrong and is null - * otherwise. - * - * @param callback - */ - save_state(callback: (error: Object | null, state: ArrayBuffer) => void): void - - /** - * Return an object with several statistics. Return value looks similar to - * (but can be subject to change in future versions or different - * configurations, so use defensively): - * - * ```javascript - * { - * "cpu": { - * "instruction_counter": 2821610069 - * }, - * "hda": { - * "sectors_read": 95240, - * "sectors_written": 952, - * "bytes_read": 48762880, - * "bytes_written": 487424, - * "loading": false - * }, - * "cdrom": { - * "sectors_read": 0, - * "sectors_written": 0, - * "bytes_read": 0, - * "bytes_written": 0, - * "loading": false - * }, - * "mouse": { - * "enabled": true - * }, - * "vga": { - * "is_graphical": true, - * "res_x": 800, - * "res_y": 600, - * "bpp": 32 - * } - * } - * ``` - * - * @deprecated - */ - get_statistics(): Object - get_instruction_counter(): number - is_running(): boolean - - /** - * Send a sequence of scan codes to the emulated PS2 controller. A list of - * codes can be found at http://stanislavs.org/helppc/make_codes.html. - * Do nothing if there is no keyboard controller. - * - * @param codes - */ - keyboard_send_scancodes(codes: number[]): void - - /** - * Send translated keys - */ - keyboard_send_keys(codes: any[]): void - - /** - * Send text - */ - keyboard_send_text(string: string): void - - - /** - * Download a screenshot. - */ - screen_make_screenshot(): void - - /** - * Set the scaling level of the emulated screen. - * - * @param {number} sx - * @param {number} sy - * - * @ignore - * @export - */ - screen_set_scale(sx: number, sy: number): void - - /** - * Go fullscreen. - */ - screen_go_fullscreen(): void - - /** - * Lock the mouse cursor: It becomes invisble and is not moved out of the browser window. - */ - lock_mouse(): void - - /** - * Enable or disable sending mouse events to the emulated PS2 controller. - */ - mouse_set_status(enabled: boolean): void - - /** - * Enable or disable sending keyboard events to the emulated PS2 controller. - */ - keyboard_set_status(enabled: boolean): void - - /** - * Send a string to the first emulated serial terminal. - * - * @param data - */ - serial0_send(data: string): void - - /** - * Send bytes to a serial port (to be received by the emulated PC). - * - * @param serial the index of the serial port - * @param data - */ - serial_send_bytes(serial: number, data: Uint8Array) - - /** - * Mount another filesystem to the current filesystem. - * @param path Path for the mount point - * @param baseurl - * @param basefs As a JSON string - * @param callback - * @export - */ - mount_fs(path: string, baseurl?: string, basefs?: string, callback?: (error: Object | null) => void): void - - /** - * Write to a file in the 9p filesystem. Nothing happens if no filesystem has - * been initialized. First argument to the callback is an error object if - * something went wrong and null otherwise. - * - * @param file - * @param data - * @param callback - */ - create_file(file: string, data: Uint8Array, callback?: (error: Object | null) => void): void - - /** - * Runs a set of automatic steps - * @param steps - */ - automatically(steps: V86AutomaticStep[]): void - - /** - * Reads data from memory at specified offset. - * - * @param offset - * @param length - */ - read_memory(offset: number, length: number): Array | Uint8Array - - /** - * Writes data to memory at specified offset. - * - * @param {Array.|Uint8Array} blob - * @param {number} offset - */ - write_memory(blob: Array | Uint8Array, offset: number): void -} \ No newline at end of file From 261521388195225aa144b018a7c603b9963cadd9 Mon Sep 17 00:00:00 2001 From: ambientlight Date: Sat, 14 May 2022 18:49:00 +0800 Subject: [PATCH 09/11] address review comments --- src/browser/starter.js | 88 +++++++++++++++++++++--------------------- src/bus.js | 13 ------- types/index.d.ts | 30 +++----------- 3 files changed, 50 insertions(+), 81 deletions(-) diff --git a/src/browser/starter.js b/src/browser/starter.js index cac0ef96a0..5717a61d8c 100644 --- a/src/browser/starter.js +++ b/src/browser/starter.js @@ -1119,50 +1119,50 @@ V86Starter.prototype.serial_send_bytes = function(serial, data) * @param {function(Object)=} callback * @export */ -V86Starter.prototype.mount_fs = async function(path, baseurl, basefs, callback) -{ - let file_storage = new MemoryFileStorage(); - - if(baseurl) - { - file_storage = new ServerFileStorageWrapper(file_storage, baseurl); - } - const newfs = new FS(file_storage, this.fs9p.qidcounter); - const mount = () => - { - const idx = this.fs9p.Mount(path, newfs); - if(!callback) - { - return; - } - if(idx === -ENOENT) - { - callback(new FileNotFoundError()); - } - else if(idx === -EEXIST) - { - callback(new FileExistsError()); - } - else if(idx < 0) - { - dbg_assert(false, "Unexpected error code: " + (-idx)); - callback(new Error("Failed to mount. Error number: " + (-idx))); - } - else - { - callback(null); - } - }; - if(baseurl) - { - dbg_assert(typeof basefs === "object", "Filesystem: basefs must be a JSON object"); - newfs.load_from_json(basefs, () => mount()); - } - else - { - mount(); - } -}; +// V86Starter.prototype.mount_fs = async function(path, baseurl, basefs, callback) +// { +// let file_storage = new MemoryFileStorage(); + +// if(baseurl) +// { +// file_storage = new ServerFileStorageWrapper(file_storage, baseurl); +// } +// const newfs = new FS(file_storage, this.fs9p.qidcounter); +// const mount = () => +// { +// const idx = this.fs9p.Mount(path, newfs); +// if(!callback) +// { +// return; +// } +// if(idx === -ENOENT) +// { +// callback(new FileNotFoundError()); +// } +// else if(idx === -EEXIST) +// { +// callback(new FileExistsError()); +// } +// else if(idx < 0) +// { +// dbg_assert(false, "Unexpected error code: " + (-idx)); +// callback(new Error("Failed to mount. Error number: " + (-idx))); +// } +// else +// { +// callback(null); +// } +// }; +// if(baseurl) +// { +// dbg_assert(typeof basefs === "object", "Filesystem: basefs must be a JSON object"); +// newfs.load_from_json(basefs, () => mount()); +// } +// else +// { +// mount(); +// } +// }; /** * Write to a file in the 9p filesystem. Nothing happens if no filesystem has diff --git a/src/bus.js b/src/bus.js index 2846d255aa..44505fcb59 100644 --- a/src/bus.js +++ b/src/bus.js @@ -78,19 +78,6 @@ BusConnector.prototype.send = function(name, value, unused_transfer) } }; -/** - * Send a message, guaranteeing that it is received asynchronously - * - * @param {string} name - * @param {Object=} value - */ -BusConnector.prototype.send_async = function(name, value) -{ - dbg_assert(arguments.length === 1 || arguments.length === 2); - - setTimeout(this.send.bind(this, name, value), 0); -}; - Bus.create = function() { var c0 = new BusConnector(); diff --git a/types/index.d.ts b/types/index.d.ts index d086cbd198..6985e7b2fe 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,7 +1,7 @@ declare module v86 { /** set when v86 is built with debug mode enabled */ - declare const DEBUG: boolean; + declare let DEBUG: boolean | undefined; declare type V86Image = | { url: string } @@ -89,18 +89,10 @@ declare module v86 { * @param {*=} unused_transfer */ send(name: string, value: any, unused_transfer?: any) - - /** - * Send a message, guaranteeing that it is received asynchronously - * - * @param {string} name - * @param {Object=} value - */ - send_async(name: string, value: any) } /** - * Custom emulated ethernet card adapter (pass in V86StarterOptions) + * Custom emulated ethernet card adapter (pass in V86Options) * @see https://github.com/copy/v86/blob/master/src/browser/network.js */ declare class NetworkAdapter { @@ -137,7 +129,7 @@ declare module v86 { /** * emulator instance constructor options. */ - declare interface V86StarterOptions { + declare interface V86Options { /** * Path to v86 wasm artifact * @default "build/v86.wasm" or "build/v86-debug.wasm" when debug mode enabled @@ -342,12 +334,12 @@ declare module v86 { } declare class V86Starter { - constructor(options?: V86StarterOptions) + constructor(options?: V86Options) /** * bus, use it when you must (there are a few wrappers on top of it in V86Starter that you might find helpful instead) */ - bus: BusConnector + protected bus: BusConnector /** * Start emulation. Do nothing if emulator is running already. Can be asynchronous. @@ -522,16 +514,6 @@ declare module v86 { */ serial_send_bytes(serial: number, data: Uint8Array) - /** - * Mount another filesystem to the current filesystem. - * @param path Path for the mount point - * @param baseurl - * @param basefs As a JSON string - * @param callback - * @export - */ - mount_fs(path: string, baseurl?: string, basefs?: string, callback?: (error: Object | null) => void): void - /** * Write to a file in the 9p filesystem. Nothing happens if no filesystem has * been initialized. First argument to the callback is an error object if @@ -555,7 +537,7 @@ declare module v86 { * @param offset * @param length */ - read_memory(offset: number, length: number): Array | Uint8Array + read_memory(offset: number, length: number): Uint8Array /** * Writes data to memory at specified offset. From 1c34108dc2999385b746c65768dc5360fc17d081 Mon Sep 17 00:00:00 2001 From: ambientlight Date: Sat, 14 May 2022 18:50:05 +0800 Subject: [PATCH 10/11] change package name and version --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index da2415b4a5..6ede149d44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@copy/v86", - "version": "0.1.0", + "name": "v86", + "version": "0.0.1", "description": "x86 virtualization in your browser, recompiling x86 to wasm on the fly", "main": "build/libv86.js", "directories": { @@ -45,5 +45,5 @@ "bugs": { "url": "https://github.com/copy/v86/issues" }, - "homepage": "https://github.com/copy/v86#readme" + "homepage": "https://copy.sh/v86/" } From a237df8bb87a16dc59625172e1edc34216be9c08 Mon Sep 17 00:00:00 2001 From: ambientlight Date: Sat, 14 May 2022 19:28:40 +0800 Subject: [PATCH 11/11] distribute with libwabt and capstone-x86 --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ede149d44..771818b179 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "build": "npm run build:all_debug & npm run build:all", "build:all_debug": "make all-debug", "build:all": "make all", - "build:release": "make build/libv86.js build/v86.wasm build/v86-fallback.wasm", + "build:release": "make build/libv86.js build/v86.wasm build/v86-fallback.wasm build/capstone-x86.min.js build/libwabt.js", "test:prepare": "wget -nv -P images/ https://k.copy.sh/{linux.iso,linux3.iso,linux4.iso,buildroot-bzimage.bin,TinyCore-11.0.iso,oberon.img,msdos.img,openbsd-floppy.img,kolibri.img,windows101.img,os8.img,freedos722.img,mobius-fd-release5.img}", "test": "make kvm-unit-test nasmtests nasmtests-force-jit expect-tests jitpagingtests qemutests qemutests-release rust-test tests" }, @@ -28,6 +28,8 @@ "build/v86.wasm", "build/v86-debug.wasm", "build/v86-fallback.wasm", + "build/capstone-x86.min.js", + "build/libwabt.js", "types/index.d.ts" ], "types": "types/index.d.ts",