Joysticks and Game Genie codes

Monday, 3rd March 2008

The biggest update to the emulator relates to input.

ConfigureControls.png

I've added a new control panel that lets you customise key bindings. For the keyboard, you simply click on the button you wish to customise, then press the key on your keyboard you wish to bind. As you can probably tell from the screenshot, I've also added joystick support (via the Multimedia Joystick Functions with a bit of P/Invoke for ease) which means that with a simple adapter and a free driver you can use original SMS pads with the emulator.

I haven't added support for the POV hat, which needs doing as the PPJoy PlayStation controller driver exposes the d-pad as a POV hat.

GameGenieEditor.png

I've also added an interface for adding Game Genie codes. The Game Genie was a cheating device that could be used to patch memory.

I have also started reintroducing (albeit in a slightly buggy fashion) multiple memory devices. Previously I've just been emulating a cartridge ROM and work RAM; the real consoles had multiple memory devices including a card slot, ROM BIOS and expansion slots. By emulating this system one can boot with the original BIOS, and (for example) not insert a cartridge to watch the BIOS animation or play its integrated game.

For ease, there's a quick-load ROM menu option that will load anything into the cartridge slot and disable all others for quick game playing. For those who wish to play with the hardware more, there's an "advanced load" dialog that will let you pick what goes in which slot, and also force various options (such as locale, hardware model, video system and so on) instead of the automatically guessed options. I'd also like it to be able to pick patch files (such as translations) so you don't need to use an external tool. Currently this dialog only supports cartridge ROM and BIOS ROM loading, though.

Cogwheel on Google Code

Sunday, 24th February 2008

On bakery2k1's suggestion, I took a look at my sprite collision flag code. It only checked for collisions between sprites appearing in the foreground - sprites that were hidden behind a background tile weren't checked, which caused the Fantastic Dizzy bug.

FantasticDizzyFixedSpriteCollision.png

I have decided to give Google's free project hosting a whirl. As usual, they can't get it working in Opera flaming.gif (no big surprises there) and it's horrifically slow, but I can't really complain given that it's free, and the issue tracking is pretty handy.

Gauntlet.png

Another game that has been fixed is the conversion of that arcade classic, Gauntlet. This was partially due to buggy controller port emulation, but a long-standing bug has been the lack of the y-scrolling inhibition flag. Games could set a flag on the VDP that would prevent the rightmost 64 pixels from scrolling vertically - this is useful to create a locked status bar on the right for a vertical scrolling game, for example.

SmsVdpTest1.png SmsVdpTest2.png

I'm slowly getting there with FluBBa's VDP tester...

/INTerminable Interrupt Problems

Friday, 22nd February 2008

WCLBGolf1.png WCLBGolf2.png
World Class Leaderboard Golf

Well, I've just about got it the way it was before with the new interrupt code; most games work again, but the few that have always given problems (such as Desert Speedtrap) still don't work properly. sad.gif I think this is the stage where I have to start trawling through disassemblies to try and work out why they're not working.

CosmicSpacehead.png
Cosmic Spacehead - one of the few games to use the 256×224 mode.

One problem I still haven't got to the bottom of is with the Dizzy games. They either reset when starting a new game or lock up. I'm hoping this is a problem with my implementation of the Codemasters mapper. I guess that The Excellent Dizzy Collection has a simple front-end game selection screen that switches to the requisite ROM page for the selected game, then jumps to the start of that page - in my case this jumps back to the initial Codemasters screen.

I'm not sure where Fantastic Dizzy's problems originate. It looks like an interrupt problem (maybe the palette should be switched when the VDP has finished with the status bar at the top?), but could also be related to the other Codemasters problems.

Interestingly, Micro Machines (1 and 2) and Cosmic Spacehead - both using the Codemasters ROM mapper - seem to work fine.

Interrupts: A Fresh Start

Thursday, 21st February 2008

I gave in and rewrote all of the Z80's interrupt emulation from scratch, finding some rather horrible bugs in the existing implementation as I went.

Some of the highlights included non-maskable interrupts ignoring the state of the IFF1 flag (this flag is automatically cleared when an interrupt is serviced, and is used to prevent the interrupt handler from being called again before it has finished) and the RETN instruction not copying the state of the IFF2 flag back to IFF1. When non-maskable interrupts are serviced, the state of IFF1 is copied to IFF2 before it gets cleared, the idea being that if you use RETN interrupts are automatically re-enabled on exit of the NMI ISR. (Contrast this with maskable interrupts, where both flags are cleared, and you need an explicit EI to re-enable them).

The HALT instruction (executes NOPs until an interrupt is requested or the CPU is reset) was also completely incorrectly (and bizarrely) implemented. The rewrite just sets a Halted property, which prevents the CPU from fetching or executing any instructions. The interrupt-triggering code simply resets this property.

This has fixed numerous bugs (I'm not sure when they were introduced, as it was all working a while back). It's gone from "not working at all" to "just about working", but some games or demos that rely on precise interrupt timing don't work properly.

HicolorDemoCorruption.png DesertSpeedtrapMisaligned.png
Game Gear Hicolor Demo and Desert Speedtrap

Both problems in the above screenshots relate to line-based interrupts from the VDP (Video Display Processor). Some other games simply hang at startup. sad.gif

Loading ROMs

Wednesday, 20th February 2008

OutRunEuropa1.png OutRunEuropa3.png
OutRun Europa

I've been adding a series of new features to Cogwheel. I wrote a basic zip file class a while back (only supporting store and deflate compression - the majority of zip files use deflate), and have added a Utility namespace with methods for help with loading ROMs.

For example, there is a method that is passed a filename by reference, and it'll return an array of bytes of the loaded file. If the passed filename was a zip file, by any chance, it'll search for ROMs inside the zip, and modify the filename (so it might end up as C:\Path\SomeFile.zip\Game.sms).

Once this is done, the CRC-32 checksum of the file is calculated then looked up against a database of known ROM dumps. I'm currently using the SMS Checker .romdata files as the database source. These contain information about known bad dumps, and can be used to strip headers and footers, patch bytes and remove redundant overdump data to end up with a valid ROM image.

Finally, the mapper is detected. Currently, I have three mappers - RAM (which is just 64KB of RAM), Standard (the standard Sega Master System ROM mapper) and Codemasters. I use the RAM mapper for all SG-1000 and SC-3000 games (I'm not sure what they're meant to use, here, but some games - such as The Castle - don't work with the standard SMS mapper).

The Codemasters mapper uses a different method to swap pages, which means that the conventional SMS BIOS checksumming code fails to swap in pages correctly and thus doesn't check the entire cartridge. The games therefore have their own checksumming routines and store their own checksum in a Codemasters-specific header; this makes detecting Codemasters games fairly easy, as all you need to do is check for the extra Codemasters checksum.

As the BIOS doesn't check the checksum, the cartridge provides code to do so itself. You can run it by holding 1 and 2 down as the game boots.

ExcellentDizzyCollectionChecksum.png
The Excellent Dizzy Collection
MicroMachinesChecksum.png
Micro Machines

I seem to have broken interrupts somewhere along the line; most noticable are non-maskable interrupts (as generated by the Pause button) which crash the emulator (it appears that once they fire, interrupts are never re-enabled). I'm not sure what's causing this, but hopefully it won't be too unpleasant to fix!

Page 28 of 54 124 25 26 27 28 29 30 31 3254

Older postsNewer postsLatest posts RSSSearchBrowse by dateIndexTags