A Chip 8 interpreter
My first emulator project.
I have tried to make this project as verbose as possible as it is a learning project. My goal is to write an NES emulator using the knowledge I have gained from this venture.
To install, navigate to root folder of project and enter the command:make
If you want to print the opcodes to the terminal during execution, build with command: make DF=1
-
Usage: ./chip8 roms/ROMNAME
-
Currently the emulator seems to run games with no issues. I have set the opcode execution speed to 1000 fps as I find the games run a little better at this speed. However, you can still set the fps manually with the -f flag when launching. Used as ./chip8 romName -f fps
-
The default window size for the emulator is 960x480 (15x scale of the original 64x32 resolution). You can also manually set the scale with the -v flag from 1-30, 1 being 64x32 and 32 being 1920x960. Used as ./chip8 romName -v scale
-
The default window background colour is black but can now be set using the command line. Used as ./chip8 romName -b colourstring
-
The default sprite colour is white but can now be set using the command line. Used as ./chip8 romName -s colourstring
-
The emulator speed can be increased and decreased using the keypad plus and minus keys. Each SDL poll event of the key down changes the frames per second value by +- 100
-
Emulation can be paused using the backspace key. This pauses cpu execution and rendering of the screen. Event polling must remain live as a second backspace key press un-pauses the emulation.
-
A ROM can be restarted by pressing the F1 key. This sets the memory, register and display pixel values back to how they were at the initial loading of the ROM.
-
Sound implemented as a printf("\a") currently. I will eventually upgrade to SDL audio to make the emulator more portable.
-
Finally, I plan to clean up the code a little bit better; remove use of global variables and remove unused functions/checks that were previously used tot debug. I tried to do this already and for example, pass the display buffer as a pointer but for reasons beyond my current understanding, performance took a drastic penalty, running at what I could visually estimate as about 60fps even at frame rate settings 1000 or higher.
- Fixed ADD-VxVy to accurately set V[F] flag
- Fixed Rom load to read file as binary
- Added program to create rom files (no error checking)
- Added getopt loop to set framerate, window size and instruction step mode via cmd args
- Moved loading of rom to cpu init
- Edited makefile so object files are created and stored in directory objs
- Fixed bug that caused V[x] to compare to kk instead of being set to it
- Fixed bug that cause sprites to be drawn flipped. While setting pixelOn, shift (7-x) bits right instead of x bits
- Implemented keyboard inputs
- Changed standard framerate from 60 to 1000 as 60 produced a very slow game
- Changed makefile so that if option DF=1 is used, Debug flag is set and opcodes are printed during execution.
- Fixed cpu function that loads values from I into V0-Vx. Was causing bug in pong where right player score would not be drawn
- Put input event and draw screen loops into separate threads to increase performance
- Fixed SHL-Vx function as it was always evaluating as false
- Initialized each SDL component separately and safely close them at program exit.
- Created new makefile with -Ofast flags to cut down size of built program and boost performance
- Can now be run by setting makefile option DF=1, allowing for debug statements to be printed to console during execution
- Reorganized code
- Implemented a pause game feature by pressing backspace.
- Implemented a reset rom feature by pressing F1
- Implemented control of game speed with keypad plus (increase) and keypad minus (decrease)
- Fixed getopt loop to correctly process arguments
- Added the ability to change sprite and background colours using the flags -s and -b respectively followed by the colour in lowercase.
- Added audio support via the std function printf "\a" console beep
- Created a separate thread to handle audio
- Adjusted RET and CALL opcode functions to set PC properly
- Added updateDT/ST functions to decrement the timers
- Initialized DT and ST to 0 in cpu_init as initializing to 0xFF was incorrect for Emulation
- Decremented DT at 60hz instead of at the cpu execution rate. Fixed issues in Tetris/Invaders where the sprites would not move down the Y-axis in game.
- Moved thread functions to respective component files
- Set up delay times as constants