This is in the off chance anyone is interested in what this demo is attempting to do.
(I used a lot of homebrew released when developing my SMS emulator!) I don't really
use comments... (I'll admit the code is very ugly).

The background is the easy bit. That's a simple plasma-by-palette-shift job, writing
out a whole new palette by shifting it all downwards and adding a new colour (using
trig to get the R, G and B elements for smooth changes) at the top end.

The only oddity, and possible reason it doesn't work in DEGA, is that the background
resource file only holds the top-left corner of the background pattern (see the .GIF
files). The program then mirrors this twice, first vertically then horizontally. It
reads the data back from the VDP then writes back out to it, storing the read data
in a temporary buffer for the vertical flip and on the stack for the horizontal flip.
It also flips the tile flip flags to mirror properly.

The 3D blobs in the foreground are done using brute force; no precomputation is used
beyond the trig tables. The transformation is:

SinRotX = Sin(RotX)
SinRotY = Sin(RotY)
CosRotX = Cos(RotX)
CosRotY = Cos(RotY)

rX = (x * SinRotX) + (y * CosRotX)
rY = (x * CosRotX * SinRotY) - ((y * SinRotX * SinRotY) + (z * CosRotY))
rZ = (x * CosRotX * CosRotY) - ((y * SinRotX * CosRotY) - (z * SinRotY))

(Now we have a rotated x, rotated y and rotated z from the original x, y, x).

At this point a crude insertion sort on z is performed to arrange the points into
front->back order and the rotated point is stored in the output buffer along with
its correctly sized and coloured blob sprite number.

$6800 is divided by rotated Z, and the result is multiplied to rotated X and rotated
Y to get the translated-to-screen coordinates after having an offset added to centre 
them on the display.

If we're in the 3D glasses mode, the translation to screen is performed twice, with
the rotated X being given an offset to the left for one eye and to the right for the
other, and a constant is added to the '2D' coordinate to shunt the point back to the
centre of the screen.

The vblank interrupt handler is used to check if we have newly transformed points
to display (and to cycle the background palette, if needed) in 2D mode, and to
flicker between left and right eyes in 3D mode.

There are two pointers - a write pointer which points to the buffer that we're
filling with new point data, and a read pointer which points to the buffer that holds
the point data for the sprites on-screen at the moment. In 2D mode the read pointer
is cleared once the sprites have been copied to the display to reduce redundant
writes, but in 3D mode this luxury is not available to us.

That's about all I can think of off the top of my head.