lalit / index.html
Studytime171's picture
Upload index.html
1a25444 verified
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Virtual x86</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="v86.css">
<!-- keep your original v86 bundle path unchanged -->
<script src="build/v86_all.js"></script>
</head>
<body style="font-family: Arial, sans-serif; background:#111; color:#eee;">
<div>
<div id="boot_options">
<h2 style="margin:0 0 8px 0">Virtual x86 - Boot Options</h2>
<hr>
<table>
<tr>
<td width="250">CD image</td>
<td>
<input type="file" id="cd_image"><br>
<input type="text" id="cd_url" placeholder="Or paste ISO/IMG URL (http(s)://...) or path" style="width:90%; margin-top:6px;"><br>
<div id="cd_display" style="font-size:12px; color:#bbb; margin-top:4px;">No file selected</div>
</td>
</tr>
<tr>
<td>Floppy disk image</td>
<td>
<input type="file" id="floppy_image"><br>
<input type="text" id="floppy_url" placeholder="Or paste floppy URL/path" style="width:90%; margin-top:6px;"><br>
<div id="floppy_display" style="font-size:12px; color:#bbb; margin-top:4px;">No file selected</div>
</td>
</tr>
<tr>
<td>Master Hard drive disk image</td>
<td>
<input type="file" id="hda_image"><br>
<input type="text" id="hda_url" placeholder="Or paste HDD URL/path" style="width:90%; margin-top:6px;"><br>
<div id="hda_display" style="font-size:12px; color:#bbb; margin-top:4px;">No file selected</div>
</td>
</tr>
<tr>
<td>Slave Hard drive disk image</td>
<td>
<input type="file" id="hdb_image"><br>
<input type="text" id="hdb_url" placeholder="Or paste second HDD URL/path" style="width:90%; margin-top:6px;"><br>
<div id="hdb_display" style="font-size:12px; color:#bbb; margin-top:4px;">No file selected</div>
</td>
</tr>
<tr>
<td>Multiboot kernel image</td>
<td>
<input type="file" id="multiboot_image"><br>
<input type="text" id="multiboot_url" placeholder="Or paste kernel image URL/path" style="width:90%; margin-top:6px;"><br>
<div id="multiboot_display" style="font-size:12px; color:#bbb; margin-top:4px;">No file selected</div>
</td>
</tr>
<tr>
<td colspan="2"><hr></td>
</tr>
<tr>
<td>Memory size</td>
<td>
<input id="memory_size" type="number" value="256" min="16" max="4096" step="16"> MB<br>
</td>
</tr>
<tr>
<td>Video Memory size</td>
<td>
<input id="video_memory_size" type="number" value="8" min="1" max="128" step="1"> MB<br>
</td>
</tr>
<tr>
<td colspan="2"><hr></td>
</tr>
<tr>
<td>Boot order</td>
<td>
<select id="boot_order">
<option value="213">CD / Floppy / Hard Disk</option>
<option value="123">CD / Hard Disk / Floppy</option>
<option value="231">Floppy / CD / Hard Disk</option>
<option value="321">Floppy / Hard Disk / CD</option>
<option value="312">Hard Disk / Floppy / CD</option>
<option value="132">Hard Disk / CD / Floppy</option>
</select>
</td>
</tr>
</table>
<br>
<button id="start_emulation" style="padding:8px 14px; font-size:16px;">Start Emulation</button>
<div id="status" style="margin-top:10px; font-size:13px; color:#cfc;"></div>
<br><br>
</div>
<div id="runtime_options" style="display: none; margin-bottom:8px;">
<input type="button" id="pause_btn" value="Pause">
<input type="button" id="reset_btn" value="Reset">
<input type="button" id="exit_btn" value="Exit">
<input type="button" id="send_cad" value="Send Ctrl-Alt-Del">
</div>
<pre style="margin: 0" id="log_levels"></pre>
<pre style="margin: 3px 0 0 0" id="debug_infos"></pre>
</div>
<!-- Screen container (keeps original structure) -->
<div id="screen_container" style="display: none; position: relative;">
<div id="screen"></div>
<canvas id="vga"></canvas>
<div style="position: absolute; top: 0; z-index: 10">
<textarea class="phone_keyboard"></textarea>
</div>
</div>
<textarea readonly id="log" style="display:none"></textarea>
<textarea spellcheck="false" cols="40" rows="12" id="serial" style="display:none"></textarea>
<script>
/*
IMPORTANT:
- This script reads selected local files into ArrayBuffers and passes them to v86.
- Browsers do NOT reveal real absolute local paths; the script shows file.name or the browser's fakepath.
- Keep your folders (build/, bios/) unchanged as requested.
*/
(function() {
// Helper: read File -> ArrayBuffer
function readFileAsArrayBuffer(file) {
return new Promise(function(resolve, reject) {
var fr = new FileReader();
fr.onload = function() { resolve(fr.result); };
fr.onerror = function(e) { reject(e); };
fr.readAsArrayBuffer(file);
});
}
// Drives mapping
var drives = [
{ fileId: "cd_image", textId: "cd_url", displayId: "cd_display", optionName: "cdrom" },
{ fileId: "floppy_image", textId: "floppy_url", displayId: "floppy_display", optionName: "fda" },
{ fileId: "hda_image", textId: "hda_url", displayId: "hda_display", optionName: "hda" },
{ fileId: "hdb_image", textId: "hdb_url", displayId: "hdb_display", optionName: "hdb" },
{ fileId: "multiboot_image", textId: "multiboot_url", displayId: "multiboot_display", optionName: "multiboot" }
];
// Attach change handlers: autofill text and update display
drives.forEach(function(d) {
var fileInput = document.getElementById(d.fileId);
var textInput = document.getElementById(d.textId);
var display = document.getElementById(d.displayId);
if (!fileInput || !textInput || !display) return;
fileInput.addEventListener("change", function() {
if (fileInput.files && fileInput.files.length > 0) {
var f = fileInput.files[0];
// Browsers restrict absolute path; we show either browser-provided fake path or filename
// some browsers set fileInput.value to "C:\fakepath\filename.ext"
var shown = fileInput.value && fileInput.value.indexOf("fakepath") > -1 ? fileInput.value : f.name;
textInput.value = shown;
display.textContent = "Selected: " + shown;
} else {
textInput.value = "";
display.textContent = "No file selected";
}
});
textInput.addEventListener("input", function() {
display.textContent = this.value ? ("Path/URL: " + this.value) : "No file selected";
});
});
// Wait for v86 to be available
function v86Available() {
return (typeof V86Starter === "function" || typeof window.V86Starter === "function");
}
// Start emulator click
document.getElementById("start_emulation").addEventListener("click", async function() {
var status = document.getElementById("status");
status.textContent = "";
if (!v86Available()) {
status.style.color = "#f88";
status.textContent = "Error: v86 library not loaded - check build/v86_all.js is present.";
return;
}
// gather config
var memorySizeMb = parseInt(document.getElementById("memory_size").value, 10) || 256;
var videoMemoryMb = parseInt(document.getElementById("video_memory_size").value, 10) || 8;
var bootOrder = parseInt(document.getElementById("boot_order").value, 10) || 213;
// base options (keep your bios paths exactly)
var options = {
wasm_path: "build/v86.wasm",
memory_size: memorySizeMb * 1024 * 1024,
vga_memory_size: videoMemoryMb * 1024 * 1024,
screen_container: document.getElementById("screen_container"),
bios: { url: "bios/seabios.bin" },
vga_bios: { url: "bios/vgabios.bin" },
boot_order: bootOrder,
autostart: true
};
// read files if selected (async). If file chosen -> use buffer, else if text is a URL -> use url
try {
for (var i = 0; i < drives.length; i++) {
var d = drives[i];
var fileEl = document.getElementById(d.fileId);
var textEl = document.getElementById(d.textId);
var val = (textEl && textEl.value) ? textEl.value.trim() : "";
if (fileEl && fileEl.files && fileEl.files.length > 0) {
// read file to ArrayBuffer
status.style.color = "#ffc";
status.textContent = "Reading " + fileEl.files[0].name + " ...";
var buf = await readFileAsArrayBuffer(fileEl.files[0]);
// pass ArrayBuffer directly to v86
options[d.optionName] = { buffer: buf };
} else if (val) {
// If user typed a URL (http/https) we provide it as url, otherwise still pass as url (user knows their path)
options[d.optionName] = { url: val };
}
}
} catch (err) {
status.style.color = "#f88";
status.textContent = "Failed reading image file: " + (err && err.message ? err.message : err);
return;
}
// hide boot UI and show screen container + runtime controls
document.getElementById("boot_options").style.display = "none";
document.getElementById("screen_container").style.display = "block";
document.getElementById("runtime_options").style.display = "block";
status.style.color = "#cfc";
status.textContent = "Starting emulator... (this may take a few seconds)";
try {
// start v86
window.emulator = new V86Starter(options);
// wire up runtime buttons safely if emulator supports methods
var pauseBtn = document.getElementById("pause_btn");
var resetBtn = document.getElementById("reset_btn");
var exitBtn = document.getElementById("exit_btn");
var cadBtn = document.getElementById("send_cad");
if (pauseBtn) {
pauseBtn.addEventListener("click", function() {
try {
if (window.emulator && window.emulator.stop) {
window.emulator.stop();
}
} catch(e) { console.warn(e); }
});
}
if (resetBtn) {
resetBtn.addEventListener("click", function() {
try { window.emulator.reset(); } catch(e){ console.warn(e); }
});
}
if (exitBtn) {
exitBtn.addEventListener("click", function() {
try { window.emulator.stop(); } catch(e){ console.warn(e); }
// show boot options again
document.getElementById("boot_options").style.display = "block";
document.getElementById("runtime_options").style.display = "none";
document.getElementById("screen_container").style.display = "none";
});
}
if (cadBtn) {
cadBtn.addEventListener("click", function() {
try { window.emulator.keyboard_send_ctrl_alt_del(); } catch(e){
// fallback attempts
try { window.emulator.send_ctrl_alt_del(); } catch(_) { console.warn("send CtrlAltDel not supported"); }
}
});
}
status.style.color = "#cfc";
status.textContent = "Emulator started.";
} catch (e) {
status.style.color = "#f88";
status.textContent = "Failed to start emulator: " + (e && e.message ? e.message : e);
console.error(e);
}
});
})();
</script>
</body>
</html>