Please be advised that access to Atari Forum this coming Friday will be sporadic whilst the backend operating system and dependency upgrades are carried out.

horizontal scrolling on ST

GFA, ASM, STOS, ...

Moderators: Zorro 2, Moderator Team

User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

troed wrote: I'm now reaching back 24 full years into the distant past but I think that's probably wakemode dependent. I'm saying that because I'm under the belief that I reacted already then to the TCB screen sometimes having a centered logo, sometimes not. Of course, then there's was no explanation known.

(Which makes me wonder which line length they managed to trigger since I remember the offset to be somewhat substantial)
Fear my memory.

WS3: Logo offset to the left.
WS2: Logo centered.

Visual inspection:

Line #1: Regular PAL 160
Line #2: NTSC 160 in WS2, PAL(? NTSC) 184 in WS3

(So I'm slightly confused - but it really looks like an opened left border on line #2 in WS3. I almost posted this claiming it was PAL 158 but .. )

A quick'n'dirty test with measurement tape supports a 48 pixel offset.

edit: If TCB knew about this being different between boots or at least between different STs, it's even possible they elected to purposely run the second line in NTSC since a 186 byte line would've created bitplane shifts and the necessity to handle that in code. Now I guess I need to go and disassemble the screen, again*, to find out.

edit2: Alright, so, looking at the code nothing really stands out**. The top border is opened with a single 60/50 switch with a 16 nop gap - followed by synclock and then they wait until it's time for the left border (so no try to open right border on first line) and do 228 fullscreen scanlines. 13 nops between right border and stabilizer, 13 nops between stabilizer and left border (so I assume it's done at cycle 4) - and the left border is a short no-gap switch.

Let's pretend they messed up and waited one nop too little after the first regular top border line. The left border would now happen at cycle 0, switch back at cycle 8 which would fail in WS2 but work in WS1/WS3/WS4. It would also cause the right border to become a short right (-2) - so - this seems almost consistent with what I see. What I don't have an explanation for is how the failed left border (switching back too soon) can create an NTSC 160 but there's visibly four pixels to the left of the line above (and four less on the right) - and that line being 508 cycles is what would then explain how come all the other lines are correct afterwards. And, equally strange, even the 184 byte line in WS1/3/4 needs to be 508 cycles then since the right border opens correctly on all other lines.

There must be something I'm missing, still [edit3: found it. wow]. Code below ..

/Troed

*) I did that already a year or so back when I investigated who was first with stabilized fullscreen lines and saw that the TCB screen had the exact same switches as Level 16. I'm positive that's where they got it from, and that the reason the SNYD screen isn't a fullscreen was to not steal Level 16's thunder in the Union Demo.

**)

Code: Select all

top border
$00ddd0 : 4238 820a                            clr.b     $ffff820a.w
$00ddd4 : 7003                                 moveq     #3,d0
$00ddd6 : 4e71                                 nop       
$00ddd8 : 51c8 fffc                            dbra      d0,$ddd6
$00dddc : 31fc 0002 820a                       move.w    #2,$ffff820a.w

synclock etc
$00dde2 : 31fc 0000 8240                       move.w    #0,$ffff8240.w
$00dde8 : 1010                                 move.b    (a0),d0
$00ddea : 67fc                                 beq.s     $dde8
$00ddec : 9440                                 sub.w     d0,d2
$00ddee : e569                                 lsl.w     d2,d1
$00ddf0 : 4df8 8800                            lea       $ffff8800.w,a6
$00ddf4 : 4e71                                 nop       
$00ddf6 : 4e71                                 nop       
$00ddf8 : 4e71                                 nop       
$00ddfa : 4e71                                 nop       
$00ddfc : 4e71                                 nop       
$00ddfe : 4e71                                 nop       
$00de00 : 4e71                                 nop       
$00de02 : 4e71                                 nop       
$00de04 : 4e71                                 nop       
$00de06 : 4e71                                 nop       
$00de08 : 4e71                                 nop       
$00de0a : 4e71                                 nop       
$00de0c : 4e71                                 nop       
$00de0e : 4e71                                 nop       
$00de10 : 4e71                                 nop       
$00de12 : 4e71                                 nop       
$00de14 : 4e71                                 nop       
$00de16 : 4e71                                 nop       
$00de18 : 4e71                                 nop       
$00de1a : 4e71                                 nop       
$00de1c : 4e71                                 nop       
$00de1e : 4e71                                 nop       
$00de20 : 4e71                                 nop       
$00de22 : 4e71                                 nop       
$00de24 : 4e71                                 nop       
$00de26 : 4e71                                 nop       
$00de28 : 4e71                                 nop       
$00de2a : 700e                                 moveq     #$e,d0
$00de2c : 4e71                                 nop       
$00de2e : 51c8 fffc                            dbra      d0,$de2c
$00de32 : 41f9 00ff 820a                       lea       $ff820a,a0
$00de38 : 303c 00e3                            move.w    #$e3,d0

