Live data from Hacker News

Statically Recompiling NES Games into Native Executables with LLVM and Go

andrewkelley.me

81–90 of 103 posts

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#81
post #78
post #77

Please forgive me for the bikeshedding, but I have a quick question as a C novice: Is the equality check in the following necessary? if (foo & 0x80 == 0x80) { I thought if you're checking a bit simply anding would be enough (since everything else would be zeros). In other words, could we just use if (foo & 0x80) { If so, then it seems like this would be the preferred form to avoid the precedence issue presented in th…

I am seeing that as basically defensive coding. Similar to how you may do this: switch (mode) { case FOO: ... break; case BAR: ... break; } Do you need the very last break? Technically no, but including it so that you don't forget it when you need it later can be a good idea. (Also, I think explicitly using comparison operators in conditionals might be the idiomatic thing to do in Go. Someone correct me here if I'm w…

The example was using C, not Go.

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#82
post #80
post #79

Earlier quoted context omitted.

0x80 is 0b01010000. Consider that (foo & 0x80) is (0x16 == 0b00010000) if foo is 0x16. (This may or may not be the intended functionality one way or the other!)

I believe 0x80 is 0b1000000

Oops, did everything in decimal. Good point and correction. Still, the difference in legibility and implications of the two lines of code are important. Modern compilers would optimize ((foo & 0x80) == 0x80) to (foo & 0x80) but leave ((foo & 0x60) == 0x60) alone because it is testing more than one bit.

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#83
post #81
post #78

Earlier quoted context omitted.

I am seeing that as basically defensive coding. Similar to how you may do this: switch (mode) { case FOO: ... break; case BAR: ... break; } Do you need the very last break? Technically no, but including it so that you don't forget it when you need it later can be a good idea. (Also, I think explicitly using comparison operators in conditionals might be the idiomatic thing to do in Go. Someone correct me here if I'm w…

The example was using C, not Go.

Aye, though the same code later appears in Go.

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#84
post #47
post #43

Earlier quoted context omitted.

Why is static pointless and why is dynamic better? If emulating a newer game console, couldn't you get better performance by running a statically recompiled game, since it doesn't have to do the extra work at runtime? Or better yet, couldn't you cross-recompile a game to run it on a platform that couldn't normally handle emulation of the target platform?

Dynamic lets you do lots of nasty tricks, and also lets you detect and work around various nasty tricks at runtime (worst case by falling back to emulation). Consider that old games often would use self-modifying code, for example. Reliably statically detecting self-modifying code can be extremely hard even when it's not intentionally obfuscated. But at runtime it is "easy": Write protect all the code pages, and trap…

[deleted]

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#85
post #67
post #54

Earlier quoted context omitted.

I've looked at this sort of stuff as utter voodoo for a long time. Then I ran into this book[1], and everything just kind of 'clicked' into place in my head. I can't recommend this book often enough. [1]: http://www.nand2tetris.org/book.php In short: It gives you a hands-on approach in designing and building your own computer and programming language, to end up writing and running your own games on the system. * It s…

Might be a good candidate to port to asm.js or even just javascript, there are platforms without Java where this could be a valuable teaching tool.

Not a real port, but I made an HDL as a Python DSL and coded most of the hardware exercises with it. The majority of the work went into emulating their test script interpreter.

Regular Javascript should be plenty fast except for full system simulation with no custom component simulators.

https://github.com/darius/logsim

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#86
post #67
post #54

Earlier quoted context omitted.

I've looked at this sort of stuff as utter voodoo for a long time. Then I ran into this book[1], and everything just kind of 'clicked' into place in my head. I can't recommend this book often enough. [1]: http://www.nand2tetris.org/book.php In short: It gives you a hands-on approach in designing and building your own computer and programming language, to end up writing and running your own games on the system. * It s…

Might be a good candidate to port to asm.js or even just javascript, there are platforms without Java where this could be a valuable teaching tool.

Or, better yet, just port the Java runtime to Javascript...

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#87
post #14

This is interesting. If this project can output LLVM byte code, then you could also codegen to javascript with emscripten and make a web based version of a NES game.

Or, you could just use an emulator written by hand in javascript: http://fir.sh/projects/jsnes

That project's name has always bothered me... My brain tokenizes it as J SNES rather than JS NES.

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#88

Earlier quoted context omitted.

I think it's more than that. It is not yet clear that this approach can work in the general case without emulation: the halting problem may be in the way.

Correct. If you think about it, the program could prompt the user for the address to jump to, and then the program could go there. In fact, that's exactly what some games (accidentally) do: http://tasvideos.org/2341M.html It is impossible to solve this statically. This is why dynamic recompilation is more practical.

Thanks for that link; That hack (and the accompanying video) has just become perhaps my favorite thing, ever. Also, it led me to this similarly incredible hack as well:

http://www.youtube.com/watch?v=D3EvpRHL_vk

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#89
post #37

Earlier quoted context omitted.

See also https://github.com/jsmess/jsmess which is a port of an existing emulator codebase using emscripten

I'm not quite sure what the point of this project is, as MESS is rather slow when built natively [1]. Perhaps some of the lower end systems can be emulated, albeit slowly. [1] http://www.mess.org/faq#it_works_but_it_is_way_too_slow

The point is historical preservation: Putting ancient games and systems on the Web as a way to enable people to experience them, as part of digital museums, online academic papers, and such, to provide some (imperfect) context for what would otherwise be dry technical history. It's in JS because it's the only language that doesn't require plugins, and so has a better-than-average chance of running on a variety of different hardware.

http://jsmess.textfiles.com

http://ascii.textfiles.com/archives/3745

http://archiveteam.org/index.php?title=Javascript_Mess

Re: Statically Recompiling NES Games into Native Executables with LLVM and Go

#90
post #67

Earlier quoted context omitted.

Might be a good candidate to port to asm.js or even just javascript, there are platforms without Java where this could be a valuable teaching tool.

Or, better yet, just port the Java runtime to Javascript...

http://int3.github.io/doppio/about.html

https://github.com/int3/doppio

Post reply on HN