Jump to content

Xenomech's Photo


Member Since 12 Jul 2016
OFFLINE Last Active Mar 20 2018 5:24 AM

Posts I've Made

In Topic: REALLY dumb question. How do I move sprites horizontally?

Fri Jan 12, 2018 1:38 PM

When it comes to programming for the Atari 2600, I think it's safe to say that there definitely are no dumb questions -- even the simplest thing can be extremely difficult to figure out.



Just for reference, here's a quote from the Stella Programmer's Guide:


7.0 Horizontal Positioning

The horizontal position of each object is set by writing to its’ associated reset
register (RESP0, RESP1, RESM0, RESM1, RESBL) which are all “strobe”
registers (they trigger their function as soon as they are addressed).  That
causes the object to be positioned wherever  the electron bean was in its
sweep across the screen when the register was reset.  for example, if the
electron beam was 60 color clocks into a scan line when RESP0 was written
to, player 0 would be positioned 60 color clocks "in” on the next scan line.
Whether or not P0 is actually drawn on the screen is a function of the data
in the GP0 register, but if it were drawn, it would show up at 60.  Resets to
these registers anywhere during horizontal blanking will position objects at
the left edge of the screen (color clock 0).  Since there are 3 color clocks per
machine cycle, and it can take up to 5 machine cycles to write the register,
the programmer is confined to positioning the objects at 15 color clock
intervals across the screen.  This “course” positioning is “fine tuned” by the
Horizontal Motion, explained in section 8.0.

Missiles have an additional positioning command.  Writing a “1” to D1 of
the reset missile-to-player register (RESMP0, RESMP1) disables that
missiles’ graphics (turns it off) and repositions it horizontally to the center
of its’ associated player.  Until a “0” is written to the register, the missiles’
horizontal position is locked to the center of its’ player in preparation to be
fired again.

8.0 Horizontal Motion

Horizontal motion allows the programmer to move any of the 5 graphics
objects relative to their current horizontal position.  Each object has a 4 bit
horizontal motion register (HMP0, HMP1, HMM0, HMM1, HMBL) that can
be loaded with a value in the range of +7 to -8 (negative values are
expressed in two’s complement from).  This motion is not executed until the
HMOVE register is written to, at which time all motion registers move their
respective objects.  Objects can be moved repeatedly by simply executing
HMOVE.  Any object that is not to move must have a 0 in its motion
register.  With the horizontal positioning command confined to positioning
objects at 15 color clock intervals, the motion registers fills in the gaps by
moving objects +7 to -8 color clocks.  Objects can not be placed at any color
clock position across the screen.  All 5 motion registers can be set to zero
simultaneously by writing to the horizontal motion clear register (HMCLR).

There are timing constraints for the HMOVE command.  The HMOVE
command must immediately follow a WSYNC (Wait for SYNC) to insure the
HMOVE operation occurs during horizontal blanking.  This is to allow
sufficient time for the motion registers to do their thing before the electron
beam starts drawing the next scan line.  Also, for mysterious internal
hardware considerations, the motion registers should not be modified for at

least 24 machine cycles after an HMOVE command.



Really, the simplest and most straight-forward way to implement horizontal movement is to implement the SetHorizPos subroutine that Kiwi mentioned above.  Lots of people use that subroutine (or a variation thereof).