Sunday, 22 November 2015

Creating an NES Emulator From Scratch Part 3: CPU Complete!

We have completed the CPU portion of our emulator. Yay! :D
Well, it was completed a while ago, but I've been so busy with school I haven't had time to write about it. I still don't really, but I'm going to update anyway. Here is what I've been up to.

Finishing and Testing Opcodes
Since my last update I was working on building the instructions for the various opcodes. After writing them I decided to try out nestest.nes - a rom designed to help programmers of emulators debug their code. Conveniently, this was possible even without any PPU - By comparing my output to a known-good log from another emulator called Nintendulator, I was able to correct some glitches in how I was addressing memory as well as fixing some instructions to work properly.

Implementing Details
Before the CPU was ready to be called 'done', I needed to implement some final touches so that it would be accurate and ready for a PPU. These details included memory mirroring (which for some reason I had neglected until now), cycle counting (making sure each instruction took as long or as short as it was supposed to) as well as a few smaller things

Added a Configuration File
Do you like recompiling every time you want to change games? Me neither! Cartridge path, number of cycles to perform, as well as execution start address override (mostly for nestest.nes which required 0xc000 rather than whatever was stored at the reset vector) have been placed into a nice config file.

I also reworked the output screens a bit and cleaned up and documented a lot of the code.

Further Improvements.
With that the CPU is "complete". I say it with quotes because there is so much that can be improved. While cleaning up the code I stuck in probably a dozen different //TODO notes. The most significant improvement I believe is to remove ALL string operations. There are A LOT of string operations in the code - Opcodes and addressmodes get assigned a string, and is compared in several dozen if statements every single cycle. Changing these strings to enums or structs would probably result in a massive performance boost. However, I want to move on to the PPU first to see how it performs, then come back to this.

Next Step: PPU
I said I would write a post about the CPU before I started on the PPU, but I lied. I actually did quite a lot of research on the PPU and started the code in a new github branch. The graphics of ALIAneS will be powered by SDL. I've successfully created a window and drawn random pixels to it each cycle, and I estimate I'm 5 hours of coding away from displaying the first graphics from the screen - as primitive as they may be. I'll talk more about the PPU in another post.

My exams are in 2 weeks, and I'm done the school term in about 3-4 weeks. After that point I'll get back into this project more full-time.
 

No comments:

Post a Comment