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");