Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
“Holy Grail” Bugs in Emulation, Part 2 (mgba.io)
128 points by MBCook on Aug 27, 2017 | hide | past | favorite | 30 comments


I suspect a lot of these bugs, especially those related to timing, were not intended specifically as anti-piracy/anti-emulation; given that the games are developed for a single platform, it's common that programmers would naturally explore and exploit the full capability of the platform, whether officially documented or otherwise. Relying on instruction, CPU-GPU, and even cartridge access timings is thus perfectly reasonable.

One way to get "perfect" emulation is to completely reverse-engineer the system down to the transistor level, wherein the timing relationships between all the components are revealed. I believe this has been done only for a very small number of game consoles, of which I'm aware of are the Atari VCS/2600[1] and NES[2]. Even a GameBoy hasn't been analysed to this level, much less a GBA or DS.

Also, this: https://trixter.oldskool.org/2015/04/07/8088-mph-we-break-al...

[1] http://blog.visual6502.org/2014/10/atari-2600-simulation.htm...

[2] https://github.com/SourMesen/VisualNes


Yeah some of this do not seem like bugs, but more like devs making full use of their sole and direct access to the hardware while the game is running.

After all, the Nintendo hand held line may well be closer to the NES and C64 than a modern PC or smartphone.

A lovely example of a bug in a game that may as well be intention is a use after free memory bug in the DOS version of SimCity. This went uncaught during development because DOS didn't have the checks in place as modern OSs do. But trying to run it on Windows and you get an error.

So what Microsoft did in the name of backwards compatibility and user friendliness was to program and exception for the SimCity binary.

Similarly the stability of Win9x was kinda compromised by how the cmd window had virtually all the capabilities of DOS. This to the point of being able to poke various BIOS memory areas.


The article is about bugs in emulators, not the games they emulate.


It is more about emulation accuracy than out and out bugs.

It is about how certain games behaves in ways that may or may not be bugs in a strict sense, but still go outside the expected environment set down by the hardware documentation while still functioning on the actual hardware.

So be it cmd in Windows, or Dosbox, if one want to run the unmodified SimCity binary from back then it will have to allow it to access ram after it was freed. Because when it worked back then, but do not work now, where is the incorrect behavior (or bug if you will) actually located?


The goal of an emulator is to reproduce the behaviour of the original machine, whether that behaviour was expected by it's designers is irrelevant. If it can't do so, for whatever reason, then it's a bug as far as I'm concerned.


> One way to get "perfect" emulation is to completely reverse-engineer the system down to the transistor level, wherein the timing relationships between all the components are revealed.

What do you gain with transistor level that you don't alreaady get with RTL level?


RTL level is good enough for digital simulation, but the uninitialized S-DSP with Magical Drop sounds like it depends on analog effects. Transistor level would let you simulate this.


Unfortunately even VisualNES experiences some inaccuracies compared to real hardware. I've only personally found an issue caused by it in one game (Who Framed Roger Rabbit,) and the effect isn't noticeable if you're not looking for it. But it is there.



higan doesn't emulate the SNES down to the transistor level. It's cycle-accurate, but it still runs at full speed on modern PCs. Transistor-level emulation would be maybe orders of magnitude slower.


It didn't occur to me until I was developing a Game Boy Color game to understand just how difficult it would be to create an accurate emulator.

