3 ms·
Last year, I wrote a fairly complete Genesis (MegaDrive) emulator in C++, for education purposes, that contains a full VDP emulation. The VDP in Megadrive is th
by giovannibajo1 11y ago
Last year, I wrote a fairly complete Genesis (MegaDrive) emulator in C++, for education purposes, that contains a full VDP emulation. The VDP in Megadrive is the father of the VDPs on Saturn, so you can have a look to see how it works:
https://github.com/rasky/genemu https://github.com/rasky/genemu
The code should be quite easy to read, as I wrote it to be close to what the hardware does, without any additional complexity for optimizations.
- city41 11y agoThanks for this, I'll definitely take a look. I like straightforward emulators for learning how hardware works.
- anonbanker 11y agoIf you're the rasky of PSX emulation fame, thanks for this new emu. Been a fan for years.
- giovannibajo1 11y agoYup that's me, and thanks, I didn't know I had fans :) Another little thing I'm currently working on is a Nintendo DS emulator written 100% in Go: https://github.com/rasky/ndsemu https://github.com/rasky/ndsemu This is very early stage, it boots the BIOS but barely boots any game and they're all very garbled. The nice thing is that I'm emulating graphics fully in parallel with goroutines, so the GPU runs in parallel with CPU. They even potentially access the same memory (VRAM) and I didn't put any mutex/lock there, as theoretically the undefined behavior is similar to what happens in the real hardware... :) I'm curious to see if the strategy pays and I'm able to complete the emulator like this. I'm going to also emulate sound in this way. As for optimizations go, the approach is a little bit different: I had to optimize things here and there to work around (many) Go compiler deficiencies and achieve decent speed. So the code is less "barebone" than Genesis, and that adds up to the fact that the hardware is vastly more complex per-se. I've also factored out generic code in the "emu" sub-package, that is a collection of generic emulation-related classes/packages that could be reused for different emulators in Go.
- voltagex_ 11y agoIs there a (legal) way to try out this emulator? Say, with a homebrew ROM?
- giovannibajo1 11y agoI didn't have time to implement support for homebrew ROMs (in fact, I don't even know how they work -- I'm not into the NDS homebrew scene so I know close to nothing on how they are developed). I would expect at least the BIOS to be needed, maybe the firmware is custom; it is certainly possible to emulate the BIOS via HLE (I know some emulators do it), but I find it a little outside of the scope of my projects. I might get to it, eventually. I also dispute that owning a dump of a game/BIOS of a console you own is illegal, but that's a large discussion for lawyers :)
- mikepavone 11y ago> I wrote it to be close to what the hardware does Your code is quite clean, but I'm not sure I'd say the rendering code is all that close to what the hardware does. For instance, the hardware does sprite rendering in 3 distinct phases (sprite list is scanned for sprites on the current line and the first 20/16 are recorded somewhere, the non-cached half of each of those 20/16 sprites is read and then up to 40/32 tiles worth of pixel data is drawn to the line buffer. Background layer rendering is a bit different too. The VDP actually renders an extra 2 columns worth of background data (so 42 or 34 total) to enable fine scrolling. Rendering takes place 2 columns at a time to what I believe is a 32 pixel ring buffer. The data in the ring buffer is composited with the data in the sprite line buffer as it's output to the display. The "window bug" is just a consequence of the 2 column coarse scroll granularity and the fact that it literally replaces the Plane A draws to the ring buffer. This is not intended as a criticism of your code. If you're only going for scanline granularity, most of the above is of little consequence (apart from the window bug) and would only add complexity. That said, I think my emulator, BlastEm[0], is probably a better reference for low-level VDP behavior as it has access slot granularity and mirrors the behavior above pretty closely. The code has gotten a bit messy though. There's also Exodus[1], which has a quite heavily commented VDP core (a bit too heavily for my taste, but I imagine others may disagree). [0] http://rhope.retrodev.com/files/blastem.html http://rhope.retrodev.com/files/blastem.html [1] https://bitbucket.org/exodusemulator/exodus https://bitbucket.org/exodusemulator/exodus EDIT: Fixed typo "line scrolling" should have ready "fine scrolling in the 3rd paragraph.
- giovannibajo1 11y ago> Your code is quite clean, but I'm not sure I'd say the rendering code is all that close to what the hardware does. OK you're right, what I really meant is that my code is a clear description of the basic hardware features and how they work, at the level of the detail discussed in the blog post being discussed (OP). As you noticed, I'm not emulating anything sub-scanline. If you look at the precise_dma_fifo branch, I've attempted some sub-scanline precision timing, while keeping the rendering at the scanline level. The result is encouraging: for instance, the 512C "your emulator suck" screen in Overdrive correctly works (at least in the PAL version IIRC). I think I hit a limit with the way timing was computed in the CPU cores I was using, and then dropped it for boredom. There were also a few regressions, visible in Overdrive itself (which is almost perfect on master, with the 512C screen being the big exception). > I think my emulator, BlastEm[0] Thanks for the reference, I'll have a look.
- yodsanklai 11y agoVery cool, thanks :)