Screen Shots
NES Specs

MonkeyNES Technical Information

System Timing

Background: The NES operated with a simple timing crystal to control its clock speed. For the NTSC version this speed was 1.7897725MHz and for the PAL version it was 1.773447MHz.

Problem: Under most operating systems you do not have access to anything that can provide detailed information about the time down to the level of 1.79 million ticks per second. In fact in most systems you can get access to about 10ms chunks of time. There are only 100x 10ms time slices in a second and that number clearly falls far short of the 1.79 million that are needed to accurately emulate a system with the clock speed of the NES.

Solution: I created a class called HighResolutionTimer that provides information about how many clock ticks should have gone by at a given clock speed since the last time you asked. This unique approach allows me to maintain the right clock speed within reasonable margins.

Problem: Keeping everything properly synchronized when clock ticks are handed to you in batches of around 28000 instead of one at a time.

Solution: A new batch of cycles is retrieved from the HighResolutionTimer and then the cycles are individually iterated over for each of the components that use them. This forces everything to be properly synchronized allowing for things such as palette hacks and other fancy PPU trickery.

Problem: The above solution presents another interesting problem however. Most of the instructions for the NES CPU require more than one cycle to complete. For that reason most of the time when you hand a cycle to the CPU, it would be jumping the gun to execute the next instruction. This would clearly throw off the precious system wide synchronization.

Solution: The last thing the CPU does when it completes an instruction is a quick calculation to determine how many cycles the next instruction will take. Each time a cycle is handed to the CPU it adds it to the ones it has collected so far. Once the number it has is equal to the number it needs to do the next instruction it executes the instruction. This system maintains synchronization because the instruction still completes when it should have based on cycle counts.