5 ms·
The traditional way of coding a console emulator was to figure out the time interval to the next interrupt in units of CPU cycles, emulate enough instructions t
by 0xcde4c3db 10y ago
The traditional way of coding a console emulator was to figure out the time interval to the next interrupt in units of CPU cycles, emulate enough instructions to cross that threshold, then emulate the interrupt and hook other routines (redrawing the screen, filling sound output buffers, reading input, etc.) off of those events (see e.g. Marat Fayzullin's classic Emulator HOWTO [1]). This approach runs a lot of stuff just fine because it does synchronize to the most important events, but can cause problems. For example, "well-behaved" code generally only writes to graphics registers or sprite tables during blanking periods, as writing during active display is usually undefined behavior. Some code breaks the rules. Sometimes this is done intentionally to do cool effects with the hardware. Other times it's a side effect of a bug that wasn't caught because there are coincidentally no symptoms with the timing of the actual hardware. But then you plug it into an emulator with only roughly accurate timing and it blows up.
In reality, the clocks for the various components don't necessarily run at the same rate, or even at integer multiples of the CPU clock. You can have a situation where, for example, there are 3.5 clock cycles on the graphics hardware for every one CPU clock cycle. For a lot of the classic systems, this happened because a single higher master clock is divided down for each component.
A "cycle-accurate" emulator is one that operates as if the emulated state of all hardware were updated on every tick of the master clock. This wasn't generally done in the past because it was far too slow ~20 years ago when emulation of classic consoles and computers really took off.
More sophisticated hardware doesn't necessarily have any single master clock in this sense, so it doesn't make much sense to talk about a "cycle-accurate" emulator of a modern PC, for example.
[1] http://fms.komkon.org/EMUL8/HOWTO.html http://fms.komkon.org/EMUL8/HOWTO.html
- colanderman 10y agoI played around with this in my own NES emulator, which works roughly the way you describe. I found that, at least for major-brand titles (Mario/Zelda/Metroid/Kirby), cycle accuracy actually doesn't matter. Everything's based off PPU/APU/mapper interrupts. In fact, doubling (or more) the CPU clock enhanced some of the games I tried. Animations in Kirby's Adventure became more smooth (e.g. the Spark ability). Screens full of enemies in Metroid ran with no slowdown. The glitchy first scanline of status overlays in various games cleared up. I haven't yet observed negative effects in major-party titles. I had designed my emulator as an experiment: treat the NES as an abstract specification, rather than a concrete implementation. Turns out that a lot of games seem to have actually been designed following the same principle. It was a wonderful feeling to see these games as I imagine they were intended to be experienced, as if I opened a letter from the game designers left unopened for thirty years.
- makomk 10y agoBear in mind that sometimes, people want to do tricks that depend on the slowdowns and glitches that happen on real hardware.
- emodendroket 10y agoAnd in fact some games won't work without them. http://arstechnica.com/gaming/2011/08/accuracy-takes-power-one-mans-3ghz-quest-to-build-a-perfect-snes-emulator/ http://arstechnica.com/gaming/2011/08/accuracy-takes-power-o...
- colanderman 10y agoI'm sure. That wasn't the point of my experiment.
- emodendroket 10y agoYeah, every emulator is pretty much going to be fine with Mario, Zelda, and Kirby, but that isn't really the point.
- colanderman 10y agoIn my case it was.
- emodendroket 10y agoI guess what I mean to say is that someone endeavoring to write a cycle-accurate emulator wants every game to work exactly like it did originally regardless of what bizarre hardware-specific hacks it relies on. For someone who just wants to play any of the top 20 most popular games on a system and isn't too concerned with minor deviations pretty much any emulator is going to suit their needs (in fact it's a common model to have hacks in the emulator just to make a particular popular game work right).
- Narishma 10y ago> It was a wonderful feeling to see these games as I imagine they were intended to be experienced Did you mean the way they were not intended to be experienced? Otherwise it doesn't make sense. The way they were intended to be experienced is on a real console connected to a CRT TV.
- blt 10y agoIt seems like the "cycle-accurate" emulator would be a lot easier to write, is this true?
- andreaorru 10y agoI'm the author. I disagree with this statement. It takes a considerable amount of effort and research to reach cycle-accuracy, especially on the PPU side. Understanding how the PPU pipeline works will take you more time than everything else. If you settle for frame-based emulation you can write the functions to emulate the opcodes without worrying about the order and duration of the internal operations. Once the opcode is emulated, you just add cycles to a global counter based on a table that contains the number of cycles per instruction. After 29781 cycles (you may end up being a little off each time, if you are not cycle-accurate), you call a function to update the state of the PPU. There you can use familiar iterative constructs to perform the rendering. Compare this with the state machine approach in my code (ppu.cpp) and how much more careful I have to be composing microinstructions to form opcodes (cpu.cpp). I came up with a (I think) clean design but it wasn't trivial.
- 0xcde4c3db 10y agoI've only actually written one in the classic style. I doubt that cycle-accurate is easier in general. It definitely isn't if you count the effort that goes into discovering the timing information by running experiments on the original hardware. If you start with everything documented, I guess it might be the least effort needed to bridge the gap between 99.5% compatibility and 100%.
- userbinator 10y agoMore sophisticated hardware doesn't necessarily have any single master clock in this sense, so it doesn't make much sense to talk about a "cycle-accurate" emulator of a modern PC, for example. Even in a modern PC, many of the clocks are divided down using PLLs which maintain a fixed frequency and phase ratio, so it is theoretically possible to make such an accurate emulator, but it would be difficult to write and many orders of magnitude slower than the real hardware. For an example of PC software which doesn't run correctly on anything but real hardware or really accurate cycle-emulation, see this amazing demo: https://trixter.oldskool.org/2015/04/07/8088-mph-we-break-all-your-emulators/ https://trixter.oldskool.org/2015/04/07/8088-mph-we-break-al...