News
Save State Manager2009-06-21
I've completed the save state manager for bsnes v048. It uses a very different approach than other emulators, but I believe that if you give it a chance, you'll really like it.
Typically, emulators provide ten save slots, along with hotkey bindings to quickly load from and save to each slot. Some will go further and offer ten bank selectors to enable up to a hundred slots. But there are quite a few problems with this approach: it's typically very easy to accidentally save when you meant to load. With saving being so easy, it makes the entire concept of save states a very temporary thing. There aren't even descriptions, so you have to rely on memory to know which state in a list of 100 are which. Small thumbnails provided by some emulators can help a bit. Next, you end up with up to 100 save state files in the folder with the game, or the assigned save folder. If you were to ever rename the game itself, you'd have to rename each save file one by one; and if you ever wanted to use save states from someone else, you'd have to rename theirs to not overwrite yours (eg if you both had gamename.s04)
With bsnes, the approach is to do away with individual save files: instead, all save files are stored in one single .bsa file. First, for quick savers, this file contains three temporary slots that act exactly like standard emulators: one can bind a single keypress to quickly load or save to any of them. By cycling through as one plays, they act as a manual rewind buffer in case one accidentally saves at a point where it's no longer possible to win.
Next, there are up to 255 slots for long-term saves. These are meant to be much more resilient to accidental overwrites, and can be used for such purposes as chronologizing entire games. For instance, you can have a .bsa file that contains saves right at the start of every level, or right before every boss fight, or both. Further, you can assign your own description to each of these slots to easily reference them in the future. You won't accidentally press a hotkey and overwrite them, because the only way to access these is through the new state manager window. The .bsa file itself is only as big as it needs to be, and will shrink and grow as you add and delete files. Both insertion and deletion happen in O(1) time, so there's no penalty for having so many saves inside a single file. And by being a single file, even ordinary compressors can act on .bsa files as solid state archivers would. Because save states from the same games are so similar, this allows massive compression gains for groups of savestates. And because there's only one filename, it won't bloat your hard disk with excess files, and you can easily swap in anothers' collection at any time.
The next question would be "what if I only wanted to share one save file, or if I wanted to keep my saves while using someone elses' as well?" -- no problem. The state manager window will accept drag-and-drop actions. To export a single state, simply select it from the list, and drag it to the desktop. It will ask for a filename, and save a plain .bst file. You can now send either a .bsa archive, or .bst individual state to a friend. Your friend can load this state by simply dragging it into their state manager window. bst files will be instantly added, and bsa files will present a list with dates and descriptions, and they can check only the states they want to import. Those will be automatically appended to their list. So you see, there's no more worrying about save state file names. It's all transparent.
One future enhancement I'd like to add that is not there now is a screenshot preview. Ideally, I'd like a thumbnail version to appear right inside the state manager listbox itself (with an option to not show them, of course.) I'd also like a way to show the full-size screenshot, perhaps by double-clicking on the list items. Another would be to add up and down arrows on the right of the listbox to allow easy re-arranging of the slot #s. Sorting by any of the columns already works.
Below is what the state manager looks like at present. Note that the temporary (quick) save slots are not visible here, as there would be no point. Also note that the temporary slots are preserved even between runs of the emulator.

