Articles posted April 2006

A Tale of Two Kickstarts

When the Amiga came out, I have to admit I had serious computer envy. Here was a machine that had no text mode, up to 32 color graphics, tons of RAM, and the best port of Marble Madness ever! Not to mention lots of other games. In fact, the Amiga seemed to be specially tailored for games.

I did get my chance, briefly, to play on an Amiga when I was in high school, but sadly it wasn't my own. The teacher who ran the Computer Science department at my school was into Amigas, and had purchased a few for the school, using them for early desktop publishing of the school paper among other things. When I was a senior, I decided to take AP Computer Science, not so much for the challenge, but because I knew it would be an easy A. There weren't many AP CompSci people in the school (I was 1 of 2), so we pretty much got to pick our own "curriculum", as long as by the end of it we knew Pascal well enough to pass the AP exam. Since I already knew Pascal inside and out from my Turbo Pascal programming on the PC, I wanted to learn something knew. Well, wouldn't you know it, there was this Amiga, and they had Modula-2 for it which was technically a new language to me (barely ;)).

In the end, I managed to work it out so that I spent my AP Computer Science time each week writing games on the Amiga in Modula-2. I seem to remember writing a Gauntlet-style bow & arrow style game, and another Qix-ish like game before the semester was over. But I never really got to understand the full system.

So it was with this background that I decided to take a look at why the Arcadia system games had no sound.

Turns out, the Amiga has a pretty basic 4-channel DMA driven 8-bit sample playing set of DACs, and it only took a couple of days to get the sound going. But by this time, I was intrigued. I had managed to track down a used copy of the Amiga Hardware Reference Manual and as I read more about the Copper and the Blitter and the custom registers, it sounded like more and more of an interesting emulation challenge. Most of the Arcadia games already worked pretty well, but there were still glitches in a few of them, and Up Scope and Moonquake were two other Amiga-based games that weren't yet in MAME.

With that incentive, I started delving into the existing implementation of the system. Although the Amiga implementation in MAME hasn't been around that long officially, I knew that Ernesto Corvi had worked on it on and off for a few years even before it made its debut. At the time, the original driver was written to be fairly low-impact, meaning it was reasonably optimized and made fairly poor documentation of how the system worked in exchange for speed (though by comparison to the UAE code, it was clear as a bell). I set out to change that.

The first thing that needed an overhaul was the video renderer. I noticed that Moonquake ran in extra half-bright mode, which wasn't supported, so I first tried to fix that. Along the way, I discovered that a lot of assumptions were being made in the code which would ensure that features such as dual playfield scolling and collision detection would not work without a substantial rewrite. A substantal rewrite ensued.

Of course, rendering on the Amiga is driven to a large extent by the Copper chip, and as I started to look into that, I realized that Magic Johnson's Fast Break (a)bused the Copper to jam multiple sprites and scrolling displays along the top and bottom of the screen. Which meant I needed to overhaul how sprite drawing worked in order to support these "manually drawn" sprites, and I also needed to tweak with the timing in the Copper code so that it changed the sprites at just the right instant within a given scanline. I'm still not convinced I have the sprite rendering and Copper timing just right, but it's good enough for the games we've got.

Then I wanted to understand this Autoconfig thing. There were some references to Autoconfig in the Arcadia driver, which is how expansion cards were plug & played on the Amiga. Taking the existing implementation at face value, I abstracted out the Autoconfig system so that MESS could eventually use it to plug in peripheral cards, and then I reconnected the expansion card in the Arcadia so that it worked via the Autoconfig mechanism.

