Suckless chip-8 emu
- 5 Devlogs
- 12 Total hours
(mostly) Suckless Chip-8 emulator built in C using ncurses as its graphics engine
(mostly) Suckless Chip-8 emulator built in C using ncurses as its graphics engine
REWORKED KEYBOARD, ADDED A DIE FUNCTION, ROMS ARE NOW LOADED VIA
TERMINAL, ADDED MACROS, ADDED README
I made the program (i think) as much compliant to the suckless philosophy as i can and did most of (not all of) the stylistic choices mentioned in the suckless style guide. I think making it suckless majorly improved the program
Because i decided i wanted to make the project basically suckless i have decided that i needed to rework the keyboard functions. I replaced the keyboard struct with long long keyboard[16]. The index is now the key and the value is the value that key_pressed compares against when the instrcutions are called. key_pressed returns (now - keypad[k]) < ACCEPTABLE_DISTANCE which made the logic way smaller and easier to read. I also replaced the ~ 60 lines key switch statement with a single array that has all the characters of the Chip-8 keyboard and compares it using strchr with the input ch and the difference between the return value of strchr and the positon of keyboard[0] is the index which the current time is written into
I added a die function that replaces all early exit functions that would kill the entire program. It gets an input string and other parameters (like printf would get) and print it to stderr. It does this by using varargs. If initscr() has been called it also does endwin() and if not it doesnt (a bool is turned to true after initscr() has been called). Because of this read_rom is now void because every error path calls die instead of returning false. fopen also calls strerror if it fails to display WHY fopen has failed
Previously rom names were hardcoded into the program and had to be changed and recompiled if i wanted to change them. Now the program takes in multiple arguments (2 in total, more or less results in an error after which the proper usage is displayed) and the rom (if found) is copied and executed which makes testing multiple programs way easier.
I removed magic number and replaced them with macros to make the code more readable and theoretically modifiable.
I added a README in the repo that explains pretty much everything that you would need to know before using the program
After a long battle with the code i finally figured out how to implement the keyboard without the keys only being picked up every once in a while.
Previously the keyboard was simple a bool array and if i a button was pressed the corresponding part of the keypad array was turned true. The issue with that was that with this simple implementation there had to be one of 2 mandatory pay-offs: Case A would be that the keys would be sticky and never get turned false, Case B would be that they get reset on every iteration of the main loop which is too fast for instructions 0x9E and 0xA1 in certain programs, as they need the value for multiple iterations. Simply holding down the key was actually too slow because of the way holding down a key works on linux which is why i had to do the following implmentation:
Previously 0x8xy6 and 0x8xyE bitshifted chip.v_reg[x] either « 1 or » 1 which i found out was false after rereading the docs because a test code wasnt working properly. The fix was just to implement the correct instruction (chip.v_reg[x] = chip.v_reg[y] « 1 or the same using » 1)
I kinda didnt click post on my last devlog which is why this is a combination of two devlogs but ig this has to suffice
I implemented a rom loader that opens and copies roms (.ch8 files) and then executes their instructions when the program runs. The rom reader opens the file with fopen and reads them into memory using fread once.
I use my (beloved) ncurses for graphics and a function is called every cycle to print out the graphics on the 64x32 screen using either # for spots where the graphic display is true and ’ ’ for spots where it isnt
The keyboard uses getch that doesnt stop the loop but rather just listens for input and then sets the keyboard value of the pressed button to true
The fontset is pretty basic (its just an array of the standard chip-8 fontset that gets loaded into the memory array starting from 0x50)
Ive written some very basic test code for testing purposes. Current functions are printing to the screen, setting variables and printing when a button is pressed. I coded the code in hex and used hexed.it to convert the hex code into .ch8 files
Luckily there where no major bugs previously in the code (there wasnt that much to be buggy) but obviously there where issues on the way to the current code. Because i dont remember everything i fixed on the way i wont list it in todays devlog (overall i just list bugs if they where in a previious commited/devlogged version)
I am building a CHIP-8 CPU emulator in C based on the specifications at http://devernay.free.fr/hacks/chip8/C8TECH10.HTM.
Currently i have implemented all of the regular CHIP-8 instructions that are listed on the source website. They are detected by checking for the specific flags and then execute code based on their variables. There are a total amount of 33 instructions available (normally there are 34 for CHIP-8 but one isn’t used in emulators). Currently the CPU cannot take instructions (will be implemented next probably)
I want to build my own CPU emulator for either a self built or Chip-8 architecture. Im very unsure which direction i want to go right now but i find the idea really interesting which is why i just started doing it. The project will (probably) be written fully in C and i hope that it will be able to run real programs. I hope the project will give me a better insight into how cpus and computers work in general
Currently the CPU can add values to and jump between register and finally terminate itself. The values that are added/subtracted are set before compilation.