154 lines
4.2 KiB
JavaScript
154 lines
4.2 KiB
JavaScript
|
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");
|