MARS MIPS Simulator Lockup Hackfix

If you are attempting to use Missouri State University’s rather excellent MIPS Simulator and IDE, MARS, to develop an application which uses the bundled Keyboard and Display Simulator (though it seems  unlikely that you would be doing so seriously today), you may encounter a sporadic bug where the entire MARS application will lock-up, and you have to end-task it.

I personally encountered this while attempting to make a simple Snake clone just over a year ago, during the Console Development 1 module of my (WIP) BScH Computer Games Programming degree and the University of Derby. At that time me and a friend tore open the MARS .jar in order to probe for the cause of this, and were actually able to implement a little work around. Since posting about this project here and putting a video demonstration up on YouTube, I have been asked several times about how we were able to do this, and rather than repeatedly send out links to the email I originally sent to Ken Vollmar, I thought it might be nice to have a decent guide I can direct people to.

Note that the below instructions cover a quick ‘n’ dirty fix, which may introduce other errors (though I haven’t noticed any). This is why I have elected not to just hand out a new .jar, though I could happily do so under the MIT License. I didn’t then have the know-how to properly dig into the problem, and since lengthly debugging of broken applications is my full-time job right now, I’d rather not do so in my free time.

What You Will Need
Java Tools – Likely an IDE like Eclipse
Archiving Tools – 7Zip or a similar application for looking into the .jars
A copy of MARS.jar

Instructions
I’m going to assume you’re using Eclipse, because that’s all I know, so you may have to dig for some of the options if you’re using something else. I will assume you may never have encountered Eclipse or Java before though. Java is a lot like C#, but Eclipse is a bit different from Visual Studio. If you’re better at Java than me, do please let me know where I’ve done things the hard way round, and feel free skip the easy sections.

As another heads-up, I’m also using Windows, so this experience may be rather different for anyone hailing from the OSX or Linux world (I’m told that the creation of an executable .jar on Linux is free from some of the woes I encountered).

Project Setup
Firstly, create a new folder, open up Eclipse and select this folder as your workspace. I called mine ‘Mars_4_1_Mod’. You then need to create a new project in this workspace (File->New->Java Project). Name your project, and hit ‘Finish’. Note that my JRE is set to JavaSE1-1.7. This setting may be important – I’m not overly familiar with it myself.

Now right-click on the project in the Package Explorer, and select ‘Import’. You want to import the contents of MARS.jar to the project, so select General->Archive File from the dialog, browse to your copy of MARS, and hit ‘Finish. Your Package Explorer should now look something like this.

MARS_01

Finally, you need to make sure that Eclipse can find the source code in the project. To do this, right-click on your project and select ‘Properties’. Go to Java Build Path->Source, click ‘Add Folder’ and select your project root. You can fiddle with exclusions and stuff if you want, but I preferred the shotgun approach for what it’s worth.

The Fix
You should now be able to build and run the project (Run->Run As…->Java Application, select ‘Mars’ and hit ‘OK’). Mars should run normally and freeze as expected. Alternatively, if you run it via Run->Debug As…->Java Application then you will be able to suspend the application from Eclipse when it locks up, and then investigate the lock-up state for yourself from the Debug perspective.

Great, now go to ‘Navigate->Open Type…’ and use it to find your way to KeyboardAndDisplaySimulator.java. Navigate to line 210. It should look like this:

updateMMIOControl(RECEIVER_CONTROL, readyBitCleared(RECEIVER_CONTROL));

This is our culprit – a threading issue, a deadlock caused by this function call and another from AbstractMarsToolAndApplication.java. To implement the workaround as I have, you simply need to replace this line with the following:

//-------------------------------------------------------------------------------------
//This call caused a deadlock sometimes when using the keyboard and display simulator.
//The syncronized block below simply plucks out the necessary call from
//updateMMIOControlAndData, which is where this call would take us in the end.
//-------------------------------------------------------------------------------------
//updateMMIOControl(RECEIVER_CONTROL, readyBitCleared(RECEIVER_CONTROL));
//-------------------------------------------------------------------------------------
synchronized (Globals.memoryAndRegistersLock) {
   try {
      Globals.memory.setRawWord(RECEIVER_CONTROL, 0);
   } catch (AddressErrorException e) {
      e.printStackTrace();
   }
}
//-------------------------------------------------------------------------------------

Now if you run Mars through either Run or Debug you should find that the freeze-up never happens. Feel free to poke around if you want to know more about the original issue – but if you’re just trying to work with Mars for a personal project, this should be good enough.

Bonus
If you’re a student working on a project for your studies you may wish to provide your marking tutor with a copy of your modified MARS application alongside your assembly program. Now, after much pain I DO have a working .jar of this, and I will detail it’s creation beneath in case you run into difficulties as well, though it’s probably stupid because I’m not experienced enough with Java to know what exactly prevented me from doing it the normal way.

In the beginning it seems there are two options – you can export a Runnable .jar from Eclipse (File->Export->Java->Runnable JAR File – make sure to select ‘Package required libraries into generated JAR, ignore the warnings), or you can try running the script, ‘CreateMarsJar.bat’ which should be in the root of your project.

For me at least, the script somehow creates a .jar with the same bug as the original, and the exported ‘Runnable’ .jar…won’t run. The way around this is to make a copy of the original Mars.jar, open both it and your Eclipse-exported jar using 7Zip or a similar application, and copy the ‘mars’ folder (contains the compiled .class files) from your version into the copy of the original, replacing it’s own.Delete your exported jar and run the copy of the original – it should now perform as well as the version you launch from Eclipse.

Thanks and Stuff
Thanks go to my friend Bombpersons, without whom I might not originally have bothered to look into this issue. If you have any further information on this issue, any corrections to the information provided here, or struggles in doing this yourself, please do get in touch.

Advertisements