fullscreen lines loop begins here
$00de3c : 4e71                                 nop       
$00de3e : 1283                                 move.b    d3,(a1)
$00de40 : 1284                                 move.b    d4,(a1)
$00de42 : 720c                                 moveq     #$c,d1
$00de44 : 4e71                                 nop       
$00de46 : 51c9 fffc                            dbra      d1,$de44
$00de4a : 4e71                                 nop       
$00de4c : 4bfa 044e                            lea       $e29c(pc),a5
$00de50 : 7a00                                 moveq     #0,d5
$00de52 : 1a1c                                 move.b    (a4)+,d5
$00de54 : e74d                                 lsl.w     #3,d5
$00de56 : 2c35 5000                            move.l    (a5,d5.w),d6
$00de5a : 3a35 5004                            move.w    4(a5,d5.w),d5
$00de5e : 4bf8 8800                            lea       $ffff8800.w,a5
$00de62 : 0dcd 0000                            movep.l   d6,0(a5)
$00de66 : 0b8d 0000                            movep.w   d5,0(a5)
$00de6a : 4e71                                 nop       
$00de6c : 4e71                                 nop       
$00de6e : 4e71                                 nop       
$00de70 : 1084                                 move.b    d4,(a0)
$00de72 : 1083                                 move.b    d3,(a0)
$00de74 : 4e71                                 nop       
$00de76 : 4e71                                 nop       
$00de78 : 4e71                                 nop       
$00de7a : 4e71                                 nop       
$00de7c : 4e71                                 nop       
$00de7e : 4e71                                 nop       
$00de80 : 4e71                                 nop       
$00de82 : 4e71                                 nop       
$00de84 : 4e71                                 nop       
$00de86 : 4e71                                 nop       
$00de88 : 4e71                                 nop       
$00de8a : 4e71                                 nop       
$00de8c : 4e71                                 nop       
$00de8e : 1283                                 move.b    d3,(a1)
$00de90 : 4e71                                 nop       
$00de92 : 1284                                 move.b    d4,(a1)
$00de94 : 4e71                                 nop       
$00de96 : 4e71                                 nop       
$00de98 : 4e71                                 nop       
$00de9a : 4e71                                 nop       
$00de9c : 4e71                                 nop       
$00de9e : 4e71                                 nop       
$00dea0 : 4e71                                 nop       
$00dea2 : 4e71                                 nop       
$00dea4 : 4e71                                 nop       
$00dea6 : 51c8 ff94                            dbra      d0,$de3c
Last edited by troed on Fri Sep 13, 2013 11:57 pm, edited 3 times in total.
User avatar
npomarede
Atari God
Atari God
Posts: 1558
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: horizontal scrolling on ST

Post by npomarede »

troed wrote: Line #1: Regular PAL 160
Line #2: NTSC 160 in WS2, PAL(?) 184 in WS3

(So I'm slightly confused - but it really looks like an opened left border on line #2 in WS3. I almost posted this claiming it was PAL 158 but .. )

A quick'n'dirty test with measurement tape supports a 48 pixel offset.

edit: If TCB knew about this being different between boots or at least between different STs, it's even possible they elected to purposely run the second line in NTSC since a 186 byte line would've created bitplane shifts and the necessity to handle that in code. Now I guess I need to go and disassemble the screen, again*, to find out.

/Troed

*) I did that already a year or so back when I investigated who was first with stabilized fullscreen lines and saw that the TCB screen had the exact same switches as Level 16. I'm positive that's where they got it from, and that the reason the SNYD screen isn't a fullscreen was to not steal Level 16's thunder in the Union Demo.
I saw the same thing when trying to debug this one some times ago. Hatari will trigger a left/right border removal, but the line requires to be a 60 Hz 160 bytes line for the logo to be centered. In Hatari, the wakeup state is fixed for now, so you always get the same result, but I never paid attention if the logo was always centered or not on my STF.

Here're the switches they use :

sync=0x00 video_cyc_w=17352 line_cyc_w=456 @ nHBL=33/video_hbl_w=33 pc=dde2 instr_cyc=16
shifter=0x02 video_cyc_w=17916 line_cyc_w=0 @ nHBL=34/video_hbl_w=35 pc=de40 instr_cyc=8
shifter=0x00 video_cyc_w=17924 line_cyc_w=8 @ nHBL=35/video_hbl_w=35 pc=de42 instr_cyc=8
detect remove left 0<->372
sync=0x00 video_cyc_w=18288 line_cyc_w=372 @ nHBL=35/video_hbl_w=35 pc=de72 instr_cyc=8
sync=0x02 video_cyc_w=18296 line_cyc_w=380 @ nHBL=35/video_hbl_w=35 pc=de74 instr_cyc=8
detect right-2 0<->372

shifter=0x02 video_cyc_w=18940 line_cyc_w=4 @ nHBL=37/video_hbl_w=37 pc=de40 instr_cyc=8
shifter=0x00 video_cyc_w=18948 line_cyc_w=12 @ nHBL=37/video_hbl_w=37 pc=de42 instr_cyc=8
detect remove left 0<->376

We can see that the hi/lo switch on hbl 35 is made at cycle 0/8 while freq is already 60 Hz. Does this switch gives a different result if freq is 50 Hz or 60 Hz ?
If we want the logo to be centered, we must consider that hi/lo at 0/8 has no effect to remove left border, so the line will start in 60 Hz and the 60/50 at 372/380 will have no effect, because the line is already at 60 Hz (this is the result I often get on my STF).