For Infinity (https://news.ycombinator.com/item?id=12291850) we employed a number of tricks, notably changing video parameters mid-render. For example, when walking around on the overworld, the screen looks tilted. This was done by adjusting the camera's X offset after each scanline.

Before this experience, I would have thought all an emulator needs to do is emulate the CPU, and render video frames as fast as possible based on video memory. Instead, the GPU needs to be fully emulated too, drawing pixels from top to bottom and left to right, at exactly the rate expected of real hardware and in sync with the CPU.

Speaking of hardware tricks, one neat thing we discovered during development was that if a cartridge isn't present, then reading from the ROM memory area returned zeros. This was possible to do if your code was running from RAM and could survive a cartridge being taken out while it was running. This only worked with Game Boy Color (and not original Game Boy) because Nintendo removed the safety lock from the power switch. There is actually code in Infinity to do something with this, although it is unfinished. Just another ridiculous thing emulator authors would have to support somehow. :)


The GBC is basically a handheld NES. And changing parameters mid-scanline was a trick on various microcomputers as well (i think it was used on the Amiga to push up the number of colors you could use by swapping the pallette).

And i am not surprised that a non-cartridge would read zeros. I suspect the GB(C) was set up somewhat similar to the C64, where the cartridge connector on the back was basically wired to certain RAM pins on CPU.


What surprised me was that the GBC didn't abruptly crash.

For something as critical as a memory chip going missing I would have expected either an abrupt halt due to inconsistent circuitry, or a halt on the next read to the ROM's addressable memory. That the CPU instructions would gracefully fall back to interpreting memory as zeros was unexpected to me. Although I don't know much about electronics.

Do you think this would work on other consoles, such as the NES? Given how finicky the NES is about the cartridge loading mechanism, I would think that cart removal while a game is running would cause the system to go into that panic mode with the power light flashing.


> The GBC is basically a handheld NES.

Do they just have roughly comparable computational power--or do they actually share some chips?


The GBC is a significantly more powerful machine than an NES, with some caveats around graphical rendering.

The NES is a MOS 6502, the GBC has a weird chip by Sharp that hybridizes a Zilog Z80 and an Intel 8080 clocked about double in Game Boy mode and quadruple in GBC mode. The GBC also has sixteen times more RAM, eight times more VRAM, supports bigger carts (up to a megabit), and twice the palettized colors on screen, albeit with marginally fewer sprites.

Huge difference in hardware--the primary reason the GBC is looked at as being "NES-like" is because of the lateness of its release and the comparative jump to the GBA, which is a recognizably modern ARM environment.


They don't share chips, and the GBC should be much more powerful than the NES.

The NES had a CPU based on the MOS Technology 6502 running at around 1MHz, 2KB of RAM, 2 screens of video tile memory, and 2 sprite layers, with support for 64 sprites, max of 8 per line.

The GBC had a CPU loosely based on a Z80 running at about 4 or 8MHz, 32KB of RAM, smaller resolution, more colors available (and more displayable on-screen at once), fewer sprites (40), but more displayable on one line (10).


> CPU loosely based on a Z80

Emphasis on "loosely". It's a weird thing.

https://realboyemulator.wordpress.com/2013/01/01/the-nintend...


Sorry, i didn't mean it in technical terms.

But as best i understand it, the basic conceptual design of the GB/GBC and the NES is pretty much the same.

Neither device do much if anything without a cartridge inserted. This unlike say a modern game console that have quite elaborate firmware that loads even without any game media present.


Can't speak to the NES, but the GB/GBC definitely has a boot ROM with firmware that remains operable without a cartridge in the system. (The SGB has a different one that shims into the slightly different SGB hardware itself. Also, if you've never read about the SGB, that thing is kind of wacky; it's basically a Game Boy that delegates colorization and, in some games, audio and multiplayer to the Super NES.)

The GB/GBC boot ROM doesn't do as much as even, say, the GBA, but if you're talking "conceptual" about firmware, we're talking about a pretty unbroken line to the current day. (Modern game consoles also have operating systems, but those aren't firmware.)


The Super Game Boy was kind of gimmicky. I remember playing with it at a friend's house.


I had one as a kid. You could tell it was "too fast". Weird stuff.


I never noticed that. But our SNES in Europe ran at different frequencies from the American anyway.


Interesting talk: "The Ultimate Game Boy Talk" at CCC https://media.ccc.de/v/33c3-8029-the_ultimate_game_boy_talk



Given clock speed isn't improving by leaps and bounds, will we get to a point where if becomes fundamentally impossible to emulate certain types of game systems on general purpose computers?


Games for high end computers trivially satisfy this.


They re-compile them though.


Funny that these things are mostly referred to as 'emulator bugs'. It would be more accurate to call them bugs in the game.

It's a bit like the situation with C, where some code depends on a specific outcome of undefined behavior.

With this, I don't mean that the programmer of the game is to blame. If you are developing for a single system, it is reasonable to use some of the properties of this system. In this specific situation, it might even be of interest for Nintendo, since it makes it harder to pirate games.

If one would like to avoid a situation like this, it seems best to develop for an emulator with unreliable properties (the principle of fail-fast: crash and let the developer know that he makes an assumption that is not guaranteed to hold), but which implements the ISA faithfully.


Nah. These are emulators built not to just run the games, but to be have as closely as possible to the real hardware companies were shipping for years.

This means that if a game that worked on actual hardware is not working in emulation, the emulator is no behaving accurately enough compared to the hardware.


> Funny that these things are mostly referred to as 'emulator bugs'. It would be more accurate to call them bugs in the game.

You are missing the point of an emulator: to correctly emulate hardware. Off-label use of the hardware was standard in that era of game development. Failure to support it is an emulator bug.

> it seems best to develop for an emulator with unreliable properties

Those emulators generally did not exist during the commercial lifespan of the system, at least not in any real quantity, and mean giving up on the advantages of the actual behavior of the hardware. Correctness is not as important as performance and fluidity in a console game.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: