RE: [stella] Horizontal Positioning and Movement

Subject: RE: [stella] Horizontal Positioning and Movement
From: Robert "A." Colbert <colbertb@xxxxxxxxxxxx>
Date: Tue, 02 Sep 1997 14:01:43 -0500
>Reply to your message of 9/2/97 12:55 PM
>Could someone please give me some assistance with horizontal moveable
>object positioning and horizontal movement.
>I could really use a simple example of how it's done. Or at least a plain
>english explanation of the process.

O.K. a plain English example it is then:

You have two ways of changing the horizontal position of a player.

	1) Coarse positioning.  Wait the appropriate number of cycles
	after the WSYNC on a scanline and then write to RESP0.  The reason
	this positioning is referred to as coarse is that since there are 3
	color cycles per machine cycle, it would be impossible to place the
	player at the exact pixel you want.  A common way to do the coarse
	positioning is:

		; Routine to position player horizontally
		; On entry X=player (0/1)
		;          Y=Coarse position

		    STA    WSYNC   ;3	Wait for horizontal sync
		    DEY            ;2	
		    BPL    resloop ;2
		    STA    RESP0,X ;4
		    sta    WSYNC   ;3
		    RTS            ;6

	2) Fine Positioning.  Set a value in the HMP0 register to move a
	player to the left or right a certain number of pixels.  The
	player is moved that number of pixels each time HMOVE is written
	to, therefore, you may need to place a $00 back in the HMP0
	register after the player is moved.  Here are the values for

		70 : LEFT 7
		60 : LEFT 6
		50 : LEFT 5
		40 : LEFT 4
		30 : LEFT 3
		20 : LEFT 2
		10 : LEFT 1
		F0 : RIGHT 1 \
		E0 : RIGHT 2  \
		D0 : RIGHT 3   \
		C0 : RIGHT 4    \ Easy way to remember these is that
		B0 : RIGHT 5    / they are 2's compliments ($100 - x)
		A0 : RIGHT 6   /
		90 : RIGHT 7  /
		80 : RIGHT 8 /

Now you're probably wondering if there is an easy way to translate a
horizontal pixel position into the coarse/fine positioning values. Yes :)
This routine takes the value in A and calculates the correct values.  I
can't remember, but I think you may have to fudge the values a little
(i.e. 8 would be the low value or something like that).

		; On entry X = Player #
		;	   A = Horizontal Position desired
		    JSR    calcpos
		    STA    HMP0,X  ;4
		    INY            ;2
		    INY            ;2
		    INY            ;2
		    STA    WSYNC   ;3
		    DEY            ;2
		    BPL    resloop ;2
		    STA    RESP0,X ;4
		    sta    WSYNC
		    sta    HMOVE
		    RTS            ;6

		    TAY            ;2
		    INY            ;2
		    TYA            ;2
		    AND    #$0F    ;2
		    STA    tempos  ;3
		    TYA            ;2
		    LSR            ;2
		    LSR            ;2
		    LSR            ;2
		    LSR            ;2
		    TAY            ;2
		    CLC            ;2
		    ADC    tempos  ;3
		    CMP    #$0F    ;2
		    BCC    nextpos ;2
		    SBC    #$0F    ;2
		    INY            ;2

		    EOR    #$07    ;2
		    ASL            ;2
		    ASL            ;2
		    ASL            ;2
		    ASL            ;2
		    RTS            ;6

The only problem with the above example is that it wastes 2 entire scanline.
This would mean that you couldn't change the graphics in the other player, or
change the playfield or whatever.  You can save one scanline by precalculating
the coarse and fine values and storing them in a table or something.

If you have only 1 copy of a player on a screen, then you can easily move the
player around by setting a movement value in HMP0 and using an HMOVE each
frame.  This would move the player the number of pixels represented in HMP0
each frame.  Of course, with multiple copies of players, you have to keep
track of each copy's position on the screen and move the player to that
position before each copy is displayed.

Hope this helps!


Wanna write a game for the Atari 2600?
Check out

Archives updated once/day at
Unsubscribing and other info at

Current Thread