| 24-Apr-07 |

Atari XL/XE Space Harrier Conversion Project

| Home | Diary | Movies | Download | FAQ |

| Latest | Mar-07 | Aug-06 | May-05 | Feb-05 | Oct-04 | Aug-04 |
| Dec-03 | Mar-03 | Jan-03 | Dec-02 | Jun-02 | Apr-02 |

5th February 2005

Plenty of diversions (and my usual slow pace of work), hasn't seen much visible progress to report on the game.

Cartridge Formats

I finally got around to looking at the pros and cons of different cartridge bank switching methods that I could use for the game.

There are 3 existing cartridge designs that cope with the amount of memory I expect to use with Space Harrier. Only MegaCart, XEGS and AtariMax MaxFlash allow for 8Mbit cartridge sizes. They are also sufficiently different that substantial changes have to be made to a program if you decide to swap from using one to another - which is what I've been doing. I had been using the MegaCart format as it seemed to be the only one that offered the potential for more than 8Mbit of memory, which I thought initially I would need.

  • 8Mbit MegaCart is organized as 64 banks of 16K. Only one bank of memory is available at any one time. (The Atari hardware is designed to map cartridges into two 8K memory areas only). Switching to another bank is achieved by writing the bank number required anywhere in $d500 to $d5ff
  • 8Mbit AtariMax MaxFlash has 128 banks of 8K banks, again with only one bank available at a time. Switching banks is done by writing anything to $d500 for bank 0, $d501 for bank 1, $d502 for bank 2. etc.
  • 8Mbit XEGS is organized as 128 banks of 8K, and is more flexible with banks. The last bank in the cartridge is always mapped to one of the 8K memory areas, whereas the other 8K area is for using the different 8K banks as needed. Writing the bank number required anywhere in $d500 to $d5ff switches the bank.

The bank flexibility is why I'm using the XEGS format now. It means for example, that the full cartridge size can be used, rather than having to dedicate a small amount of space in each bank for dealing with silly little things like someone deciding to press the reset key. I may revisit the AtariMax MaxFlash though as it is the only cartridge which is re-writable by the owner themselves - an ideal way to distribute games over the Internet for use on real Atari hardware. However good it may be, the trouble is it's a recent development, and is not widely supported under emulation. Steven Tucker (of APE fame) has done an excellent job with it though, and I hope it will gain in popularity. Many games that required multiple disk swaps have been converted to use this cartridge. It is even possible to store high scores and game settings on it (although there's no example code on how to do that, yet). More details on MaxFlash and APE at www.atarimax.com

Display Mode Experiments

Richard Phipps of Reflected Games dropped me an e-mail a little while back, offering some great words of encouragement. Although he's now programming some lovely shareware games for PC, he still remembers a lot of technical details about the Atari 8-bit. We exchanged some ideas about getting more colours on screen, and he even whipped up some simulated screenshots for me (see below). These ideas involved mixing GTIA modes (9 or 16 colour, but low resolution) with higher resolution (but limited colour) modes on alternate scan lines, and then interlacing the screen to make the scan lines merge. Unlike the best modes for displaying lots of colour on the Atari, some of these modes can be done without having to use Display List Interrupts on every scan line or tying the processor to a display kernel routine, which both leave few CPU cycles to do anything else. The lack of colour resolution on these modes can make for some strange artifacting around colour boundaries, and overlaps of moving objects can look a bit messy (reminiscent of the infamous Sinclair Spectrum colour clash), so chances are I'm not going to use these modes. There doesn't seem to be anything new under the sun though - I recently saw CIN pictures for the first time, and it looks as though they work pretty much the same way!

By the way, be sure to check out Richard's excellent original retro styled PC shoot'em up game, called Storm. It reminds me somewhat of Thrust or Oids in visual style, although most of the gameplay elements are different. A free demo or the full Shareware version can be downloaded from www.reflectedgames.com

I know some people don't like using interlacing methods to get more colours, because of the flickering produced. However, I was reminded of why I went down this route when I looked back at my oldest, 4 colour version of the game started in the late eighties. Black, Green, Grey and a changing background colour were to be used throughout the game; I think it would have ended up looking very dull indeed.

Backgrounds and Run Length Encoding

There's a neat trick the original arcade machine uses on the background parallax layers. Several layers just have a different colour palette applied to them and get reused on many stages. Now that I'm doing parallax layers too, I can also use the same trick to save memory.

Looking into how best to store the background parallax layers and stage data, took me on an interesting detour into different implementations of Run Length Encoding. Experts look away, as what follows is an "Idiot's Guide" to Run Length Encoding, and I will be your idiot for today.

Run Length Encoding (or just RLE) is a kind of poor man's compression which is easy to implement and quick to run, even on old 8-bit computers. Even the concept is simple and obvious, unlike most other (admittedly much better) compression algorithms. The concept is just this - when you get several repeating items of the same value (a run), just store a count of how many there are, along with the value of the repeating item.

4,4,4,4,4,4,5,5,5 becomes 6,4, 3,5

This saves space when we have nothing but repeats, but what happens when values do not repeat? In the easiest approach we might store a count of just 1 for those items that do not repeat.

1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,1, 1,2, 1,3, 6,4, 2,5, 1,6, 1,7

As you can see, in this case it has the unfortunate effect of expanding the data, rather than compressing it. This is where things get slightly more interesting. There are a few different approaches to that problem, and which one gets the best result is dependent on the kind of data you will be encoding.

Approach number 1. Use two repeats of the same value to show that a run is required, and the value after is the count remaining. This is pretty cunning, but not always that efficient. Note how in the example the two 5's below actually expand in size. Runs of 3 take up the same size, but any bigger runs will start to benefit. The non-repeating data takes up the same amount of space.

1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,2,3, 4,4,4, 5,5,0, 6,7

Approach number 2. Use an unambiguous symbol to represent that a run is required. In our examples we are just using numbers, so we could use anything other than a number for a symbol. Below the character "C" is chosen as a symbol. This approach has the advantage of not having to expand the data when it is not worth it; we can leave the 2 fives as just 2 fives.

1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,2,3, C,4,6, 5,5,6,7

What if there is no suitable value for a symbol though? If we want to have "C" as part of the data in the above example we hit a problem. One answer is again to use a repeating value to indicate that the symbol is to be used as real data, rather than just a symbol - but any runs of the symbol cannot then be represented as a count. Alternately we could represent the occurrence of the symbol as a run with a count of just 1 item. It is therefore important that a rarely used value is chosen as the symbol, or the data will start to expand every time the symbol is required to be represented in the data. If the symbol is not always going to be the same then we must also record the symbol value in the data. Right at the beginning is an obvious place to put it.

1,2,3,4,4,4,4,4,4,5,5,C,6,7 becomes C, 1,2,3, C,4,6, 5,5, C,C, 6,7 (symbol as a repeat)

or 1,2,3,4,4,4,4,4,4,5,5,C,6,7 becomes C, 1,2,3, C,4,6, 5,5, C,C,1, 6,7 (symbol as a count)

Approach number 3. This one actually has a name - it's sometimes referred to as "PackBits". The basic idea is to have a count for the runs and also a count of how many non-repeating values there are before the next run. We do need to distinguish between the two kinds of count though, and this reduces the range of the count. The usual method is to represent one of the counts as a positive number, and the other as a negative number. In the example here we use a negative value to show when the count is for a run.

1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 3,1,2,3, -6,4, -2,5, 2,6,7

That's pretty much the basics for Run Length Encoding. One thing that hasn't been mentioned yet, is how to know when we've got to the end of the data. You could have the file length stored at the beginning of the data, and keep count of when to stop. A normally more efficient way (at least on old processors with few registers, like the 6502) is to have a zero in the count value to represent we've finished.

The Real Thing (in our House)

A couple of weeks ago, proof came that my brother is, unbelievably, an even bigger Space Harrier nut than me - he won a full motion deluxe version of the original arcade machine on eBay (and it is supposed to fit in the back room of our small 3 bedroom semi-detached house). Below is a picture after the machine had to be totally dismantled just to get all 300Kg of it through the door. I won't even go into detail about the ferry trip to France, and the 480 mile round trip with a 3 1/2 Tonne tail lift lorry to collect it. As you can see from the picture, it now joins a smaller version of Space Harrier and a JAMMA cabinet. It is in working order, but there is quite a bit of restoration required; all part of the fun!

 

Top