diff --git a/webv86/web/app.js b/webv86/web/app.js new file mode 100644 index 0000000..0d7c092 --- /dev/null +++ b/webv86/web/app.js @@ -0,0 +1,153 @@ +var emulator, zoom = 1, cdrom={url: "basekernel.iso"}, serialLine="", + debugMode = false + +function loadCDROM(url) { + if (typeof process == 'object' && process.__nwjs) { + try { + var fs = require('fs') + cdrom = { _url:url, + buffer: Uint8Array.from(fs.readFileSync((process.env.PWD||process.env.HOME||process.env.CWD)+'/'+url)).buffer } + } catch (e) { + alert(e.toString()) + } + } +} +loadCDROM(cdrom.url) + +function createEmulator() { + emulator = new V86({ + wasm_path : "v86.wasm", + memory_size : 64 * 1024 * 1024, // 64 MB memory ought to be enough for anyone + vga_memory_size : 2 * 1024 * 1024, + screen_container : screen_container, + bios : {url: "seabios.bin"}, + vga_bios : {url: "vgabios.bin"}, + cdrom : cdrom, + hda : { + buffer: new Uint8Array(16*1024*1024).buffer + }, + boot_order : 0x123, + autostart : true + }) +} +createEmulator() + +emulator.add_listener("serial0-output-byte", function(byte) { + var char = String.fromCharCode(byte); + // console.log('serial0-output-byte',char,byte,serialLine); + if(char === "\n") + { + console.log(serialLine) + terminal0Queue.push(serialLine); + serialLine="" + return; + } else + serialLine += char +}) +$('#debugger').terminal(function(command) { + var tokens = command.split(' ') + switch (tokens[0]) { + case 'help': + this.echo([ + 'debug #on', + 'dumpidt', + 'dumpregs', + 'dumpstate', + 'reboot', + 'restart', + 'run', + 'stop', + 'zoom #scale' + ].join('\n')) + break; + case 'debug': + debugMode=tokens[1]=='0'?false:true + break; + case 'dumpregs': + this.echo(emulator.v86.cpu.debug.get_regs_short()[0].split(' ').filter(x => x).join('\n')) + break; + case 'dumpidt': + var _debug = debugMode + debugMode=1 + this.echo(emulator.v86.cpu.debug.dump_idt()) + debugMode=_debug + break; + case 'dumpstate': + this.echo(emulator.v86.cpu.debug.get_state().split(' ').filter(x => (x&&x.length>2)).join('\n')) + break; + case 'reboot': + loadCDROM(cdrom.url||cdrom._url); + emulator.destroy(); + createEmulator(); + break; + case 'restart': + emulator.restart() + break; + case 'run': + this.echo("Resumed VM. Use stop to suspend VM.") + emulator.run() + break; + case 'stop': + emulator.stop() + this.echo("Stopped VM. Use run to resume") + break; + case 'zoom': + zoom=Number(tokens[1]||1) + resizeAll() + break; + } +}, { + greetings: '### VM86 Debugger ###', + height:280 +}); +$('#terminal').terminal(function(command) { + emulator.serial0_send(command+'\n'); +}, { + greetings: '### Serial Console ###', + height:280 +}); +var terminal0 = $('#terminal').terminal(), + terminal0Queue = [] +$('#terminal').terminal().echo("Ready.") +// get the debug output the hard way +consoleCallback=function (message) { + // terminal0.echo(message) + if (debugMode && message!=undefined) terminal0Queue.push(message) +} +setInterval(function () { + if (terminal0Queue.length) { + terminal0.echo(terminal0Queue.join('\n')) + terminal0Queue=[] + } +},200); + +function resizeAll() { + var vmcell = $('#vmcell'), + vmcanv = $('canvas'), + win = $(window) + // console.log(vmcell.width(),vmcanv.width(),vmcanv.height()) + if (vmcanv.height()>100) { + vmcell.css('max-width',(vmcanv.width()*zoom+30)+'px') + vmcell.css('width',(vmcanv.width()*zoom+30)+'px') + vmcell.css('height',(Math.floor(vmcanv.height()*zoom*1.1+30)+'px')) + } + vmcanv[0].style='display:block;transform:scale('+zoom+','+(zoom*1.1)+');' +} + +setInterval(resizeAll,1000) +$("#terminal").on('click', function() { + $("#terminal").css("border","2px solid white"); + $("#debugger").css("border","1px solid white"); + $("#vmcell").css("border","1px solid white"); +}); +$("#debugger").on('click', function() { + $("#debugger").css("border","2px solid white"); + $("#terminal").css("border","1px solid white"); + $("#vmcell").css("border","1px solid white"); +}); +$("canvas").on('click', function() { + $("#debugger").css("border","1px solid white"); + $("#terminal").css("border","1px solid white"); + $("#vmcell").css("border","2px solid white"); +}); +$("#vmcell").css("border","2px solid white");