2023-09-07 10:14:07 +02:00
|
|
|
var emulator;
|
|
|
|
|
|
|
|
// Whether or not to restore the VM state from a file. Set to false to perform a regular boot.
|
|
|
|
let restoreState = true;
|
|
|
|
|
2023-09-07 11:43:51 +02:00
|
|
|
function testy(cmd) {
|
|
|
|
return new Promise((resolve, reject) => {
|
2023-09-07 10:14:07 +02:00
|
|
|
setTimeout(() => {
|
2023-09-07 11:43:51 +02:00
|
|
|
resolve("testy!!" + cmd);
|
|
|
|
}, 100);
|
2023-09-07 10:14:07 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
window.testy = testy;
|
|
|
|
|
|
|
|
// Run a command via the serial port (/dev/ttyS0) and return the output.
|
|
|
|
function run_in_vm(cmd) {
|
|
|
|
emulator.serial0_send(cmd + "\n");
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
var output = "";
|
|
|
|
var listener = (char) => {
|
|
|
|
if (char !== "\r") {
|
|
|
|
output += char;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (output.endsWith("# ")) {
|
|
|
|
emulator.remove_listener("serial0-output-char", listener);
|
|
|
|
let outputWithoutPrompt = output.slice(0, -4);
|
|
|
|
let outputWithoutFirstLine = outputWithoutPrompt.slice(
|
|
|
|
outputWithoutPrompt.indexOf("\n") + 1
|
|
|
|
);
|
|
|
|
if (outputWithoutFirstLine.endsWith("\n")) {
|
|
|
|
outputWithoutFirstLine = outputWithoutFirstLine.slice(0, -1);
|
|
|
|
}
|
|
|
|
emulator.remove_listener("serial0-output-char", listener);
|
|
|
|
resolve(outputWithoutFirstLine);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
emulator.add_listener("serial0-output-char", listener);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
window.run_in_vm = run_in_vm;
|
2023-09-07 11:43:51 +02:00
|
|
|
window.web_shell = { run_in_vm, testy };
|
2023-09-07 10:14:07 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
// Run a test command and return true if the exit code is 0, false otherwise.
|
|
|
|
async function test(condition) {
|
|
|
|
let result = await run(`test ${condition} && echo 'yes' || echo 'no'`)
|
|
|
|
return result == "yes"
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Set emulator config.
|
|
|
|
let config = {
|
|
|
|
wasm_path: "web-shell/lib/v86.wasm",
|
|
|
|
memory_size: 64 * 1024 * 1024,
|
|
|
|
vga_memory_size: 2 * 1024 * 1024,
|
|
|
|
screen_container: document.getElementById("screen_container"),
|
|
|
|
bios: { url: "web-shell/images/seabios.bin" },
|
|
|
|
vga_bios: { url: "web-shell/images/vgabios.bin" },
|
|
|
|
cdrom: { url: "web-shell/images/image.iso.zst" },
|
|
|
|
disable_mouse: true,
|
|
|
|
autostart: true,
|
|
|
|
};
|
|
|
|
if (restoreState) {
|
|
|
|
config.initial_state = {
|
|
|
|
url: "web-shell/images/booted-state.bin.zst",
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function boot() {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
// Start the emulator!
|
|
|
|
emulator = window.emulator = new V86Starter(config);
|
|
|
|
|
|
|
|
// Wait for the emulator to start, then resolve the promise.
|
|
|
|
var interval = setInterval(() => {
|
|
|
|
if (emulator.is_running()) {
|
|
|
|
clearInterval(interval);
|
|
|
|
resolve();
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
// Allow saving and restoring the state using the buttons below the console.
|
|
|
|
var state
|
|
|
|
document.getElementById("save_restore").onclick = async function () {
|
|
|
|
var button = this
|
|
|
|
|
|
|
|
if (state) {
|
|
|
|
button.value = "Save state"
|
|
|
|
await emulator.restore_state(state)
|
|
|
|
state = undefined
|
|
|
|
} else {
|
|
|
|
const new_state = await emulator.save_state()
|
|
|
|
console.log("Saved state of " + new_state.byteLength + " bytes")
|
|
|
|
button.value = "Restore state"
|
|
|
|
state = new_state
|
|
|
|
}
|
|
|
|
|
|
|
|
button.blur()
|
|
|
|
}
|
|
|
|
document.getElementById("save_file").onclick = async function () {
|
|
|
|
const new_state = await emulator.save_state()
|
|
|
|
var a = document.createElement("a")
|
|
|
|
a.download = "v86state.bin"
|
|
|
|
a.href = window.URL.createObjectURL(new Blob([new_state]))
|
|
|
|
a.dataset.downloadurl =
|
|
|
|
"application/octet-stream:" + a.download + ":" + a.href
|
|
|
|
a.click()
|
|
|
|
|
|
|
|
this.blur()
|
|
|
|
}
|
|
|
|
document.getElementById("restore_file").onchange = function () {
|
|
|
|
if (this.files.length) {
|
|
|
|
var filereader = new FileReader()
|
|
|
|
emulator.stop()
|
|
|
|
|
|
|
|
filereader.onload = async function (e) {
|
|
|
|
await emulator.restore_state(e.target.result)
|
|
|
|
emulator.run()
|
|
|
|
}
|
|
|
|
|
|
|
|
filereader.readAsArrayBuffer(this.files[0])
|
|
|
|
|
|
|
|
this.value = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
this.blur()
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|