Astro-Dodge's Dirty Video Tricks

I was recently asked about Astro-Dodge and how it's supposed to work on real hardware.  This decent Asteroids clone is a very early IBM PC release (March 1982, it says here), made when you could still afford to treat the PC as a fixed hardware platform, twist it around itself in any barely-documented way you saw fit, and remain blissfully unaware of the clones and future iterations which would soon arrive to break your tricks and ruin your day.  With Astro-Dodge, it's all about the video setup.

The game tweaks the 6845 CRTC parameters to create a custom CGA video mode, evidently meant to display a resolution of 256x254 as opposed to the usual 320x200.  The playfield takes up this screen space in its entirety, so as a prospective player you might actually like to, I dunno, see all of it.  A reasonable expectation?  Not so fast.

Here's what the game does on an IBM 5153 monitor.  Most CGA displays (digital or composite) aren't going to show you 254 scanlines, at least not when the picture size is anywhere near a reasonable setting.  If your monitor has an external V SIZE control, which the 5153 does, you might try to squash it vertically.  But even then the game won't show you the full thing; you only get to see 240 lines:

Astro-Dodge as displayed with a 'sensible' vertical size (V SIZE control around mid-point)
Astro-Dodge as displayed with a 'sensible' vertical size (V SIZE control around mid-point)
Astro-Dodge with the vertical size adjusted to near minimum; only 240 lines are visible (out of 254)
Astro-Dodge with the vertical size adjusted to near minimum; only 240 lines are visible (out of 254)

This can be compared to the screenshot below, which shows the full video memory dump, all 254 lines included.  There's a respectable slice all the way down at the bottom which gets cut off on the CRT.  Curiously enough DOSBox will happily show you the whole thing, but as we'll see that's more of a happy accident.

Astro-Dodge screenshot

By the way, most screenshots you'll find show a different palette for this game (green-red-yellow), but the game's instructions leave out a few things: you can press F4 to get the alternate cyan-red-white palette seen here, which looks nicer to me; F1/F2 to change the status bar colors, and F3 to flip the background color between black and dark grey.

14 missing lines may not sound like much, but since your ship wraps around the screen's edges, you can often find yourself in the dark.  Even worse are those little red bastards, which like to cross the screen almost perfectly horizontally while taking pot-shots at you.  They can very well take refuge within that strip of missing video down below, and these bottom-dwellers can get real aggravating.

Anyway, to see why we're being cheated out of seeing the entire playfield, we have to examine the CRTC settings being used.  In the common version of the game, converted from the original booter disk to a DOS executable, the table resides at offset 1453h within the .COM file:

01453h | 00 38 01 20 02 2A 03 0A 04 7F 05 10 06 7F 07 78
01463h | 08 02 09 01 0A 06 0B 07 0C 00 0D 00

This is a simple sequence of register/value pairs, so we can compare what the game is doing against the default values which the PC BIOS sets for CGA video mode 4, i.e. 320x200 in 4 colors.  The relevant registers are 0-7, which control horizontal and vertical timings:

Register    Description                  BIOS Default    Astro-Dodge
--------    ------------------------     ------------    -----------
R0          Horizontal Total             38              38
R1          Horziontal Displayed         28              20*
R2          Horizontal Sync Position     2D              2A*
R3          Horizontal Sync Width        0A              0A
R4          Vertical Total               7F              7F
R5          Vertical Total Adjust        06              10*
R6          Vertical Displayed           64              7F*
R7          Vertical Sync Position       70              78*

In the horizontal department, registers R1 and R2 are modified from the default.  R1 sets the displayed width to 32 characters, i.e. 256 pixels, which also determines the difference in memory addresses generated by the CRTC for consecutive scanlines.  R2 only modifies the hsync position to center the narrower picture (actually, the values 28h or 29h seem to provide better centering than 2Ah on my monitor).  The new reduced width allows for more efficient code: X coordinates now fit in a byte, and Y coordinates can be translated to VRAM addresses using only bit-shifts.  R0 is left alone, so the horizontal scan rate remains a nice and conventional 15.7 KHz.

The vertical parameters are where it gets weird.  The total duration of a frame is given by (R4+1)*(R9+1)+R5, where R9 is the "Maximum Scan Line" register, which this game keeps at its default value of 1.  For standard CGA modes this adds up to 262 lines, which gets us the familiar 59.92 Hz refresh rate.  R5 sets the count of extra scanlines added to the end of the CRTC frame, i.e. at the top of the screen (since vsync has already occurred).  They display the same solid color as the border, in our case black.

The game increases R5 from 06h to 10h, so each frame is now 272 lines long, giving an oddball frame rate of 57.72 Hz.  This isn't going to play nice with every monitor out there - my 5153 needed a tiny adjustment of the V HOLD knob to still its protests; even so, when starting a new game the picture still rolls a bit until it finds its bearings.  But the real strange bit is R7, which determines when vsync happens (and therefore sets the vertical positioning of the image).

VerticalTotal +1row (256) Actualvisiblearea (240) VerticalDisplayed(254) VBlank (16) VTotal Adjust (16) 240256 254 272

The programmed value of 78h sets the vsync position to line 240.  At this point, the 6845 CRTC inserts 16 lines of vertical blanking while the CGA sends out a vsync pulse.  When blanking ends we're at line 256, and here we get 16 more black lines courtesy of R5 (Vertical Total Adjust).

So although Vertical Displayed (R6) is set for 254 visible lines, vsync occurs within the active area, and the last 14 are lost to the blanking period: only 240 are ever displayed in practice.  (DOSBox only seems to consider the frequency of the vsync signal, without implementing the fixed 16-line vblank interval, and that's why it conveniently lets you side-step this issue.)

You might ask yourself why the author saw fit to increase the length of the frame and make the refresh rate all funny.  Or if we do keep those extra lines, why the vertical blanking couldn't be set to occur a little later, and recover some/all of the missing area.  I can only speculate here, but Astro-Dodge actually predates the IBM 5153: it couldn't have been tested on a 'reference' CGA display, because there was no such thing.

Whatever monitor was used during development, it likely needed both of these tweaks to achieve acceptable vertical centering: without them, the status display might just get obscured by the bezel at the top edge of the CRT.  Increasing R5 and reducing R7 both have the effect of shifting the image downwards, and if you look at the above photos, it's very much off-center on the IBM 5153 too.  (True, you may wonder why the lives and score weren't simply printed lower down, and the blanked-out portion made to span less of the bottom and more of the top, but there's only so much conjecture I can do here.)

Grafting Back the Missing Chunk

Either way, nothing prevents us from making our own surgical modifications.  I tried patching the above-mentioned table and changing the value of R7 (offset 1462h) to 7F, so that vsync/vblank occur at line 254.  Sure enough, all 254 lines are now visible, if you compare the photos below and the raw VRAM dump seen above.

Of course V-SIZE still needs to be dialled down, but not as extremely as before, since the new vsync position happens to give us a more centered image.  As a little coincidental perk, the modified pixel aspect ratio is better suited to this game - those big round space rocks look a bit elliptical at the typical CGA PAR (nominally 5:6), but here they appear almost perfectly circular.  It's all about the little things in life.

Before (original mode): 240 visible lines
Before (original mode): 240 visible lines
After (patched R7 to 7F): 254 visible lines
After (patched R7 to 7F): 254 visible lines

Since vertical blanking now starts at line 254, those 10 extra lines at the end of the frame are (finally) truly necessary; the blanking interval is always 16 lines.  With the normal count of 262 lines, the next frame would begin halfway through this interval, and have a chunk lopped off the top instead.  But at 272 lines per frame, the blanking is over just in time to leave us with a 100% visible playfield.

(For easy visual comparison, all photos in this post show the same static shot from the game with the different CRTC settings applied, but the changes were verified to work the same way when the actual game is patched.)

There's a modded version of Astro-Dodge floating around which runs at 59.92 Hz, at the cost of showing you only 200 lines; the shots at Mobygames were evidently taken from that one.  You don't need such a drastic reduction just to get a standard refresh rate, but I guess this was deemed to be the most compatible setting.  Since none of the game logic is modified to account for it, you end up with one-fifth of the playfield invisible, so it's far from a great all-round fix.

Modifying the CGA Pixel Aspect Ratio... in Software

The above seems to be a decent enough 'fix' for the 5153 display.  But what about monitors or TVs which hide their V-HOLD and V-SIZE controls inside the chassis, and may not cope so well with the 57.72 Hz vertical refresh?  Just for fun, I thought I'd try another approach: increasing the horizontal scan rate.

The idea here is to shorten the duration of each scanline period, so the same total line count (272) could be maintained at a frame rate closer to the normal 59.92 Hz.  The oscillators in a CGA monitor have a certain range of tolerance for the frequencies they sync to, which is often adjustable; if you go somewhat out of bounds, you won't get a stable image but nothing's likely to break.  If the game's original video mode causes vertical rolling, the horizontal hold circuitry may just be lenient enough to put up with a higher scan rate and compensate.

Many of you will already know this, but: never ever try this with a TTL monochrome monitor (MDA/Hercules-type), or you could be in for some all-too-realistic smoke effects.  

All standard CGA modes set the line duration to 57 low-res characters, for the normal horizontal frequency of 15.7 KHz.  Your mileage may vary, but my 5153 can go down to 54 lchars without losing horizontal sync (the H-HOLD control can modify this range somewhat, but changing this one does require you to open up the monitor).

The shorter total length has no effect on the visible portion of each line, which is still just 32 lchars (256 dots).  54 lchars works out to 16.57 KHz, and 272 lines of that will yield a vertical refresh rate of... wait, 60.93 Hz?  Uh, I seem to have overshot the target a bit... but my monitor is fine with it, and so am I.

In fact, a more moderate reduction (55 lchars per line) would be the sweet spot in terms of compatibility - vertical refresh would then become an almost-dead-on 59.82 Hz.  But there's another reason to go with the lower number: your scanlines huddle a little closer to each other, so you get to fit more of them on your screen.

The original video mode, with the vertical size control at normal
The original video mode, with the vertical size control at normal
Patched for 16.57 KHz/60.93 Hz, same vertical size setting
Patched for 16.57 KHz/60.93 Hz, same vertical size setting

This happens because the electron beam scans down the screen at a specific rate; when you reduce the line duration, the beam gets less downwards travel time per scanline, and the next one starts a wee bit higher up than normal.  Effectively you can modify the vertical stretch factor (i.e., the CGA's pixel aspect ratio) entirely in software.

For the last photo above, I also modified the H/V sync positions to tweak the centering a bit, since the new timings shift the image around.  To apply this change to the game's CRTC parameter table at the above offset, edit these values:

R0 (offset 1454h): 38h -> 35h
R2 (offset 1458h): 2Ah -> 28h
R7 (offset 1462h): 70h -> 7Bh

Interestingly, the higher horizontal rate also seems to make the image a little bit darker than normal, but that's neither here nor there.  With the aid of the raw screenshot for comparison, I can tell that Astro-Dodge's original mode shows me 216 visible lines, while the custom 16.57 KHz/60.93 Hz mode manages 222 lines at the exact same V SIZE setting.  Not an earth-shattering difference by any stretch (ahem), but it demonstrates the principle.  "It ain't much, but it's honest work."

A Non-IBM Version?


Starting up the game brings up a screenful of plain old instruc­tional text, which also serves to teach us a few things that aren't plainly spelled out.  Even with this sort of thing, additional tidbits can sometimes be hidden between the lines.

One of these is in the screen's layout: it was clearly meant to be displayed at 40 columns, although the game doesn't bother to set this mode explicitly.  If the machine happens to be in 80-column mode when the game starts up, which is what most people are going to encounter, the text will simply get squeezed into the left half of the screen.

Since the original game is a booter, there's no DOS from which you can set this mode: to boot up at 40 columns, the original IBM PC had to have its motherboard switches set that way.  That only made sense if you were limited to a composite monitor, or worse yet a TV set (which back then required an unwelcome middleman in the form of an RF modulator, further degrading the signal).  80-column text would get beaten into a smeary mess on such displays.

So coming back to the earlier question - what kind of funny monitor was used to develop and test Astro-Dodge - this tells us that it was most likely a composite monitor or TV.  In turn, that points to a different purpose for the F4 key, which the instructions also keep silent about.  I mentioned how it sets the cyan-red-white palette on a color RGBI monitor, but programming this palette has a different effect on the composite output: it suppresses the NTSC color burst to avoid unwelcome artifacts on monochrome CRTs.

The other little bit of info is in the "IBM VERSION" under the title.  The obvious take-away is that at least one other version existed for a non-IBM system, but no such thing seems to have been documented anywhere.

However, the author's name does seem to point us somewhere in particular.  'David Gangola' is mentioned in the July-August 1983 issue of Ad Astra, "The Journal of the Atari Microcomputer Net Amateur Radio Operator Users' Group"(!).  Page 23 hosts some very excited discussion of a new expansion module for Atari XL systems, in which we find:

ATARI is openly encouraging third-party support for this system... to the point that every CP/M card will have a catalog from "ADD-ON COMPUTER CORP." included! ADD-ON is a direct-marketing vendor of CP/M software and will be providing CP/M 2.2 software pre-configured for the ATARI system! One of the members of this organization, David Gangola, was a technician and designer at North Star Computer, Inc. and was chief designer of the CP/M card for the ATARI system.

North Star was an early microcomputer manufacturer specializing in machines based on the S-100 bus, by that time running mostly CP/M.  In 1982, they had just happened to release their new North Star Advantage, announced as early as January.  This Z80 system supported an optional 8088 CPU card which ran MS-DOS, presumably shooting for a piece of IBM's pie in the 16-bit market.

As a North Star engineer who was evidently designing co-processor boards, the same person could well have been involved with the Advantage's 8088 board too.  I suspect that anyone working on such a project would've been busy getting deeply familiar with the IBM PC... and who knows, that sort of thing might just result in a little game on the side.  If so, perhaps our hypothetical non-IBM version of Astro-Dodge was written for the Advantage?

This was a serious business sort of machine, and gaming was just about the last market it targeted; the internet isn't exactly bulging with lore about any games for it.  However, I did find something in one North Star distributor's price list, hidden away at the bottom of page 32 (which bears the revision date 03/82):

                             ADVANTAGE PRODUCTS
     PART #      DESCRIPTION                      LIST       DEALER
   A3 NL00357    ASTRO-DODGE                      39.95          24

It also crops up in a later price list within the same document (page 18, dated 1/83) as "ASTRODODGE".  Hyphen or no hyphen, that seems pretty conclusive.  Interestingly enough, the North Star Advantage sported monochrome bitmapped graphics at a resolution of 640 by 240; perhaps the latter figure explains the sheer depravity of the IBM version's custom video mode.

The North Star Advantage (Nov. '82 brochure)
The North Star Advantage (Nov. '82 brochure)
North Star Astro-Dodge (03/82 price list)
North Star Astro-Dodge (03/82 price list)
North Star Astro-Dodge (01/83 price list)
North Star Astro-Dodge (01/83 price list)

So in the interest of shedding some light into this obscure and dusty little corner of digital history: if anyone has any information whatsoever about the North Star Advantage version of Astro-Dodge, please do drop me a line or just leave a comment down below.


FavoritoHJS says:

Wait a minute, if you can just about get 256 lines in a CGA monitor... is a 720x512i-on-RGBI EGA tweakmode possible?

...what kind of cursed idea did i just say...

VileR says:

Ha, interesting thought - I don't think (standard) EGA can do interlaced modes, but it may be possible to fake them in software, if your timing is tight enough to manually delay the vsync by half a scanline and if you flip the start address every other frame...

As it happens, someone did patch Astro-Dodge for EGA, but that version renders the 256x254 screen at the top left corner within a tweaked 320x350 resolution (I think - it seems to be mode 10h but with the half-rate pixel clock). The aspect ratio is completely off, but it lets you have some fun playing around with the color palette.

SckMud says:

The Northstar connection sure came outta nowhere! I expected maybe the apple ][, or some Atari like that newsletter seemed to hint at first...

BTW that Northstar card didn't run just any old DOS... they called it "Graphics" MS-DOS:

Ian says:

Where you say, "Increasing R5 and reducing R7 both have the effect of shifting the image downwards", I don't understand how REDUCING R7 shifts the image downwards. What am I missing?

VileR says:

@Ian: it helps to think of the vsync pulse as "anchoring" the image to the bottom edge of the screen. The leading edge of the pulse follows the bottom-most line of the image, as displayed by the monitor... or rather, the monitor's vertical hold oscillator establishes a phase lock on it, so the beam gets deflected back upwards at fixed intervals (giving you a stable image).

Changing the vsync position (R7) sets a different reference phase for the vertical oscillator to lock onto: this effectively repositions the image with respect to its bottom edge. When you increase R7, the vsync pulse triggers later relative to the beginning of the frame - but since this 'anchor' point is vertically fixed, it's the top of the image that moves upwards; reduce R7, and it moves downwards.

Write a response:

* Required.
Your email address will not be published.