But those timings are really like the ones when you want to remove left/right border (maybe there was also a hi/lo stabilizer on line 35, I didn't note it at the time I saved some traces) ; so did this screen worked just by luck with no plane being shifted but only the logo moved from 48 pixels depending on the WS ?
Maybe they found this combination to be good in the different WS but without having no real explanation ?

Nicolas
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

(See my major edit after disassembling just now - sorry - didn't check to see if anyone had posted in between)
npomarede wrote: We can see that the hi/lo switch on hbl 35 is made at cycle 0/8 while freq is already 60 Hz. Does this switch gives a different result if freq is 50 Hz or 60 Hz ?
Well if that line is in 60Hz then it explains the 508 cycles I need for the math to add up - but I don't see why it's in 60Hz :(

edit: Oh, lol, now I do. Wow. That just cannot have been done on purpose.
If we want the logo to be centered, we must consider that hi/lo at 0/8 has no effect to remove left border, so the line will start in 60 Hz and the 60/50 at 372/380 will have no effect, because the line is already at 60 Hz (this is the result I often get on my STF).
hi/low at 0/8 will indeed fail in WS2 (only) according to Paolo's Excel-sheet.
Maybe they found this combination to be good in the different WS but without having no real explanation ?
Could be - since the logo is centered only in WS2 I'm almost assuming that's what their ST defaulted to - but I'm sure any WS2-liking machine gets into WS1 every so often as well.
User avatar
npomarede
Atari God
Atari God
Posts: 1558
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: horizontal scrolling on ST

Post by npomarede »

troed wrote: Well if that line is in 60Hz then it explains the 508 cycles I need for the math to add up - but I don't see why it's in 60Hz :(

edit: Oh, lol, now I do. Wow. That just cannot have been done on purpose.
My guess is that they really wanted to do a left/right removal just after removing top border, but this one looks just like a usual left/right removal done 4 cycles too soon.
It happens 4 cycles too soon because previous line is 60 Hz for too long and only has 508 cycles.
As you say, their ST probably was always in WS2, so I think they applied the usual solution in such case : adapt the gfx in memory to get the correct result on screen, even if you don't know why ;-)
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

(Btw, all lurkers, the current discussion about TCB's SNYD-screen is likely extremely on-topic, I'll get back to that at the end of this post)
npomarede wrote:My guess is that they really wanted to do a left/right removal just after removing top border, but this one looks just like a usual left/right removal done 4 cycles too soon.
It happens 4 cycles too soon because previous line is 60 Hz for too long and only has 508 cycles.
Well, I agree they wanted to do regular fullscreen lines and failed due to the quite critical typo in the top border switch :oops: - but - my visual inspection tells me the first line isn't in 60Hz (it's visibly four pixels to the right of the 60Hz line below) and also if it was 508 cycles it would have the effect of all the following lines being one nop too late, not too early. (That's what saves the alignment of the whole screen after the 508-cycle #2 line). I believe it's a combination of the typo _and_ being one nop too early after the sync lock.

So, I'm guessing that when starting out in 50Hz removing the top border, in that failed way, the state machine cannot (?) create a 60Hz first line. This would of course have to be verified but I cannot really explain why it's in 50Hz otherwise just by looking at the top border switch position.

Anyway, so about the fact that we're on topic: I believe this screen is the origin of the TCB sync scroller (which was one of at least two concurrent and independently invented*) - since it so very visibly by accident shows that by doing sync line combinations you can "move" the screen with stable bitmap appearance by 48 pixels. It also shows a line ending that's different from the regular 160, and even though TCB never used that in a syncscroller (not in Cuddly, not in SoWatt and not in Enchanted Lands) 158 and 184 were used by SYNC already in the spring of 1989.

/Troed

*) One other was by The Flying Egg/Omega - never released. I'm still hoping to be able to rescue code from Redhead's crashed hard drives before stating too certainly what SYNC did and when. Currently I have a lot of scroll texts written for the Synchron Mega Demo in march 1989 (never released then nor later) but not the most interesting screens themselves ...
User avatar
Steven Seagal
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2018
Joined: Sun Dec 04, 2005 9:12 am
Location: Undisclosed

Re: horizontal scrolling on ST

Post by Steven Seagal »

troed wrote: Fear my memory.

WS3: Logo offset to the left.
WS2: Logo centered.

Visual inspection:

Line #1: Regular PAL 160
Line #2: NTSC 160 in WS2, PAL(? NTSC) 184 in WS3

(So I'm slightly confused - but it really looks like an opened left border on line #2 in WS3. I almost posted this claiming it was PAL 158 but .. )

A quick'n'dirty test with measurement tape supports a 48 pixel offset.

edit: If TCB knew about this being different between boots or at least between different STs, it's even possible they elected to purposely run the second line in NTSC since a 186 byte line would've created bitplane shifts and the necessity to handle that in code. Now I guess I need to go and disassemble the screen, again*, to find out.

edit2: Alright, so, looking at the code nothing really stands out**. The top border is opened with a single 60/50 switch with a 16 nop gap - followed by synclock and then they wait until it's time for the left border (so no try to open right border on first line) and do 228 fullscreen scanlines. 13 nops between right border and stabilizer, 13 nops between stabilizer and left border (so I assume it's done at cycle 4) - and the left border is a short no-gap switch.

Let's pretend they messed up and waited one nop too little after the first regular top border line. The left border would now happen at cycle 0, switch back at cycle 8 which would fail in WS2 but work in WS1/WS3/WS4. It would also cause the right border to become a short right (-2) - so - this seems almost consistent with what I see. What I don't have an explanation for is how the failed left border (switching back too soon) can create an NTSC 160 but there's visibly four pixels to the left of the line above (and four less on the right) - and that line being 508 cycles is what would then explain how come all the other lines are correct afterwards. And, equally strange, even the 184 byte line in WS1/3/4 needs to be 508 cycles then since the right border opens correctly on all other lines.

There must be something I'm missing, still [edit3: found it. wow]. Code below ..

/Troed

*) I did that already a year or so back when I investigated who was first with stabilized fullscreen lines and saw that the TCB screen had the exact same switches as Level 16. I'm positive that's where they got it from, and that the reason the SNYD screen isn't a fullscreen was to not steal Level 16's thunder in the Union Demo.

**)
Thx a lot dude!
I asked here before what the TCB screen was supposed to be but never got an answer.
Thanks to your precise findings, this behaviour according to wake-up state 1/2 will soon be emulated in Steem.

One difficulty in Steem is the confusion due to 508 cycles scanlines in a 50hz frame.
In Steem the timings of all HBLs are prepared for each frame using the "event" system.
In a 50hz frame, when there are 60hz (508 cycles) scanlines, Steem will be off by 4 cycles in its reckoning of the start of the HBL (linecycle 0).
Because scanlines -29 and -30 are 60hz in "TCB", Steem got the wrong cycles: R2 at 4 instead of 0 on line -28.
It's hard to fix without messing other timings (like CPU, MFP...) but I finally found a simple way.

Code: Select all

fix: Steem cycle confusion with 508 cycles lines

TCB before fix, ignore WU

-30 - 376:S0000 460:S0000 512:T0100 512:#0160
-28 - 004:R0002 012:R0000 376:S0000 384:S0002 444:R0002 456:R0000 508:T2009 508:#0184
-27 - 004:R0002 012:R0000 376:S0000 384:S0002 444:R0002 456:R0000 512:T2011 512:#0230

TCB after fix, WU1

-30 - 368:S0000 452:S0000 512:T0100 512:#0160
-28 - 000:R0002 008:R0000 372:S0000 380:S0002 440:R0002 452:R0000 508:T2009 508:#0184
-27 - 004:R0002 012:R0000 376:S0000 384:S0002 444:R0002 456:R0000 512:T2011 512:#0230

TCB after fix, WU2 (CPU timing)

-30 - 372:S0000 458:S0000 512:T0100 512:#0160
-28 - 000:R0002 008:R0000 372:S0000 380:S0002 440:R0002 452:R0000 508:T2000 508:#0160
-27 - 004:R0002 012:R0000 376:S0000 384:S0002 444:R0002 456:R0000 512:T2011 512:#0230

TCB after fix, WU2 (when registers are hit)

-30 - 370:S0000 454:S0000 512:T0100 512:#0160
-28 - 002:R0002 010:R0000 374:S0000 382:S0002 442:R0002 454:R0000 508:T2000 508:#0160
-27 - 006:R0002 014:R0000 378:S0000 386:S0002 446:R0002 458:R0000 512:T2011 512:#0230
In the CIA we learned that ST ruled
Steem SSE: http://sourceforge.net/projects/steemsse
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Steven Seagal wrote: Thx a lot dude!
I asked here before what the TCB screen was supposed to be but never got an answer.
Thanks to your precise findings, this behaviour according to wake-up state 1/2 will soon be emulated in Steem.
Thanks - although I'm still slightly confused over how -29 and -28 are not vertically aligned (WS2) nor right-aligned (WS1/3/4) when they both are 508 cycle lines according to this theory (which seems to pan out). My visual judgment was that -29 is PAL 160 and -28 is NTSC 160, but the code shouldn't be able to produce that due to the failed top border switch to 50Hz.

I'll probably keep pondering it but as long as it emulates correctly I guess it's fine ;)
TCB after fix, WU1
TCB after fix, WU2 (CPU timing)
TCB after fix, WU2 (when registers are hit)
You're opening up a big can of worms ;) I think if emulation wants to go down the way of supporting the known wakestates a proper state machine must be implemented. I don't think it'll be slower than the current tests.

