JHack - convert Hack VM code to Java bytecode

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

JHack - convert Hack VM code to Java bytecode

Teledar
I modified my VM translator to convert Hack VM code to a Java class file. Now I can run my Hack programs on the JVM. Stuff runs way faster! The Pong game is currently too fast to play.

https://github.com/Teledar/JHack
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Renslay
I want to try this on my own Jack program, but I'm not familiar with Java. I assume I first have to convert all the .java files to .class files by using JDK's javac command. but if I do this in the JHack folder:

javac *.java

I get 169 errors. If I do only this:

javac HackApplication.java

This the result:

HackApplication.java:31: error: missing return statement
    }
    ^
1 error

Am I doing something wrong? (I'm using Windows 10, javac 16.0.2)
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
I see that he is using the Apache commons lib. Ideally you would add it with a build automation tool like Maven. Also since there is no module-info file, it seems the code could be based on an older Java standard? Perhaps that requires parameters for javac to be set accordingly.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
Right, I'm using Apache BCEL to generate the bytecode, and Maven to handle the dependency. This is the first time I've used Maven or GitHub, so I'm still figuring stuff out.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
In reply to this post by Renslay
The project requires the Apache BCEL library, which I should have mentioned in the readme. I'll see if I can create a JAR file to make the project easier to use.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Renslay
This post was updated on .
In reply to this post by Teledar
Meanwhile, I have another question. I noticed that certain system constants in the provided java files follow the Hack computer architecture, such as the SCREEN and KBD constants, the maximum number of statics, and so on. I assume there is a limit on ram/rom size.

The Jack language itself does not define limitations, but the Jack (more precisely, the VM) compilation to the Hack machine does have a limit on ram/rom size, number of static variables, and so on.

I want to run a Jack program that is bigger in terms of rom than what the Hack computer allows. It uses about 120 static variables, which should be fine, but I'm also not sure about the ram usage.

Will I be able to compile my program to Java; and if not, can I modify the provided java files in a trivial way to make it work?
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
Yes, the RAM size is currently set to 24577. You can increase it by modifying the initram() function in JHack.java. However, JHack doesn't support more than 32768 addresses, because every math operation gets truncated to a short integer internally.

You can also use the RAM addresses from 0 to 2048 - the JVM handles the stack, and I implemented static variables in a separate array, so these addresses aren't being used.

I uploaded a JAR file for VMtoClass that includes all the dependencies. You can run it with java -jar.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Renslay
This post was updated on .
In reply to this post by Teledar
I managed to make it work, but it seems to be buggy with the display.

For testing purposes, this is the result of N2T's own Square game (using N2T's JackCompiler.bat to create the .vm files) with the N2T's own provided OS vm files; so I am quite certain that the problem is not in these files.

Here is the result I see:



And if I increase the size of the square:



Also, though this is just a minor inconvenience: instead of pressing the x (or y or q) key on the keyboard, I have to use shift-x or capslock + x. Also-also, pressing Q does not close the program, but freezes it.

Any idea for this weird visual bug? Moving the window itself does not solve it, so it's not like a buffering issue. I think. It seems to be consistent, with every run it looks the same, and with every size change it the visual bug changes the same way.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Renslay
I just realized that this problem also stands on your side, since the chess image you provided on the github page seem to have this very same graphical issue:

Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
The original tool suite took the decision to convert keyboard inputs to capital letters. That's a design decision for the emulator, probably taken to simplify things?! The Hack platform theoretically supports lowercase inputs as well, so I find it a more accurate emulation if that is possible. In my own emulator I added an option to switch between both behaviours.

Regarding the screen: this is linked to scaling with odd scaling factors (i.e. 125%). You can simply start the application with an additional parameter (-Dsun.java2d.uiScale=1.0) to fix this as described here:
http://nand2tetris-questions-and-answers-forum.52.s1.nabble.com/Screen-display-issue-CPUEmulator-tp4037443p4037465.html

Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
Thanks for the graphics fix! I wasn't sure how to approach the issue, other than switch to a different GUI like JavaFX. I found that using a scale factor of 2.0 instead of 1.0 makes the display larger without annoying gaps.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
In reply to this post by Renslay
I wanted to be able to input lowercase letters as well as uppercase. If you'd like the input to default to uppercase, you can just modify line 12 of JHack.java to set "Caps Lock" on by default:

private boolean caps_lock = true;
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Renslay
In reply to this post by Teledar
I finally did it!

I converted my raytracer (together with my own OS) into Java. The OS has about 3900 vm instructions, and it is a bit optimized compared to what the lectures contain (but not super optimized... I would say it's comparable with the provided OS in size and speed).

The raytracer has ~4700 vm instructions.



The rendertime was quite fast, almost exactly one hour. On the N2T's VMEmulator it ran for nearly 10 hours WITH the VMEmulator's built-in OS (instead of the using vm files for the OS).

It ran without any issues, and I didn't have to change any of the pre-defined constants on the Java side.

(Shameless promotion here)
https://github.com/HantosNorbert/Raymarching-in-Jack
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
Cool!
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
In reply to this post by Renslay
Interesting approach. I would have expected much higher speed though, given that the JIT compilation of the JVM should reach native speed. Anyway, I have now at least published the binary version of my Hack CPU emulator (not VM, so it emulates .asm or .hack files). Feel free to play around with it. I'll publish the source code hopefully sometime after Christmas. Your raytracer runs much faster with the translated binaries as posted in your original raytracer thread, which is somehow surprising.

https://github.com/axelkern/hackemulator

Just launch the batch file or start the jar with java -jar. Once you have loaded the ROM, you can speed it up with Ctrl-C (or you do it while running the emulation, it will compile in the background and boost when ready). There are a couple of features in the menu, mostly self-explanatory. To make the profiler useful, you should load .asm files. It works with .hack files as well, but has no symbols then.

Let me know if you run into any issues.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

WBahn
Administrator
@dolomiti7: I'm curious about your CPU emulator. Does it emulate the (natural) ALU implementation, or just the 28 defined Hack instructions?
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
In reply to this post by dolomiti7
Btw, there is no need to set the scaling factor for my emulator. As a standard it ignores the OS scaling and everything can be set via the menus. With a proper rendering setting (set to bicubic in the menu), you can basically adjust the screen size as you wish while maintaining quality, even with a different aspect ratio.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
In reply to this post by WBahn
It has an option in the source code to switch to a logic gate based emulation in interpreter mode, but the standard is just limited to the defined instruction set. In compilation mode I haven't added any support, though it would be relatively simple to add.
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

dolomiti7
In reply to this post by Renslay
Interesting to see that Chess seems to run without modifications. I would have expected that it crashes due to lack of heap memory (charset etc occupying too much). Did you adjust anything in your OS or in the emulator?
Reply | Threaded
Open this post in threaded view
|

Re: JHack - convert Hack VM code to Java bytecode

Teledar
I had to use the first 2048 addresses of the RAM to get enough heap for Chess. (Stack is managed by the JVM, so these addresses aren't used by the system in my implementation.) Of course, I had to modify my OS memory management to include these addresses in the heap.

I also changed my OS heap management to use only one register as overhead per block, instead of two. I can't remember if this was necessary to get Chess to run.