Of course, after doing that work, I am now convinced that it is wrong. :) First off, it doesn't make sense that a custom piece of hardware like the Arcadia would bother to implement anything as elaborate as the Autoconfig protocol. Second, the first word of the Arcadia BIOS ROM is a standard Amiga "ROMtag", and if you map the BIOS up into the Fxxxxx space it boots fine without any Autoconfig mumbo-jumbo. And third, the docs say that the Arcadia systems ran off the Kickstart 1.2 boot ROM. But when you boot an Autoconfig device with the Kickstart 1.2 boot ROM, you run into a bug in the 1.2 code that causes a crash on startup if the device has a boot ROM (you can tell it's a bug because it is very clearly fixed in the 1.3 version of the ROM). I suppose the documentation about the 1.2 boot ROM could be wrong -- after all, up until now the Arcadia systems all ran fine with the Kickstart 1.3 boot ROM, right?

Well, actually, no. I now have proof that the original system couldn't have run off the 1.3 boot ROM. Sidewinder, a vertical shooter, always had particularly odd problems. The background bitmap would wrap strangely, and when you shot, you would hit random targets in the middle of nowhere. I tracked this down yesterday to code that would attempt to blit data from one bitmap to another, but which would somtimes specify the destination to be a location outside of RAM somewhere. Until recently, there had been a hack in the blitter that would throw away accesses outside of chip RAM, but I knew that was wrong because the documentation is very clear that outside accesses would wrap around and clobber important bits of program code.

Looking into this problem more closely, it turns out that the blitting code was doing a bunch of careful 16-bit calculations in the low half of the 68000's D1 register, and then at the end, adding the full 32-bit D1 value to the address. Which means it was assuming that the upper half of the register was 0. Tracing backwards, it was clear that this code was called as part of the VBLANK interrupt routine, and the code which put the non-zero data in the upper half of D1 was the part of the Amiga Kickstart ROM which actually handled the first part of the interrupt. Comparing that same section of code between the 1.2 and 1.3 Kickstart ROMs revealed very different register usage patterns, and sure enough, booting the system under the 1.2 Kickstart ROM produces no invalid blitter accesses and yes, all the graphics problems are fixed.

Of course, prior to discovering the Kickstart problem, I thought for sure it was a bug in the blitter. So yes, I ended up rewriting the blitter routines as well, attempting to document them moreso than optimize them. Which in the end was a good thing as I managed to somehow fix the blitting problems in SportTime Bowling. By this time, I'd rewritten 80% of the emulation, so finishing it off by rewriting the 8520 CIA I/O routines and cleaning up the rest of the driver goes without saying.

If I had the time, I'd probably play around with the Amiga emulation in MESS, now that I've made a number of fixes and improvements to the system, but there are more pressing matters, as always. Oh, and what about Up Scope and Moonquake? More later.

It’s About Friggin’ Time!

A while back, I emulated a couple of the early Gaelco 3D games, Radikal Bikers and Surf Planet. I knew at the time that there was a third game on almost identical hardware, which was the racing game Speed Up, but unfortunately the dump of that game we had was incomplete. Over the past couple of years, I've managed to acquire two different board sets for Speed Up, yet getting a good dump of the 42-pin mask ROMs on the board has been challenging to say the least. Guru and I even manually mapped the address and data lines back to the ADSP-2105 that runs the sound, and confirmed that they matched the standard pinout of an ST 27C160/27C322, yet my programmer would always end up with garbage.

A couple weeks ago, I was given a tip that sometimes these mask ROMs have either the /CE or /OE signals inverted. Last night I finally got around to trying it out, and sure enough, if I tied the /OE signal to Vcc during the dump, I got a good read of the sound and polygon data ROMs. Seemingly victorious, I also dumped the texture ROMs in the same way, but discovered that I had another obstacle in my way in reading those.

With the texture ROMs, my programmer complained that pins 15, 17, 19, 21, 23, 25 and 27 weren't providing good connections. Curious, I looked at the pinout and discovered that these were the D8-D14 lines on the chip. This is a good indication that these ROMs are intended to be read in BYTE mode, not WORD mode. Of course, my programmer only handles WORD mode, which makes things tricky but not impossible. I simply had to read the ROM twice, tying the A"-1" pin alternately to GND and Vcc, and then merge the results, removing the bogus upper byte of each word.