(I use "WU1" and "WU2" notation for the old Ijor wakeup modes myself, and WS1/2/3/4 for the new Paolo ones. In LoSTE I elected to use Dio's DL3-6 notation instead since it's less likely to cause confusion between the two)

Your current implementation if I read the tables correctly, while working for this screen, is a mixture between WU and WS support. I guess it's a choice between emulating known code properly or emulating the hardware as closely as possible.

It's relatively straight forward to convert Paolo's Excel-sheet into a pseudo-code state machine. I might do that later.

/Troed
User avatar
Steven Seagal
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 2018
Joined: Sun Dec 04, 2005 9:12 am
Location: Undisclosed

Re: horizontal scrolling on ST

Post by Steven Seagal »

troed wrote: Thanks - although I'm still slightly confused over how -29 and -28 are not vertically aligned (WS2) nor right-aligned (WS1/3/4) when they both are 508 cycle lines according to this theory (which seems to pan out). My visual judgment was that -29 is PAL 160 and -28 is NTSC 160, but the code shouldn't be able to produce that due to the failed top border switch to 50Hz.

I'll probably keep pondering it but as long as it emulates correctly I guess it's fine ;)
What matters is what you see. This line -29 should be 60hz (NTSC) but you see that it starts at the 50hz position (PAL), so that's what happens, right?
You couldn't know, but there's a hack in Steem for precisely this program at this scanline, when the shifter counter is read, the value has to be as for a 50hz line (starting at cycle 56), if it's 2 bytes higher (starting at cycle 52), the screen is broken.
I thought it had something to do with Steem internal problems, but your visual inspection implies that it's a ST issue.

Not working:
-30 - 364:S0000 450:S0000 472:r0900 492:r0900 512:r0900 512:T0100 512:#0000
-29 - 020:r0900 040:r0900 060:r0900 080:r0908 512:R0002

Working:
-30 - 388:S0000 474:S0000 496:r0900 512:T0100 512:#0000
-29 - 004:r0900 024:r0900 044:r0900 064:r0900 084:r0908

(r09=read $FF8209, XX=value)


You're opening up a big can of worms ;) I think if emulation wants to go down the way of supporting the known wakestates a proper state machine must be implemented. I don't think it'll be slower than the current tests.

(I use "WU1" and "WU2" notation for the old Ijor wakeup modes myself, and WS1/2/3/4 for the new Paolo ones. In LoSTE I elected to use Dio's DL3-6 notation instead since it's less likely to cause confusion between the two)

Your current implementation if I read the tables correctly, while working for this screen, is a mixture between WU and WS support. I guess it's a choice between emulating known code properly or emulating the hardware as closely as possible.

It's relatively straight forward to convert Paolo's Excel-sheet into a pseudo-code state machine. I might do that later.

