3

I'm trying to make a javascript emulator, and i'd like it to be very light, so I don't want to load the "ROMs" with jQuery and jDataView. Si I made my own ROM loader in pure JS.

It works pretty well (thanks to many topics on this site), but there's still a problem on IE, for which I couldn't find any help elsewhere.

Here's my JS code:

/**
* @param file - the path or URL of the ROM file to load. The file must be served with the Mime-Type: 'text/plain; charset=x-user-defined'
* @param callback - a function to call when the loading is complete. Its first parameter contains an array of numbers representing the ROM bytes.
*/
function loadRom(file, callback)
{
  var xhr = new XMLHttpRequest();                             // AJAX loader
  xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){                                  // When the file content is received
      var str = xhr.responseText;                             // Store it as a string
      var ch, bytes = [];
      for (var i = 0; i < str.length; i++){
        ch = str.charCodeAt(i);                               // Read each character
        bytes.push(ch & 0xFF);                                // Store the last byte of the character
      }
      callback(bytes);                                        // Call the callback function with bytes as parameter
    }
  };
  xhr.open("GET", file, true);                                // Load the file
  xhr.send(null);                                             // Send the AJAX request
}

// Test
var mem=[];
loadRom("TEST.ch8", function(m){
  for(i=0;i<m.length;i++)console.log(m[i].toString(16))                 // Log each byte in hexa
});

Here's my .htaccess (the chip8 ROMs have the extension .ch8):

AddType 'text/plain; charset=x-user-defined' ch8

And here's my test ROM (it contains the bytes 0x00 to 0xFF)

http://www.filedropper.com/test_16

Results of the test:

Firefox and Chrome work fine: they log every byte from 0x00 to 0xFF

IE9 does the same, except for the 32 bytes between 0x80 to 0x9F, that are replaced with totally unrelated numbers. ( Even if we compare binary codes, there's no apparent conversion logic )

So my questions are:

  • What does IE9 do with these bytes?
  • How could I fix it?

Thanks for your ideas (or solutions)!

Max.

1

2 Answers 2

1

Have you considered base-64 encoding the data and decoding it on the client-side?

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, I have seen and thought about solutions involving base64 and/or PHP, but i'd like a pure JS solution. Or at least an explanation of what's happening on IE9 for these characters.
You can decode base64 in Javascript. See stackoverflow.com/questions/2820249/… for an example. Still, I am glad you found something that works.
1

I finally found the answer:

  • IE converts these characters, no matter what you do.

  • But it provides a way to export directly the AJAX response in a bytes array, and that's almost cooler than the other browsers

    var bytes = VBArray(xhr.responseBody).toArray(); // Only on IE!

So here's the functionn to convert a file to a bytes array, down to IE7!

function loadRom(path, memory, callback)
{
  var i = 0,                                                                                        // Loop iterator
      ie /*@cc_on=1@*/,                                                                             // IE detection with conditional compilation
      xhr = new XMLHttpRequest;                                                                     // XHR object
  xhr.onreadystatechange = function(){                                                              // When the XHR object state changes
    if(xhr.readyState > 3){                                                                         // When the file is received (readyState 4)
      for(xhr = ie ? VBArray(xhr.responseBody).toArray() : xhr.responseText; i < xhr.length; i++){  // Get the response text as a bytes array (on IE) or a string (on other browsers) and iterate
        memory.push(ie ? xhr[i] : xhr.charCodeAt(i) & 0xFF);                                        // Store in memory the byte (on IE) or the last byte of the character code (on other browsers)
      }
      callback()                                                                                    // Call the callback function
    }
  }
  xhr.open("GET", path);                                                                            // Load the file
  xhr.send()                                                                                        // Send the XHR request
}

1 Comment

VBArray is probably not something you want to use. JS has typed arrays now and they're well supported by the various browsers. See html5rocks.com/en/tutorials/file/xhr2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.