Created a program to read the binary from NES games, convert it into an Assembly language, and make the CPU read and perform those instructions.
I had to:
Understand the 6502s CPU architecture.
Emulate memory reading and writing.
Emulate the Picture Processing Unit.
Debug low level code.
Test for edge cases in a variety of games.
Use bitwise operations to manipulate bitfields.
Github: https://github.com/barter127/H-NES
Note: This was by no means made by scratch. I used some lovely resources by:
javidx9: https://youtube.com/playlist?list=PLrOv9FMX8xJHqMvSGB_9G9nZZ_4IgteYf&si=bv0OOjsrgRIXWJUN
NESdev Wiki: https://www.nesdev.org/wiki/Nesdev_Wiki
To emulate the CPU, I had to create functions that emulate the 6502 (NES CPU) assembly language that can manipulate values like the program counter, registers, the status bits, and the stack pointer. I then needed to read and convert the binary from the .nes file to the corresponding assembly so the program could run.
I also had to control CPU write access so that it wouldn't write to places it shouldn't whilst knowing the memory addresses to manipulate parts of the system like the Picture Processing Unit and the Audio Processing Unit.
The Picture Processing Unit controls the rendering of the CPU. I had to read the texture data from cartridge memory and store it in Name Tables (used in backgrounds) and Pattern Tables (used for sprites). I also needed to implement memory mirroring which allows memory to be accessed from multiple addresses and is used in rendering to fake paralax in games like Mario and Metroid.
Scanlines and PPU cycles also needed to be accounted for so that behaviour time specific behaviour could be properly carried out. Such as, The Vertical Blank period ,occuring after a frame is drawn, where the PPU can be written to by the CPU but if the CPU tries to write data at any other time major visual glitches will occur.