I've rewritten my emulator from scratch, keeping decoupling patterns in mind. Every part of the emulator is isolated and needs the caller to set up callback/hook functions for them to communicate. Not only that, I've also tried other approaches to emulation, namely:
While I've only implemented basic features (no undocumented opcodes, immediate interrupt handling, basic PPU emulation, the same old bad APU emulator), it seems pretty solid. It seems to run tests like scanline.nes more precisely than Nintendulator or FCEUX, for instance. Of course, it could be that either that MY emulator is the wrong one, that the test is broken, or that these emulators just don't care about precise things like that. Well, does anyone happen to know which is the case?
Has there been any other emulator projects using precise instruction/PPU timing like this?
Here's a Windows build.
It will immediately open a file prompt to select a ROM. Press the Letter O key to select another ROM. Controls are Arrow keys = D-Pad, Space = A Button, X = B Button, Enter = Start Button, Ctrl = Select Button. Only working mappers are 0x0 and 0x2 (NROM and UxROM). Some games still freeze for unknown reasons.
Also, here's a peek at the CPU source file. You can see a big switch block taking the instruction cycle as parameter (line 186). Then, for every case, there's another switch taking the instruction addressing mode as parameter (e.g., line 213). When it is the final cycle for an instruction, it branches to yet another switch which handles specific opcode behavior (e.g., line 490 and beyond).
- - The CPU is emulated for every clock tick. Instead of emulating instructions instantly and sleeping on clock timings, I've mimicked the real hardware and emulated every instruction cycle. So, memory reads and writes fall exactly on the clock they're supposed to. I was expecting this to be slow and not cache-friendly, but on my system, it eats just as much CPU time as any other emulators.
- The PPU also runs for every clock tick. No batch-running only when state changes. The PPU alternates execution with the CPU at precise clock timings. Again, this kind of emulation eats just as much CPU time as any other, on my system.
- Also, mappers are also isolated with hook functions, and they mimic real cartridges' pinout. There's the CIRAM Enable and Mirror pins, and they may also receive CPU/PPU reads and writes.
While I've only implemented basic features (no undocumented opcodes, immediate interrupt handling, basic PPU emulation, the same old bad APU emulator), it seems pretty solid. It seems to run tests like scanline.nes more precisely than Nintendulator or FCEUX, for instance. Of course, it could be that either that MY emulator is the wrong one, that the test is broken, or that these emulators just don't care about precise things like that. Well, does anyone happen to know which is the case?
Has there been any other emulator projects using precise instruction/PPU timing like this?
Here's a Windows build.
It will immediately open a file prompt to select a ROM. Press the Letter O key to select another ROM. Controls are Arrow keys = D-Pad, Space = A Button, X = B Button, Enter = Start Button, Ctrl = Select Button. Only working mappers are 0x0 and 0x2 (NROM and UxROM). Some games still freeze for unknown reasons.
Also, here's a peek at the CPU source file. You can see a big switch block taking the instruction cycle as parameter (line 186). Then, for every case, there's another switch taking the instruction addressing mode as parameter (e.g., line 213). When it is the final cycle for an instruction, it branches to yet another switch which handles specific opcode behavior (e.g., line 490 and beyond).