ATARI-2600 question anyone?
When a byte is stored in the TIA HMP0 register, a fine position adjustment is applied to the coarse beam position. The Stella manual says the value can be anywhere from -8 to 7. Where -8 is (1000 binary) and 7 is (0111 binary) because the nibble is read as two's complement.
My issue is that I am having trouble getting the Sprite to render when any of the negative fine position values are applied. As a demo, observe the diagonal lines rendered for Sprite 0 as the result of HMOVE shifts by raster line. However when the value applied has an high bit of 1 (aka negative) the sprite disappears and there is nothing on that scan line. For comparison Sprite 1 renders as a straight line the length of the screen b/c no fine position is applied.
The code of the visible lines loop is as follows:
ScanLoop
REPEAT 10 ; wait to
nop ; get beam
REPEND ; arbitrarily near center
; All we do here is ++ the hi nibble in the Accumulator
; and apply it to HMP0 to adjust the fine position.
; QUESTION FOR READER: WHY DOESN'T THE SPRITE RENDER WHEN
; THE VALUE EQUATES TO A NEGATIVE VALUE (-7...-1?)
clc
adc #%00010000 ; Add (UI) '1' to high nibble in A
sta HMCLR ; Due diligence - clear all Motion values
sta HMP0 ; Set fine P0 Sprite pos to incremented value (*)
sta RESP0 ; set coarse position of P0 Sprite
sta RESP1 ; Set coarse position (only) of P1 Sprite
sta WSYNC ; Wait for next scanline
sta HMOVE ; Apply fine tweak
stx COLUBK ; Set the background color
dex ; decrement the scanline
bne ScanLoop
;(*)PS: Tried putting HMP0 after RESP's, didn't help
The project is for this code is here on teh githubs, and the project on the online Atari emulator 8bitworkshop is here.
As I understand, if a solution is provided, then the Sprite on the left will render on every line w/o break with the dot position two's complement bit-pattern.
Player objects do not display upon reset (i.e. when you hit
RESP0
); there is a delay that causes the position you've set to be effective on the next line but not the current. To quote TIA_HW_Notes.txt:So the reason you're not seeing player objects appear when you specify offsets to the right of their original position is simply that you're hitting
RESP0
on the next line before object output has begun, which delays it a line.Conversely, in the cases where you're moving it to the left output begins before you hit reset, and therefore is visible.
To provide a little more detail, even if possibly redundant, the 2600's player objects:
Reset is distinct from overflow, so doesn't trigger an object display.
For fine movement, the hardware allows you to:
HMOVE
, which extends the left border by eight pixels thereby moving all objects eight pixels to the right due to the absence in counter clocking; andHMPx
value, which is a number of extra clocks up to 15 that can be pushed to the object's counter during the border.So you can undo any number of the lost clocks of the
HMOVE
, and even add up to 7 additional clocks, causing the object to be triggered earlier than it otherwise would have been. As a convenience, the two's complement number you supply has its top bit inverted.So, what I think is happening with your code:
For lines on which the object does appear you:
Therefore it appears as positioned.
For lines on which the object does not appear you:
HMOVE
andHMP0
such that the counter would overflow on the next line after the position at which you just reset it; butSo the counter never gets a chance to overflow and the object doesn't appear.