FWIW this is what happens inside the chip:
Each sprite has its own position counter that gets incremented at every visible pixel and wraps around to 0 at position 159. When it happens, a signal is generated to start drawing the sprite. Other signals are generated at positions 16, 32 and 64 and fed into the logic that generates 2nd/3rd copies of the sprite.
Under normal circumstances there are 160 visible pixels and so the counter overflows and the sprite is drawn at the same position on every scanline.
RESxx strobe resets the counter to 0 immediately. As there is no wrap around from 159, the sprite is not generated at the new position, but its 2nd/3rd copy will be drawn. Since 1 cpu cycle = 3pixels, it only works with 3 pixel accuracy.
When HMOVE is issued, 2 things happen:
1. A flag is set, causing subsequent horizontal blanking to be extended by 8 pixels, reducing the number of visible pixels to 152.
2. A sequence of N pulses (1 pulse every 4 pixel clocks) is generated and injected into the counter clock line. N is the value 0..15 that was written to HMxx register.
Now the way these pulses and regular counter clock pulses are mixed together causes some interesting side effects:
* If a pulse occurs during blanking interval, the counter is incremented by 1
* If a pulse occurs during visible portion, the clock misses a beat and the counter is NOT incremented by 1
So when you issue HMOVE immediately after WSYNC, the counter is first incremented by N (0..15) during the blank and then not incremented during the first 8 pixels, resulting in -8/+7 motion range, everything works as advertised.
If HMOVE is issued at other times, the pulses that occur during hblank are added, and pulses that occur during visible portion are subtracted from position counter, causing all sorts of weird effects depending on the timing. Plus, extending hblank by 8 pixels or may may not happen, causing extra 8 pixel shift. Also the sprites themselves may be weirdly stretched (sprite logic is driven by the same clock as the position counter).
HTH,
dmk