/Troed
I call it WU because it's the symbol for wake-up in some devices (HD6301), but I try to enforce WS1 & WS2 of Paolo, ignoring WS3 & WS4 for now.
But you're right that the current implementation is still a mixture.
In the CIA we learned that ST ruled
Steem SSE: http://sourceforge.net/projects/steemsse
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Steven Seagal wrote:What matters is what you see. This line -29 should be 60hz (NTSC) but you see that it starts at the 50hz position (PAL), so that's what happens, right?
You couldn't know, but there's a hack in Steem for precisely this program at this scanline, when the shifter counter is read, the value has to be as for a 50hz line (starting at cycle 56), if it's 2 bytes higher (starting at cycle 52), the screen is broken.
I thought it had something to do with Steem internal problems, but your visual inspection implies that it's a ST issue.

Working:
-30 - 388:S0000 474:S0000 496:r0900 512:T0100 512:#0000
-29 - 004:r0900 024:r0900 044:r0900 064:r0900 084:r0908
Is line -29 508 or 512 cycles in the working scenario? I've redone my visual check and there's a very obvious 4 pixel difference between line -29 and -28 that the only explanation I can think of I really should just write code to test.

Anyway,
troed wrote:It's relatively straight forward to convert Paolo's Excel-sheet into a pseudo-code state machine. I might do that later.
This is a first stab at it - and mostly just to show what I mean. It's not fully complete (STE lacking, doesn't use H to trigger actual line starts/ends), and currently only deal with line lengths. It's very similar to Alien's pseudo-code state machines for a reason - those were pretty complete besides the new wakestate knowledge.

Code: Select all

VAR H; H signal as per Alien's doc
VAR LINE; PAL = 512 cycle 50Hz, NTSC = 508 cycle 60Hz, HIRES = 224 cycle 71Hz
VAR RES; $ff8260, 0 = LO, 2 = HI
VAR FREQ; $ff820a, 0 = 60, 2 = 50
VAR BLANK; Activate blank (? Alien's doc says it isn't used in high res but obviously is causative)

Cycle values are for WS3/4. In WS1 all ff8260 state checks happen 2 cycles earlier, in WS2 2 cycles later.

6     IF(RES == HI) H = TRUE
[lots of checks relating to blank skipped]
(32     IF(RES == HI) LINE = HIRES // todo, there must be a matching position for LORES, if it isn't default)
58     IF(RES == LO) H = TRUE // todo, "unique spot"
166     IF(RES == HI) H = FALSE
186     IF(RES == HI) BLANK = TRUE
378     IF(RES == LO) H = FALSE
["no line 1" and "no line 2" not handled - want to understand what checks cause them]

Cycle values are for WS1/3, in WS2/4 all ff820a state checks happen 2 cycles later

[checks relating to blank skipped]
52     IF(FREQ == 60) H = TRUE
54     IF(FREQ == 50) LINE = PAL // todo, there must be a matching position for NTSC, if it isn't default
56     IF(FREQ == 50) H = TRUE // todo, "unique spot"
372     IF(FREQ == 60) H = FALSE
376     IF(FREQ == 50) H = FALSE
For emulator use I would see the above implemented in a single loop triggering when the emulated cycle hits the checks - offset with -2,0,+2 and 0,+2 respectively for 8260 and 820a either randomly (lol) or configurable. While the above is a naïve and very incomplete version I believe it's closer to the real hardware and a better way to emulate the known wakestates. I'm hugely impressed with the current state of emulators - reading through shifter.cpp in Steem and video.c in Hatari is a fun way to spend an evening (I mean it :)) - but there are a lot of checks for "switching to and from" which really should be closer to states at specific cycles.

Opinions - Steven and Nicolas?
User avatar
npomarede
Atari God
Atari God
Posts: 1558
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: horizontal scrolling on ST

Post by npomarede »

troed wrote: For emulator use I would see the above implemented in a single loop triggering when the emulated cycle hits the checks - offset with -2,0,+2 and 0,+2 respectively for 8260 and 820a either randomly (lol) or configurable. While the above is a naïve and very incomplete version I believe it's closer to the real hardware and a better way to emulate the known wakestates. I'm hugely impressed with the current state of emulators - reading through shifter.cpp in Steem and video.c in Hatari is a fun way to spend an evening (I mean it :)) - but there are a lot of checks for "switching to and from" which really should be closer to states at specific cycles.

Opinions - Steven and Nicolas?
Hello
that's my intention since some months to rewrite video.c in a more state machine way, but there're other parts I'd like to split more cleanly in Hatari before doing it. In some cases Hatari behaves like a state machine, it can handle ranges of changes instead of changes at the precise cycles (for example if you do 60 Hz at line 20 and 50 Hz at line 40, it will remove top border (and create some 508 cycles lines also), top border detection is not limited to line 33).
But in the case of Hatari it would not be implemented as a loop, because it would decrease emulation's speed too much. Instead of looping in the state machine every 4 cycles and see what is changing, it's more efficient to update the state machine only when a write to ff820a/ff8260 is made (plus some other updates at end of hbl/vbl).

Nicolas
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

npomarede wrote: But in the case of Hatari it would not be implemented as a loop, because it would decrease emulation's speed too much. Instead of looping in the state machine every 4 cycles and see what is changing, it's more efficient to update the state machine only when a write to ff820a/ff8260 is made (plus some other updates at end of hbl/vbl)
Thanks - yes I remember when we talked about STE switches this summer you mentioned wanting to have another go at video.c :) I'll concede that there are two aspects in play - one being able to as accurately as possible emulate (to the border of simulating) the real hardware - and the other being able to implement something that works in realtime on suitable hardware at each point in time. The second goal post is always in motion - the first is pretty much stable.

Another good reason for separating this into two activities would be that FPGA implementations like Suska and MiST and high level emulation on computer platforms differ vastly in what's an efficient implementation path.

