Nick Massey on Monday, September 12, 2011
I did the math and realized that it has been AGES since I last made a new post and it just so happens that I have made a ton of changes to my NES emulator so I figured I should throw something up here summarizing what I've done. To start off I decided to emulate all the dummy reads 6502 operations tend to do; dummy reads are extra addresses that the CPU reads from that are quite unrelated to the operation at hand. They are very forgettable and hardly worth emulating as only like 2 games will fail without them, however once I had every individual read/write emulated I could then just treat them all as 1 cycle instead of just treating instructions as 2 - 7 cycle chunks. This allows me to run the other components (APU, PPU, Mappers) at a much finer grain improving timing all around. Once I had this done I was able to fine tune my PPU timing and get it passing almost every test there is. Thanks to the more accurate PPU I can now run the notoriously picky Battletoads absolutely perfectly along with almost every other game out there. If I disregard mapper bugs, which I really don't care about outside the 4 or 5 major mappers, there is only one game I can think of that fails to run which pleases me greatly.
Super Mario Bros. 3 is objectively the BEST NES game and runs flawlessly.
After getting the timing all spruced up I went on a bit of a bug hunting spree and managed to fix some pretty big ones. I was unable to run Galaxian or Qix for over a year despite them once working perfectly, these weren't very demanding games so this bug really bothered me but once I sat down and poured over some trace logs I was able to fix it. I also fixed a bug I had accidently introduced when trying to emulate the I flag latency that was causing some pretty big scrolling errors with a lot of MMC 3 games. My MMC3 mapper had a big over sight that was causing a decent percentage of the MMC3 titles to fail to boot, while fixing this I gave my MMC3 code a much needed cleanup. And perhaps most pleasingly I fixed a bug that I had in the DMC channel that introduced a ton of clicking in games such as Kirby and really made my emulator sound quite sloppy. Once I started running out of bugs to fix I decided to do a slight overhaul of the APU which hadn't been cleaned up once since I initially wrote the thing, it was really a big mess all sitting in one file that was by far the largest of the emulation core. As I was moving all the separate NES audio channels into their own classes I decided to have a go at supporting the external audio channels that NES cartridges could provide. Not counting FDS titles, probably only 2% of games actually used this ability and they were all Japanese titles as the European and American Nintendo couldn't even use external sound. I added the FME-7, Namco 163, Konami VRC6, MMC5, and FDS sound chips so now the only one I am missing is the Konami VRC7 which was only used by one game and is wildly complicated and a completely different breed then the others. I however hope I can support it eventually as these sound chips really are excellent and can make some amazing sounding music and sound effects; previously I had no idea that the Japanese version of Castlevania 3 (using the VRC6 chip) sounded SO much better than its American counterpart. I also added some features outside of the emulation core to improve my quality of life while working on it. The debugger now gives a fair bit more information and has far more useful breakpoints, you can now use the interface to select what add-on is plugged into the expansion port of the NES, and I now have a way of kinda-sorta dumping video so I no longer need to use Fraps to get videos for this blog. I really didn't want to have to bundle a large project like FFmpeg just to dump a video once every six months so instead I quickly whipped up something to dump frames as bitmaps (which could also allow pixel perfect screen caps), combined that with the wav file dumper I already had, and then had it automatically produce an AviSynth script that mixes it all together. The AviSynth script can easily be transcoded like any other media format for distribution or for uploading to YouTube and gives me a completely lossless source to transcode from. With all that done it seems that the thing I need to work on in the future will be improving my APU timing, as of right now it tends to be within one or two cycles of being perfect but that really is not enough. Once I that out of the way I'll probably get Sprite and DMC DMA timing down along with interrupts interrupting interrupts, this stuff is really quite finicky and I don't know anything outside of test ROMs that rely on it but I just can't reduce the urge of increasing accuracy.
Nick Massey on Wednesday, April 13, 2011
I've been pressing on with my work on Emu-o-Tron, and it is about time for me to post an update. I have made the video and sound processing systems far more modular, so now instead of being forced to use DirectX 9 and Xaudio2 you can choose between DirectX9, DirectX10, GDI, OpenGL, Xaudio2, DirectSound, and OpenAL. The big upside to this is that Emu-o-Tron can now be run with Mono on Mac and Linux systems with full sound and video support which is all kinds awesome. The other big big BIG change since I last posted is that I have finally added a cycle-based PPU. Previously when emulating the NES video I would render entire scanlines at a time which is fine for the vast majority of games, but when a game tries to make changes that last for less than one scanline you can get some graphical glitches. With my cycle-based PPU every pixel is rendered individually, though this can have quite the performance cost (runs at about half the speed now, though still easily manages the 60FPS required even on my craptop). A game that really demonstrates the difference in PPUs is Rad Racer, here is a screenshot with the old PPU and below is a video of it running with the cycle PPU.
Rad Racer with cycle-based PPU.
I have decided to keep developing my scanline PPU in parallel to the new one for platforms where speed is a priority over accuracy like my Silverlight emu or if I were to decide to make a Win Phone 7 port. There is still going to be quite a long period of tiny accuracy tweaks (mostly timing related) to the new PPU before I'm really happy with it, but at least I have finally gotten over the big hurdle of initially writing it. Another fun little thing I have implemented is proper NSF playback support, even has a simple little GUI for displaying the NSF meta information. That covers pretty much all the major changes since I last posted, hopefully I will stay pretty motivated and will have another new blog post shortly.
Nick Massey on Monday, February 14, 2011
My fascination with emulation has still not petered out and I am still making the occasional progress. My Nintendo emulator now supports basically a bijillion different mappers and is a bit faster, although I still have not gotten around to creating a pixel accurate PPU so the accuracy has really remained unchanged. While I was working on speed optimizations I had noticed that the Silverlight build of it had not been compiled with the optimize flag, now that I remedied that it is actually pretty playable but the UI is still very lacking. You can check out the latest Silverlight version here. About a week ago I started working on a Gameboy emulator for a bit of fun, I have temporarily titled it GB-o-Tron. I intended my GB emu to be an extremely short project without super concern for accuracy or a GUI of any type, I just wanted to get some knowledge of another platform so that I can make educated comparisons with the NES I know and love. Just being able to run Pokemon Yellow without sound was my initial goal, and now in only a week I've accomplished that.
Wario Land II (an awesome game) running in Super Gameboy mode
GB-o-Tron currently supports the Classic Gameboy, the Gameboy Color, and the Super Gameboy, and can actually play a fairly large percentage of games glitch free. Working with the Gameboy instead of the NES has been quite an enlightening experience, the Gameboy has been trivial to emulate compared to the NES despite the NES having a very active and helpful community with endless documentation. Basically all my Gameboy knowledge has come from a single document written by nocash (you can check it out here
) and a few glances at the VBA and Gambatte source code, and yet my Gameboy emulator can probably run a higher percentage of games then my Nintendo one can. The Gameboy uses a z80 processor which I found more complicated than the 6502 of the NES but was still quite trivial to implement. The BIG difference is in how simple the GBs video registers are, and how they don't rely on nearly as much obscure or undocumented behavior as the NES ones tend to. Also the Gameboy uses very standardized mappers that are incredibly simple, I currently only support 3 different Gameboy mappers and outside of things like the Gameboy camera I've almost never run into a cartridge it can't load. Whereas in the Nintendo world I have about 60 different mappers 99% of which are VASTLY more complicated then what you would see on the Gameboy. Just having a built in scan line counter in the Gameboy has replaced the required feature of most NES mappers. Anyway I'm not sure if I'll just abandon GB-o-Tron now or what, audio support would be nice and I have nothing against emulating it, I just hate all the hassle it brings with new dependencies to output the sound and all the work involved with syncing the video to it. Also as an almost completely unrelated related point I semi-recently read the book Racing the Beam
which was actually pretty interesting, and I would recommend it to anyone else interested in retro computing. It doesn't go super in-depth or anything but it has some interesting facts about what developers had to go through to create games on the Atari 2600, and it also has some lovely diagrams which is always nice.
Nick Massey on Tuesday, November 30, 2010
I have been meaning to make a new post for some time now, just up until now I wasn't motivated enough to do it but there is getting to be too many things that have changed since I last updated this. The debugger I mentioned adding last time has proven to be invaluable; it has helped me diagnose countless bugs that previously would have taken me ages to find. I've moved my source control from Google Code to bitbucket, Google Code was awesome it's just that bitbucket recently added a free package and I have wanted to try out a DVCS system for a while and it seemed like convenient time to switch. Mercurial seems far better for what I'm doing, I can switch between revisions much quicker and test ROM regressions easily. The SlimDX guys had a twitter contest a couple weeks ago and you just had to be developing a project which used SlimDX to enter. I was lucky enough to win so they sent me a 1-year MSDN Visual Studio Ultimate subscription which is just amazing and makes me somehow love SlimDX even more.
Famicom Disk System
I added partial FDS support which was interesting due to kinda poor documentation. So far only read mode is supported correctly so games that write back to the disks tend to have some issues, but reading is all that is needed for Super Mario Bros. 2J and Yume Kojo: Doki Doki Panic which are the only FDS games I think anyone actually has a reason to play so I'm not too bothered. I currently do not emulate the extra FDS sound channels (or any mapper sound channels), the way I have sound setup there is not really a clean way for me to add conditional sound channels, and the North American NES didn't even support them itself so it is quite a low priority for me. The constant process of audio clean-up has continued and I've managed to remove pretty much all of the clicking the emulator used to do so games are now actually pleasant to listen to. I am now up to around 30 different mappers supported which is nice, I have just been adding them as I encounter games that need a new mapper. The PAL PPU had a pretty large accuracy improvement and is now on par with its NTSC counterpart. And of course there have been countless minor PPU accuracy increases including mid scan line sprite zero hit finally being added back and "cycle accurate" tint and greyscale bits. I am once again at a loss of what to work on next, I suppose all it could really be is a pixel based PPU which I have been putting off for ages, I could also update the Silverlight players audio to be not terrible but it's not too fun to debug that thing, we will see.
Nick Massey on Wednesday, September 29, 2010
I am still occasionally messing around with my emulator and it's time again for a progress update. I am really starting to run low on changes to make. I found some mistakes I was making in the APU and now I can no longer hear the difference in audio between my emulator and the real more popular ones. It is really quite awesome to be able to play some games entirely in the way they were meant to be played. I hacked in some netplay support, in ideal conditions it would work pretty well but with frame and network lag desyncs are not uncommon but I don't see myself fixing it. It now supports all the VRC mappers which means it supports pretty much every popular game mapper. I have no plans to ever add the 100 odd pirate ROM mappers because who honestly enjoys those terrible multi-carts and bootlegs. There is an experimental MMC5 mapper that allows games to boot but I don't think, without a ton of disgusting hacks, I will ever have proper MMC5 support, it is just too unique when compared to other mappers, and my system doesn't really support it. Finally I added a pretty deep debugger which I should of added ages ago, I don't really have too much use for it anymore. But it may occasionally save me a few minutes of searching through 50mb log files.
The debugger debugging away.
The debugger lets me take a peek at all the register values and program ROM, and even supports setting break points on addresses. The interface is a bit of a mess but I think that anyone who actually has a need for the debugger would be able to figure it out pretty quickly. In the future I'm not really sure what I will add. Famicom Disk System support might be fun though pretty useless; also it could very well have complexities that I have not foreseen. I also would not mind making a pixel accurate version of my PPU, although it would probably end up being too slow to use, and is unnecessary in 95% of games. The CPU could also use a switch from processing opcodes at a time to individual cycles, would help me pass all those really annoying super accurate timing test ROMs. Other than those few things all I can see doing is endless boring bug finding and fixing.
Nick Massey on Wednesday, September 01, 2010
I have been working away on my emulator quite a bit lately and have recently made quite a break through. First off I rewrote the PPU completely, it is now probably a bit faster, the code is much much much better organized, and perhaps most importantly it now provides loopy based scrolling which is far more accurate. So now any game that doesn't work is pretty much down to mapper errors / omissions or it requires extremely precise timing (Battletoads), which is just plain awesome. I found and fixed a huge stupid insane typo in my APU code that has been in place since its inception which was completely breaking the APU in 70% of games. Though far from perfect the APU now produces recognizable audio in the majority of games. The pulse sweep units are doing something wrong and just don't sound quite right, the triangle channel does stupid things which I don't understand, and the DMC channel tends to introduce a fair bit of static, but it's good enough for me. I finally added the ability to toggle between PAL and NTSC emulation though my focus will remain on NTSC accuracy.
Adventure Island 3 first world play through
I put a copy of the latest binaries up here if you want to try it out. I'm not really sure what I will be working on next, I would like to add the VRC mappers which would add support for ~20 reasonably high quality games and it would be quite easy. I also of course want to improve the APU quality but I don't really know how to fix it right now and it would mostly be me just changing random parameters and then testing if it is any better. I am tempted to do a cycle accurate PPU but it would be quite finicky and not really add support for many new games. THAT'S ALL FOLKS.
Edit: Whaoaoaooaoaoaoao, so I was just playing around updating my Silverlight emulator to the newest version of my NESCore and I decided to give adding audio a try and somehow... I managed to actually do it. It may have some audio artifacts because I'm doing some very sloppy format conversions to get it playing but it seems to be working pretty freaken good. I have to run it on about a 50ms delay which isn't terrible but also isn't very good. You can scroll down the page to whichever post I made to unveil the damn thing if you want to try it out. I of course take no responsibility if it completely crashes your browser or blows your ear drums out.
Nick Massey on Wednesday, June 16, 2010
I spent the last couple of days pounding out an APU for my glorious Emu-o-Tron and now have something worth posting about. I made use of XAudio2 through Slimdx for the output and that was all pretty straightforward. However actually generating the sound data was intense especially with my limited understanding of how sound works with all its wave lengths and frequencies and mixing channels, but after a lot of trial and error I got some excellent results
Mega Man III Intro
There are still a bunch of bugs in the sound generation channels will sometimes not mute themselves at the right time or their volume or frequency will be completely wrong, but I've noticed almost the entire Mega Man series is emulated perfectly. I also need to figure out how to filter out extremely high pitch notes that shatter my ear drums in a few tracks. Savestates don't currently keep track of the APUs state but I will add that once I have the APU set in stone. Also I fully intend to eventually allow for the playback of .nsf files, which doesn't look TOO hard. And finally to help me keep track of revisions I have started keep an up to date repo for my emu on my Google Code page
, so if you have some desire to try out my latest changes you can download it there.
Nick Massey on Tuesday, April 06, 2010
When I first started working on my NES emulator I had set my target at being able to emulate Super Mario Bros. and now I can happily say my emulator can do just that. Running SMB is pretty much glitch free (and audio free, but I'm okay with that) at this point and can be played start to finish without any issues, so I am officially tickled pink. It can also play quite a few other big name titles; in fact I would estimate that around 80% of the games it has the mapper for are playable.
A few games running in Emu-o-Tron
I added the ability to "rewind" games using save states which is really fun and a nifty looking effect and I'm now dependant on it to progress in games I'm testing, it can eat up quite a bit of RAM depending on how long of a rewind buffer you want and how smooth you want the animation to be but I think it is worth it. There are now quite a few new frontend features, it supports Xbox 360 Controllers thanks to GLORIOUS SlimDX, it uses the 7zip library to allow it to play ROMs that are archived, you can finally rebind keys, and it supports using Scale2x and Scale3x display modes which it actually manages to handle while still maintaining 60FPS.
Super Mario Bros. in Scale2x mode
I'm not quite sure what to work on next, I could do audio but I am really scared that it will completely destroy my FPS. I could also add some more mappers like MMC3 which is used by a lot of the best NES games like Super Mario Bros. 3 and Kirby's Adventure but I have my doubts that games that complex will even be able to boot. I also need to massively improve the timing of the CPU which will be an absolute snore fest and take aggggggesss.
Nick Massey on Saturday, February 20, 2010
After going almost two months without touching my Emulator in the slightest I for some reason decided to pick it up again, and ended up making a ton of changes. I switched from using SdlDotNet to the DirectX framework SlimDx which is just far better suited for the type of things I'm doing. In the process of switching graphics libraries I changed my emulator from being frame based to being scanline based which allows me to do split-screen horizontal scrolling, which almost every game out there uses, so that gave me a massive compatibility boost. Everything now runs at a much higher framerate now so it is really no longer a concern though if I were to add audio support it would probably be slow as ass again. I added the ability to use game genie codes just for fun and it is working pretty well. I did not touch my mappers since I last worked on it so right now it can only run mapper 0, 2, and 3 games, I coded support for mapper 1 but there is something really wrong with it and over half of the mapper 1 games won't even boot. The main reason I'm making this post is to show off what I just whipped up today in about an hour or two of boredom. I decided to give porting my Emu to Silverlight a go and it actually worked really well once I got my head around what Silverlight will and will not let me do, I've embedded it below it's framerate may be messed up and it could even crash but it's still pretty nifty.
Controls: Q = Change rom, A = Select, S = Start, A = Z, X = B, Up = Up, Down = Down, etc?
I want to try adding the ability for it to run roms straight from my server but didn't feel like doing that right away. Also due to the way I re-did the graphics of the Emulator updating this Silverlight version to match the desktops emulation accuracy is as simple as copying and pasting one file, so I will try to keep it up to date.
Quickly updated it today to load roms straight from the net, so no need to download any roms to test it.
Nick Massey on Friday, November 06, 2009
Yesterday I decided to make a fun little program to generate Strange Attractors which are wacky fractal-like images which I'm sure have some complex mathematical explanation behind them but I just think they look pretty. Generating them was extremely trivial I all there is to it is the take x and y cords, perform a simple math operation on them, and draw a pixel at the result, then repeat that a few million times. I chose to use the Peter de Jong formula for generation attractors created with it tend to look really cool and varied and the formula is trivial so less work for me then.
Peter de Jong formula
It can take quite some time to generate high quality attractors so I have been just dumping out really low quality low resolution images until I find one that may look nifty and start it going at 36megapixels. It takes around 30 minutes for my craptop to dump one out but they end up looking sooo neat. Once generated my program applies a gradient map to it based on the brightness of each pixel, the map is just something I whipped up in a couple minutes in Photoshop to try and get the most detail showing though while keeping it looking good. Also I have made a couple animated
ones by generating it then changing one variable by like 1/100 and generating again then stringing them together, it does create a neat effect but there are noticeable flickers and it will dim and brighten so it does not work perfectly.
One of my Strange Attractors
In other news I was able to approximately double my NES emulators FPS, through some crazy window hyjinks and hacks. I can now run it at a respectable resolution and have it still be playable which is nice.