<< Newer Article #158 Older >>

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.