So, I think it'll be a worthwhile activity to keep documenting the workings of the hardware with pseudo state machine notation and then optimize those implementations for target platforms. In this specific case the loop even needs to run every 2 cycles - something I know emulators aren't currently.

With that said. From the above state machines we should create the DE signal, add Dio's measurements of DE-to-LOAD and then the Shifter register behaviour as described by Alien (which seems complete). This will give us the correct starting positions of the screen (including wakestate differences) as well as, I believe, sync scrolling due to the fact that we'll keep track of when the Shifter's registers are fully read and it starts to display data. I even think that's enough for emulators to be able to start emulating "unstable sync scroll combinations" :)

I haven't written the pseudo code for the above yet - I'm somewhat sure of the previous pseudo code - but everything below should be seen as a thought experiment. I'd love input on it.

My thoughts got stuck on how come signal H is activated on cycle 56 in PAL yet Steven wrote that that's where the screen starts displaying. There should be DE-to-LOAD for the different wakestates and then 16 cycles of LOAD before the Shifter starts displaying something* so there are obviously a few things I need to wrap my head around first. There's also a delay from frequency changes in the Shifter to when those hit GLUE (controls DE) which is either 0 or 2 depending on wakestate .. I think.

My incomplete train of thought was, for WS4:
DE activate on cycle 6, add DE-to-LOAD 4, add LOAD 16 -> Left border screen position should be cycle 26.
DE activate on cycle 54, DL4, LOAD 16 -> 56/162/206 line screen start position 74.
DE activate on cycle 58, DL4, LOAD 16 -> PAL 160 line screen start position 78.

/Troed

*) Alien: "In the usual non-overscan scenario, DE is activated and disactivated 16 pixels before and after each line of the useable screen."
User avatar
npomarede
Atari God
Atari God
Posts: 1558
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: horizontal scrolling on ST

Post by npomarede »

troed wrote: My incomplete train of thought was, for WS4:
DE activate on cycle 6, add DE-to-LOAD 4, add LOAD 16 -> Left border screen position should be cycle 26.
DE activate on cycle 54, DL4, LOAD 16 -> 56/162/206 line screen start position 74.
DE activate on cycle 58, DL4, LOAD 16 -> PAL 160 line screen start position 78.
Are you sure ? On a normal 160 bytes PAL lines, 1st displayed pixel is on cycle 56, not around 78. So for me, screen start position is 56 and load from memory to shifter needs to be done at least 16 cycles before, ie DE activates at or before cycle 40.

Nicolas
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

npomarede wrote: Are you sure ? On a normal 160 bytes PAL lines, 1st displayed pixel is on cycle 56, not around 78. So for me, screen start position is 56 and load from memory to shifter needs to be done at least 16 cycles before, ie DE activates at or before cycle 40.
No ;) Thus the "incomplete-got-stuck" disclaimer - something is wrong with my model when it tries to incorporate DLx and LOAD. What I'm trying to do is making sense of Alien's articles, Dio's measurements and Paolo's Excel sheet and produce state machines that function according to those descriptions and produces the expected output for the different wakestates :P

For reference, GLUE creating DL, BLANK etc:
http://alive.atari.org/alive9/ovrscn1.php
DE from signal H:
http://alive.atari.org/alive11/oscan2a.php

So, if signal H (thus DE) is activated at cycle 56, there's no time for a DL-to-LOAD delay nor LOAD itself if the screen also starts at cycle 56. The other option* is that DE (thus LOAD) is activated at or before cycle 40 - but how can we then change starting positions by manipulating signal H with a frequency switch at cycle 52/56? That's what I don't get my head around atm.

I'm guessing Dio might have relevant input from his measuring here.

*) A third option is that DE is activated decoupled from when the Shifter considers it's time to start displaying the screen. That would be a very interesting outcome but it's more likely there's a simple solution I just don't see atm.
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

