Re: [stella] 11 Invaders "Reloaded"

Subject: Re: [stella] 11 Invaders "Reloaded"
From: Erik Mooney <erik@xxxxxxxxxx>
Date: Thu, 27 Nov 2003 20:43:07 -0500
On Thu, 27 Nov 2003 17:06:07 -0500, <christophertumber@xxxxxxxxxx> wrote:


Is that even possible? The 0's would be RESPn trick, but is there a configuration of duplicated sprites that can span that vertical distance?

Here's how mine did it (I think).

Every sprite displayed by my program is a second-copy of the sprite, with both NUSIZ registers always set to 1. Every sprite is simply drawn by hitting RESPx. The self-modifying code changes the STA RESPx to STA another-location to not-draw a sprite. Because RESP0 and RESP1 are always hit at least once during a line, the *first* copy of each sprite is never drawn at all.

For the above configuration, my program would do this:
(Before the leftmost column of the formation)
(Now the leftmost column starts)
STA templocation  ;right now the second copy of the previous
                  ;STA GRP1 is already clocking out
STA GRP0          ;now the 2nd copy of previous GRP0 is clocking out
STA templocation  ;now no copies of P1 being drawn
STA GRP0          ;now the 2nd copy of previous GRP0 is clocking out
STA templocation
STA GRP0          ;ditto
STA templocation
STA GRP0          ;the 4th copy of P0 is clocking out and this
                  ;sets up the 5th
STA GRP1          ;no copy of P1 being drawn currently but this
                  ;sets up the last one

This will actually handle every case, except when there are *no* copies of one of the players on the current line. All that needs to be done to handle that case is to set GRPx to zero, and that can be done ahead of time, by changing the pointer-to-invader-graphics (indirect indexed loading) to point to memory holding zeroes instead. I never coded that in but it's quite doable.

I believe that's how Eckhard handled it as well. He said there's a special case for when there's only one copy of one of the players on a line, but I don't remember coding for that - I think the above logic handles even that. GRPx is only hit once per line, but I think the timing worked out (thanks to the "mysterious 5-pixel delay") that the GRPx hit takes effect before the sprite starts clocking out, so only the second copy of the sprite is ever displayed. I could be wrong on this, though.

(BTW - All the previous stuff about GRPn is irrelevant, the reason there are so many different kernals is one for each vertical position of the formation. At the time I couldn't come up with any other delay loop with 1 cycle of accuracy (ie: a delay between 0 to 11 cycles or whatever)

Here's how I did the positioning. First, my code actually displays *15* columns of invaders, spanning the entire screen. The between-rows self-modifying code sets up to draw 11 in the correct columns. This means I only need to start my kernel at any one of 9 pixel positions (when the formation has moved by 9 pixels, the whole invader formation moves over to the next of the 15 columns).

I delay the formation by 0, 3, or 6 pixels by self-modifying none, one, or both GRPx writes to take one extra cycle, by changing the opcode from zeropage to zeropage,X (X is always zero.) Then for single-pixel positioning, I just have three separate ROM copies of the 6-pixel-wide invader sprites, at different positions within the 8-pixel-wide GRP register. The indirect-indexed pointer to the invader graphics is set up accordingly. (Indirect indexed loading is very flexible.)

Archives (includes files) at
Unsub & more at

Current Thread