Re: [stella] MultiSpriteDemo update (source+binary)

Subject: Re: [stella] MultiSpriteDemo update (source+binary)
From: Piero Cavina <p.cavina@xxxxxxxxxxxxx>
Date: Wed, 9 Apr 1997 14:08:43 +0200 (METDST)
At 07.29 08/04/97 GMT, Erik Mooney wrote:

>>>I had a routine that needed to rewrite both GRP registers each line while
>>>updating all three PF registers twice per scanline (non-repeating
>>
>>hmmm... looks like you're working on something very interesting... :)
>
>I was working on a kernel for an Arkanoid-type game, using the playfield
>for the walls and the GRP registers for the capsules (and of course the
>ball for the ball).  It wasn't working out the way I had it - there just

Are you still working on it? A good Arkanoid game is missing from the 2600
library, as the old Breakout games are defintely aged, and "Off the wall" is
awful (IMHO).

>weren't enough cycles.  Trimming it down to 32 blocks wide and setting
>PF-Reflect so it didn't use PF0 (see Super Breakout),

hehe... I've had to do just the same to add the background grid to my
current demo. The 8 extra blocks that could be obtained with PF0 caused more
troubles than advantages.   
And 32 is a power of two...

>>>and checking the ball's Y coordinate and writing to ENABL if necessary
>>
>>There's that incredible PHP trick for this... I always wonder if Stella
>>designers had already it in mind when they created the hardware.

>It is a very nice routine, fast and does not branch.
(...)
>I think the Stella designers must have had this in mind, because what other
>reason is there for ENAxx using bit 1 instead of bit 0 for data?  This
>works very well for single-height objects.  And considering this routine is
>used in Combat, I'm pretty sure it was intentional.

Uh, maybe the correct question was: had the _6502_ designers that trick in
mind? Afer all, what's the use of PHP if not for tricks like that?! (BTW,
how many years before the 2600 was the 6502 designed?)

>Is there an easy way to modify the PHP routine for a
>multiple height object?  Looks like you'd SBC the two numbers and if the
>result is less than N you'd enable the object.. this would work with an
>easy way of setting the Z flag from the carry flag without a branch. 
>
>Warning, untested code!  For the following code, MissileY equals the LAST
>scanline on which you want the missile to display

The LAST scanline! That's very clever, I hadn't thought of it!

>LDX #$1E        ;for ENAM1 - could also be used for ENABL or ENAM0
>TXS
>LDA MissileY
>SEC
>SBC Scanline    ;A has (MissileY - Scanline).  If it is >=0 but <4,
>                ;we want the carry clear.
>CLC
>ADC #252        ;If 0 <= A <= 3, the carry will now be clear.
>LDA #00
>ADC #00         ;If the carry was clear, A now = 0, so Z is set.
>PHP             ;Plug it into ENABL.

Looks like it could work...
Usually you will be doing that inside a loop; you can keep LDX#$1E and TXS
outside the loop, then do a PLA after PHP to restore the stack pointer to #$1E.

>Not bad, 21 cycles to handle an object of any height..

(...)

>Comparing with an alternate approach, using branching:
>LDX #0          ;+2  2
>LDA MissileY    ;+3  5
>SEC             ;+2  7
>SBC Scanline    ;+3 10
>CMP #3          ;+2 12
>BCS L1          ;+2 14
>LDX #2          ;+2 16
>L1 STX ENAM1    ;+3 19(18 if branch taken)
>
>This takes 18-19 for one object, 36-38 for two and 54-57 for three, so the
>timing is pretty close to the same.  Unless someone can optimize one
>instruction out of either routine?

This way you lose X (or Y), so the PHP trick is definitely better.

Ciao,
 P.


--
Archives available at http://www.biglist.com/lists/stella/archives/
E-mail UNSUBSCRIBE in the body to stella-request@xxxxxxxxxxx to be removed.

Current Thread