The basic output path of the Shifter is almost certainly pretty simple:
- it has a shift register which runs continuously
- data is loaded into that from the staging registers when they are full (this is almost certainly a huge simplification, there are details here we don't quite understand)
- The data gets shifted out; once it's all gone, everything is colour 0 again (i.e. the border colour).

So the Shifter starts outputting data after it receives 4 /LOAD signals from MMU, plus possibly up to a few cycles of latency for the transfer and / or any output pipelining (e.g. for the colour lookup). In my emulator I measure DE to visible pixel as a 19 cycle latency to make Spectrum 512 work right, but it's possible that the extra 3 cycles are due to the timing of the colour register write being rounded down to the nearest 4-clock boundary. Therefore I think the 'extra' latency might be zero, which implies that there are only 3 staging registers, and the 4th LOAD writes the shift register directly. Or it could be 1 - which might mean an extra staging reg, or might mean a single cycle on output of the shift reg, either in a latch there or after the colour lookup.

Although the Shifter sees DE, I don't know why, it doesn't seem necessary for me. One possibility is that it's used to manage the border in 70Hz. Another is that it forms part of the Shifter's reset condition (it may explain why the DL6 case won't hold a single word in the shifter over line end, for example).

What I need to do next is write a test that will probe exactly how the H counter works, by simply flipping from one resolution to another at a given cycle on the line and seeing what that does to the following timing. That hopefully will give much better insight as to how the counter behaves.
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

(This post is of the speculative kind)
Dio wrote:In my emulator I measure DE to visible pixel as a 19 cycle latency to make Spectrum 512 work right
Alright, let's speculate a bit :) I believe Alien was correct in that there's a signal H that decides when the screen should start to display - but it doesn't seem possible that it's used to create DE due to there simply being no time for the Shifter to start receiving the data that should be shown.

If we count backwards from cycle 52, around 19 cycles, we end up at one the interesting locations in Paolo's Excel sheet. There are a few of those, and they're usually identified by "first possible move back" or similar comments. I used those to create the state machines for 8260 and 820a above, and I think they're pretty much correct. This location I had marked, in parentheses, as:

(32 IF(RES == HI) LINE = HIRES // todo, there must be a matching position for LORES, if it isn't default)

The reason for the parenthesis was that I wasn't really sure what happens there. It's the position separating a normal opened left border and the 14 byte line - which we know thanks to your probing distorts sync. I speculated that it's because if 8260 is HI res at that precise moment the decision is taken to use 71Hz timing for the line*. If not, the line defaults (?) to low/mid res timing.

My speculation could of course be off. Maybe it's related to DE instead.

However. Let's say we open the left border - a decision taken at cycle 6 (on ST). How can it start displaying pixels immediately (actually, where DOES it start?) if we need ~20 cycles to load up the Shifter?

So, when I keep subtracting I end up at the end of the previous line - where we have "No Line 1" and "No Line 2" in Paolo's document. I'm guessing those are BLANK locations, and by poking them it's possible to extend BLANK for the whole next line.

Being able to disturb DE should produce a 0-byte line** - and it might even be pretty blank. There is one such position - and now we're back to cycle 32 again. Being in HI res there seems to cause something I would expect a cancelled DE to result in. For a normal PAL or NTSC 160 that seems fine timing wise.
Although the Shifter sees DE, I don't know why, it doesn't seem necessary for me. One possibility is that it's used to manage the border in 70Hz. Another is that it forms part of the Shifter's reset condition (it may explain why the DL6 case won't hold a single word in the shifter over line end, for example).
(FYI, for one subsequent line it's possible to skew the Shifter even in DL6 - however - on the next line it will have corrected itself)
troed wrote:There's also a delay from frequency changes in the Shifter to when those hit GLUE (controls DE) which is either 0 or 2 depending on wakestate .. I think.
To get back to this: Opening the right border by poking 8260 is done at cycle 376 in WS1, 378 in WS3/4 and 380 in WS2. Opening the right border is done by poking 820a 376 in WS1/WS3, 378 in WS2/WS4.

We see the same with "the good" 0-byte line, it can be produced with 8260 at 56 in WS1, 58 in WS3/4 and 60 in WS2. It's done with 820a at cycle 56 in WS1/WS3, 58 in WS2/WS4.

Thus, for states which can be effected by both chips there's a wakestate dependent lag from Shifter to GLUE:

WS1 (DL6): 0 cycles lag
WS4 (DL4): 0 cycles lag
WS3 (DL5): 2 cycles lag
WS2 (DL3): 2 cycles lag

Just an observation, I don't know what if anything it could influence.

/Troed

*) And if switched back to 0 before cycle 56 the GLUE will end up being extremely confused - it had decided the line was started and with HIRES timings - and now finds itself claiming it should start a LORES line. I believe the 14 byte line is an artefact of an "unreachable" state being set that is then the reason for the long HSYNC Dio measured (which aborts any further LOAD - thus 14 bytes).

**) Different from the 0-byte line caused by making sure no line start condition is ever met
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

I don't think it tells the Shifter when to display. It tells MMU when to start sending data to Shifter. That's all the timing that's needed, because Shifter just reacts to the data it's given.
troed wrote:And if switched back to 0 before cycle 56 the GLUE will end up being extremely confused - it had decided the line was started and with HIRES timings - and now finds itself claiming it should start a LORES line. I believe the 14 byte line is an artefact of an "unreachable" state being set that is then the reason for the long HSYNC Dio measured (which aborts any further LOAD - thus 14 bytes).
Yeah. I'm trying to shed light on something in theory simple: "What's the reset condition for the counter"? This is particularly interesting when thinking about 70Hz, where the counter only has 224/4 values rather than 512/4. But there doesn't appear to be anywhere where having the counter briefly in the 'wrong' state causes a 224 byte line. However, having it briefly in 60Hz does appear to (later) cause the line to be the 'wrong' length.

I think I should be able to test that, by scanning a line, switching the timing and watching what happens. (However, it does rely on being able to reset the shifter into a sane state, in order that it's repeatable). But it's questions like "At some point in the line, switching must cause the line to reset, but what?"

And that then leads on to questions like "What could go wrong when the counter is outside the range that it expects during a 70Hz line"?

I think the bad 14 line proves that there's multiple different hsync conditions going on in there though, since you can start two hsyncs per line.
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Dio wrote:I don't think it tells the Shifter when to display. It tells MMU when to start sending data to Shifter. That's all the timing that's needed, because Shifter just reacts to the data it's given.
Of course, but, poking the Shifter (820a) at cycle 52 will produce an NTSC starting position instead of PAL - and if the actual pixels also are displayed at cycle 52 (and 56 respectively) then I can't imagine how there would be time for anything else to be involved.

So, if Alien's wrong about signal H being combined with V to produce DE then at least there's an earlier DE sent to the MMU (thanks) which loads up the Shifter in advance and _then_ signal H (state machine boundary condition) will cause pixels to be displayed.

How this explains there being a good 0-byte line being possible at cycle 56 in the Shifter and 58 in GLUE I'm less sure of though. It's as if some decisions are taken by the Shifter alone and some are deferred (with a 0 or 2 cycle delay) to GLUE. I also don't see how a PAL line 160 with pixels starting at 56 can become a 0-byte line by anything that happens at cycle 58 (GLUE) ..

I feel like there's something obvious regarding switch cycle positions and where pixels start to be displayed I don't understand here.
Yeah. I'm trying to shed light on something in theory simple: "What's the reset condition for the counter"? This is particularly interesting when thinking about 70Hz, where the counter only has 224/4 values rather than 512/4. But there doesn't appear to be anywhere where having the counter briefly in the 'wrong' state causes a 224 byte line. However, having it briefly in 60Hz does appear to (later) cause the line to be the 'wrong' length.
Cycle 32 looked to me to be such a place, however, the 14 byte line is due to switching back again and thus it triggers more states that are impossible for a 71Hz line. This doesn't happen with the position for 508 cycles (well, it seems inverted, there's one for 512) because it's so close to line start that there will be nothing else that can be switched back to.

(I'm not sure that hypothesis was easy to follow, sorry, it's based off the state machines for 8260 and 820a I posted above)
I think the bad 14 line proves that there's multiple different hsync conditions going on in there though, since you can start two hsyncs per line.
Alien claims that when stopping a low res line with the 71Hz line boundary (54/56/80 byte lines) condition you shouldn't stay in 71Hz long because "one has to quickly return to low or medium resolution to avoid causing an Hsync and a new line.". If we now look at the ancient 80-byte line I kept in LoSTE it indeeds stays in 71Hz for a very long time (see Steven's question to me earlier, with timings) but I know of no sync problems or double lines caused by it. I think Alien's wrong here :P It's a state machine - it's not "in" 71Hz, the line (and counter) is still 512 cycles.

It's much more obvious why it happens in the 14 byte line case because it switches back early enough.

Finding a place to cause a 224/4 counter would indeed be very interesting - although I'm guessing it would initially cause the exact same 54 and maybe 80 byte lengths as by using the end condition alone. Being able to _skip_ a subsequent HBL and HSYNC and only create yet another line of that length - on the same displayed line - however. It would involve very detailed knowledge about exactly at which all cycles the different BLANK and HSYNC intervals are.

The best description of those that I have are yours - did you make pictures as well? I'd like to be able to assign cause to "No Line 1", "No Line 2" and both "Just Blank" (8260 and 820a).

/Troed
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

troed wrote:Of course, but, poking the Shifter (820a) at cycle 52 will produce an NTSC starting position instead of PAL - and if the actual pixels also are displayed at cycle 52 (and 56 respectively) then I can't imagine how there would be time for anything else to be involved.
They're not. They appear on the monitor 16-19 cycles after that, it's the latency you have to program into an emulator to make Spectrum 512 work.

I've got all the pngs and the logic traces but I need to find time to put them on the net somewhere :) .
mc6809e
Captain Atari
Captain Atari
Posts: 159
Joined: Sun Jan 29, 2012 10:22 pm

Re: horizontal scrolling on ST

Post by mc6809e »

Dio wrote:
troed wrote:Of course, but, poking the Shifter (820a) at cycle 52 will produce an NTSC starting position instead of PAL - and if the actual pixels also are displayed at cycle 52 (and 56 respectively) then I can't imagine how there would be time for anything else to be involved.
They're not. They appear on the monitor 16-19 cycles after that, it's the latency you have to program into an emulator to make Spectrum 512 work.

I've got all the pngs and the logic traces but I need to find time to put them on the net somewhere :) .
Oh boy oh boy oh boy!

I've been Jonesin' for traces since I gave up my old LeCroy. (They've even got a 100 GHz scope now.)
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Dio wrote:They're not. They appear on the monitor 16-19 cycles after that, it's the latency you have to program into an emulator to make Spectrum 512 work.

I've got all the pngs and the logic traces but I need to find time to put them on the net somewhere :) .
Perfect - thanks! So, just to be clear, the DE-to-LOAD you've measured (DL3-DL6) gets swallowed up there as well?

As for _where_ - just open an account at Dropbox, or Wuala, or .. anywhere :D
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

Good point - the DE to load latency must shift the timing slightly (after all, it's visible on the monitor).

I have plenty of webspace. I just need to get organised :) .
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

OK, blizzard of diagrams. Note that these are mostly captured at a quite heavily quantised sampling rate - for example, in the DE to screen latency capture it's 20MS/S so there's 50ns quantisation, hence why the 8MHz clock looks ropy as hell and signals which should be nominally pretty simultaneous shuffle about a bit:

50Hz video vertical timing:
Image

50Hz video DE to load to display latency:
Image

Normal 160-byte PAL line:
Image

0-byte line:
Image

54-byte line:
Image

80-byte line:
Image

158-byte line:
Image

The faulty 14-byte line:
Image

If anyone wants the actual logic traces to zoom around in I can supply them.
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Dio wrote:OK, blizzard of diagrams.
THANK YOU!! :D

Revised state machine hypotheses coming up when I've had the opportunity to take a detailed look incl. some pixel counting (which they are detailed enough for - excellent).
Dio
Captain Atari
Captain Atari
Posts: 451
Joined: Thu Feb 28, 2008 3:51 pm

Re: horizontal scrolling on ST

Post by Dio »

If you really want to get that detailed I can give you a zip of all the traces, which you can load into the software even without the OLS board...?
User avatar
troed
Atari God
Atari God
Posts: 1799
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: horizontal scrolling on ST

Post by troed »

Dio wrote:If you really want to get that detailed I can give you a zip of all the traces, which you can load into the software even without the OLS board...?
Well more information is seldom worse, I assume others are interested as well, although for the moment I think there's a lot I can gain from these. What I did just now was to overlay the 14 byte line on top of both 160 and 80 to see where the differences are. The description you wrote earlier in this thread actually seems to lack one interesting tidbit - BLANK is shorter on 14 than on the others and is thus an earlier "oddity" compared to the second HSYNC.

(I also did a quick cycle count of DE to screen and it looked to be 6 cycles DE-to-LOAD, 16 cycles LOAD and 2 cycles latency until color change. Does it look reasonable to you?)

Many thanks for creating these :)

Return to “Coding”