stella icon indicating copy to clipboard operation
stella copied to clipboard

HMOVE positioning odd TIA glitch

Open thrust26 opened this issue 4 years ago • 14 comments

James "Zeropage Homebrew" O'Brian's console is showing another glitch, where P0 is positioned one pixel too far right. The code does an early HMOVE immediately followed by RESP0. Maybe this can be emulated too.

image

thrust26 avatar Sep 09 '20 09:09 thrust26

I remember I had similar glitch on my 7800 and light sixer consoles when running the early 128 pixel "bus stuffing" demo by @SpiceWare:

https://atariage.com/forums/topic/183085-bus-stuffing-like-the-graduate/?do=findComment&comment=3588197

I just tested the "plus.bin" rom that @andrew-davie posted here. It works fine on the 7800, but shows the 1 pixel offset for the 1st and 3rd column on the light sixer just like James' console: IMG_20200909_215224 IMG_20200909_215311

ale-79 avatar Sep 09 '20 20:09 ale-79

Thanks, good to know that this is a common problem. Have you tested the console with other early HMOVE values?

thrust26 avatar Sep 09 '20 20:09 thrust26

No, it's not my primary console and I rarely power it on. Is there any test rom or game that I should check?

ale-79 avatar Sep 09 '20 20:09 ale-79

I have to check. Else I will write one myself.

thrust26 avatar Sep 09 '20 20:09 thrust26

I added a subroutine to the bus stuffing demo that would test for this issue and adjust the value used for HMxx

alex_79:        
        ; most systems use $B0 in HMP0 for the player arrangement to work
        ; alex_79 has 2 systems, a Light Sixer and 7800, which require the
        ; use of $C0 for the alignment to work.  This is most like the same
        ; reason that stars generated by the HM trick don't look the same on
        ; all systems.
        ; 
        ; to test for alex_79's system, we'll position player0 using the $C0
        ; value and see if it collides with a pattern in PF1.  If it does not
        ; collide then it's a system like his so we need to use $C0
        ; if it does collide then we'll assume it's a normal system.  It's
        ; possible other TIA variations exist, such as one that needs to use
        ; $A0.  If so, we can add additional tests
        
        sta WSYNC       ;    0
        lda #$C3        ; 2  2 
        sta HMP0        ; 3  5 - uses upper nybble
        sta NUSIZ0      ; 3  8 - uses lower nybble for player0
        lda #%00110011  ; 2 10
        sta PF1         ; 3 13
        lda #%11111111  ; 2 15
        sta GRP0        ; 3 18
        jsr SLEEP12     ;12 30
        jsr SLEEP12     ;12 42
        jsr SLEEP12     ;12 54
        jsr SLEEP12     ;12 66
        SLEEP 4         ; 4 70
        sta HMOVE       ; 3 73
        sta RESP0       ; 3 76/0
        sta CXCLR       ; 3  3 - clear collisions
        sta WSYNC       ; 3  6/0 - let the scanline get drawn
        ldy #$B0        ; assume a normal system (timing from here is not critical)
        bit CXP0FB      ; bit 7 holds results for P0 PF
        bmi .normal     ; 
        ldy #$C0
.normal:
        sty hmvalue
        ldy #0
        sty HMP0
        sty NUSIZ0
        sty PF1
        sty GRP0
        rts

Hmm - the code markup doesn't work quite right for this. (TJ: Fixed that fror you)

SpiceWare avatar Sep 09 '20 20:09 SpiceWare

I made a test rom for HMOVE that outputs the HMOVE chart as a text file by connecting the Atari to a PC serial port or USB to serial adapter, which allows to quickly test different systems.

Attached is the rom and the resulting tables from my consoles.

I think it's likely that some values will change a bit after the console is "warmed up", so I'll do more tests when I have the time. HMOVE_TEST.zip

ale-79 avatar Sep 14 '20 22:09 ale-79

Another test: HMOVE_RESPx_test.zip

This one strobes HMOVE and then RESP0 and prints the resulting absolute position of Player0 (0-159) Rows in the charts are for different HMOVE cycles (from 73 to 3), columns are the delay until RESP0 is strobed (from 3 to 24 cycles). The test is repeated for each of the 15 HMP0 values.

All my consoles give the same results, except for the Light Sixer.

As you can see, the L6 position the Player one pixel to the right compared to the other consoles if the RESP0 strobe happens at the same time the position counter receives an extra clock pulse (This can only happen if the cpu cycle is divisible by 4).

For HMP0=$80, there aren't extra pulses, and in fact in that case the chart is identical for all consoles, while with HMP0=$70, which corresponds to 15 extra pulses, we have the max number of differences. diff1 diff2 Vader L6

So it's a race condition between RESPx and HMOVE pulses: on the Light 6er, the position counter gets the extra clock pulse, then it is reset (so the extra pulse has no effect), while on the other consoles, it's reset and then it's clocked (so it's moved one pixel to the left).

ale-79 avatar Sep 20 '20 10:09 ale-79

Great analysis! Thanks a lot!

So either HMOVE is slower or RESPx is faster in the odd consoles. Can we find out somehow?

Does this only happen with P0 or also with P1 and missiles and ball?

thrust26 avatar Sep 22 '20 18:09 thrust26

So either HMOVE is slower or RESPx is faster in the odd consoles. Can we find out somehow?

Maybe someone with the right skills and equipment could get some hints by looking at the shape and/or phase of the clock signals on the board: the 3.58 MHz one from which the TIA derives all its internal clocks, and the "phase 2" 1.19 MHz one coming from the 6507, which would affect the timing of write operation to the registers.

Does this only happen with P0 or also with P1 and missiles and ball?

I only tested P0, but it's easy to modify the rom to try the other objects. Will do that.

ale-79 avatar Sep 22 '20 20:09 ale-79

I repeated the test for all the graphic objects. As with the previous tests, variations in positioning only happen if a strobe to RESxx coincide with an extra motion CLK pulse after an HMOVE. In all the other cases, all the consoles behave the same. Interestingly, on the same console the result of this race condition can differ for the various objects.

		BL	M0	M1	P0	P1

7800 (PAL)	L	L	L	L	L
JR_84 (PAL)	L	R	R	L	L
JR_91 (PAL)	L	R	R	L	L
L6 (PAL)	L	R	R	R	R
VADER (PAL)	L	R	R	L	L
WOODY (SECAM)	L	L	L	L	L

R = extra motion CLK pulse before the motion counter is reset (the extra CLK has no effect) L = the motion counter is reset before the extra motion CLK pulse (the extra CLK moves the object 1 pixel to the left)

HMOVE_RESPx_v2.zip results.zip

ale-79 avatar Sep 23 '20 22:09 ale-79

Thanks for the tests. Very interesting results, it looks even more complicated now.

@DirtyHairy Do you have an idea how to emulate this?

thrust26 avatar Sep 24 '20 06:09 thrust26

A very thorough analysis; thanks @ale-79 . Im a pretty sure this can be emulated, I'll give it a try.

DirtyHairy avatar Sep 24 '20 21:09 DirtyHairy

@DirtyHairy, pinging you to remind you to look at this when you find some extra time.

sa666666 avatar May 30 '22 21:05 sa666666

@DirtyHairy, pinging you to remind you to look at this when you find some extra time.

https://atariage.com/forums/topic/336441-boom-atari-2600/?do=findComment&comment=5068632

thrust26 avatar Jun 05 '22 17:06 thrust26