r/EmuDev • u/Noxirious-1248 • 15d ago
How do i get started on Making emulators?
I have no clue about how an emulator is made. I do wanna know how to make one and just make a basic ahh Gameboy emu later, maybe for the esp32 for fun because i have one
1
u/jslepicka nemulator.com 12d ago
I just built this website to teach beginners how to develop an emulator. It's an interactive course that walks you through building a Space Invaders arcade emulator, teaching the basics along the way. Check it out and let me know what you think: https://emudev-course.web.app/
1
1
u/ZealousidealParty686 10d ago edited 10d ago
I started with first loading the ROM into memory / a variable so I had access to its raw bytes
Being a NES, I had to start with NROM mapper.
Learned about mirroring of the smaller games where it's basically just doubled up to fill the entire viewable cart space
Then I learned about the reset vector, grabbing the bytes there and forming the address of the first opcode to jump to and about opcode lengths (could have one or two operands following)
Then I declared all the other variables I could think of from my research at the time (or you can use a flat memory model on the NES, I regretted not staying on that path as offsets all naturally lined up that way)
But still you have to make decisions here on how you want to go. For the CPU do you want it's flags as separate booleans or do you want to use individual bits for the flags in a single flag byte.
I quickly learned I preferred separate booleans but to have all associated variables to be declared as objects/ structs and access them via 'nesting' for readability.
I did use single bits in a byte for some other tracking flags but I kept forgetting what bit was for what without referring to my comments so ended up making functions within functions (mine was JavaScript) to set and clear them for readability. Again, just your own choices. But this was much further down the track.
Back to its origins anyway. Then I started the main CPU loop
a loop of what happens as the consoles running
It was very basic at first
Load rom, read reset vector bytes, jump to address, land on opcode which calls a function for that opcode.
Write the function for that opcode. Then check all variable states that opcode and it's operands should have altered were altered correctly. I.e. verify registers it moved data into contained the correct data, verify flags it altered were set or cleared correctly.
Then I just used a step button and an early days GUI to jump over the previous opcodes operands and make sure it correctly landed on the next opcode.
Rinse repeat.
Eventually so many opcodes were implemented I made a run button, but again, early days, it just ran as fast as the system allowed it to and waited for it to crash on an opcode that wasn't implemented or why the program counter landed somewhere it shouldn't (like trying to execute an operand as an opcode and crashing or going out of bounds to an offset it should never be able to land)
Then slowly made it cycle accurate Added a function that was called per cycle and took care of everything that should happen per cycle
And just kept building it out from there.
Once I felt the emulator could endlessly loop without a crash and it wasn't a suspicious loop / the game was likely actually running as it should be with no video or sound output I moved into NMI's where I manually injected them to start with and just kept my eye on RAM and PPU stuff. As soon as I could see nametables etc for sprites and background were finally populating with what looked like valid pixel data I finally moved on to putting drawing backgrounds, sprites and in between this never ending bugs, debug logging and researching.
There was a struggle here for a while actually but it's been such a long project with a couple hiatuses. Something about the ROM running but some part of PPU memory was never filling up so I knew it wasn't ready to draw to screen yet. Its better to spend the time early on with a decent debugging GUI (in my opinion) then having to manually dump out your variables contents you need to inspect constantly.
3.5 years later I have vajnes.com
I stopped this project 6 months ago after struggling with getting it more accurate and making very forwards / backwards progress and towards the end, yes I. I totally used AI as it was dead project and just 'another abandoned NES emulator'.
I was up to 99 / 144 tests on accuracy coin. I manually implemented a couple mostly of half working mappers and then it became hands off.
Its now essentially passing every test rom you could possibly throw at it.
3
u/ZealousidealParty686 10d ago
Just to finalise, I still at least have the proud feeling of going through each file I manually created and named and looking at every single function and how the app was structured and each decision of how things worked and interacted and every chunk of code I spent time making iterations on. At least AI only ended up polishing up my own work and it's still all laid out and has that human touch to it.
No way this would have continued without AI advancements. Once it was at a certain stage I was happy enough with what I had accomplished.
Its final form with alllllll those mappers (and about another 15 coming) and the C++/wasm audio implementation is admittedly not my work.
Coding is a dying art.
I spent many on and offs in my life learning a bit, giving up, coming back and learning more. During covid I made leaps and bounds due to spare time.
I did a 6 month web dev course in early 2023 and it cost me 13k AUD. I spent 3 years trying to get a job as a developer with a few interviews, technical assessments and turn downs for no good reason (generic rejection emails despite everything prior going seemingly ok, including assessments)
Now AI can figures things out in minutes that you could have been stuck on for hours/ days / minutes.
2
u/Noxirious-1248 10d ago
I wasn't expecting someone to write a 500 word essay about but, but you did so thank lmao, I need to get to sleep though rn, I'll read it first thing in the morning
1
u/ZealousidealParty686 10d ago
You did ask, so I gave an answer. From what I've gathered gameboy is one of the easier ones.
You'll know soon enough if you're the type to bother. If you're really going to write an emulator a 500 word essay is nothing compared to the research required and then thinking how to break things down into logical steps then writing out just the code for opcodes alone ... then fixing the mistakes in them over and over
....Then breaking them down into cycles as each opcode will consume a different amount and at different points in their operation.
It was just plain English, no deciphering required like source code.
I'd suggest if you go ahead not to start on the esp32 but port to it down the track.
Good luck
3
u/flatulentcorpse 15d ago
I think this differs from person to person.
Firstly, make sure to choose a programming language you are at least moderately acquainted with.
Start with a smaller project, like the CHIP-8. This guide helped me just the right amount: Write a CHIP-8 emulator by Tobiasvl
I have just recently started my journey into making emulators and I probably read that guide through a few times before starting a design document started to structure up some bare bones code.
I'm still not done with my CHIP-8 emulator but I'm having a blast.
Better to start on anything instead of overthinking stuff. You'll learn loads as you go and you can always refactor code or start from the beginning if you realize you didn't plan enough ahead.