The window itself can be resized as much as you want, and all widgets will scale accordingly. So there is plenty of room for even longer descriptions, if desired.
SA-1 speedup2009-06-19
The SA-1 isn't quite the same as the SuperFX: it has a bus conflict manager that allows both the SNES CPU and the SA-1 to share ROM and RAM at the same time. It does this by stalling the SA-1 CPU when the SNES is asserting the same chip. That means we must sync on IRAM / BWRAM reads and writes, but we don't have to sync on ROM reads since, by definition, the data can never change. Well, technically what's mapped to a given offset can be changed by modifying MMIO registers, but if we sync on those we avoid that problem. With that now in place, bsnes v048 will gain a ~15% speedup in SA-1 games over the last release.
Also, save state data is now fully portable across both operating systems and processor types (32-bit or 64-bit, little-endian or big-endian). And now I have to start working on getting them to work with all the various special chips. Just when I finally thought I was done with those, heh.
Lots of new stuff2009-06-17
I'll start with the biggest news: bsnes now has save-state support. It uses ten slots with single keys for each action. You can map load, save, previous and next to any keyboard, mouse or gamepad. Note that so far, this only works for games without special chips. It should easily be extendable to all special chips, but due to the threading model used, will require a lot of special care to work with SuperFX and SA-1 games. The next release most likely won't work across the board just yet.
And speaking of SuperFX ... I've added an optimization to not synchronize on ROM or RAM accesses, as the SuperFX does not allow sharing of the bus like the SA-1 (which has bus conflict resolution circuitry.) This allows a nice speedup, but it's heavily dependant on the situation. You should see anywhere from an ~8% to a ~20% speedup in all SuperFX games in the next release. I may be able to pull off half of that with the SA-1, but it's going to need a lot of work to use the new syncing model.
I forgot to mention in the v047 release notes, but the NTSC filter is now more than twice as fast as with v046. If it was just a little too slow for you before, please be sure to try it again. I also fixed a bug in that release with the scanline renderer, so the 50% opacity scanlines should show properly now.
Various refinements2009-06-10
First and foremost: the timing value for SuperFX2 cache access speed is incorrect in the official bsnes v047 release. This causes one of the menus in Stunt Race FX to flicker. This can be fixed by editing bsnes.cfg (located at either %appdata%/.bsnes/bsnes.cfg or ~/.bsnes/bsnes.cfg depending on your platform), and changing "superfx.fast_cache_speed" from 2 to 1. Sorry for any inconvenience, but I'm not going to release a new build as it can be fixed by hand without recompiling the software. v048 and above will have this working out-of-the-box.
Next up, it was pointed out that Snes9X v1.51+ can run Dirt Racer. Turns out it was just the v1.43 SFX tracer version I was using that was broken. Good to know.
Outside of that, I've been refining the codebase. I completely removed bpp, a custom C++ pre-processor designed to unroll macros in a cleaner method than the default one (eg no trailing backslashes at the end of every line.) I have since rewritten both the S-CPU and S-SMP processor cores to use templates instead, using the tricks gleaned from the SuperFX processor core. I've also added preliminary stubs for the ST011 and ST018 chips. Now both titles can get in-game before failing. There aren't any plans to continue this work any further, it was mainly just a placeholder to get past the "Transmit Wait" screen in the latter title.
bsnes v0.047 released2009-06-06
The most notable feature for this release is the addition of SuperFX support. This enables an additional eight commercial games, and two unreleased betas, to run with full support. Most notably of these would be Super Mario World 2: Yoshi's Island and Starfox. Though timing is not quite perfect just yet, there should be no known issues with any titles at the time of this release. That means there should only be two official, commercially-released titles that are not compatible with bsnes at this time: Quick-move Shogi Match with Nidan Rank-holder Morita 1 and 2 (using the ST011 and ST018 co-processors, respectively.)
SuperFX support was the work of many people. GIGO was a great help by providing the source code to his SuperFX emulator (for reference; the implementation in bsnes is my own design), _Demo_ was very helpful in getting Starfox to work properly, and Jonas Quinn provided roughly a half-dozen very important bug fixes that affected nearly every SuperFX game. Without them, this release would not be possible. So please do thank them if you appreciate SuperFX support in bsnes.
Please note that SuperFX emulation is very demanding. I hate to have to repeat this, but once again: bsnes is a reference emulator. It exists to better understand the SNES hardware. It is written in such a manner as to be friendly to other developers (both emulator authors and game programmers), and the findings are meant to help improve other emulators. As far as I know, bsnes is the first emulator to fully support all SuperFX caching mechanisms (instruction cache, both pixel caches, ROM and RAM buffering caches, ...); as well as many other obscure features, such as full support for ROM / RAM access toggling between the SNES and SuperFX CPUs, and multiplier overhead timing. By emulating these, I was able to discover what additional components are needed to emulate Dirt Racer and Power Slide, two titles that no emulator has yet been able to run (they aren't very good games, you weren't missing much.) It should be possible to backport these fixes to faster emulators now.
That said, with a Core 2 Duo E8400 @ 3GHz, on average I get ~100fps in Super Mario World 2, ~95fps in Starfox and ~85fps in Doom. Compare this to ~165fps in Zelda 3, a game that does not use the SuperFX chip. My binary releases also target 32-bit x86 architecture. For those capable of building 64-bit binaries, especially Linux users, that should provide an additional ~10% speedup. Be sure to profile the application if you build it yourself.
Lastly on the SuperFX front, note that Starfox 2 is fully playable, but that most images floating around have corrupted headers. I do not attempt to repair bad headers, so these images will not work. Please either use NSRT on the Japanese version, or use Gideon Zhi's English fan translation patch, if you are having trouble running this title.
With that out the way, a few other improvements have been made to this release: xinput1_3.dll is no longer required for the Windows port (though you will need it if you want to use an Xbox 360 controller), the video drivers in ruby now allocate the smallest texture size possible for blitting video, and the code has been updated with preliminary compilation support for Mac OS X. Note that I will not be releasing binaries for this: it is primarily meant for developers and for porting my other libraries to the platform. Richard Bannister maintains a much better OS X port with full EE support and a native Apple GUI that follows their interface guidelines much better than a Qt port ever could. He has also synced the Mac port with this release. You can find a link to that in the bsnes download section.
SuperFX perfected2009-06-05
Jonas Quinn managed to find the cause of the last bug: when POR.OBJ is set, SCMR.HT should be forced into 256-height mode. And with that, SuperFX support should be complete. I really can't thank Jonas enough for all of his help. This would've taken me many times longer, assuming I ever found the motivation to keep at it that long. In fact, without his help, GIGO's source reference, and _Demo_'s note about Starfox polygons, I'm not sure if a single title would be playable right now.
Down to one known bug2009-06-05
Writes to PBR via the S-CPU should flush the cache. This fixes crashing and incorrect sprites shown in Super Mario World 2. Writes to r14 should re-start the ROM caching process, even when the value written is the same as the previous value (or at least after ROMBR changes.) This fixes island sprite corruption in SMW2. RPIX should flush the primary pixel cache, not just the secondary pixel cache. This fixes small 8x1 block rendering issues in most games. Jonas noted that I wasn't returning the value from RPIX. While an important oversight, I was surprised to see that no game ever actually looks at the value: it appears to exist solely to flush the primary pixel cache. Oh, and I also re-added UPS soft-patching. Still don't have the new patching lib written, so I used the old one for now.
Many bugs down2009-06-03
Jonas Quinn spotted a serious bug with add / sub opcodes not setting the zero flag properly. He also pointed me at a problem with the ROM buffering system, which fixed Doom and Stunt Race FX; but I still don't have this 100% correct. I also added emulation of both the instruction and pixel caches, support for RON / RAN GSU wait states, proper RAM size detection (thanks, Nach!), and multiply speed selection, among other things. These fix Dirt Racer, Power Slide and Winter Gold. That means everything is running with the exception that Super Mario World 2 only works fully when ROM buffering occurs during the romb instruction (it should not.) So, one more bug to go.
One more bug down2009-06-01
Eight hours and four trace logs with over three million instructions each, before I realize there appears to be two separate RAM chips for most SuperFX carts. That or I'm still not understanding the mapping. At any rate, this gets Stunt Race FX working properly, and both Doom and Super Mario World 2 get farther along.
SuperFX support2009-05-31
For those of you saying "finally", I should note this was only about
five days worth of work :P
Now please don't start bugging me incessantly about ST011 / ST018 support :P
Do note that only Starfox and Vortex are running fully at the moment. Still trying to track down a serious bug somewhere. Assuming I'm successful, cache emulation should finish things off.
Also, many thanks to GIGO for his SuperFX emulator source (I wrote the module myself, used his source as a cleanroom reference — not that it matters); and _Demo_ for telling me how to fix the polygons in Starfox. Couldn't have done this without their help.
Various updates2009-05-16
First, I forgot to comment out the profile optimize mode in bsnes v046's source code archive. If you're trying to compile it on Linux, be sure to edit the Makefile and comment out line 18.
Next, I figured out the issue with dynamically linking xinput1_3.dll, so v047 and above will no longer require this DLL to run — however, Xbox 360 controllers will not work properly without it. The drivers for the controller should install the DLL anyway.
Source code wise, I was able to greatly clean up the S-CPU DMA sync code, by merging two timing events into one. Won't affect accuracy, just readability.
Lastly, I've officially discontinued my GUI toolkit, hiro. I wrote it due to wanting native looking widgets on all platforms I develop for, without being bound to the GPL. Now that Qt 4.5 and above are licensed under the LGPL, it doesn't make much sense to continue it. The major downside here is that both tsukuyomi (a UPS patcher) and bview (a sprite viewer) were written using this, so they have been discontinued as well. I hope to rewrite these utilities using Qt eventually. The upside is that Qt ports of these utilities will allow them to run on Mac OS X as well. I've just re-installed OS X here, and plan to step up on my efforts to provide software for this OS.
bsnes v0.046 released2009-05-09
Unfortunately, I was not able to include any actual Super Game Boy support in this release. I was however able to back-port all other changes since v045, as well as add a lot of new stuff. Though there are few visible changes from the last release, internally much has changed. I'm releasing this mostly as a point release whilst everything should be stable.
I've decided to support the Super Game Boy via external DLL (or SO for Linux users.) There are many reasons for this. Most notably is that the largest special chip in bsnes right now weighs in at ~30kb of code. Emulating an entire Game Boy, not including the SGB enhancements, would require an additional ~800kb of code, or nearly half the size of the entire SNES emulation core. Add to that potential issues with licensing, conflicts with the build process / namespace, a significant increase to build time, and a lack of flexibility over which Game Boy emulator to use, and it's pretty clear that this is something best left external. At least until we have a fully trimmed, fully working SGB emulator available.
The way this will work is bsnes will look for SuperGameBoy.(dll,so), and if present, it will call out to pre-defined functions. Users will need the SGB BIOS loaded, at which point they can select a Game Boy cartridge, and bsnes will use the DLL for actual emulation. Sadly I don't have a working DLL ready for this release, and even if I did, there's no sound bridge yet for the Game Boy audio.
Other than that, much of the core has been updated in an attempt to make the core more library-like. It still has a few major limitations: it requires libco (which is not portable) and nall (which is quite large), and only one instance can be instantiated as all of the base objects are pre-defined and inter-linked. Not that I can imagine any practical use for multiple simultaneous SNES emulators anyway ...
Changelog:- Save RAM is now automatically saved once per minute
- Added delay to Super Scope / Justifier latching to fix X-Zone
- Fixed an edge case in CPU<>PPU counter history
- S-CPU can now run up to one full scanline ahead of S-PPU before syncing
- Added interface for Super Game Boy support (no emulation yet)
- Fixed a bug with path selection not adding trailing slash
- All S-SMP opcodes re-written to use new pre-processor
- Entire core encapsulated into SNES namespace
- Core accepts files via memory only; zlib and libjma moved outside of core
- Major Makefile restructuring: it's now possible to build with just "make" alone
- Linux: libxtst / inputproto is no longer required for compilation
- Lots of additional code cleanup
Abandoned Super Game Boy support2009-04-30
For the past two weeks, I've tried my best to add support for the Super Game Boy, but I have ultimately failed to reverse engineer the protocol. It has a method of keeping the video from the DMG in sync with the SGB that I just cannot understand. Hopefully someone else can figure it out in the future. If they do, I can attempt re-adding support at that time. Very sorry to anyone who was looking forward to that.
I've reverted my source tree to v045 official, and I've written up technical notes on my findings, available here in the hopes someone can make something of them.
bsnes v0.045 released2009-04-19
This is a maintenance release to fix a crashing bug in S-DD1 games (Star Ocean, Street Fighter Alpha 2), and a video issue in games using the WAI instruction.
As always, my apologies for any inconvenience. SA-1 support required modification of a large amount of delicate code in the emulation core, and our limited testing team was not able to catch these in time before release.
bsnes v0.044 released2009-04-19
This release adds full SA-1 support, with no known issues. All 26 games have been tested by myself and others, and a few have been beaten from start to finish. The latter include Super Mario RPG, Kirby's Dreamland 3, Kirby Super Star and Jikkyou Oshaberi Parodius.
Please understand that the SA-1 is essentially four times faster than the SNES' main CPU, so system requirements will be very high for these games. For example, on an E8400 @ 3.0GHz, I average ~160fps in ordinary games. But for SA-1 emulation, this drops to ~90fps, with the worst case being ~80fps.
The following features are emulated:
- 5a22 CPU core (bus-cycle accurate)
- Memory access timing
- SA-1 -> S-CPU interrupts (IRQ + CHDMA IRQ)
- S-CPU -> SA-1 interrupts (IRQ + Timer IRQ + DMA IRQ + NMI)
- SIV / SNV interrupt vector selection
- Timer unit (linear and H/V)
- Super MMC unit (ROM + BW-RAM)
- BS-X flash cart slot mapping
- Normal DMA
- Character-conversion 1 DMA (2bpp + 4bpp + 8bpp)
- Character-conversion 2 DMA (2bpp + 4bpp + 8bpp)
- BW-RAM virtual bitmap mode (2bpp + 4bpp)
- Arithmetic unit (multiplication + division + cumulative sum)
- Variable-length bit processing (fixed and auto increment)
While the following features are not currently emulated, mostly due to lack of information:
- SA-1 bus conflict delays
- Write protection (BW-RAM + I-RAM)
- SA-1 CPU priority for DMA transfers
- DMA access timing
Thanks once again to tukuyomi for hosting this release.