From 8eaef79602d6aab9ed49bc05a9a676f4932a819d Mon Sep 17 00:00:00 2001 From: Anselm Levskaya Date: Sun, 19 Oct 2014 15:24:09 -0700 Subject: [PATCH] Works on modern browsers again by fixing XHR loading of binaries to be asynchronous. --- PCEmulator.js | 2 +- cpux86-ta.js | 159 ++++---------------------------------------------- index.html | 2 +- jslinux.js | 73 ++++++++++++++++++++++- 4 files changed, 83 insertions(+), 153 deletions(-) diff --git a/PCEmulator.js b/PCEmulator.js index 117ae5b..e80cbb9 100644 --- a/PCEmulator.js +++ b/PCEmulator.js @@ -36,7 +36,7 @@ function PCEmulator(params) { cpu.get_hard_intno = this.pic.get_hard_intno.bind(this.pic); } -PCEmulator.prototype.load_binary = function(url, mem8_loc) { return this.cpu.load_binary(url, mem8_loc); }; +PCEmulator.prototype.load_binary = function(binary_array, mem8_loc) { return this.cpu.load_binary(binary_array, mem8_loc); }; PCEmulator.prototype.start = function() { setTimeout(this.timer_func.bind(this), 10); }; diff --git a/cpux86-ta.js b/cpux86-ta.js index 972b3e0..e14cd2e 100644 --- a/cpux86-ta.js +++ b/cpux86-ta.js @@ -9703,154 +9703,17 @@ CPU_X86.prototype.exec = function(N_cycles) { /* - Binary Loaders + Binary Loader ========================================================================================== - These routines load binary files into memory via AJAX. + This routine loads a binary array into memory. */ -CPU_X86.prototype.load_binary_ie9 = function(url, mem8_loc) { - var req, binary_array, len, i; - req = new XMLHttpRequest(); - req.open('GET', url, false); - req.send(null); - if (req.status != 200 && req.status != 0) { - throw "Error while loading " + url; - } - binary_array = new VBArray(req.responseBody).toArray(); - len = binary_array.length; - for (i = 0; i < len; i++) { - this.st8_phys(mem8_loc + i, binary_array[i]); - } - return len; -}; - -CPU_X86.prototype.load_binary = function(url, mem8_loc) { - var req, binary_array, len, i, typed_binary_array, typed_arrays_exist; - if (typeof ActiveXObject == "function") - return this.load_binary_ie9(url, mem8_loc); - req = new XMLHttpRequest(); - req.open('GET', url, false); - typed_arrays_exist = ('ArrayBuffer' in window && 'Uint8Array' in window); - if (typed_arrays_exist && 'mozResponseType' in req) { - req.mozResponseType = 'arraybuffer'; - } else if (typed_arrays_exist && 'responseType' in req) { - req.responseType = 'arraybuffer'; - } else { - req.overrideMimeType('text/plain; charset=x-user-defined'); - typed_arrays_exist = false; - } - req.send(null); - if (req.status != 200 && req.status != 0) { - throw "Error while loading " + url; - } - if (typed_arrays_exist && 'mozResponse' in req) { - binary_array = req.mozResponse; - } else if (typed_arrays_exist && req.mozResponseArrayBuffer) { - binary_array = req.mozResponseArrayBuffer; - } else if ('responseType' in req) { - binary_array = req.response; - } else { - binary_array = req.responseText; - typed_arrays_exist = false; - } - if (typed_arrays_exist) { - len = binary_array.byteLength; - typed_binary_array = new Uint8Array(binary_array, 0, len); - for (i = 0; i < len; i++) { - this.st8_phys(mem8_loc + i, typed_binary_array[i]); - } - } else { - len = binary_array.length; - for (i = 0; i < len; i++) { - this.st8_phys(mem8_loc + i, binary_array.charCodeAt(i)); - } - } - return len; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CPU_X86.prototype.load_binary = function(binary_array, mem8_loc) { + var len, i, typed_binary_array; + len = binary_array.byteLength; + typed_binary_array = new Uint8Array(binary_array, 0, len); + for (i = 0; i < len; i++) { + this.st8_phys(mem8_loc + i, typed_binary_array[i]); + } + return len; +}; \ No newline at end of file diff --git a/index.html b/index.html index 2866b71..564fd10 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,7 @@ } - +
diff --git a/jslinux.js b/jslinux.js index e17be89..a51d491 100644 --- a/jslinux.js +++ b/jslinux.js @@ -50,6 +50,73 @@ function get_boot_time() return (+new Date()) - boot_start_time; } +/* global to hold binary data from async XHR requests */ +var binaries = [false,false,false]; + +function loadbinary(url,slot) { + var req, binary_array, len, typed_arrays_exist; + + req = new XMLHttpRequest(); + + req.open('GET', url, true); + + typed_arrays_exist = ('ArrayBuffer' in window && 'Uint8Array' in window); + if (typed_arrays_exist && 'mozResponseType' in req) { + req.mozResponseType = 'arraybuffer'; + } else if (typed_arrays_exist && 'responseType' in req) { + req.responseType = 'arraybuffer'; + } else { + req.overrideMimeType('text/plain; charset=x-user-defined'); + typed_arrays_exist = false; + } + + req.onerror = function(e) { + throw "Error while loading " + req.statusText; + }; + + req.onload = function (e) { + console.log('onload triggered'); + if (req.readyState === 4) { + if (req.status === 200) { + if (typed_arrays_exist && 'mozResponse' in req) { + binaries[slot] = req.mozResponse; + } else if (typed_arrays_exist && req.mozResponseArrayBuffer) { + binaries[slot] = req.mozResponseArrayBuffer; + } else if ('responseType' in req) { + binaries[slot] = req.response; + } else { + binaries[slot] = req.responseText; + } + //cb_f() + } else { + throw "Error while loading " + url; + } + } + } + + req.send(null); +}; + +function checkbinaries() { + //console.log("checkbinaries: ",(binaries[0]!=false),(binaries[1]!=false),(binaries[2]!=false)); + if((binaries[0] != false) && (binaries[1] != false) && (binaries[2] != false)){ + console.log("...binaries done loading, calling start()") + start(); + } else { + setTimeout(checkbinaries, 500); + } +}; + +function load_binaries() { + console.log("requesting binaries"); + loadbinary("vmlinux-2.6.20.bin", 0); + loadbinary("root.bin", 1); + loadbinary("linuxstart.bin", 2); + + console.log("waiting for binaries to finish loading..."); + checkbinaries(); +} + function start() { var start_addr, initrd_size, params, cmdline_addr; @@ -70,12 +137,12 @@ function start() pc = new PCEmulator(params); - pc.load_binary("vmlinux-2.6.20.bin", 0x00100000); + pc.load_binary(binaries[0], 0x00100000); - initrd_size = pc.load_binary("root.bin", 0x00400000); + initrd_size = pc.load_binary(binaries[1], 0x00400000); start_addr = 0x10000; - pc.load_binary("linuxstart.bin", start_addr); + pc.load_binary(binaries[2], start_addr); /* set the Linux kernel command line */ /* Note: we don't use initramfs because it is not possible to