And so, at last, we have Speed Up. It pretty much worked straight away, apart from some input port problems, and looks pretty nice. Reminds me a bit of Cruisin' USA, except a bit smoother since the Gaelco hardware supports bilinear filtering.

Speed Up
Speed Up
Speed Up
Speed Up
Speed Up
Speed Up

Long Time Coming…

And so another month and a half without a post. So what's been keeping me busy recently?

Well, the MAME 0.105 release for one thing. When I started out doing some initial cleanup work, I did not expect to stretch the dev cycle for that release into two months! But I just kept finding more and more ways of getting the core system into better shape, and decided it was best to get as much of it done at once while I still had the interest. And then there was the usual cycle of bugs. But in the end, I'm much happier with the way the system is initialized and cleaned up. It all makes much more sense now, and is much better documented.

Near the end of 0.105, I started getting the itch to actually emulate some stuff again instead of breaking a bunch of already-working things some more (imagine that!) Sega's Universal Sound Board is something I've been meaning to dive into for quite some time. Only two games were known to use it: Star Trek and Tac/Scan. As Sega vector games, they were also on my list to fix for another reason ... MAME was far too accurate at emulating the vector generator.

Wait, what do you mean, "too accurate?" you might be asking. Well, I couldn't help but notice when I was at California Extreme last year, playing Zektor, that after the big face taunts you at the start of the level and it begins to shrink down, the arcade game was very jerky -- it wasn't a nice, smooth scaling like I had always seen it in MAME. I looked into it a bit then, and found that the vector generation code in MAME used real double precision floating point sine and cosine values to accuracies that were not likely for 1981.

So I decided to completely rewrite the Sega vector generator according to the schematics. Turns out I was right. The Sega vector generator lets you specify an angle and length for each vector in a shape, and an overall angle and size for each shape as a whole. This is done by adding the vector and shape angles, computing the sine/cosine, and multiplying them by the vector length and shape size. In MAME, this was done to high precision, using a sine/cosine lookup table with full accuracy, and 32-bit math. On the actual hardware, the sine/cosine lookup table was sigificantly smaller with less resolution, and only the top 9 bits were used out of the multiplcation result. So now if you play any of the Sega vector games, you may notice some jerkiness that wasn't there before. It's most noticeable in the lower window in Star Trek and during the previously mentioned shrinking effect in Zektor.

But back to the Universal Sound Board. I figured this wouldn't be too difficult because it had some similarities to the Exidy sound board (used in Venture-era games), and I had already conquered that one many years ago. But the Sega board had its own share of interesting surprises. It is really a hybrid digital/analog system, so I ended up having to emulate a number of RC and CR filters along the various paths. It also used a digital noise source which produced white noise, but then ran it through an interesting series of filters that I just couldn't figure out. Luckily Frank Palazzolo had the insight that it was filtering the white noise into pink noise, and from there I was able to generate a pretty reasonable facsimile of the correct effect. In fact, if I run the sound self-test in Star Trek using the old samples and the new emulation, they are very close to identical apart from volume (maybe not as good as Derrick's stuff, but pretty good). Unfortunately Tac/Scan doesn't quite match up as well as I'd like, but it's actually pretty close. Hopefully with some more advice from the analog experts, I can nail that one soon.

After I did that, someone pointed out to me that Pig Newton also used the Universal Sound Board. Sweet! Plugging that it did indeed confirm that the main CPU uploads the sound code to the USB and plays some sound effects at the appropriate time. I love it when a plan comes together. :)

With all that work behind me, and most of the bugs caused by my core shuffling quashed, it was finally time to get 0.105 out the door. And then on to something new. I've been curious for a long time why the Arcadia games -- which are based off the Amiga hardware -- didn't have sound. Turns out it's just that it hadn't been implemented yet. So I started (re-)learning about the Amiga. But that's for another post.