You can't possibly increment a register every TIA cycle. The TIA is 3 times faster than the CPU, and INX/INY take 2 CPU cycles, so the minimum you can have is one increment every 6 TIA cycles/pixels. But this is not how you go about positioning sprites anyway.
If you never reuse objects during the frame, moving objects can be really simple, because they retain their positions from one frame to the next, so you can simply use the HMOVE registers to move stuff up to 8 pixels to the left or 7 pixels to the right. If you're not comfortable with timing all the RESET writes, you can even reset everything to the far left and use HMOVE across several scanlines to get everything to the correct positions.
If you do need to reposition sprites mid-screen though, you better get acquainted with the method of counting cycles and resetting them near the desired position and adjusting with HMOVE. There are countless general-purpose routines for this that anyone can use, if you don't want to write your own.
As for vertical positioning, that happens completely in software, since the TIA itself only has enough state for 1 scanline (or even less, if you consider that the playfield is mirrored or reflected), so it's entirely up to you to count scanlines and figure out what should be displayed when.
One simple way to do it is to maintain an scanline counter in RAM, and every scanline (or every other scanline, in the case of a 2-scanline kernel) subtract the sprite's position from the scanline index, so that the result is the index of the row of graphics to use. If the row is valid, use it to fetch the graphics, otherwise, clear the graphics to make the object invisible. For example, say you find yourself with the following state:
Scanline: 27
SpriteY: 28
Sprite height: 16
GraphicsRow = 27 - 28 = -1
The result is not a valid row (i.e. between 0 and 15), so the sprite should not be displayed. Then, on the next scanline:
Scanline: 28
SpriteY: 28
Sprite height: 16
GraphicsRow = 28 - 28 = 0
Now we have a valid graphics row index, that can be used to fetch sprite patterns, by loading this index in Y and indexing from a pointer. The row index will remain valid until scanline 43. After that, we have the following situation:
Scanline: 44
SpriteY: 28
Sprite height: 16
GraphicsRow = 44 - 28 = 16
Index 16 is no longer valid, so we can stop drawing the sprite. If you were paying attention, you may have noticed that a single verification can tell you whether the index is valid, since negative numbers in 2's complement are > 127, so the check for > 15 will also catch negative numbers:
Code:
lda Scanline
sbc SpriteY
cmp SpriteHeight
bcc Fetch
lda #$00
beq Draw
Fetch:
lda (SpritePattern), y
Draw:
sta GRP0
As long as you have 128 or less scanlines where this sprite can be. There are several ways to optimize this further, but this is the basic idea.